From d24fe97bf9a1614acf4e7431d17b762a73642e15 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sun, 13 Oct 2019 12:35:39 +0200 Subject: Rename --- 0.4.15/hardening-patch-4.4.2-0.4.15.patch | 9419 +++++++++++++++++++++++++++ 0.4.15/hardening-patch-4.4.3-0.4.15.patch | 8957 ++++++++++++++++++++++++++ 0.4.15/hardening-patch-4.4.4-0.4.15.patch | 8300 ++++++++++++++++++++++++ 0.4.15/hardening-patch-5.1.4-0.4.15.patch | 9802 +++++++++++++++++++++++++++++ 0.4.15/hardening-patch-5.1.5-0.4.15.patch | 8817 ++++++++++++++++++++++++++ 0.4.15/hardening-patch-5.1.6-0.4.15.patch | 8759 ++++++++++++++++++++++++++ hardening-patch-4.4.2-0.4.15.patch | 9419 --------------------------- hardening-patch-4.4.3-0.4.15.patch | 8957 -------------------------- hardening-patch-4.4.4-0.4.15.patch | 8300 ------------------------ hardening-patch-5.1.4-0.4.15.patch | 9802 ----------------------------- hardening-patch-5.1.5-0.4.15.patch | 8817 -------------------------- hardening-patch-5.1.6-0.4.15.patch | 8759 -------------------------- 12 files changed, 54054 insertions(+), 54054 deletions(-) create mode 100644 0.4.15/hardening-patch-4.4.2-0.4.15.patch create mode 100644 0.4.15/hardening-patch-4.4.3-0.4.15.patch create mode 100644 0.4.15/hardening-patch-4.4.4-0.4.15.patch create mode 100644 0.4.15/hardening-patch-5.1.4-0.4.15.patch create mode 100644 0.4.15/hardening-patch-5.1.5-0.4.15.patch create mode 100644 0.4.15/hardening-patch-5.1.6-0.4.15.patch delete mode 100644 hardening-patch-4.4.2-0.4.15.patch delete mode 100644 hardening-patch-4.4.3-0.4.15.patch delete mode 100644 hardening-patch-4.4.4-0.4.15.patch delete mode 100644 hardening-patch-5.1.4-0.4.15.patch delete mode 100644 hardening-patch-5.1.5-0.4.15.patch delete mode 100644 hardening-patch-5.1.6-0.4.15.patch diff --git a/0.4.15/hardening-patch-4.4.2-0.4.15.patch b/0.4.15/hardening-patch-4.4.2-0.4.15.patch new file mode 100644 index 0000000..206dcfa --- /dev/null +++ b/0.4.15/hardening-patch-4.4.2-0.4.15.patch @@ -0,0 +1,9419 @@ +diff -Nura php-4.4.2/Changelog.hphp hardening-patch-4.4.2-0.4.15/Changelog.hphp +--- php-4.4.2/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Changelog.hphp 2006-09-07 19:33:12.000000000 +0200 +@@ -0,0 +1,61 @@ ++Changelog of the Hardening-Patch ++-------------------------------- ++ ++0.4.15 - 07. September 2006 ++ ++ PHP4: ++ [+] Fix for potential DOS in handling of include blacklists ++ ++ PHP4+5: ++ [+] Backported a fix for open_basedir problems with insanse PHP scripts ++ [+] Added a fix for ini_restore() PHP security vulnerability ++ ++0.4.14 - 11. August 2006 ++ ++ PHP4: ++ [+] Remove unecessary call to AC_BROKEN_REALPATH ++ ++ PHP5: ++ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant ++ ++ PHP4+5: ++ [+] Added a few PHP security fixes / see changelog.secfix for details ++ [+] Fixed the memory_limit protection for systems with different perdir memory_limits ++ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments ++ ++0.4.13 - 07. August 2006 ++ ++ PHP4+5: ++ [+] Added a fix for a compile problem on solaris due to missing strcasestr() ++ ++0.4.12 - 19. July 2006 ++ ++ PHP4: ++ [+] Added fixes from sf4 security patch / see changelog.secfix for details ++ ++ PHP5: ++ [+] Added fixes from sf5 security patch / see changelog.secfix for details ++ ++ PHP4+5: ++ [+] Added anti mail spam feature ++ [+] Speedup of zend_hash canary (clear/destroy) ++ [+] Added a fix for a DOS in the handling of URL blacklists ++ ++0.4.11 - 13. May 2006 ++ ++ PHP5: ++ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache ++ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 ++ ++ PHP4+5: ++ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories ++ ++ ++0.4.10 - 11. May 2006 ++ ++ PHP4: ++ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed ++ ++ PHP4+5: ++ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir ++ +diff -Nura php-4.4.2/Changelog.secfix hardening-patch-4.4.2-0.4.15/Changelog.secfix +--- php-4.4.2/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Changelog.secfix 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,38 @@ ++Changelog of PHP 4.4.2 Security Fixes ++ ++Release 5 - 11. August 2006 ++ ++ [+] Added IMAP open_basedir/safe_mode check ++ [+] Added a upstream fix for previous ext/session fixes ++ [+] Added upstream fix to ext/socket ++ [+] Added sscanf() security fix ++ [+] Added fixes for handling of corrupt .gif files to gdlib ++ ++Release 4 - 13. July 2006 ++ ++ [+] Added recursive array printing fix to phpinfo() XSS fix ++ ++Release 3 - 08. July 2006 ++ ++ [+] Added a fix for an overflow in the bundled libmysql on win32 systems ++ [+] Added a fix for overlong tempfilename ++ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl ++ [+] Added a fix for an integer overflow in str_repeat() ++ [+] Added a variable initialisation in stream factory code ++ [+] Added a fix for crashbugs in http_fopen_wrapper ++ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability ++ [+] Added a *working* wordwrap() fix ++ [+] Added code to make memory_limit work on 64bit systems ++ [+] Added bufferoverflow and high character fix to ext/wddx ++ ++Release 2 - 10. May 2006 ++ ++ [+] Added a fix for the serious zend_hash_del() vulnerability ++ [+] Added a fix for another ext/curl open_basedir/safe_mode bypass vulnerability ++ [+] Added a wordwrap() bufferoverflow fix ++ [+] Added a phpinfo() XSS fix ++ [+] Added html_entity_decode() binary safety fix ++ [+] Added safe_mode/open_basedir fixes to tempnam() and copy() ++ [+] Added check for invalid characters in session identifiers to ext/session ++ [+] Added a fix for a double file unlink in ext/session ++ +diff -Nura php-4.4.2/configure hardening-patch-4.4.2-0.4.15/configure +--- php-4.4.2/configure 2006-01-12 19:24:23.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/configure 2006-09-05 20:30:33.000000000 +0200 +@@ -402,6 +402,16 @@ + ac_default_prefix=/usr/local + # Any additions from configure.in: + ac_help="$ac_help ++ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." ++ac_help="$ac_help ++ --disable-hardening-patch-ll-protect Disable the Linked List protection." ++ac_help="$ac_help ++ --disable-hardening-patch-inc-protect Disable include/require protection." ++ac_help="$ac_help ++ --disable-hardening-patch-fmt-protect Disable format string protection." ++ac_help="$ac_help ++ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." ++ac_help="$ac_help + + SAPI modules: + " +@@ -854,6 +864,8 @@ + ac_help="$ac_help + --disable-tokenizer Disable tokenizer support" + ac_help="$ac_help ++ --disable-varfilter Disable Hardening-Patch's variable filter" ++ac_help="$ac_help + --enable-wddx Enable WDDX support." + ac_help="$ac_help + --disable-xml Disable XML support using bundled expat lib" +@@ -2942,6 +2954,157 @@ + + + ++# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. ++if test "${enable_hardening_patch_mm_protect+set}" = set; then ++ enableval="$enable_hardening_patch_mm_protect" ++ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. ++if test "${enable_hardening_patch_ll_protect+set}" = set; then ++ enableval="$enable_hardening_patch_ll_protect" ++ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. ++if test "${enable_hardening_patch_inc_protect+set}" = set; then ++ enableval="$enable_hardening_patch_inc_protect" ++ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. ++if test "${enable_hardening_patch_fmt_protect+set}" = set; then ++ enableval="$enable_hardening_patch_fmt_protect" ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. ++if test "${enable_hardening_patch_hash_protect+set}" = set; then ++ enableval="$enable_hardening_patch_hash_protect" ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++ ++fi ++ ++ ++echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 ++echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 ++echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 ++echo "configure:2733: checking whether to protect include/require statements" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect PHP Format String functions" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 ++ ++ ++cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH 1 ++EOF ++ ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 0 ++EOF ++ ++fi + + + +@@ -16017,6 +16180,62 @@ + fi + + ++ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 ++echo "configure:14928: checking whether realpath is broken" >&5 ++if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then ++ echo $ac_n "(cached) $ac_c" 1>&6 ++else ++ ++ if test "$cross_compiling" = yes; then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -fr conftest* ++ ++ ac_cv_broken_realpath=yes ++ ++fi ++rm -fr conftest* ++fi ++ ++ ++fi ++ ++echo "$ac_t""$ac_cv_broken_realpath" 1>&6 ++ if test "$ac_cv_broken_realpath" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 1 ++EOF ++ ++ else ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 0 ++EOF ++ ++ fi ++ ++ + echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 + echo "configure:16022: checking for declared timezone" >&5 + if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then +@@ -86718,7 +86937,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + cat >> confdefs.h <&6 ++echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 ++# Check whether --enable-varfilter or --disable-varfilter was given. ++if test "${enable_varfilter+set}" = set; then ++ enableval="$enable_varfilter" ++ PHP_VARFILTER=$enableval ++else ++ ++ PHP_VARFILTER=yes ++ ++ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then ++ PHP_VARFILTER=$PHP_ENABLE_ALL ++ fi ++ ++fi ++ ++ ++ ++ext_output="yes, shared" ++ext_shared=yes ++case $PHP_VARFILTER in ++shared,*) ++ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` ++ ;; ++shared) ++ PHP_VARFILTER=yes ++ ;; ++no) ++ ext_output=no ++ ext_shared=no ++ ;; ++*) ++ ext_output=yes ++ ext_shared=no ++ ;; ++esac ++ ++ ++ ++echo "$ac_t""$ext_output" 1>&6 ++ ++ ++ ++ ++if test "$PHP_VARFILTER" != "no"; then ++ cat >> confdefs.h <<\EOF ++#define HAVE_VARFILTER 1 ++EOF ++ ++ ++ ext_builddir=ext/varfilter ++ ext_srcdir=$abs_srcdir/ext/varfilter ++ ++ ac_extra= ++ ++ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then ++ ++ ++ ++ case ext/varfilter in ++ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; ++ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; ++ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; ++ esac ++ ++ ++ ++ b_c_pre=$php_c_pre ++ b_cxx_pre=$php_cxx_pre ++ b_c_meta=$php_c_meta ++ b_cxx_meta=$php_cxx_meta ++ b_c_post=$php_c_post ++ b_cxx_post=$php_cxx_post ++ b_lo=$php_lo ++ ++ ++ old_IFS=$IFS ++ for ac_src in varfilter.c; do ++ ++ IFS=. ++ set $ac_src ++ ac_obj=$1 ++ IFS=$old_IFS ++ ++ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" ++ ++ case $ac_src in ++ *.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" ;; ++ *.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" ;; ++ esac ++ ++ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 +@@ -104088,7 +104566,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + streams.c network.c php_open_temporary_file.c php_logos.c \ +- output.c memory_streams.c user_streams.c; do ++ output.c memory_streams.c user_streams.c hardening_patch.c; do + + IFS=. + set $ac_src +@@ -104273,7 +104751,7 @@ + zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ +- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do ++ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do + + IFS=. + set $ac_src +diff -Nura php-4.4.2/configure.in hardening-patch-4.4.2-0.4.15/configure.in +--- php-4.4.2/configure.in 2006-01-12 18:52:29.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/configure.in 2006-09-05 20:30:33.000000000 +0200 +@@ -247,7 +247,7 @@ + sinclude(Zend/acinclude.m4) + sinclude(Zend/Zend.m4) + sinclude(TSRM/tsrm.m4) +- ++sinclude(main/hardening_patch.m4) + + + divert(2) +@@ -621,6 +621,7 @@ + AC_FUNC_ALLOCA + dnl PHP_AC_BROKEN_SPRINTF + dnl PHP_AC_BROKEN_SNPRINTF ++dnl PHP_AC_BROKEN_REALPATH + PHP_DECLARED_TIMEZONE + PHP_TIME_R_TYPE + PHP_READDIR_R_TYPE +@@ -1260,7 +1261,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + streams.c network.c php_open_temporary_file.c php_logos.c \ +- output.c memory_streams.c user_streams.c) ++ output.c memory_streams.c user_streams.c hardening_patch.c) + PHP_ADD_SOURCES(/main, internal_functions.c,, sapi) + case $host_alias in + *netware*) +@@ -1281,7 +1282,7 @@ + zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ +- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c) ++ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c ) + + if test -r "$abs_srcdir/Zend/zend_objects.c"; then + PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c) +diff -Nura php-4.4.2/ext/curl/curl.c hardening-patch-4.4.2-0.4.15/ext/curl/curl.c +--- php-4.4.2/ext/curl/curl.c 2006-01-05 19:03:18.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/curl/curl.c 2006-09-05 20:30:33.000000000 +0200 +@@ -87,6 +87,7 @@ + #define SMART_STR_PREALLOC 4096 + + #include "ext/standard/php_smart_str.h" ++#include "ext/standard/php_string.h" + #include "ext/standard/info.h" + #include "ext/standard/file.h" + #include "ext/standard/url.h" +@@ -111,7 +112,7 @@ + + #define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \ + if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \ +- strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \ ++ strncasecmp(str, "file:", sizeof("file:") - 1) == 0) \ + { \ + php_url *tmp_url; \ + \ +@@ -119,6 +120,11 @@ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid url '%s'", str); \ + RETURN_FALSE; \ + } \ ++ \ ++ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ ++ RETURN_FALSE; \ ++ } \ + \ + if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ + (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ +@@ -839,7 +845,6 @@ + case CURLOPT_FTPLISTONLY: + case CURLOPT_FTPAPPEND: + case CURLOPT_NETRC: +- case CURLOPT_FOLLOWLOCATION: + case CURLOPT_PUT: + #if CURLOPT_MUTE != 0 + case CURLOPT_MUTE: +@@ -876,6 +881,16 @@ + convert_to_long_ex(zvalue); + error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); + break; ++ case CURLOPT_FOLLOWLOCATION: ++ convert_to_long_ex(zvalue); ++ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ++ if (Z_LVAL_PP(zvalue) != 0) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set"); ++ RETURN_FALSE; ++ } ++ } ++ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); ++ break; + case CURLOPT_URL: + case CURLOPT_PROXY: + case CURLOPT_USERPWD: +diff -Nura php-4.4.2/ext/curl/curlstreams.c hardening-patch-4.4.2-0.4.15/ext/curl/curlstreams.c +--- php-4.4.2/ext/curl/curlstreams.c 2006-01-01 14:46:50.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/curl/curlstreams.c 2006-09-05 20:30:33.000000000 +0200 +@@ -297,7 +297,11 @@ + curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream); + + /* currently buggy (bug is in curl) */ +- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); ++ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ++ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); ++ } else { ++ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); ++ } + + curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr); + curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0); +diff -Nura php-4.4.2/ext/fbsql/php_fbsql.c hardening-patch-4.4.2-0.4.15/ext/fbsql/php_fbsql.c +--- php-4.4.2/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1797,8 +1797,24 @@ + } + else if (fbcmdErrorsFound(md)) + { ++#if HARDENING_PATCH ++ char* query_copy; ++ int i; ++#endif + FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); + char* emg = fbcemdAllErrorMessages(emd); ++#if HARDENING_PATCH ++ query_copy=estrdup(query_copy); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ free(emg); ++ fbcemdRelease(emd); ++ result = 0; ++ zend_bailout(); ++ } ++#endif + if (FB_SQL_G(generateWarnings)) + { + if (emg) +diff -Nura php-4.4.2/ext/gd/libgd/gd_gif_in.c hardening-patch-4.4.2-0.4.15/ext/gd/libgd/gd_gif_in.c +--- php-4.4.2/ext/gd/libgd/gd_gif_in.c 2005-09-25 14:13:49.000000000 +0200 ++++ hardening-patch-4.4.2-0.4.15/ext/gd/libgd/gd_gif_in.c 2006-09-05 20:30:33.000000000 +0200 +@@ -212,6 +212,12 @@ + if (!im) { + return 0; + } ++ ++ if (!im->colorsTotal) { ++ gdImageDestroy(im); ++ return 0; ++ } ++ + /* Check for open colors at the end, so + we can reduce colorsTotal and ultimately + BitsPerPixel */ +@@ -502,6 +508,19 @@ + int v; + int xpos = 0, ypos = 0, pass = 0; + int i; ++ ++ /* ++ ** Initialize the Compression routines ++ */ ++ if (! ReadOK(fd,&c,1)) { ++ return; ++ } ++ ++ if (c > MAX_LWZ_BITS) { ++ return; ++ } ++ ++ + /* Stash the color map into the image */ + for (i=0; (ired[i] = cmap[CM_RED][i]; +@@ -511,12 +530,7 @@ + } + /* Many (perhaps most) of these colors will remain marked open. */ + im->colorsTotal = gdMaxColors; +- /* +- ** Initialize the Compression routines +- */ +- if (! ReadOK(fd,&c,1)) { +- return; +- } ++ + if (LWZReadByte(fd, TRUE, c) < 0) { + return; + } +diff -Nura php-4.4.2/ext/gd/tests/bug38112.gif hardening-patch-4.4.2-0.4.15/ext/gd/tests/bug38112.gif +--- php-4.4.2/ext/gd/tests/bug38112.gif 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/gd/tests/bug38112.gif 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,140 @@ ++GIF89a}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M ++ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuutt! NETSCAPE2.0!d,}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M ++ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuuttq]sH6U~F7Jػ|[rEwЫ*4;W(ƺj ++Ȗ֨_x֚hyvVyxc-%Bak(XF(yv aϑ@HZkhڊ'M )Zk[0K\G%y,l [6%F2 >ǾUI?6N>MhغCJ ++JmڶiIeʑ%~!T"2ZU ++禅^@-BAYVY0KTFXLs)rR+0l-BV%UrÜ Jmy@-QYŦm1%ΤOjvr3hm!1`0WDJj%To4Qə%)0 *Ƌ%LTt9sWKș#D(Qѧ_NGPHx#{ ++1He{"˥Z\U+Mf#HPB ++B}1wV$.[zsJ'MN("Os$R'D!EA=#L!`0[S6wL`AxPN* Q+9DŽ"X=R\20Z-ٕ hLRK 8R,QEX:$< ++@p&$ x d\ݵ@HyD5C*sY: ++ auc%l!F!Zr9BH  eP# Q ++!EG}Apk)lĞzZYn,A~*nY( ׌ƨ*1&r\gb*TS%~ZP}DÐhk;`BAkF.g- G!X` DD+8PA\0 ++";_BeI-ൂZ8A6 Mgv͚JG:Rױ` `څ,Ȁ-3bZ5A 7ÈR ++e!0/Jl!@tuACj< P>[[%^:uph ꀄ:`!XY, x/T†{33@46jX`!B0A/h^G) d{c4<J0q+*"ȼZPNaA,7;PHs7x1y 1@XTUnEX"$Q-jJM C@I܀ HD& :d" ++`G*`VgP`CXѰl3_ώ=𙛔f'}K1 F&`GFbL*0ف. @^0d';IPTd0|a˟*R6WpfF&UE_()=pOԻ [KS-Y&KG)$[UB%+Up/*1t5%[¡P ]y^"ZM8uX1Yb}C&mJP W9n2чzjTax9́,8R  Lp ++p"TUf %o,l(kPW$> ;Pp@ ++:>=#^db "Vxq?e+ﶓNCHK؁ ++l"?a @AOK*G:K!ƎƊ'8HB])ƞD?TVp \b1Fᰔ4ӨH7߹"mW~9 E.cM[F/W b׮WƤm335 PssP( TH;cyQr Đ'`1dS(m({frK Me D :  s%x 0' 3cSyp' ++vYao78yd0L zB-I qz=Cy0;9>d=`Fk^0@cƒ9Wpw03 ..@ ++)03f\@@阽 "o9 з l臙 S9gl e+c0S5_G0G9CZ@%P6E9@‖:=lD 03 i3EG0P!d05B#o 919ڐӣP:+WK*_' ++=ß5 &`~S vF= C8 1 sIp#PΖ@p̝X3WA`\=,ࢤT3 ++0l x@@ ++X m 0x茎 ++^qP鸪Epk Y8P0  oXS벎 Hc|i. +l?+\ I@ܐ   lѠ1/=0ݮv@O_n\ݾ@*֖-K ++Ќ g) : \ފ Nm^` h @_RK Z ++Mc5 a ΀ l0x > ? OVG c<^>N` -@`_R Pc@8ofmO?/)@T`r񒰻c^PHM VP{P, c0 ++UiDbb ++ Њ/\mbT]0#U(a0 ++Yij j25_Oߗ?`V{q mysm᮪t1OseXtk~> Q̖ەT;,tؗjzNUHYPIaSsZ*-)6:$NJHP>2Tšd2Z2^Q"XfRrS[p ./4:yd_Z[QP>4HTpwws>ȨNB!s7Q@ ,~G ocC\pC' /%_"RLDvDBK7;13nC}~dkTA  Ê@|3*A2L EA &D;rC2մ!E=a ++7ފSm#HOIC]y3RcorKXO$՚kD +zk#ˀ.ɂ" 7]{tL)[G-w -8E^ۂt@!0#őd ȉ#a"!"$C7 5B fN u&P~ 4 ex|%+փNE["W[(hALv9T0PaG#,?~ r&,Ra$\2љi\,Q3x惆EeVCѶI.CAh$,I%r9lA3)yws8uV`K(Oѭܭ m=Z8ڀ9}1? >)S\zA UV`d`h'57Za| 4_ҧ "blD4]h,PXnfAR"`@؉ ( R.@E4 m8B `m!J}CL np r6]aÞiF(DuB,q8aQrxceO@E`xa yM88(b f\6xE 6AD"r3_N!%(hu:D2I0ґ+4IJZh,@av{8 ++zs-Sqb!Ѕ I,?[:C.`n` @ b@Ϙ6JiJy387X͐t \KS ⴆ+ЇKAPEpP,s{ =eO|^"i;BJ#A9}TchX1qxD$Jno{DK\I2BQ ++?Bf-,6?VS@/B5=V@or ++umD0 %^ vs;DRja kF/vS>ܓ/X5?M+ H#lpH ++Hhwu 3;X+X} 9x!4 $ [uجg7)k08D1-bq@# ~#pacMF=a%9,nWF^|n7._6P0bw/#L!؄z]jj~ԕ_Uz`ЈFCXtI!d,կιǩUXuًȫȣdr*/>ç-Qȫ6AXIRbg *лۭΚʱțyۤsȑ炎ϯ운ΐë›랼ػࢮ柫ֳܐӢȜz;HPҩߟ^hkٟڧԢW^^nqq쮰ɭvzy7D@޹痛خHJ>zilTοȣĘþסϰHp?! OEQ2Zl%*D CII JMD% '>ɳ'Ot+JԪRDV"A|JJU!eC-[֠A4'V V]˶ ʔQLUZ$ ++,%+yռ5+&b!*. #2Ԗk<Bd+է')H]s!zѠ#TT Ÿ \9ViDK/sn ڵ+ z8zdb$ ,,DpJ >Vp:v Tn+M?b׿ gԒL7Ǝ6`2 Q\r, ^rtb+G $ZP3H86hc  hO+&LMp0BG刘XÄsM; g`lӎ)OL)h` }x$g d NCS1,M.#;: qTS©z~&X'|( B1nin&PB ,w\RB3*Ab¶ά`0 A|x!#IrW.fB8D`0 7`> l60 ++R # |ĻRRK-,.@8Ks7HPp hL/C ;|S, \J@^0 =QC&5/1VvD @ќ ? ++=0=G~"Jd[xm 5US! ,7D =| 1C6x(nB|*Mᆧ"!Ik,B+Ov݁Ag08?Km?LfJdL S0_,Ъ>PX ++ĥ'LO~:唑 eBiA,Ε?aKaWO*[(*G-`C8+TP0ZV: q&-,@MY>` 0 ۝$(5gD٪4<0G5!]0Ġ:"08P D>PX)UĀ @{ ++`uXwe`pu !w9Wɶf> Vǀ` -|XFטroi  !"MuP~oƚ5 } OL0&khnk}X ++ JP!D͸" ++@w `|wlوo tls{jmښ5igugLو&GPAř Z5H8v|EH"/,eG  Zz q@ ++` $ ++Pʉ Jn>#RzcPj?Z ` ZVpiC 500}z?i !| Z>==%X1k1 *=YFcT=SE `0((vN mQ;ziPYY+U1v fp0ԝ Н{P 0~ Q5`;|%μʵA ۻ{&ߪ0Xg Fc`NPό>IJR)Іhp@Q-0+sݚ 4f#L&,J ++0 t̆Z@1] [}K} @ ++in`*'` (geWf`0ˌ@g ++ uW͘ P,x- ++ƀWΓ[ˆ -b,i `?{  ++$p ix KA @`Гp݈ɻoSKPѱ=ؙjnDFS/dL$GG@, ++o FO4 ++ ߭4qݩݽ-4M00p ++,k p ++  ++ }0U02ߥ ++ ++Q_P˻Kr@m%fY  P =[Y՗  @ ; VJ@z, xݭ=^ބI,HC ++0 x PJNH*Pt q ++0j>\ڭ u -h *@Ϡ }XQ  ++@ 劮 _^ 6]i~ݞ;`p ,v P  ++R j 0^ h400uR "!`0 ^խuY @ 티 ޾ P߾z@8| ++y ++@5S~ > _nm{ ++n%  훀R H@8 L ++P[Dp'~`EɀV ++%P [ k  ++BLS? ^x! ++dPž_]0O%Udpp & ++jPP& y ++QY ++L0x]- _Qd =h S .> ppS@uk`bQ͏Ⱥyb6,\\ *eR#Y]PR叢:&}4)Dx>TPE- ++!kգ'iɱUp%!e&O ++J.3rϠTɲ̘4 F'OH FlSy@`ҭSh,W,DYDB`9I4FZ8[vK)WiIa Cpbő2m[Yٛg71& yȸE6TPcŴb)1*I^܊\;𞴌pk z FgyXt tl x .aDKJRJi7] Kd?"%21 4o>4@yF:nitx-MDeE1U|/1ы0jizܱBG ,)ďg&n@^|>>J!J`@`R\F9adH X N(>)Er9 "XÏ5@@MW 7Ƌ/@Xj֦HVXT ++f 5>‚qa|e@B ++)ָcK\c pj=E 9(bi|GtcU)=m8cYc>?ذd ++$\>PKreP& 45WL!v(`x?06W,=Qfy ++wB ++aM61 $`.ÎH`H vCjԏ^UjkX%k>f)= 0) X@fo^Jo-(e!ዖM߂{G%lܝayrH<#Lp e#H@EuBqtl/Ekd%]Gs#'>;LЂ(a 8d! w$;x `}R ++L~8 >f?# {8hD#d|%";XCB0~  ą1*l,5P_lYXyr*pz'b$|pEQ ++X@&mX0v` gFIr;F#$y-. ++Qz K(=/yUHMZ(>^s?sE0x84%{D@!KAtXk8 ++H }[)Bb>"G0*tPCE8hQ9xZ(Z# ++~H[Y2x`P?;@5BB*A0kF\2k4̃U}@7C@Z(\!W`x`opGxH:͢)Bp70#_a8CXd dDP;0/C(Gkdl`4 1Ss obX̃kFq?`TȪ8X ++--FILE-- ++ ++--EXPECTF-- ++Warning: imagecreatefromgif() [%s]: '%sbug38112.gif' is not a valid GIF file in %sbug38112.php on line %d +diff -Nura php-4.4.2/ext/imap/php_imap.c hardening-patch-4.4.2-0.4.15/ext/imap/php_imap.c +--- php-4.4.2/ext/imap/php_imap.c 2006-01-05 01:50:19.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/imap/php_imap.c 2006-09-05 20:30:33.000000000 +0200 +@@ -26,7 +26,7 @@ + | PHP 4.0 updates: Zeev Suraski | + +----------------------------------------------------------------------+ + */ +-/* $Id: php_imap.c,v 1.142.2.44.2.4 2006/01/05 00:50:19 iliaa Exp $ */ ++/* $Id: php_imap.c,v 1.142.2.44.2.5 2006/08/04 20:32:44 iliaa Exp $ */ + + #define IMAP41 + +@@ -731,6 +731,13 @@ + efree(IMAPG(imap_password)); + } + ++ /* local filename, need to perform open_basedir and safe_mode checks */ ++ if (Z_STRVAL_PP(mailbox)[0] != '{' && ++ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || ++ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { ++ RETURN_FALSE; ++ } ++ + IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); + IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); + +diff -Nura php-4.4.2/ext/mbstring/mbstring.c hardening-patch-4.4.2-0.4.15/ext/mbstring/mbstring.c +--- php-4.4.2/ext/mbstring/mbstring.c 2006-01-01 14:46:54.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/mbstring/mbstring.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1488,6 +1488,7 @@ + char *strtok_buf = NULL, **val_list; + zval *array_ptr = (zval *) arg; + int n, num, val_len, *len_list; ++ unsigned int new_val_len; + enum mbfl_no_encoding from_encoding; + mbfl_string string, resvar, resval; + mbfl_encoding_detector *identd = NULL; +@@ -1610,8 +1611,14 @@ + val_len = len_list[n]; + } + n++; +- /* add variable to symbol table */ +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ /* we need val to be emalloc()ed */ ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ /* add variable to symbol table */ ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); ++ + if (convd != NULL){ + mbfl_string_clear(&resvar); + mbfl_string_clear(&resval); +diff -Nura php-4.4.2/ext/mysql/libmysql/libmysql.c hardening-patch-4.4.2-0.4.15/ext/mysql/libmysql/libmysql.c +--- php-4.4.2/ext/mysql/libmysql/libmysql.c 2003-07-28 09:28:55.000000000 +0200 ++++ hardening-patch-4.4.2-0.4.15/ext/mysql/libmysql/libmysql.c 2006-09-05 20:30:33.000000000 +0200 +@@ -213,6 +213,10 @@ + if (!host || !strcmp(host,LOCAL_HOST)) + host=LOCAL_HOST_NAMEDPIPE; + ++ if (sizeof(szPipeName) <= (strlen(host) + strlen(unix_socket) + sizeof("\\\\\\pipe\\"))) { ++ return INVALID_HANDLE_VALUE; ++ } ++ + sprintf( szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket); + DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s", + host, unix_socket)); +diff -Nura php-4.4.2/ext/mysql/php_mysql.c hardening-patch-4.4.2-0.4.15/ext/mysql/php_mysql.c +--- php-4.4.2/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1218,6 +1218,8 @@ + { + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; ++ char *copy_query; ++ int i; + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); + +@@ -1268,6 +1270,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #else +@@ -1275,12 +1284,20 @@ + /* check possible error */ + if (MySG(trace_mode)){ + if (mysql_errno(&mysql->conn)){ +- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn)); ++ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #endif ++ + if(use_store == MYSQL_USE_RESULT) { + mysql_result=mysql_use_result(&mysql->conn); + } else { +diff -Nura php-4.4.2/ext/pgsql/pgsql.c hardening-patch-4.4.2-0.4.15/ext/pgsql/pgsql.c +--- php-4.4.2/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1001,10 +1001,28 @@ + case PGRES_EMPTY_QUERY: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: +- case PGRES_FATAL_ERROR: +- PHP_PQ_ERROR("Query failed: %s", pgsql); +- PQclear(pgsql_result); +- RETURN_FALSE; ++ case PGRES_FATAL_ERROR: ++ { ++#if HARDENING_PATCH ++ int i; ++ char *query_copy; ++#endif ++ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); ++ PQclear(pgsql_result); ++#if HARDENING_PATCH ++ query_copy = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ efree(msgbuf); ++ zend_bailout(); ++ } ++#endif ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); ++ efree(msgbuf); ++ RETURN_FALSE; ++ } + break; + case PGRES_COMMAND_OK: /* successful command that did not return rows */ + default: +diff -Nura php-4.4.2/ext/session/mod_files.c hardening-patch-4.4.2-0.4.15/ext/session/mod_files.c +--- php-4.4.2/ext/session/mod_files.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/mod_files.c 2006-09-05 20:30:33.000000000 +0200 +@@ -16,7 +16,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: mod_files.c,v 1.83.2.9.2.2 2006/01/01 13:46:56 sniper Exp $ */ ++/* $Id: mod_files.c,v 1.83.2.9.2.4 2006/08/08 14:57:04 iliaa Exp $ */ + + #include "php.h" + +@@ -364,10 +364,17 @@ + if (!ps_files_path_create(buf, sizeof(buf), data, key)) + return FAILURE; + +- ps_files_close(data); ++ if (data->fd != -1) { ++ ps_files_close(data); + +- if (VCWD_UNLINK(buf) == -1) { +- return FAILURE; ++ if (VCWD_UNLINK(buf) == -1) { ++ /* This is a little safety check for instances when we are dealing with a regenerated session ++ * that was not yet written to disk ++ */ ++ if (!VCWD_ACCESS(buf, F_OK)) { ++ return FAILURE; ++ } ++ } + } + + return SUCCESS; +@@ -389,6 +396,34 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(files) ++{ ++ char buf[MAXPATHLEN]; ++ int fd; ++ PS_FILES_DATA; ++ ++ if (!ps_files_valid_key(key)) { ++ return FAILURE; ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { ++ return FAILURE; ++ } ++ ++ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600); ++ ++ if (fd != -1) { ++ close(fd); ++ return SUCCESS; ++ } ++ ++ return FAILURE; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-4.4.2/ext/session/mod_mm.c hardening-patch-4.4.2-0.4.15/ext/session/mod_mm.c +--- php-4.4.2/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/mod_mm.c 2006-09-05 20:30:33.000000000 +0200 +@@ -425,6 +425,42 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(mm) ++{ ++ PS_MM_DATA; ++ ps_sd *sd; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ } ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ mm_lock(data->mm, MM_LOCK_RD); ++ ++ sd = ps_sd_lookup(data, key, 0); ++ if (sd) { ++ mm_unlock(data->mm); ++ return SUCCESS; ++ } ++ ++ mm_unlock(data->mm); ++ ++ return FAILURE; ++} ++ + #endif + + /* +diff -Nura php-4.4.2/ext/session/mod_user.c hardening-patch-4.4.2-0.4.15/ext/session/mod_user.c +--- php-4.4.2/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/mod_user.c 2006-09-05 20:30:33.000000000 +0200 +@@ -23,7 +23,7 @@ + #include "mod_user.h" + + ps_module ps_mod_user = { +- PS_MOD(user) ++ PS_MOD_SID(user) + }; + + #define SESS_ZVAL_LONG(val, a) \ +@@ -174,6 +174,83 @@ + FINISH; + } + ++PS_CREATE_SID_FUNC(user) ++{ ++ int i; ++ char *val = NULL; ++ zval *retval; ++ ps_user *mdata = PS_GET_MOD_DATA(); ++ ++ if (!mdata) ++ return estrndup("", 0); ++ ++ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { ++ return php_session_create_id(mod_data, newlen TSRMLS_CC); ++ } ++ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); ++ ++ if (retval) { ++ if (Z_TYPE_P(retval) == IS_STRING) { ++ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); ++ } else { ++ val = estrndup("", 0); ++ } ++ zval_ptr_dtor(&retval); ++ } else { ++ val = estrndup("", 0); ++ } ++ ++ return val; ++} ++ ++static int ps_user_valid_key(const char *key TSRMLS_DC) ++{ ++ size_t len; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ ret = FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ ret = FAILURE; ++ ++ return ret; ++} ++ ++PS_VALIDATE_SID_FUNC(user) ++{ ++ zval *args[1]; ++ STDVARS; ++ ++ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { ++ return ps_user_valid_key(key TSRMLS_CC); ++ } ++ SESS_ZVAL_STRING(key, args[0]); ++ ++ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); ++ ++ if (retval) { ++ convert_to_long(retval); ++ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; ++ zval_ptr_dtor(&retval); ++ } ++ ++ return ret; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-4.4.2/ext/session/mod_user.h hardening-patch-4.4.2-0.4.15/ext/session/mod_user.h +--- php-4.4.2/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/mod_user.h 2006-09-05 20:30:33.000000000 +0200 +@@ -22,7 +22,7 @@ + #define MOD_USER_H + + typedef union { +- zval *names[6]; ++ zval *names[8]; + struct { + zval *ps_open; + zval *ps_close; +@@ -30,6 +30,8 @@ + zval *ps_write; + zval *ps_destroy; + zval *ps_gc; ++ zval *ps_create; ++ zval *ps_validate; + } name; + } ps_user; + +diff -Nura php-4.4.2/ext/session/php_session.h hardening-patch-4.4.2-0.4.15/ext/session/php_session.h +--- php-4.4.2/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/php_session.h 2006-09-05 20:30:33.000000000 +0200 +@@ -23,7 +23,7 @@ + + #include "ext/standard/php_var.h" + +-#define PHP_SESSION_API 20020330 ++#define PHP_SESSION_API 20051121 + + #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC + #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC +@@ -32,6 +32,7 @@ + #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC + #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC + #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC ++#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC + + /* default create id function */ + char *php_session_create_id(PS_CREATE_SID_ARGS); +@@ -45,6 +46,7 @@ + int (*s_destroy)(PS_DESTROY_ARGS); + int (*s_gc)(PS_GC_ARGS); + char *(*s_create_sid)(PS_CREATE_SID_ARGS); ++ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); + } ps_module; + + #define PS_GET_MOD_DATA() *mod_data +@@ -57,6 +59,7 @@ + #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) + #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) + #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) ++#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) + + #define PS_FUNCS(x) \ + PS_OPEN_FUNC(x); \ +@@ -65,11 +68,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID_FUNC(x) + + #define PS_MOD(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, php_session_create_id ++ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x + + /* SID enabled module handler definitions */ + #define PS_FUNCS_SID(x) \ +@@ -79,11 +83,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID(x) + + #define PS_MOD_SID(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, ps_create_sid_##x ++ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x + + typedef enum { + php_session_disabled, +@@ -120,6 +125,7 @@ + zend_bool use_only_cookies; + zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ ++ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + int send_cookie; + int define_sid; + } php_ps_globals; +diff -Nura php-4.4.2/ext/session/session.c hardening-patch-4.4.2-0.4.15/ext/session/session.c +--- php-4.4.2/ext/session/session.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/session.c 2006-09-05 20:30:33.000000000 +0200 +@@ -17,7 +17,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: session.c,v 1.336.2.53.2.4 2006/01/01 13:46:56 sniper Exp $ */ ++/* $Id: session.c,v 1.336.2.53.2.5 2006/01/15 16:52:10 iliaa Exp $ */ + + #ifdef HAVE_CONFIG_H + #include "config.h" +@@ -155,6 +155,7 @@ + STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) ++ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals) +@@ -626,6 +627,12 @@ + char *val; + int vallen; + ++ /* check session name for invalid characters */ ++ if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) { ++ efree(PS(id)); ++ PS(id) = NULL; ++ } ++ + if (!PS(mod)) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session."); + return; +@@ -637,6 +644,15 @@ + return; + } + ++ /* If there is an ID, use session module to verify it */ ++ if (PS(id)) { ++ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ efree(PS(id)); ++ PS(id) = NULL; ++ PS(send_cookie) = 1; ++ } ++ } ++ + /* If there is no ID, use session module to create one */ + if (!PS(id)) + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); +@@ -1256,22 +1272,31 @@ + } + /* }}} */ + +-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) ++/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) + Sets user-level functions */ + PHP_FUNCTION(session_set_save_handler) + { +- zval **args[6]; +- int i; ++ zval **args[8]; ++ int i, numargs; + ps_user *mdata; + char *name; + ++ numargs = ZEND_NUM_ARGS(); ++ args[6] = NULL; ++ args[7] = NULL; ++ ++ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) ++ WRONG_PARAM_COUNT; + if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) + WRONG_PARAM_COUNT; + + if (PS(session_status) != php_session_none) + RETURN_FALSE; + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ continue; ++ } + if (!zend_is_callable(*args[i], 0, &name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); + efree(name); +@@ -1284,7 +1309,11 @@ + + mdata = emalloc(sizeof(*mdata)); + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ mdata->names[i] = NULL; ++ continue; ++ } + ZVAL_ADDREF(*args[i]); + mdata->names[i] = *args[i]; + } +@@ -1345,8 +1374,20 @@ + Update the current session id with a newly generated one. */ + PHP_FUNCTION(session_regenerate_id) + { ++ zend_bool del_ses = 0; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) { ++ WRONG_PARAM_COUNT; ++ } ++ + if (PS(session_status) == php_session_active) { +- if (PS(id)) efree(PS(id)); ++ if (PS(id)) { ++ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed"); ++ RETURN_FALSE; ++ } ++ efree(PS(id)); ++ } + + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); + +@@ -1395,8 +1436,8 @@ + WRONG_PARAM_COUNT; + + if (ac == 1) { +- convert_to_long_ex(p_cache_expire); +- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); ++ convert_to_string_ex(p_cache_expire); ++ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + } + + RETVAL_LONG(old); +diff -Nura php-4.4.2/ext/session/tests/014.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/014.phpt +--- php-4.4.2/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:30:33.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.bug_compat_42=1 +diff -Nura php-4.4.2/ext/session/tests/015.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/015.phpt +--- php-4.4.2/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:30:33.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + arg_separator.output=& + session.name=PHPSESSID +diff -Nura php-4.4.2/ext/session/tests/018.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/018.phpt +--- php-4.4.2/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:30:33.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + session.name=PHPSESSID +diff -Nura php-4.4.2/ext/session/tests/020.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/020.phpt +--- php-4.4.2/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:30:33.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + arg_separator.output=& +diff -Nura php-4.4.2/ext/session/tests/021.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/021.phpt +--- php-4.4.2/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:30:33.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" +diff -Nura php-4.4.2/ext/session/tests/bug38377.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/bug38377.phpt +--- php-4.4.2/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++bug #38377 (session_destroy() gives warning after session_regenerate_id()) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECT-- ++Done +diff -Nura php-4.4.2/ext/sockets/sockets.c hardening-patch-4.4.2-0.4.15/ext/sockets/sockets.c +--- php-4.4.2/ext/sockets/sockets.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/sockets/sockets.c 2006-09-05 20:30:33.000000000 +0200 +@@ -19,7 +19,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: sockets.c,v 1.125.2.29.2.3 2006/01/01 13:46:56 sniper Exp $ */ ++/* $Id: sockets.c,v 1.125.2.29.2.6 2006/08/01 12:04:14 tony2001 Exp $ */ + + #ifdef HAVE_CONFIG_H + #include "config.h" +@@ -515,6 +515,7 @@ + int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, SOCKET *max_fd TSRMLS_DC) { + zval **element; + php_socket *php_sock; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -529,9 +530,10 @@ + if (php_sock->bsd_socket > *max_fd) { + *max_fd = php_sock->bsd_socket; + } ++ num++; + } + +- return 1; ++ return num ? 1 : 0; + } + + int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) { +@@ -539,6 +541,8 @@ + zval **dest_element; + php_socket *php_sock; + HashTable *new_hash; ++ int num = 0; ++ + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + + ALLOC_HASHTABLE(new_hash); +@@ -555,6 +559,7 @@ + zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); + if (dest_element) zval_add_ref(dest_element); + } ++ num++; + } + + /* Destroy old array, add new one */ +@@ -564,7 +569,7 @@ + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(sock_array) = new_hash; + +- return 1; ++ return num ? 1 : 0; + } + + +diff -Nura php-4.4.2/ext/standard/array.c hardening-patch-4.4.2-0.4.15/ext/standard/array.c +--- php-4.4.2/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/array.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1162,6 +1162,32 @@ + } + } + } ++ ++ if (var_name[0] == 'H') { ++ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_FILES")==0)|| ++ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { ++ return 0; ++ } ++ } else if (var_name[0] == '_') { ++ if ((strcmp(var_name, "_COOKIE")==0)|| ++ (strcmp(var_name, "_ENV")==0)|| ++ (strcmp(var_name, "_FILES")==0)|| ++ (strcmp(var_name, "_GET")==0)|| ++ (strcmp(var_name, "_POST")==0)|| ++ (strcmp(var_name, "_REQUEST")==0)|| ++ (strcmp(var_name, "_SESSION")==0)|| ++ (strcmp(var_name, "_SERVER")==0)) { ++ return 0; ++ } ++ } else if (strcmp(var_name, "GLOBALS")==0) { ++ return 0; ++ } + + return 1; + } +diff -Nura php-4.4.2/ext/standard/basic_functions.c hardening-patch-4.4.2-0.4.15/ext/standard/basic_functions.c +--- php-4.4.2/ext/standard/basic_functions.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:35:15.000000000 +0200 +@@ -107,12 +107,14 @@ + typedef struct _php_shutdown_function_entry { + zval **arguments; + int arg_count; ++ zend_bool created_by_eval; + } php_shutdown_function_entry; + + typedef struct _user_tick_function_entry { + zval **arguments; + int arg_count; + int calling; ++ zend_bool created_by_eval; + } user_tick_function_entry; + + /* some prototypes for local functions */ +@@ -295,6 +297,8 @@ + PHP_FE(get_html_translation_table, NULL) + PHP_FE(sha1, NULL) + PHP_FE(sha1_file, NULL) ++ PHP_FE(sha256, NULL) ++ PHP_FE(sha256_file, NULL) + PHP_NAMED_FE(md5,php_if_md5, NULL) + PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) + PHP_NAMED_FE(crc32,php_if_crc32, NULL) +@@ -676,7 +680,7 @@ + PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) + + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +- PHP_FE(realpath, NULL) ++ PHP_STATIC_FE("realpath", zif_real_path, NULL) + #endif + + #ifdef HAVE_FNMATCH +@@ -1866,7 +1870,7 @@ + break; + + case 3: /*save to a file */ +- stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); ++ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); + if (!stream) + return FAILURE; + php_stream_write(stream, message, strlen(message)); +@@ -2096,6 +2100,13 @@ + { + zval retval; + char *function_name = NULL; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (shutdown_function_entry->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { + php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); +@@ -2111,6 +2122,9 @@ + if (function_name) { + efree(function_name); + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + return 0; + } + +@@ -2118,6 +2132,13 @@ + { + zval retval; + zval *function = tick_fe->arguments[0]; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (tick_fe->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + /* Prevent reentrant calls to the same user ticks function */ + if (! tick_fe->calling) { +@@ -2149,6 +2170,9 @@ + + tick_fe->calling = 0; + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + } + + static void run_user_tick_functions(int tick_count) +@@ -2216,6 +2240,13 @@ + if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { + RETURN_FALSE; + } ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ shutdown_function_entry.created_by_eval = 1; ++ } else { ++ shutdown_function_entry.created_by_eval = 0; ++ } ++#endif + + /* Prevent entering of anything but valid callback (syntax check only!) */ + if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { +@@ -2497,6 +2528,15 @@ + + convert_to_string_ex(varname); + ++ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ ++ if (PG(safe_mode)) { ++ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || ++ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || ++ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { ++ RETURN_FALSE; ++ } ++ } ++ + zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); + } + /* }}} */ +@@ -2753,6 +2793,13 @@ + } + + tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ tick_fe.created_by_eval = 1; ++ } else { ++ tick_fe.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { + RETURN_FALSE; +@@ -3050,6 +3097,35 @@ + new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); + } + ++ if (new_key[0] == 'H') { ++ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_FILES")==0)|| ++ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (new_key[0] == '_') { ++ if ((strcmp(new_key, "_COOKIE")==0)|| ++ (strcmp(new_key, "_ENV")==0)|| ++ (strcmp(new_key, "_FILES")==0)|| ++ (strcmp(new_key, "_GET")==0)|| ++ (strcmp(new_key, "_POST")==0)|| ++ (strcmp(new_key, "_REQUEST")==0)|| ++ (strcmp(new_key, "_SESSION")==0)|| ++ (strcmp(new_key, "_SERVER")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (strcmp(new_key, "GLOBALS")==0) { ++ efree(new_key); ++ return 0; ++ } ++ + zend_hash_del(&EG(symbol_table), new_key, new_key_len); + ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); + +diff -Nura php-4.4.2/ext/standard/config.m4 hardening-patch-4.4.2-0.4.15/ext/standard/config.m4 +--- php-4.4.2/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/config.m4 2006-09-05 20:30:33.000000000 +0200 +@@ -203,7 +203,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) + ]) +@@ -419,6 +419,6 @@ + url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ + http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ +- var_unserializer.c ftok.c aggregation.c sha1.c ) ++ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ) + + PHP_ADD_MAKEFILE_FRAGMENT +diff -Nura php-4.4.2/ext/standard/crypt_blowfish.c hardening-patch-4.4.2-0.4.15/ext/standard/crypt_blowfish.c +--- php-4.4.2/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,748 @@ ++/* ++ * This code comes from John the Ripper password cracker, with reentrant ++ * and crypt(3) interfaces added, but optimizations specific to password ++ * cracking removed. ++ * ++ * Written by Solar Designer in 1998-2002 and ++ * placed in the public domain. ++ * ++ * There's absolutely no warranty. ++ * ++ * It is my intent that you should be able to use this on your system, ++ * as a part of a software package, or anywhere else to improve security, ++ * ensure compatibility, or for any other purpose. I would appreciate ++ * it if you give credit where it is due and keep your modifications in ++ * the public domain as well, but I don't require that in order to let ++ * you place this code and any modifications you make under a license ++ * of your choice. ++ * ++ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) ++ * by Niels Provos , and uses some of his ++ * ideas. The password hashing algorithm was designed by David Mazieres ++ * . ++ * ++ * There's a paper on the algorithm that explains its design decisions: ++ * ++ * http://www.usenix.org/events/usenix99/provos.html ++ * ++ * Some of the tricks in BF_ROUND might be inspired by Eric Young's ++ * Blowfish library (I can't be sure if I would think of something if I ++ * hadn't seen his code). ++ */ ++ ++#include ++ ++#include ++#ifndef __set_errno ++#define __set_errno(val) errno = (val) ++#endif ++ ++#undef __CONST ++#ifdef __GNUC__ ++#define __CONST __const ++#else ++#define __CONST ++#endif ++ ++#ifdef __i386__ ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#elif defined(__alpha__) || defined(__hppa__) ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#else ++#define BF_ASM 0 ++#define BF_SCALE 0 ++#endif ++ ++typedef unsigned int BF_word; ++ ++/* Number of Blowfish rounds, this is also hardcoded into a few places */ ++#define BF_N 16 ++ ++typedef BF_word BF_key[BF_N + 2]; ++ ++typedef struct { ++ BF_word S[4][0x100]; ++ BF_key P; ++} BF_ctx; ++ ++/* ++ * Magic IV for 64 Blowfish encryptions that we do at the end. ++ * The string is "OrpheanBeholderScryDoubt" on big-endian. ++ */ ++static BF_word BF_magic_w[6] = { ++ 0x4F727068, 0x65616E42, 0x65686F6C, ++ 0x64657253, 0x63727944, 0x6F756274 ++}; ++ ++/* ++ * P-box and S-box tables initialized with digits of Pi. ++ */ ++static BF_ctx BF_init_state = { ++ { ++ { ++ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, ++ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, ++ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, ++ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, ++ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, ++ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, ++ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, ++ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, ++ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, ++ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, ++ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, ++ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, ++ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, ++ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, ++ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, ++ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, ++ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, ++ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, ++ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, ++ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, ++ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, ++ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, ++ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, ++ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, ++ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, ++ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, ++ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, ++ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, ++ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, ++ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, ++ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, ++ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, ++ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, ++ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, ++ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, ++ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, ++ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, ++ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, ++ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, ++ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, ++ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, ++ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, ++ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, ++ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, ++ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, ++ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, ++ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, ++ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, ++ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, ++ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, ++ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, ++ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, ++ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, ++ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, ++ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, ++ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, ++ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, ++ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, ++ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, ++ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, ++ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, ++ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, ++ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, ++ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a ++ }, { ++ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, ++ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, ++ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, ++ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, ++ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, ++ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, ++ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, ++ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, ++ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, ++ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, ++ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, ++ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, ++ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, ++ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, ++ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, ++ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, ++ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, ++ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, ++ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, ++ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, ++ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, ++ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, ++ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, ++ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, ++ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, ++ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, ++ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, ++ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, ++ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, ++ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, ++ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, ++ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, ++ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, ++ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, ++ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, ++ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, ++ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, ++ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, ++ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, ++ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, ++ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, ++ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, ++ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, ++ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, ++ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, ++ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, ++ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, ++ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, ++ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, ++ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, ++ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, ++ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, ++ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, ++ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, ++ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, ++ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, ++ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, ++ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, ++ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, ++ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, ++ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, ++ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, ++ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, ++ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 ++ }, { ++ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, ++ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, ++ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, ++ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, ++ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, ++ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, ++ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, ++ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, ++ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, ++ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, ++ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, ++ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, ++ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, ++ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, ++ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, ++ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, ++ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, ++ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, ++ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, ++ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, ++ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, ++ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, ++ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, ++ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, ++ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, ++ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, ++ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, ++ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, ++ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, ++ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, ++ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, ++ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, ++ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, ++ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, ++ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, ++ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, ++ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, ++ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, ++ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, ++ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, ++ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, ++ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, ++ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, ++ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, ++ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, ++ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, ++ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, ++ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, ++ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, ++ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, ++ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, ++ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, ++ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, ++ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, ++ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, ++ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, ++ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, ++ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, ++ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, ++ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, ++ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, ++ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, ++ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, ++ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 ++ }, { ++ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, ++ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, ++ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, ++ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, ++ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, ++ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, ++ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, ++ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, ++ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, ++ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, ++ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, ++ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, ++ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, ++ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, ++ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, ++ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, ++ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, ++ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, ++ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, ++ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, ++ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, ++ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, ++ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, ++ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, ++ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, ++ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, ++ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, ++ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, ++ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, ++ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, ++ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, ++ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, ++ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, ++ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, ++ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, ++ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, ++ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, ++ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, ++ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, ++ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, ++ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, ++ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, ++ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, ++ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, ++ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, ++ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, ++ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, ++ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, ++ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, ++ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, ++ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, ++ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, ++ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, ++ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, ++ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, ++ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, ++ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, ++ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, ++ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, ++ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, ++ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, ++ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, ++ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, ++ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 ++ } ++ }, { ++ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, ++ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, ++ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, ++ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, ++ 0x9216d5d9, 0x8979fb1b ++ } ++}; ++ ++static unsigned char BF_itoa64[64 + 1] = ++ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ++ ++static unsigned char BF_atoi64[0x60] = { ++ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, ++ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, ++ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, ++ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, ++ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 ++}; ++ ++/* ++ * This may be optimized out if built with function inlining and no BF_ASM. ++ */ ++static void clean(void *data, int size) ++{ ++#if BF_ASM ++ extern void _BF_clean(void *data); ++#endif ++ memset(data, 0, size); ++#if BF_ASM ++ _BF_clean(data); ++#endif ++} ++ ++#define BF_safe_atoi64(dst, src) \ ++{ \ ++ tmp = (unsigned char)(src); \ ++ if (tmp == '$') break; \ ++ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ ++ tmp = BF_atoi64[tmp]; \ ++ if (tmp > 63) return -1; \ ++ (dst) = tmp; \ ++} ++ ++static int BF_decode(BF_word *dst, __CONST char *src, int size) ++{ ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned char *end = dptr + size; ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned int tmp, c1, c2, c3, c4; ++ ++ do { ++ BF_safe_atoi64(c1, *sptr++); ++ BF_safe_atoi64(c2, *sptr++); ++ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c3, *sptr++); ++ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c4, *sptr++); ++ *dptr++ = ((c3 & 0x03) << 6) | c4; ++ } while (dptr < end); ++ ++ while (dptr < end) ++ *dptr++ = 0; ++ ++ return 0; ++} ++ ++static void BF_encode(char *dst, __CONST BF_word *src, int size) ++{ ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned char *end = sptr + size; ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned int c1, c2; ++ ++ do { ++ c1 = *sptr++; ++ *dptr++ = BF_itoa64[c1 >> 2]; ++ c1 = (c1 & 0x03) << 4; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 4; ++ *dptr++ = BF_itoa64[c1]; ++ c1 = (c2 & 0x0f) << 2; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 6; ++ *dptr++ = BF_itoa64[c1]; ++ *dptr++ = BF_itoa64[c2 & 0x3f]; ++ } while (sptr < end); ++} ++ ++static void BF_swap(BF_word *x, int count) ++{ ++ static int endianness_check = 1; ++ char *is_little_endian = (char *)&endianness_check; ++ BF_word tmp; ++ ++ if (*is_little_endian) ++ do { ++ tmp = *x; ++ tmp = (tmp << 16) | (tmp >> 16); ++ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); ++ } while (--count); ++} ++ ++#if BF_SCALE ++/* Architectures which can shift addresses left by 2 bits with no extra cost */ ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp2 = L >> 8; \ ++ tmp2 &= 0xFF; \ ++ tmp3 = L >> 16; \ ++ tmp3 &= 0xFF; \ ++ tmp4 = L >> 24; \ ++ tmp1 = data.ctx.S[3][tmp1]; \ ++ tmp2 = data.ctx.S[2][tmp2]; \ ++ tmp3 = data.ctx.S[1][tmp3]; \ ++ tmp3 += data.ctx.S[0][tmp4]; \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#else ++/* Architectures with no complicated addressing modes supported */ ++#define BF_INDEX(S, i) \ ++ (*((BF_word *)(((unsigned char *)S) + (i)))) ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp1 <<= 2; \ ++ tmp2 = L >> 6; \ ++ tmp2 &= 0x3FC; \ ++ tmp3 = L >> 14; \ ++ tmp3 &= 0x3FC; \ ++ tmp4 = L >> 22; \ ++ tmp4 &= 0x3FC; \ ++ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ ++ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ ++ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ ++ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#endif ++ ++/* ++ * Encrypt one block, BF_N is hardcoded here. ++ */ ++#define BF_ENCRYPT \ ++ L ^= data.ctx.P[0]; \ ++ BF_ROUND(L, R, 0); \ ++ BF_ROUND(R, L, 1); \ ++ BF_ROUND(L, R, 2); \ ++ BF_ROUND(R, L, 3); \ ++ BF_ROUND(L, R, 4); \ ++ BF_ROUND(R, L, 5); \ ++ BF_ROUND(L, R, 6); \ ++ BF_ROUND(R, L, 7); \ ++ BF_ROUND(L, R, 8); \ ++ BF_ROUND(R, L, 9); \ ++ BF_ROUND(L, R, 10); \ ++ BF_ROUND(R, L, 11); \ ++ BF_ROUND(L, R, 12); \ ++ BF_ROUND(R, L, 13); \ ++ BF_ROUND(L, R, 14); \ ++ BF_ROUND(R, L, 15); \ ++ tmp4 = R; \ ++ R = L; \ ++ L = tmp4 ^ data.ctx.P[BF_N + 1]; ++ ++#if BF_ASM ++#define BF_body() \ ++ _BF_body_r(&data.ctx); ++#else ++#define BF_body() \ ++ L = R = 0; \ ++ ptr = data.ctx.P; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.P[BF_N + 2]); \ ++\ ++ ptr = data.ctx.S[0]; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.S[3][0xFF]); ++#endif ++ ++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) ++{ ++ __CONST char *ptr = key; ++ int i, j; ++ BF_word tmp; ++ ++ for (i = 0; i < BF_N + 2; i++) { ++ tmp = 0; ++ for (j = 0; j < 4; j++) { ++ tmp <<= 8; ++ tmp |= *ptr; ++ ++ if (!*ptr) ptr = key; else ptr++; ++ } ++ ++ expanded[i] = tmp; ++ initial[i] = BF_init_state.P[i] ^ tmp; ++ } ++} ++ ++char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, ++ char *output, int size) ++{ ++#if BF_ASM ++ extern void _BF_body_r(BF_ctx *ctx); ++#endif ++ struct { ++ BF_ctx ctx; ++ BF_key expanded_key; ++ union { ++ BF_word salt[4]; ++ BF_word output[6]; ++ } binary; ++ } data; ++ BF_word L, R; ++ BF_word tmp1, tmp2, tmp3, tmp4; ++ BF_word *ptr; ++ BF_word count; ++ int i; ++ ++ if (size < 7 + 22 + 31 + 1) { ++ __set_errno(ERANGE); ++ return NULL; ++ } ++ ++ if (setting[0] != '$' || ++ setting[1] != '2' || ++ setting[2] != 'a' || ++ setting[3] != '$' || ++ setting[4] < '0' || setting[4] > '3' || ++ setting[5] < '0' || setting[5] > '9' || ++ setting[6] != '$') { ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); ++ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { ++ clean(data.binary.salt, sizeof(data.binary.salt)); ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ BF_swap(data.binary.salt, 4); ++ ++ BF_set_key(key, data.expanded_key, data.ctx.P); ++ ++ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); ++ ++ L = R = 0; ++ for (i = 0; i < BF_N + 2; i += 2) { ++ L ^= data.binary.salt[i & 2]; ++ R ^= data.binary.salt[(i & 2) + 1]; ++ BF_ENCRYPT; ++ data.ctx.P[i] = L; ++ data.ctx.P[i + 1] = R; ++ } ++ ++ ptr = data.ctx.S[0]; ++ do { ++ ptr += 4; ++ L ^= data.binary.salt[(BF_N + 2) & 3]; ++ R ^= data.binary.salt[(BF_N + 3) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 4) = L; ++ *(ptr - 3) = R; ++ ++ L ^= data.binary.salt[(BF_N + 4) & 3]; ++ R ^= data.binary.salt[(BF_N + 5) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 2) = L; ++ *(ptr - 1) = R; ++ } while (ptr < &data.ctx.S[3][0xFF]); ++ ++ do { ++ data.ctx.P[0] ^= data.expanded_key[0]; ++ data.ctx.P[1] ^= data.expanded_key[1]; ++ data.ctx.P[2] ^= data.expanded_key[2]; ++ data.ctx.P[3] ^= data.expanded_key[3]; ++ data.ctx.P[4] ^= data.expanded_key[4]; ++ data.ctx.P[5] ^= data.expanded_key[5]; ++ data.ctx.P[6] ^= data.expanded_key[6]; ++ data.ctx.P[7] ^= data.expanded_key[7]; ++ data.ctx.P[8] ^= data.expanded_key[8]; ++ data.ctx.P[9] ^= data.expanded_key[9]; ++ data.ctx.P[10] ^= data.expanded_key[10]; ++ data.ctx.P[11] ^= data.expanded_key[11]; ++ data.ctx.P[12] ^= data.expanded_key[12]; ++ data.ctx.P[13] ^= data.expanded_key[13]; ++ data.ctx.P[14] ^= data.expanded_key[14]; ++ data.ctx.P[15] ^= data.expanded_key[15]; ++ data.ctx.P[16] ^= data.expanded_key[16]; ++ data.ctx.P[17] ^= data.expanded_key[17]; ++ ++ BF_body(); ++ ++ tmp1 = data.binary.salt[0]; ++ tmp2 = data.binary.salt[1]; ++ tmp3 = data.binary.salt[2]; ++ tmp4 = data.binary.salt[3]; ++ data.ctx.P[0] ^= tmp1; ++ data.ctx.P[1] ^= tmp2; ++ data.ctx.P[2] ^= tmp3; ++ data.ctx.P[3] ^= tmp4; ++ data.ctx.P[4] ^= tmp1; ++ data.ctx.P[5] ^= tmp2; ++ data.ctx.P[6] ^= tmp3; ++ data.ctx.P[7] ^= tmp4; ++ data.ctx.P[8] ^= tmp1; ++ data.ctx.P[9] ^= tmp2; ++ data.ctx.P[10] ^= tmp3; ++ data.ctx.P[11] ^= tmp4; ++ data.ctx.P[12] ^= tmp1; ++ data.ctx.P[13] ^= tmp2; ++ data.ctx.P[14] ^= tmp3; ++ data.ctx.P[15] ^= tmp4; ++ data.ctx.P[16] ^= tmp1; ++ data.ctx.P[17] ^= tmp2; ++ ++ BF_body(); ++ } while (--count); ++ ++ for (i = 0; i < 6; i += 2) { ++ L = BF_magic_w[i]; ++ R = BF_magic_w[i + 1]; ++ ++ count = 64; ++ do { ++ BF_ENCRYPT; ++ } while (--count); ++ ++ data.binary.output[i] = L; ++ data.binary.output[i + 1] = R; ++ } ++ ++ memcpy(output, setting, 7 + 22 - 1); ++ output[7 + 22 - 1] = BF_itoa64[(int) ++ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; ++ ++/* This has to be bug-compatible with the original implementation, so ++ * only encode 23 of the 24 bytes. :-) */ ++ BF_swap(data.binary.output, 6); ++ BF_encode(&output[7 + 22], data.binary.output, 23); ++ output[7 + 22 + 31] = '\0'; ++ ++/* Overwrite the most obvious sensitive data we have on the stack. Note ++ * that this does not guarantee there's no sensitive data left on the ++ * stack and/or in registers; I'm not aware of portable code that does. */ ++ clean(&data, sizeof(data)); ++ ++ return output; ++} ++ ++char *_crypt_gensalt_blowfish_rn(unsigned long count, ++ __CONST char *input, int size, char *output, int output_size) ++{ ++ if (size < 16 || output_size < 7 + 22 + 1 || ++ (count && (count < 4 || count > 31))) { ++ if (output_size > 0) output[0] = '\0'; ++ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); ++ return NULL; ++ } ++ ++ if (!count) count = 5; ++ ++ output[0] = '$'; ++ output[1] = '2'; ++ output[2] = 'a'; ++ output[3] = '$'; ++ output[4] = '0' + count / 10; ++ output[5] = '0' + count % 10; ++ output[6] = '$'; ++ ++ BF_encode(&output[7], (BF_word *)input, 16); ++ output[7 + 22] = '\0'; ++ ++ return output; ++} +diff -Nura php-4.4.2/ext/standard/crypt.c hardening-patch-4.4.2-0.4.15/ext/standard/crypt.c +--- php-4.4.2/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/crypt.c 2006-09-05 20:30:33.000000000 +0200 +@@ -100,6 +100,8 @@ + return SUCCESS; + } + ++char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); ++char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); + + static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +@@ -135,7 +137,14 @@ + + /* The automatic salt generation only covers standard DES and md5-crypt */ + if(!*salt) { +-#if PHP_MD5_CRYPT ++#if PHP_BLOWFISH_CRYPT ++ char randat[16]; ++ int i; ++ ++ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; ++ ++ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); ++#elif PHP_MD5_CRYPT + strcpy(salt, "$1$"); + php_to64(&salt[3], PHP_CRYPT_RAND, 4); + php_to64(&salt[7], PHP_CRYPT_RAND, 4); +@@ -145,8 +154,24 @@ + salt[2] = '\0'; + #endif + } +- +- RETVAL_STRING(crypt(str, salt), 1); ++ ++ if (salt[0] == '$' && ++ salt[1] == '2' && ++ salt[2] == 'a' && ++ salt[3] == '$' && ++ salt[4] >= '0' && salt[4] <= '3' && ++ salt[5] >= '0' && salt[5] <= '9' && ++ salt[6] == '$') { ++ ++ char output[PHP_MAX_SALT_LEN+1]; ++ ++ output[0] = 0; ++ _crypt_blowfish_rn(str, salt, output, sizeof(output)); ++ RETVAL_STRING(output, 1); ++ ++ } else { ++ RETVAL_STRING(crypt(str, salt), 1); ++ } + } + /* }}} */ + #endif +diff -Nura php-4.4.2/ext/standard/dl.c hardening-patch-4.4.2-0.4.15/ext/standard/dl.c +--- php-4.4.2/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/dl.c 2006-09-05 20:30:33.000000000 +0200 +@@ -160,8 +160,35 @@ + RETURN_FALSE; + } + module_entry = get_module(); ++ ++ /* check if Hardening-Patch is installed */ ++ if (module_entry->zend_api < 1000000000) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ ++ /* check if correct Hardening-Patch is installed */ ++ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ + if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) +- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { ++ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { + /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ + struct pre_4_1_0_module_entry { + char *name; +@@ -195,7 +222,7 @@ + zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; + } else { + name = module_entry->name; +- zend_api = module_entry->zend_api; ++ zend_api = module_entry->real_zend_api; + zend_debug = module_entry->zend_debug; + zts = module_entry->zts; + } +diff -Nura php-4.4.2/ext/standard/file.c hardening-patch-4.4.2-0.4.15/ext/standard/file.c +--- php-4.4.2/ext/standard/file.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/file.c 2006-09-05 20:30:33.000000000 +0200 +@@ -21,7 +21,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: file.c,v 1.279.2.70.2.3 2006/01/01 13:46:57 sniper Exp $ */ ++/* $Id: file.c,v 1.279.2.70.2.7 2006/04/14 17:46:59 pollita Exp $ */ + + /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ + +@@ -552,7 +552,7 @@ + pval **arg1, **arg2; + char *d; + char *opened_path; +- char p[64]; ++ char *p; + FILE *fp; + + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { +@@ -566,7 +566,11 @@ + } + + d = estrndup(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1)); +- strlcpy(p, Z_STRVAL_PP(arg2), sizeof(p)); ++ ++ p = php_basename(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2), NULL, 0); ++ if (strlen(p) > 64) { ++ p[63] = '\0'; ++ } + + if ((fp = php_open_temporary_file(d, p, &opened_path TSRMLS_CC))) { + fclose(fp); +@@ -574,6 +578,7 @@ + } else { + RETVAL_FALSE; + } ++ efree(p); + efree(d); + } + /* }}} */ +@@ -819,7 +824,7 @@ + + /* If seconds is not set to null, build the timeval, else we wait indefinitely */ + if (sec != NULL) { +- convert_to_long_ex(&sec); ++ convert_to_long(sec); + + if (usec > 999999) { + tv.tv_sec = Z_LVAL_P(sec) + (usec / 1000000); +@@ -2196,7 +2201,7 @@ + safe_to_copy: + + srcstream = php_stream_open_wrapper(src, "rb", +- STREAM_DISABLE_OPEN_BASEDIR | REPORT_ERRORS, ++ ENFORCE_SAFE_MODE | REPORT_ERRORS, + NULL); + + if (!srcstream) +@@ -2522,7 +2527,7 @@ + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) + /* {{{ proto string realpath(string path) + Return the resolved path */ +-PHP_FUNCTION(realpath) ++PHP_FUNCTION(real_path) + { + zval **path; + char resolved_path_buff[MAXPATHLEN]; +diff -Nura php-4.4.2/ext/standard/file.h hardening-patch-4.4.2-0.4.15/ext/standard/file.h +--- php-4.4.2/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/file.h 2006-09-05 20:30:33.000000000 +0200 +@@ -64,7 +64,7 @@ + PHP_FUNCTION(fd_set); + PHP_FUNCTION(fd_isset); + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +-PHP_FUNCTION(realpath); ++PHP_FUNCTION(real_path); + #endif + #ifdef HAVE_FNMATCH + PHP_FUNCTION(fnmatch); +diff -Nura php-4.4.2/ext/standard/head.c hardening-patch-4.4.2-0.4.15/ext/standard/head.c +--- php-4.4.2/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/head.c 2006-09-05 20:30:33.000000000 +0200 +@@ -44,7 +44,7 @@ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, + &ctr.line_len, &rep, &ctr.response_code) == FAILURE) + return; +- ++ + sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); + } + /* }}} */ +diff -Nura php-4.4.2/ext/standard/html.c hardening-patch-4.4.2-0.4.15/ext/standard/html.c +--- php-4.4.2/ext/standard/html.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/html.c 2006-09-05 20:30:33.000000000 +0200 +@@ -18,7 +18,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: html.c,v 1.63.2.23.2.1 2006/01/01 13:46:57 sniper Exp $ */ ++/* $Id: html.c,v 1.63.2.23.2.2 2006/02/25 21:33:06 rasmus Exp $ */ + + /* + * HTML entity resources: +@@ -793,7 +793,7 @@ + enum entity_charset charset = determine_charset(hint_charset TSRMLS_CC); + unsigned char replacement[15]; + +- ret = estrdup(old); ++ ret = estrndup(old, oldlen); + retlen = oldlen; + if (!retlen) { + goto empty_source; +diff -Nura php-4.4.2/ext/standard/http_fopen_wrapper.c hardening-patch-4.4.2-0.4.15/ext/standard/http_fopen_wrapper.c +--- php-4.4.2/ext/standard/http_fopen_wrapper.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/http_fopen_wrapper.c 2006-09-05 20:30:33.000000000 +0200 +@@ -18,7 +18,7 @@ + | Wez Furlong | + +----------------------------------------------------------------------+ + */ +-/* $Id: http_fopen_wrapper.c,v 1.53.2.20.2.5 2006/01/01 13:46:57 sniper Exp $ */ ++/* $Id: http_fopen_wrapper.c,v 1.53.2.20.2.9 2006/04/16 17:45:55 iliaa Exp $ */ + + #include "php.h" + #include "php_globals.h" +@@ -339,7 +339,7 @@ + size_t tmp_line_len; + /* get response header */ + +- if (_php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len TSRMLS_CC) != NULL) { ++ if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) { + zval *http_response; + int response_code; + +@@ -353,6 +353,7 @@ + } + switch(response_code) { + case 200: ++ case 206: /* partial content */ + case 302: + case 301: + reqok = 1; +@@ -394,7 +395,7 @@ + + while (!body && !php_stream_eof(stream)) { + size_t http_header_line_length; +- if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length TSRMLS_CC) && *http_header_line != '\n' && *http_header_line != '\r') { ++ if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') { + char *e = http_header_line + http_header_line_length - 1; + while (*e == '\n' || *e == '\r') { + e--; +@@ -502,9 +503,11 @@ + } \ + } \ + /* check for control characters in login, password & path */ +- CHECK_FOR_CNTRL_CHARS(resource->user) +- CHECK_FOR_CNTRL_CHARS(resource->pass) +- CHECK_FOR_CNTRL_CHARS(resource->path) ++ if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) { ++ CHECK_FOR_CNTRL_CHARS(resource->user) ++ CHECK_FOR_CNTRL_CHARS(resource->pass) ++ CHECK_FOR_CNTRL_CHARS(resource->path) ++ } + + stream = php_stream_url_wrap_http_ex(NULL, new_path, mode, options, opened_path, context, --redirect_max, 0 STREAMS_CC TSRMLS_CC); + if (stream && stream->wrapperdata) { +diff -Nura php-4.4.2/ext/standard/info.c hardening-patch-4.4.2-0.4.15/ext/standard/info.c +--- php-4.4.2/ext/standard/info.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/info.c 2006-09-05 20:30:33.000000000 +0200 +@@ -18,7 +18,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: info.c,v 1.218.2.18.2.6 2006/01/01 13:46:57 sniper Exp $ */ ++/* $Id: info.c,v 1.218.2.18.2.7 2006/06/28 13:12:09 derick Exp $ */ + + #include "php.h" + #include "php_ini.h" +@@ -58,6 +58,23 @@ + + PHPAPI extern char *php_ini_opened_path; + PHPAPI extern char *php_ini_scanned_files; ++ ++static int php_info_write_wrapper(const char *str, uint str_length) ++{ ++ int new_len, written; ++ char *elem_esc; ++ ++ TSRMLS_FETCH(); ++ ++ elem_esc = php_escape_html_entities((char *)str, str_length, &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC); ++ ++ written = php_body_write(elem_esc, new_len TSRMLS_CC); ++ ++ efree(elem_esc); ++ ++ return written; ++} ++ + + /* {{{ _display_module_info + */ +@@ -133,23 +150,12 @@ + PUTS(" => "); + } + if (Z_TYPE_PP(tmp) == IS_ARRAY) { +- zval *tmp3; +- MAKE_STD_ZVAL(tmp3); + if (!sapi_module.phpinfo_as_text) { + PUTS("
");
+-				}
+-				php_start_ob_buffer(NULL, 4096, 1 TSRMLS_CC);
+-				zend_print_zval_r(*tmp, 0);
+-				php_ob_get_buffer(tmp3 TSRMLS_CC);
+-				php_end_ob_buffer(0, 0 TSRMLS_CC);
+-				
+-				elem_esc = php_info_html_esc(Z_STRVAL_P(tmp3) TSRMLS_CC);
+-				PUTS(elem_esc);
+-				efree(elem_esc);
+-				zval_ptr_dtor(&tmp3);
+-
+-				if (!sapi_module.phpinfo_as_text) {
++					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
+ 					PUTS("
"); ++ } else { ++ zend_print_zval_r(*tmp, 0); + } + } else if (Z_TYPE_PP(tmp) != IS_STRING) { + tmp2 = **tmp; +@@ -408,7 +414,7 @@ + + if (flag & PHP_INFO_GENERAL) { + char *zend_version = get_zend_version(); +- char temp_api[9]; ++ char temp_api[11]; + + php_uname = php_get_uname('a'); + +@@ -430,11 +436,22 @@ + } + } + ++#if HARDENING_PATCH ++ if (!sapi_module.phpinfo_as_text) { ++ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); ++ } else { ++ char temp_ver[40]; ++ ++ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); ++ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); ++ } ++#else + if (!sapi_module.phpinfo_as_text) { + php_printf("

PHP Version %s

\n", PHP_VERSION); + } else { + php_info_print_table_row(2, "PHP Version", PHP_VERSION); + } ++#endif + php_info_print_box_end(); + php_info_print_table_start(); + php_info_print_table_row(2, "System", php_uname ); +diff -Nura php-4.4.2/ext/standard/mail.c hardening-patch-4.4.2-0.4.15/ext/standard/mail.c +--- php-4.4.2/ext/standard/mail.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/mail.c 2006-09-05 20:30:33.000000000 +0200 +@@ -78,6 +78,25 @@ + } + /* }}} */ + ++/* {{{ hphp_strcasestr */ ++char *hphp_strcasestr(char *haystack, char *needle) ++{ ++ unsigned char *t, *h, *n; ++ ++ h = (unsigned char *) haystack; ++conts: ++ while (*h) { ++ n = (unsigned char *) needle; ++ for (t=h++; *n && *h; t++, n++) { ++ if (toupper(*t) != toupper(*n)) goto conts; ++ } ++ return ((char*)h-1); ++ } ++ ++ return (NULL); ++} ++/* }}} */ ++ + /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) + Send an email message */ + PHP_FUNCTION(mail) +@@ -103,6 +122,44 @@ + return; + } + ++ if (HG(hphp_mailprotect) > 0) { ++ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { ++ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ /* check for spam attempts with buggy webforms */ ++ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (HG(hphp_mailprotect) > 1) { ++ /* search for to, cc or bcc headers */ ++ if (headers_len > 0 && headers != NULL) { ++ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { ++ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { ++ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { ++ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ } ++ } ++ } ++ + if (to_len > 0) { + to_r = estrndup(to, to_len); + for (; to_len; to_len--) { +diff -Nura php-4.4.2/ext/standard/pack.c hardening-patch-4.4.2-0.4.15/ext/standard/pack.c +--- php-4.4.2/ext/standard/pack.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/pack.c 2006-09-05 20:30:33.000000000 +0200 +@@ -15,7 +15,7 @@ + | Author: Chris Schneider | + +----------------------------------------------------------------------+ + */ +-/* $Id: pack.c,v 1.40.2.7.2.4 2006/01/01 13:46:57 sniper Exp $ */ ++/* $Id: pack.c,v 1.40.2.7.2.5 2006/01/26 15:47:31 iliaa Exp $ */ + + #include "php.h" + +@@ -693,7 +693,9 @@ + len = size * 2; + } + +- len -= argb % 2; ++ if (argb > 0) { ++ len -= argb % 2; ++ } + + buf = emalloc(len + 1); + +diff -Nura php-4.4.2/ext/standard/php_standard.h hardening-patch-4.4.2-0.4.15/ext/standard/php_standard.h +--- php-4.4.2/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/php_standard.h 2006-09-05 20:30:33.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "php_mail.h" + #include "md5.h" + #include "sha1.h" ++#include "sha256.h" + #include "html.h" + #include "exec.h" + #include "file.h" +diff -Nura php-4.4.2/ext/standard/scanf.c hardening-patch-4.4.2-0.4.15/ext/standard/scanf.c +--- php-4.4.2/ext/standard/scanf.c 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/scanf.c 2006-09-05 20:30:33.000000000 +0200 +@@ -16,7 +16,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: scanf.c,v 1.16.4.9.2.1 2006/01/01 13:46:58 sniper Exp $ */ ++/* $Id: scanf.c,v 1.16.4.9.2.2 2006/08/04 11:59:50 tony2001 Exp $ */ + + /* + scanf.c -- +@@ -732,7 +732,7 @@ + if (*end == '$') { + format = end+1; + ch = format++; +- objIndex = varStart + value; ++ objIndex = varStart + value - 1; + } + } + +@@ -762,8 +762,10 @@ + switch (*ch) { + case 'n': + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { +- current = args[objIndex++]; ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { ++ current = args[objIndex++]; + zval_dtor( *current ); + ZVAL_LONG( *current, (long)(string - baseString) ); + } else { +@@ -883,8 +885,10 @@ + } + } + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { +- current = args[objIndex++]; ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { ++ current = args[objIndex++]; + zval_dtor( *current ); + ZVAL_STRINGL( *current, string, end-string, 1); + } else { +@@ -922,7 +926,9 @@ + goto done; + } + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + zval_dtor( *current ); + ZVAL_STRINGL( *current, string, end-string, 1); +@@ -1079,8 +1085,10 @@ + value = (int) (*fn)(buf, NULL, base); + if ((flags & SCAN_UNSIGNED) && (value < 0)) { + sprintf(buf, "%u", value); /* INTL: ISO digit */ +- if (numVars) { +- /* change passed value type to string */ ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { ++ /* change passed value type to string */ + current = args[objIndex++]; + convert_to_string( *current ); + ZVAL_STRING( *current, buf, 1 ); +@@ -1088,7 +1096,9 @@ + add_index_string(*return_value, objIndex++, buf, 1); + } + } else { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + convert_to_long( *current ); + Z_LVAL(**current) = value; +@@ -1196,7 +1206,9 @@ + double dvalue; + *end = '\0'; + dvalue = zend_strtod(buf, NULL); +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + convert_to_double( *current ); + Z_DVAL_PP( current ) = dvalue; +diff -Nura php-4.4.2/ext/standard/sha256.c hardening-patch-4.4.2-0.4.15/ext/standard/sha256.c +--- php-4.4.2/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/sha256.c 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,398 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ ++ ++#include ++#include "php.h" ++ ++/* This code is heavily based on the PHP md5/sha1 implementations */ ++ ++#include "sha256.h" ++ ++PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ sprintf(sha256str, "%02x", digest[i]); ++ sha256str += 2; ++ } ++ ++ *sha256str = '\0'; ++} ++ ++/* {{{ proto string sha256(string str [, bool raw_output]) ++ Calculate the sha256 hash of a string */ ++PHP_FUNCTION(sha256) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ PHP_SHA256_CTX context; ++ unsigned char digest[32]; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ sha256str[0] = '\0'; ++ PHP_SHA256Init(&context); ++ PHP_SHA256Update(&context, arg, arg_len); ++ PHP_SHA256Final(digest, &context); ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++ ++} ++ ++/* }}} */ ++ ++/* {{{ proto string sha256_file(string filename [, bool raw_output]) ++ Calculate the sha256 hash of given filename */ ++PHP_FUNCTION(sha256_file) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ unsigned char buf[1024]; ++ unsigned char digest[32]; ++ PHP_SHA256_CTX context; ++ int n; ++ FILE *fp; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { ++ RETURN_FALSE; ++ } ++ ++ if (php_check_open_basedir(arg TSRMLS_CC)) { ++ RETURN_FALSE; ++ } ++ ++ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); ++ RETURN_FALSE; ++ } ++ ++ PHP_SHA256Init(&context); ++ ++ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { ++ PHP_SHA256Update(&context, buf, n); ++ } ++ ++ PHP_SHA256Final(digest, &context); ++ ++ if (ferror(fp)) { ++ fclose(fp); ++ RETURN_FALSE; ++ } ++ ++ fclose(fp); ++ ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++} ++/* }}} */ ++ ++ ++static void SHA256Transform(php_uint32[8], const unsigned char[64]); ++static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); ++static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); ++ ++static unsigned char PADDING[64] = ++{ ++ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++/* F, G, H and I are basic SHA256 functions. ++ */ ++#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) ++#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) ++#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) ++#define I(x, y, z) (((x) & (y)) | ((~x) & z)) ++ ++/* ROTATE_RIGHT rotates x right n bits. ++ */ ++#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) ++ ++/* W[i] ++ */ ++#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ ++ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ ++ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) ++ ++/* ROUND function of sha256 ++ */ ++ ++#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ ++ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ ++ (h) = F((a)) + G((a), (b), (c)) + t1; \ ++ (d) += t1; \ ++ } ++ ++ ++/* {{{ PHP_SHA256Init ++ * SHA256 initialization. Begins an SHA256 operation, writing a new context. ++ */ ++PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context) ++{ ++ context->count[0] = context->count[1] = 0; ++ /* Load magic initialization constants. ++ */ ++ context->state[0] = 0x6a09e667; ++ context->state[1] = 0xbb67ae85; ++ context->state[2] = 0x3c6ef372; ++ context->state[3] = 0xa54ff53a; ++ context->state[4] = 0x510e527f; ++ context->state[5] = 0x9b05688c; ++ context->state[6] = 0x1f83d9ab; ++ context->state[7] = 0x5be0cd19; ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Update ++ SHA256 block update operation. Continues an SHA256 message-digest ++ operation, processing another message block, and updating the ++ context. ++ */ ++PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, ++ unsigned int inputLen) ++{ ++ unsigned int i, index, partLen; ++ ++ /* Compute number of bytes mod 64 */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ++ ++ /* Update number of bits */ ++ if ((context->count[0] += ((php_uint32) inputLen << 3)) ++ < ((php_uint32) inputLen << 3)) ++ context->count[1]++; ++ context->count[1] += ((php_uint32) inputLen >> 29); ++ ++ partLen = 64 - index; ++ ++ /* Transform as many times as possible. ++ */ ++ if (inputLen >= partLen) { ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ++ SHA256Transform(context->state, context->buffer); ++ ++ for (i = partLen; i + 63 < inputLen; i += 64) ++ SHA256Transform(context->state, &input[i]); ++ ++ index = 0; ++ } else ++ i = 0; ++ ++ /* Buffer remaining input */ ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], ++ inputLen - i); ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Final ++ SHA256 finalization. Ends an SHA256 message-digest operation, writing the ++ the message digest and zeroizing the context. ++ */ ++PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) ++{ ++ unsigned char bits[8]; ++ unsigned int index, padLen; ++ ++ /* Save number of bits */ ++ bits[7] = context->count[0] & 0xFF; ++ bits[6] = (context->count[0] >> 8) & 0xFF; ++ bits[5] = (context->count[0] >> 16) & 0xFF; ++ bits[4] = (context->count[0] >> 24) & 0xFF; ++ bits[3] = context->count[1] & 0xFF; ++ bits[2] = (context->count[1] >> 8) & 0xFF; ++ bits[1] = (context->count[1] >> 16) & 0xFF; ++ bits[0] = (context->count[1] >> 24) & 0xFF; ++ ++ /* Pad out to 56 mod 64. ++ */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ++ padLen = (index < 56) ? (56 - index) : (120 - index); ++ PHP_SHA256Update(context, PADDING, padLen); ++ ++ /* Append length (before padding) */ ++ PHP_SHA256Update(context, bits, 8); ++ ++ /* Store state in digest */ ++ SHA256Encode(digest, context->state, 32); ++ ++ /* Zeroize sensitive information. ++ */ ++ memset((unsigned char*) context, 0, sizeof(*context)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Transform ++ * SHA256 basic transformation. Transforms state based on block. ++ */ ++static void SHA256Transform(state, block) ++php_uint32 state[8]; ++const unsigned char block[64]; ++{ ++ php_uint32 a = state[0], b = state[1], c = state[2]; ++ php_uint32 d = state[3], e = state[4], f = state[5]; ++ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; ++ ++ SHA256Decode(x, block, 64); ++ ++ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) ++ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) ++ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) ++ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) ++ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) ++ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) ++ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) ++ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) ++ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) ++ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) ++ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) ++ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) ++ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) ++ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) ++ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) ++ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) ++ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) ++ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) ++ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) ++ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) ++ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) ++ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) ++ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) ++ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) ++ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) ++ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) ++ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) ++ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) ++ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) ++ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) ++ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) ++ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) ++ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) ++ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) ++ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) ++ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) ++ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) ++ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) ++ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) ++ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) ++ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) ++ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) ++ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) ++ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) ++ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) ++ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) ++ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) ++ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) ++ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) ++ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) ++ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) ++ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) ++ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) ++ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) ++ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) ++ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) ++ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) ++ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) ++ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) ++ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) ++ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) ++ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) ++ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) ++ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) ++ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ state[5] += f; ++ state[6] += g; ++ state[7] += h; ++ ++ /* Zeroize sensitive information. */ ++ memset((unsigned char*) x, 0, sizeof(x)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Encode ++ Encodes input (php_uint32) into output (unsigned char). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Encode(output, input, len) ++unsigned char *output; ++php_uint32 *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) { ++ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); ++ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); ++ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); ++ output[j + 3] = (unsigned char) (input[i] & 0xff); ++ } ++} ++/* }}} */ ++ ++/* {{{ SHA256Decode ++ Decodes input (unsigned char) into output (php_uint32). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Decode(output, input, len) ++php_uint32 *output; ++const unsigned char *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) ++ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | ++ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.2/ext/standard/sha256.h hardening-patch-4.4.2-0.4.15/ext/standard/sha256.h +--- php-4.4.2/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/sha256.h 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ ++ ++#ifndef SHA256_H ++#define SHA256_H ++ ++#include "ext/standard/basic_functions.h" ++ ++/* SHA1 context. */ ++typedef struct { ++ php_uint32 state[8]; /* state (ABCD) */ ++ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ++ unsigned char buffer[64]; /* input buffer */ ++} PHP_SHA256_CTX; ++ ++PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *); ++PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); ++PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); ++ ++PHP_FUNCTION(sha256); ++PHP_FUNCTION(sha256_file); ++ ++#endif +diff -Nura php-4.4.2/ext/standard/string.c hardening-patch-4.4.2-0.4.15/ext/standard/string.c +--- php-4.4.2/ext/standard/string.c 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/string.c 2006-09-05 20:30:33.000000000 +0200 +@@ -18,7 +18,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: string.c,v 1.333.2.52.2.3 2006/01/01 13:46:58 sniper Exp $ */ ++/* $Id: string.c,v 1.333.2.52.2.4 2006/03/13 14:41:27 iliaa Exp $ */ + + /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ + +@@ -628,7 +628,8 @@ + { + const char *text, *breakchar = "\n"; + char *newtext; +- int textlen, breakcharlen = 1, newtextlen, alloced, chk; ++ int textlen, breakcharlen = 1, newtextlen, chk; ++ size_t alloced; + long current = 0, laststart = 0, lastspace = 0; + long linelength = 75; + zend_bool docut = 0; +@@ -672,15 +673,13 @@ + /* Multiple character line break or forced cut */ + if (linelength > 0) { + chk = (int)(textlen/linelength + 1); ++ newtext = safe_emalloc(chk, breakcharlen, textlen + 1); + alloced = textlen + chk * breakcharlen + 1; + } else { + chk = textlen; ++ newtext = safe_emalloc(textlen, (breakcharlen + 1), 1); + alloced = textlen * (breakcharlen + 1) + 1; + } +- if (alloced <= 0) { +- RETURN_FALSE; +- } +- newtext = emalloc(alloced); + + /* now keep track of the actual new text length */ + newtextlen = 0; +@@ -3515,7 +3514,7 @@ + zval **input_str; /* Input string */ + zval **mult; /* Multiplier */ + char *result; /* Resulting string */ +- int result_len; /* Length of the resulting string */ ++ size_t result_len; /* Length of the resulting string */ + + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { + WRONG_PARAM_COUNT; +@@ -3540,11 +3539,7 @@ + + /* Initialize the result string */ + result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); +- if (result_len < 1) { +- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes"); +- RETURN_FALSE; +- } +- result = (char *)emalloc(result_len + 1); ++ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1); + + /* Heavy optimization for situations where input string is 1 byte long */ + if (Z_STRLEN_PP(input_str) == 1) { +diff -Nura php-4.4.2/ext/standard/syslog.c hardening-patch-4.4.2-0.4.15/ext/standard/syslog.c +--- php-4.4.2/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/syslog.c 2006-09-05 20:30:33.000000000 +0200 +@@ -42,6 +42,8 @@ + */ + PHP_MINIT_FUNCTION(syslog) + { ++ ++#if !HARDENING_PATCH + /* error levels */ + REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ + REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ +@@ -97,7 +99,7 @@ + /* AIX doesn't have LOG_PERROR */ + REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ + #endif +- ++#endif + return SUCCESS; + } + /* }}} */ +diff -Nura php-4.4.2/ext/standard/tests/strings/bug38322.phpt hardening-patch-4.4.2-0.4.15/ext/standard/tests/strings/bug38322.phpt +--- php-4.4.2/ext/standard/tests/strings/bug38322.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/tests/strings/bug38322.phpt 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++Bug #38322 (reading past array in sscanf() leads to segfault/arbitary code execution) ++--FILE-- ++ ++--EXPECTF-- ++int(1) ++Done +diff -Nura php-4.4.2/ext/standard/url.c hardening-patch-4.4.2-0.4.15/ext/standard/url.c +--- php-4.4.2/ext/standard/url.c 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/standard/url.c 2006-09-05 20:30:33.000000000 +0200 +@@ -15,7 +15,7 @@ + | Author: Jim Winstead | + +----------------------------------------------------------------------+ + */ +-/* $Id: url.c,v 1.58.2.21.2.2 2006/01/01 13:46:58 sniper Exp $ */ ++/* $Id: url.c,v 1.58.2.21.2.3 2006/02/12 16:43:03 iliaa Exp $ */ + + #include + #include +@@ -137,7 +137,7 @@ + p++; + } + +- if ((*p) == '\0' || *p == '/') { ++ if ((*p == '\0' || *p == '/') && (p - e) < 7) { + goto parse_port; + } + +diff -Nura php-4.4.2/ext/varfilter/config.m4 hardening-patch-4.4.2-0.4.15/ext/varfilter/config.m4 +--- php-4.4.2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/varfilter/config.m4 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,11 @@ ++dnl ++dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++dnl ++ ++PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, ++[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) ++ ++if test "$PHP_VARFILTER" != "no"; then ++ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) ++ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) ++fi +diff -Nura php-4.4.2/ext/varfilter/CREDITS hardening-patch-4.4.2-0.4.15/ext/varfilter/CREDITS +--- php-4.4.2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,2 @@ ++varfilter ++Stefan Esser +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-4.4.2/ext/varfilter/php_varfilter.h hardening-patch-4.4.2-0.4.15/ext/varfilter/php_varfilter.h +--- php-4.4.2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,144 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifndef PHP_VARFILTER_H ++#define PHP_VARFILTER_H ++ ++extern zend_module_entry varfilter_module_entry; ++#define phpext_varfilter_ptr &varfilter_module_entry ++ ++#ifdef PHP_WIN32 ++#define PHP_VARFILTER_API __declspec(dllexport) ++#else ++#define PHP_VARFILTER_API ++#endif ++ ++#ifdef ZTS ++#include "TSRM.h" ++#endif ++ ++#include "SAPI.h" ++ ++#include "php_variables.h" ++ ++#ifdef ZEND_ENGINE_2 ++#define HASH_HTTP_GET_VARS 0x2095733f ++#define HASH_HTTP_POST_VARS 0xbfee1265 ++#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 ++#define HASH_HTTP_ENV_VARS 0x1fe186a8 ++#define HASH_HTTP_SERVER_VARS 0xc987afd6 ++#define HASH_HTTP_SESSION_VARS 0x7aba0d43 ++#define HASH_HTTP_POST_FILES 0x98eb1ddc ++#define HASH_HTTP_RAW_POST_DATA 0xdd633fec ++#else ++#define HASH_HTTP_GET_VARS 0x8d8645bd ++#define HASH_HTTP_POST_VARS 0x7c699bf3 ++#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f ++#define HASH_HTTP_ENV_VARS 0x84da3016 ++#define HASH_HTTP_SERVER_VARS 0x6dbf964e ++#define HASH_HTTP_SESSION_VARS 0x322906f5 ++#define HASH_HTTP_POST_FILES 0xe4e4ce70 ++#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e ++#endif ++ ++PHP_MINIT_FUNCTION(varfilter); ++PHP_MSHUTDOWN_FUNCTION(varfilter); ++PHP_RINIT_FUNCTION(varfilter); ++PHP_RSHUTDOWN_FUNCTION(varfilter); ++PHP_MINFO_FUNCTION(varfilter); ++ ++ ++ZEND_BEGIN_MODULE_GLOBALS(varfilter) ++/* request variables */ ++ long max_request_variables; ++ long cur_request_variables; ++ long max_varname_length; ++ long max_totalname_length; ++ long max_value_length; ++ long max_array_depth; ++ long max_array_index_length; ++ zend_bool disallow_nul; ++/* cookie variables */ ++ long max_cookie_vars; ++ long cur_cookie_vars; ++ long max_cookie_name_length; ++ long max_cookie_totalname_length; ++ long max_cookie_value_length; ++ long max_cookie_array_depth; ++ long max_cookie_array_index_length; ++ zend_bool disallow_cookie_nul; ++/* get variables */ ++ long max_get_vars; ++ long cur_get_vars; ++ long max_get_name_length; ++ long max_get_totalname_length; ++ long max_get_value_length; ++ long max_get_array_depth; ++ long max_get_array_index_length; ++ zend_bool disallow_get_nul; ++/* post variables */ ++ long max_post_vars; ++ long cur_post_vars; ++ long max_post_name_length; ++ long max_post_totalname_length; ++ long max_post_value_length; ++ long max_post_array_depth; ++ long max_post_array_index_length; ++ zend_bool disallow_post_nul; ++/* fileupload */ ++ long max_uploads; ++ long cur_uploads; ++ zend_bool disallow_elf_files; ++ char *verification_script; ++ ++ zend_bool no_more_variables; ++ zend_bool no_more_get_variables; ++ zend_bool no_more_post_variables; ++ zend_bool no_more_cookie_variables; ++ zend_bool no_more_uploads; ++ ++ZEND_END_MODULE_GLOBALS(varfilter) ++ ++ ++#ifdef ZTS ++#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) ++#else ++#define VARFILTER_G(v) (varfilter_globals.v) ++#endif ++ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); ++SAPI_TREAT_DATA_FUNC(varfilter_treat_data); ++ ++ ++ ++#endif /* PHP_VARFILTER_H */ ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: t ++ * End: ++ */ +diff -Nura php-4.4.2/ext/varfilter/varfilter.c hardening-patch-4.4.2-0.4.15/ext/varfilter/varfilter.c +--- php-4.4.2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:48:50.000000000 +0200 +@@ -0,0 +1,915 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "php.h" ++#include "php_ini.h" ++#include "ext/standard/info.h" ++#include "php_varfilter.h" ++#include "hardening_patch.h" ++ ++ZEND_DECLARE_MODULE_GLOBALS(varfilter) ++ ++/* True global resources - no need for thread safety here */ ++static int le_varfilter; ++ ++static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; ++static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; ++static zend_bool hooked = 0; ++ ++/* {{{ varfilter_module_entry ++ */ ++zend_module_entry varfilter_module_entry = { ++#if ZEND_MODULE_API_NO >= 20010901 ++ STANDARD_MODULE_HEADER, ++#endif ++ "varfilter", ++ NULL, ++ PHP_MINIT(varfilter), ++ PHP_MSHUTDOWN(varfilter), ++ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ ++ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ ++ PHP_MINFO(varfilter), ++#if ZEND_MODULE_API_NO >= 20010901 ++ "0.4.15", /* Replace with version number for your extension */ ++#endif ++ STANDARD_MODULE_PROPERTIES ++}; ++/* }}} */ ++ ++#ifdef COMPILE_DL_VARFILTER ++ZEND_GET_MODULE(varfilter) ++#endif ++ ++/* {{{ PHP_INI ++ */ ++PHP_INI_BEGIN() ++ /* for backward compatibility */ ++ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) ++ ++ ++PHP_INI_END() ++/* }}} */ ++ ++/* {{{ php_varfilter_init_globals ++ */ ++static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) ++{ ++ varfilter_globals->max_request_variables = 200; ++ varfilter_globals->max_varname_length = 64; ++ varfilter_globals->max_value_length = 10000; ++ varfilter_globals->max_array_depth = 100; ++ varfilter_globals->max_totalname_length = 256; ++ varfilter_globals->max_array_index_length = 64; ++ varfilter_globals->disallow_nul = 1; ++ ++ varfilter_globals->max_cookie_vars = 100; ++ varfilter_globals->max_cookie_name_length = 64; ++ varfilter_globals->max_cookie_totalname_length = 256; ++ varfilter_globals->max_cookie_value_length = 10000; ++ varfilter_globals->max_cookie_array_depth = 100; ++ varfilter_globals->max_cookie_array_index_length = 64; ++ varfilter_globals->disallow_cookie_nul = 1; ++ ++ varfilter_globals->max_get_vars = 100; ++ varfilter_globals->max_get_name_length = 64; ++ varfilter_globals->max_get_totalname_length = 256; ++ varfilter_globals->max_get_value_length = 512; ++ varfilter_globals->max_get_array_depth = 50; ++ varfilter_globals->max_get_array_index_length = 64; ++ varfilter_globals->disallow_get_nul = 1; ++ ++ varfilter_globals->max_post_vars = 200; ++ varfilter_globals->max_post_name_length = 64; ++ varfilter_globals->max_post_totalname_length = 256; ++ varfilter_globals->max_post_value_length = 65000; ++ varfilter_globals->max_post_array_depth = 100; ++ varfilter_globals->max_post_array_index_length = 64; ++ varfilter_globals->disallow_post_nul = 1; ++ ++ varfilter_globals->max_uploads = 25; ++ varfilter_globals->disallow_elf_files = 1; ++ varfilter_globals->verification_script = NULL; ++ ++ varfilter_globals->no_more_variables = 0; ++ varfilter_globals->no_more_get_variables = 0; ++ varfilter_globals->no_more_post_variables = 0; ++ varfilter_globals->no_more_cookie_variables = 0; ++ varfilter_globals->no_more_uploads = 0; ++ ++ varfilter_globals->cur_request_variables = 0; ++ varfilter_globals->cur_get_vars = 0; ++ varfilter_globals->cur_post_vars = 0; ++ varfilter_globals->cur_cookie_vars = 0; ++ ++ varfilter_globals->cur_uploads = 0; ++ ++} ++/* }}} */ ++ ++ ++void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) ++{ ++ HashTable *svars; ++ int retval, failure=0; ++ ++ orig_register_server_variables(track_vars_array TSRMLS_CC); ++ ++ svars = Z_ARRVAL_P(track_vars_array); ++ ++ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ ++ if (failure) { ++ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); ++ } ++} ++ ++int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) ++{ ++ int retval = SAPI_HEADER_ADD, i; ++ char *tmp; ++ ++ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { ++ ++ tmp = sapi_header->header; ++ for (i=0; iheader_len; i++, tmp++) { ++ if (tmp[0] == 0) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); ++ sapi_header->header_len = i; ++ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); ++ sapi_header->header_len = i; ++ tmp[0] = 0; ++ } ++ } ++ } ++ ++ if (orig_header_handler) { ++ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); ++ } ++ ++ return retval; ++} ++ ++/* {{{ PHP_MINIT_FUNCTION ++ */ ++PHP_MINIT_FUNCTION(varfilter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); ++ REGISTER_INI_ENTRIES(); ++ ++ if (!hooked) { ++ void *temp; ++ hooked = 1; ++ ++ temp = (void *)sapi_module.register_server_variables; ++ if (temp != varfilter_register_server_variables) { ++ orig_register_server_variables = temp; ++ } ++ temp = (void *)sapi_module.header_handler; ++ if (temp != varfilter_header_handler) { ++ orig_header_handler = temp; ++ } ++ } ++ ++ sapi_register_input_filter(varfilter_input_filter); ++ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); ++ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); ++ sapi_register_upload_content_filter(varfilter_upload_content_filter); ++ sapi_register_post_upload_filter(varfilter_post_upload_filter); ++ ++ sapi_module.header_handler = varfilter_header_handler; ++ sapi_module.register_server_variables = varfilter_register_server_variables; ++ ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MSHUTDOWN_FUNCTION ++ */ ++PHP_MSHUTDOWN_FUNCTION(varfilter) ++{ ++ UNREGISTER_INI_ENTRIES(); ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request start */ ++/* {{{ PHP_RINIT_FUNCTION ++ */ ++PHP_RINIT_FUNCTION(varfilter) ++{ ++ VARFILTER_G(cur_request_variables) = 0; ++ VARFILTER_G(cur_get_vars) = 0; ++ VARFILTER_G(cur_post_vars) = 0; ++ VARFILTER_G(cur_cookie_vars) = 0; ++ ++ VARFILTER_G(cur_uploads) = 0; ++ ++ VARFILTER_G(no_more_variables) = 0; ++ VARFILTER_G(no_more_get_variables) = 0; ++ VARFILTER_G(no_more_post_variables) = 0; ++ VARFILTER_G(no_more_cookie_variables) = 0; ++ VARFILTER_G(no_more_uploads) = 0; ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request end */ ++/* {{{ PHP_RSHUTDOWN_FUNCTION ++ */ ++PHP_RSHUTDOWN_FUNCTION(varfilter) ++{ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MINFO_FUNCTION ++ */ ++PHP_MINFO_FUNCTION(varfilter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); ++ php_info_print_table_end(); ++ ++ DISPLAY_INI_ENTRIES(); ++} ++/* }}} */ ++ ++/* {{{ normalize_varname ++ */ ++static void normalize_varname(char *varname) ++{ ++ char *s=varname, *index=NULL, *indexend=NULL, *p; ++ ++ /* overjump leading space */ ++ while (*s == ' ') { ++ s++; ++ } ++ ++ /* and remove it */ ++ if (s != varname) { ++ memmove(varname, s, strlen(s)+1); ++ } ++ ++ for (p=varname; *p && *p != '['; p++) { ++ switch(*p) { ++ case ' ': ++ case '.': ++ *p='_'; ++ break; ++ } ++ } ++ ++ /* find index */ ++ index = strchr(varname, '['); ++ if (index) { ++ index++; ++ s=index; ++ } else { ++ return; ++ } ++ ++ /* done? */ ++ while (index) { ++ ++ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { ++ index++; ++ } ++ indexend = strchr(index, ']'); ++ indexend = indexend ? indexend + 1 : index + strlen(index); ++ ++ if (s != index) { ++ memmove(s, index, strlen(index)+1); ++ s += indexend-index; ++ } else { ++ s = indexend; ++ } ++ ++ if (*s == '[') { ++ s++; ++ index = s; ++ } else { ++ index = NULL; ++ } ++ } ++ *s++='\0'; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC ++ */ ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) ++{ ++ char *index, *prev_index = NULL, *var; ++ unsigned int var_len, total_len, depth = 0; ++ ++ var = estrdup(varname); ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); ++ ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; ++ break; ++ } ++ ++ efree(var); ++ return SUCCESS; ++protected_varname2: ++ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); ++return_failure: ++ efree(var); ++ return FAILURE; ++} ++/* }}} */ ++ ++/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC ++ */ ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) ++{ ++ /* Drop if no more variables flag is set */ ++ if (VARFILTER_G(no_more_uploads)) { ++ return FAILURE; ++ } ++ /* Drop this fileupload if the limit is reached */ ++ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { ++ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); ++ VARFILTER_G(no_more_uploads) = 1; ++ return FAILURE; ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC ++ */ ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) ++{ ++ ++ if (VARFILTER_G(disallow_elf_files)) { ++ ++ if (offset == 0 && buffer_len > 10) { ++ ++ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { ++ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); ++ return FAILURE; ++ } ++ } ++ ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC ++ */ ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) ++{ ++ int retval = SUCCESS; ++ ++ if (VARFILTER_G(verification_script)) { ++ char cmd[8192]; ++ FILE *in; ++ int first=1; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); ++ return FAILURE; ++ } ++ ++ retval = FAILURE; ++ ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ if (first) { ++ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; ++ first = 0; ++ } ++ } ++ pclose(in); ++ } ++ ++ if (retval != SUCCESS) { ++ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); ++ return FAILURE; ++ } ++ ++ VARFILTER_G(cur_uploads)++; ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_INPUT_FILTER_FUNC ++ */ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) ++{ ++ char *index, *prev_index = NULL; ++ unsigned int var_len, total_len, depth = 0; ++ ++ /* Drop this variable if the limit was reached */ ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(no_more_get_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(no_more_post_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(no_more_cookie_variables)) { ++ return 0; ++ } ++ break; ++ default: /* we do not want to protect parse_str() and friends */ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ return 1; ++ } ++ if (VARFILTER_G(no_more_variables)) { ++ return 0; ++ } ++ ++ /* Drop this variable if the limit is now reached */ ++ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { ++ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_variables) = 1; ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { ++ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_get_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { ++ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_cookie_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { ++ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_post_variables) = 1; ++ return 0; ++ } ++ break; ++ } ++ ++ ++ /* Drop this variable if it exceeds the value length limit */ ++ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { ++ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { ++ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { ++ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { ++ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { ++ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { ++ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Check if variable value is truncated by a \0 */ ++ ++ if (val && *val && val_len != strlen(*val)) { ++ ++ if (VARFILTER_G(disallow_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(disallow_get_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(disallow_cookie_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(disallow_post_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ } ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname; ++ break; ++ } ++ ++ /* Okay let PHP register this variable */ ++ VARFILTER_G(cur_request_variables)++; ++ switch (arg) { ++ case PARSE_GET: ++ VARFILTER_G(cur_get_vars)++; ++ break; ++ case PARSE_COOKIE: ++ VARFILTER_G(cur_cookie_vars)++; ++ break; ++ case PARSE_POST: ++ VARFILTER_G(cur_post_vars)++; ++ break; ++ } ++ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ ++ return 1; ++protected_varname: ++ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); ++ return 0; ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: noet sw=4 ts=4 fdm=marker ++ * vim<600: noet sw=4 ts=4 ++ */ ++ ++ +diff -Nura php-4.4.2/ext/wddx/wddx.c hardening-patch-4.4.2-0.4.15/ext/wddx/wddx.c +--- php-4.4.2/ext/wddx/wddx.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/ext/wddx/wddx.c 2006-09-05 20:30:33.000000000 +0200 +@@ -16,7 +16,11 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: wddx.c,v 1.96.2.6.2.3 2006/01/01 13:46:59 sniper Exp $ */ ++/* $Id: wddx.c,v 1.96.2.6.2.7 2006/05/26 01:55:26 iliaa Exp $ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif + + #include "php.h" + #include "php_wddx.h" +@@ -400,9 +404,9 @@ + break; + + default: +- if (iscntrl((int)*(unsigned char *)p)) { ++ if (iscntrl((int)*(unsigned char *)p) || (int)*(unsigned char *)p >= 127) { + FLUSH_BUF(); +- sprintf(control_buf, WDDX_CHAR, *p); ++ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); + php_wddx_add_chunk(packet, control_buf); + } else + buf[l++] = *p; +@@ -428,7 +432,7 @@ + tmp = *var; + zval_copy_ctor(&tmp); + convert_to_string(&tmp); +- sprintf(tmp_buf, WDDX_NUMBER, Z_STRVAL(tmp)); ++ snprintf(tmp_buf, Z_STRLEN(tmp), WDDX_NUMBER, Z_STRVAL(tmp)); + zval_dtor(&tmp); + + php_wddx_add_chunk(packet, tmp_buf); +@@ -620,17 +624,19 @@ + */ + void php_wddx_serialize_var(wddx_packet *packet, zval *var, char *name, int name_len TSRMLS_DC) + { +- char tmp_buf[WDDX_BUF_LEN]; ++ char *tmp_buf; + char *name_esc; + int name_esc_len; + + if (name) { + name_esc = php_escape_html_entities(name, name_len, &name_esc_len, 0, ENT_QUOTES, NULL TSRMLS_CC); +- sprintf(tmp_buf, WDDX_VAR_S, name_esc); ++ tmp_buf = emalloc(name_esc_len + 1); ++ snprintf(tmp_buf, name_esc_len, WDDX_VAR_S, name_esc); + php_wddx_add_chunk(packet, tmp_buf); ++ efree(tmp_buf); + efree(name_esc); + } +- ++ + switch(Z_TYPE_P(var)) { + case IS_STRING: + php_wddx_serialize_string(packet, var); +diff -Nura php-4.4.2/main/fopen_wrappers.c hardening-patch-4.4.2-0.4.15/main/fopen_wrappers.c +--- php-4.4.2/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:23.000000000 +0200 +@@ -106,7 +106,10 @@ + } + + /* Resolve the real path into resolved_name */ +- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { ++ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { ++ return -2; ++ } ++ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { + /* Handler for basedirs that end with a / */ + resolved_basedir_len = strlen(resolved_basedir); + if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { +@@ -116,14 +119,20 @@ + } + } + ++ resolved_name_len = strlen(resolved_name); + if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { +- resolved_name_len = strlen(resolved_name); + if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { + resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; + resolved_name[++resolved_name_len] = '\0'; + } + } + ++ if (resolved_name_len == resolved_basedir_len - 1) { ++ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { ++ resolved_basedir_len--; ++ } ++ } ++ + /* Check the path */ + #ifdef PHP_WIN32 + if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { +@@ -137,7 +146,7 @@ + } + } else { + /* Unable to resolve the real path, return -1 */ +- return -1; ++ return -3; + } + } + /* }}} */ +@@ -156,22 +165,44 @@ + char *pathbuf; + char *ptr; + char *end; ++ char path_copy[MAXPATHLEN]; ++ int path_len; ++ ++ /* Special case path ends with a trailing slash */ ++ path_len = strlen(path); ++ if (path_len >= MAXPATHLEN) { ++ errno = EPERM; /* we deny permission to open it */ ++ return -1; ++ } ++ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { ++ memcpy(path_copy, path, path_len+1); ++ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; ++ path_copy[path_len] = '\0'; ++ path = (const char *)&path_copy; ++ } + + pathbuf = estrdup(PG(open_basedir)); + + ptr = pathbuf; + + while (ptr && *ptr) { ++ int res; + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end != NULL) { + *end = '\0'; + end++; + } + +- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { ++ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); ++ if (res == 0) { + efree(pathbuf); + return 0; + } ++ if (res == -2) { ++ efree(pathbuf); ++ errno = EPERM; ++ return -1; ++ } + + ptr = end; + } +diff -Nura php-4.4.2/main/hardened_globals.h hardening-patch-4.4.2-0.4.15/main/hardened_globals.h +--- php-4.4.2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/hardened_globals.h 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENED_GLOBALS_H ++#define HARDENED_GLOBALS_H ++ ++typedef struct _hardened_globals hardened_globals_struct; ++ ++#ifdef ZTS ++# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) ++extern int hardened_globals_id; ++#else ++# define HG(v) (hardened_globals.v) ++extern struct _hardened_globals hardened_globals; ++#endif ++ ++ ++struct _hardened_globals { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_1; ++ unsigned int canary_2; ++#endif ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_3; ++ unsigned int canary_4; ++ unsigned int ll_canary_inited; ++#endif ++ zend_bool hphp_sql_bailout_on_error; ++ zend_bool hphp_multiheader; ++ unsigned long hphp_mailprotect; ++ long hard_memory_limit; ++ HashTable *eval_whitelist; ++ HashTable *eval_blacklist; ++ HashTable *func_whitelist; ++ HashTable *func_blacklist; ++ HashTable *include_whitelist; ++ HashTable *include_blacklist; ++ unsigned int dummy; ++}; ++ ++ ++#endif /* HARDENED_GLOBALS_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-4.4.2/main/hardening_patch.c hardening-patch-4.4.2-0.4.15/main/hardening_patch.c +--- php-4.4.2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/hardening_patch.c 2006-09-07 18:48:28.000000000 +0200 +@@ -0,0 +1,430 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ ++ ++#include "php.h" ++ ++#include ++#include ++ ++#if HAVE_UNISTD_H ++#include ++#endif ++#include "SAPI.h" ++#include "php_globals.h" ++ ++#if HARDENING_PATCH ++ ++#ifdef HAVE_SYS_SOCKET_H ++#include ++#endif ++ ++#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) ++#undef AF_UNIX ++#endif ++ ++#if defined(AF_UNIX) ++#include ++#endif ++ ++#define SYSLOG_PATH "/dev/log" ++ ++#include "snprintf.h" ++ ++#include "hardening_patch.h" ++ ++#ifdef ZTS ++#include "hardened_globals.h" ++int hardened_globals_id; ++#else ++struct _hardened_globals hardened_globals; ++#endif ++ ++static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) ++{ ++ memset(hardened_globals, 0, sizeof(*hardened_globals)); ++} ++ ++ ++PHPAPI void hardened_startup() ++{ ++#ifdef ZTS ++ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); ++#else ++ hardened_globals_ctor(&hardened_globals TSRMLS_CC); ++#endif ++} ++ ++PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) ++{ ++ HG(canary_1) = php_canary(); ++ HG(canary_2) = php_canary(); ++} ++ ++char *loglevel2string(int loglevel) ++{ ++ switch (loglevel) { ++ case S_FILES: ++ return "FILES"; ++ case S_INCLUDE: ++ return "INCLUDE"; ++ case S_MEMORY: ++ return "MEMORY"; ++ case S_MISC: ++ return "MISC"; ++ case S_SQL: ++ return "SQL"; ++ case S_EXECUTOR: ++ return "EXECUTOR"; ++ case S_VARS: ++ return "VARS"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++PHPAPI void php_security_log(int loglevel, char *fmt, ...) ++{ ++#if defined(AF_UNIX) ++ int s, r, i=0; ++ struct sockaddr_un saun; ++ char buf[4096+64]; ++ char error[4096+100]; ++ char *ip_address; ++ char *fname; ++ int lineno; ++ va_list ap; ++ TSRMLS_FETCH(); ++ ++ if (EG(hphp_log_use_x_forwarded_for)) { ++ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "X-FORWARDED-FOR not set"; ++ } ++ } else { ++ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "REMOTE_ADDR not set"; ++ } ++ } ++ ++ ++ va_start(ap, fmt); ++ ap_php_vsnprintf(error, sizeof(error), fmt, ap); ++ va_end(ap); ++ while (error[i]) { ++ if (error[i] < 32) error[i] = '.'; ++ i++; ++ } ++ ++ if (zend_is_executing(TSRMLS_C)) { ++ lineno = zend_get_executed_lineno(TSRMLS_C); ++ fname = zend_get_executed_filename(TSRMLS_C); ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); ++ } else { ++ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); ++ if (fname==NULL) { ++ fname = "unknown"; ++ } ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); ++ } ++ ++ /* Syslog-Logging disabled? */ ++ if ((EG(hphp_log_syslog) & loglevel)==0) { ++ goto log_sapi; ++ } ++ ++ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); ++ ++ s = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ s = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ goto log_sapi; ++ } ++ } ++ send(s, error, strlen(error), 0); ++ ++ close(s); ++ ++log_sapi: ++ /* SAPI Logging activated? */ ++ if ((EG(hphp_log_sapi) & loglevel)!=0) { ++ sapi_module.log_message(buf); ++ } ++ ++log_script: ++ /* script logging activaed? */ ++ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { ++ char cmd[8192], *cmdpos, *bufpos; ++ FILE *in; ++ int space; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); ++ space = sizeof(cmd) - strlen(cmd); ++ cmdpos = cmd + strlen(cmd); ++ bufpos = buf; ++ if (space <= 1) return; ++ while (space > 2 && *bufpos) { ++ if (*bufpos == '\'') { ++ if (space<=5) break; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\\'; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\''; ++ bufpos++; ++ space-=4; ++ } else { ++ *cmdpos++ = *bufpos++; ++ space--; ++ } ++ } ++ *cmdpos++ = '\''; ++ *cmdpos = 0; ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); ++ return; ++ } ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ } ++ pclose(in); ++ } ++ ++#endif ++} ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++PHPAPI unsigned int php_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++ ++PHPAPI int php_is_valid_include(zval *z) ++{ ++ char *filename; ++ int len, i; ++ TSRMLS_FETCH(); ++ ++ /* must be of type string */ ++ if (z->type != IS_STRING || z->value.str.val == NULL) { ++ return (0); ++ } ++ ++ /* short cut */ ++ filename = z->value.str.val; ++ len = z->value.str.len; ++ ++ /* 1. must be shorter than MAXPATHLEN */ ++ if (len > MAXPATHLEN) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 2. must not be cutted */ ++ if (len != strlen(filename)) { ++ char *fname = estrndup(filename, len); ++ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ ++ if (strstr(filename, "://")) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ ++ /* no black or whitelist then disallow all */ ++ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* whitelist is stronger than blacklist */ ++ if (HG(include_whitelist)) { ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ zend_bool isOk = 0; ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_whitelist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ isOk = 1; ++ break; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_whitelist)); ++ } while (1); ++ ++ /* not found in whitelist */ ++ if (!isOk) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); ++ efree(fname); ++ return 0; ++ } ++ ++ s = h + 3; ++ } while (1); ++ } else { ++ /* okay then handle the blacklist */ ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_blacklist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); ++ efree(fname); ++ return 0; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_blacklist)); ++ } while (1); ++ ++ s = h + 3; ++ } while (1); ++ } ++ ++ efree(fname); ++ } ++ ++ /* 4. must not be an uploaded file */ ++ if (SG(rfc1867_uploaded_files)) { ++ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { ++ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); ++ return (0); ++ } ++ } ++ ++ /* passed all tests */ ++ return (1); ++} ++ ++#endif ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.2/main/hardening_patch.h hardening-patch-4.4.2-0.4.15/main/hardening_patch.h +--- php-4.4.2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/hardening_patch.h 2006-09-07 18:48:35.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENING_PATCH_H ++#define HARDENING_PATCH_H ++ ++#include "zend.h" ++ ++#if HARDENING_PATCH ++PHPAPI void php_security_log(int loglevel, char *fmt, ...); ++PHPAPI void hardened_startup(); ++#define HARDENING_PATCH_VERSION "0.4.15" ++ ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++PHPAPI unsigned int php_canary(); ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++PHPAPI int php_is_valid_include(zval *z); ++#endif ++ ++#endif /* HARDENING_PATCH_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-4.4.2/main/hardening_patch.m4 hardening-patch-4.4.2-0.4.15/main/hardening_patch.m4 +--- php-4.4.2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/hardening_patch.m4 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,95 @@ ++dnl ++dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ ++dnl ++dnl This file contains Hardening Patch for PHP specific autoconf functions. ++dnl ++ ++AC_ARG_ENABLE(hardening-patch-mm-protect, ++[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-ll-protect, ++[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-inc-protect, ++[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-fmt-protect, ++[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-hash-protect, ++[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++]) ++ ++AC_MSG_CHECKING(whether to protect the Zend Memory Manager) ++AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the Zend Linked Lists) ++AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect include/require statements) ++AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect PHP Format String functions) ++AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) ++AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) ++ ++ ++AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) ++fi ++ +diff -Nura php-4.4.2/main/main.c hardening-patch-4.4.2-0.4.15/main/main.c +--- php-4.4.2/main/main.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/main.c 2006-09-05 20:30:33.000000000 +0200 +@@ -92,6 +92,10 @@ + PHPAPI int core_globals_id; + #endif + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#endif ++ + #define ERROR_BUF_LEN 1024 + + typedef struct { +@@ -142,17 +146,39 @@ + */ + static PHP_INI_MH(OnChangeMemoryLimit) + { ++#if HARDENING_PATCH ++ long hard_memory_limit = 1<<30; ++ ++ if (stage == ZEND_INI_STAGE_RUNTIME) { ++ if (HG(hard_memory_limit) == 0) { ++ HG(hard_memory_limit) = PG(memory_limit); ++ } ++ hard_memory_limit = HG(hard_memory_limit); ++ } else { ++ HG(hard_memory_limit) = 0; ++ } ++#endif + if (new_value) { + PG(memory_limit) = zend_atoi(new_value, new_value_length); ++#if HARDENING_PATCH ++ if (PG(memory_limit) > hard_memory_limit) { ++ PG(memory_limit) = hard_memory_limit; ++ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); ++ return FAILURE; ++ } ++#endif + } else { ++#if HARDENING_PATCH ++ PG(memory_limit) = hard_memory_limit; ++#else + PG(memory_limit) = 1<<30; /* effectively, no limit */ ++#endif + } + return zend_set_memory_limit(PG(memory_limit)); + } + /* }}} */ + #endif + +- + /* {{{ php_disable_functions + */ + static void php_disable_functions(TSRMLS_D) +@@ -1008,6 +1034,9 @@ + + zend_try { + shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); ++#if HARDENING_PATCH ++ hardened_clear_mm_canaries(TSRMLS_C); ++#endif + } zend_end_try(); + + zend_try { +@@ -1098,6 +1127,10 @@ + tsrm_ls = ts_resource(0); + #endif + ++#if HARDENING_PATCH ++ hardened_startup(); ++#endif ++ + sapi_initialize_empty_request(TSRMLS_C); + sapi_activate(TSRMLS_C); + +@@ -1110,6 +1143,12 @@ + php_output_startup(); + php_output_activate(TSRMLS_C); + ++#if HARDENING_PATCH_INC_PROTECT ++ zuf.is_valid_include = php_is_valid_include; ++#endif ++#if HARDENING_PATCH ++ zuf.security_log_function = php_security_log; ++#endif + zuf.error_function = php_error_cb; + zuf.printf_function = php_printf; + zuf.write_function = php_body_write_wrapper; +@@ -1211,6 +1250,10 @@ + REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS); + 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); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); ++#endif + REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); +@@ -1318,7 +1361,7 @@ + */ + static inline void php_register_server_variables(TSRMLS_D) + { +- zval *array_ptr=NULL; ++ zval *array_ptr=NULL, *vptr; + + ALLOC_ZVAL(array_ptr); + array_init(array_ptr); +diff -Nura php-4.4.2/main/php_config.h.in hardening-patch-4.4.2-0.4.15/main/php_config.h.in +--- php-4.4.2/main/php_config.h.in 2006-01-12 19:24:28.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/php_config.h.in 2006-09-05 20:30:33.000000000 +0200 +@@ -865,6 +865,39 @@ + /* Enabling BIND8 compatibility for Panther */ + #undef BIND_8_COMPAT + ++/* Hardening-Patch */ ++#undef HARDENING_PATCH ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ + /* Whether you have AOLserver */ + #undef HAVE_AOLSERVER + +@@ -1148,6 +1181,12 @@ + /* Define if you have the getaddrinfo function */ + #undef HAVE_GETADDRINFO + ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ + /* Whether system headers declare timezone */ + #undef HAVE_DECLARED_TIMEZONE + +diff -Nura php-4.4.2/main/php_content_types.c hardening-patch-4.4.2-0.4.15/main/php_content_types.c +--- php-4.4.2/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/php_content_types.c 2006-09-05 20:30:33.000000000 +0200 +@@ -77,6 +77,7 @@ + sapi_register_post_entries(php_post_entries); + sapi_register_default_post_reader(php_default_post_reader); + sapi_register_treat_data(php_default_treat_data); ++ sapi_register_input_filter(php_default_input_filter); + return SUCCESS; + } + /* }}} */ +diff -Nura php-4.4.2/main/php.h hardening-patch-4.4.2-0.4.15/main/php.h +--- php-4.4.2/main/php.h 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/php.h 2006-09-05 20:30:33.000000000 +0200 +@@ -35,11 +35,19 @@ + #include "zend_qsort.h" + #include "php_compat.h" + ++ + #include "zend_API.h" + + #undef sprintf + #define sprintf php_sprintf + ++#if HARDENING_PATCH ++#if HAVE_REALPATH ++#undef realpath ++#define realpath php_realpath ++#endif ++#endif ++ + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ + #undef PHP_DEBUG + #define PHP_DEBUG ZEND_DEBUG +@@ -409,6 +417,10 @@ + #endif + #endif /* !XtOffsetOf */ + ++#if HARDENING_PATCH ++#include "hardening_patch.h" ++#endif ++ + #endif + + /* +diff -Nura php-4.4.2/main/php_open_temporary_file.c hardening-patch-4.4.2-0.4.15/main/php_open_temporary_file.c +--- php-4.4.2/main/php_open_temporary_file.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/php_open_temporary_file.c 2006-09-05 20:30:33.000000000 +0200 +@@ -16,7 +16,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: php_open_temporary_file.c,v 1.18.2.10.2.2 2006/01/01 13:46:59 sniper Exp $ */ ++/* $Id: php_open_temporary_file.c,v 1.18.2.10.2.3 2006/05/23 23:23:39 iliaa Exp $ */ + + #include "php.h" + +@@ -115,17 +115,16 @@ + + path_len = strlen(path); + +- if (!(opened_path = emalloc(MAXPATHLEN))) { +- return -1; +- } +- + if (!path_len || IS_SLASH(path[path_len - 1])) { + trailing_slash = ""; + } else { + trailing_slash = "/"; + } + +- (void)snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", path, trailing_slash, pfx); ++ if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", path, trailing_slash, pfx) >= MAXPATHLEN) { ++ efree(opened_path); ++ return -1; ++ } + + #ifdef PHP_WIN32 + if (GetTempFileName(path, pfx, 0, opened_path)) { +diff -Nura php-4.4.2/main/php_variables.c hardening-patch-4.4.2-0.4.15/main/php_variables.c +--- php-4.4.2/main/php_variables.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/php_variables.c 2006-09-05 20:30:33.000000000 +0200 +@@ -236,17 +236,28 @@ + while (var) { + val = strchr(var, '='); + if (val) { /* have a value */ +- int val_len; ++ unsigned int val_len, new_val_len; + + *val++ = '\0'; + php_url_decode(var, strlen(var)); + val_len = php_url_decode(val, strlen(val)); +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } + var = php_strtok_r(NULL, "&", &strtok_buf); + } + } + ++SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) ++{ ++ /* TODO: check .ini setting here and apply user-defined input filter */ ++ *new_val_len = val_len; ++ return 1; ++} ++ + SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) + { + char *res = NULL, *var, *val, *separator=NULL; +@@ -324,15 +335,26 @@ + while (var) { + val = strchr(var, '='); + if (val) { /* have a value */ +- int val_len; ++ unsigned int val_len, new_val_len; + + *val++ = '\0'; + php_url_decode(var, strlen(var)); + val_len = php_url_decode(val, strlen(val)); +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } else { ++ unsigned int val_len, new_val_len; ++ + php_url_decode(var, strlen(var)); +- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC); ++ val_len = 0; ++ val = estrndup("", 0); ++ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } + var = php_strtok_r(NULL, separator, &strtok_buf); + } +diff -Nura php-4.4.2/main/rfc1867.c hardening-patch-4.4.2-0.4.15/main/rfc1867.c +--- php-4.4.2/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/rfc1867.c 2006-09-05 20:30:33.000000000 +0200 +@@ -128,6 +128,8 @@ + #define UPLOAD_ERROR_D 4 /* No file uploaded */ + #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ + #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ ++#define UPLOAD_ERROR_X 99 /* Filter forbids upload */ ++ + + void php_rfc1867_register_constants(TSRMLS_D) + { +@@ -138,6 +140,7 @@ + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); + } + + static void normalize_protected_variable(char *varname TSRMLS_DC) +@@ -849,6 +852,7 @@ + char buff[FILLUNIT]; + char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; + int blen=0, wlen=0; ++ unsigned long offset; + + zend_llist_clean(&header); + +@@ -897,21 +901,24 @@ + if (!filename && param) { + + char *value = multipart_buffer_read_body(mbuff TSRMLS_CC); ++ unsigned int new_val_len; /* Dummy variable */ + + if (!value) { + value = estrdup(""); + } + ++ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) { + #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) +- if (php_mb_encoding_translation(TSRMLS_C)) { +- php_mb_gpc_stack_variable(param, value, &val_list, &len_list, +- &num_vars, &num_vars_max TSRMLS_CC); +- } else { +- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); +- } ++ if (php_mb_encoding_translation(TSRMLS_C)) { ++ php_mb_gpc_stack_variable(param, value, &val_list, &len_list, ++ &num_vars, &num_vars_max TSRMLS_CC); ++ } else { ++ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); ++ } + #else +- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); ++ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); + #endif ++ } + if (!strcasecmp(param, "MAX_FILE_SIZE")) { + max_file_size = atol(value); + } +@@ -963,7 +970,11 @@ + tmp++; + } + } +- ++ ++ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { ++ skip_upload = 1; ++ } ++ + total_bytes = cancel_upload = 0; + + if (!skip_upload) { +@@ -987,6 +998,11 @@ + cancel_upload = UPLOAD_ERROR_D; + } + ++ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ ++ offset = 0; + end = 0; + while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) + { +@@ -997,6 +1013,11 @@ + sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); + cancel_upload = UPLOAD_ERROR_B; + } else if (blen > 0) { ++ ++ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + wlen = write(fd, buff, blen); + + if (wlen < blen) { +@@ -1004,6 +1025,7 @@ + cancel_upload = UPLOAD_ERROR_F; + } else { + total_bytes += wlen; ++ offset += wlen; + } + } + } +@@ -1025,6 +1047,10 @@ + } + #endif + ++ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + if (cancel_upload) { + if (temp_filename) { + if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ +diff -Nura php-4.4.2/main/SAPI.c hardening-patch-4.4.2-0.4.15/main/SAPI.c +--- php-4.4.2/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/SAPI.c 2006-09-05 20:30:33.000000000 +0200 +@@ -854,6 +854,37 @@ + return SUCCESS; + } + ++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)) ++{ ++ sapi_module.input_filter = input_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) ++{ ++ sapi_module.upload_varname_filter = upload_varname_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) ++{ ++ sapi_module.pre_upload_filter = pre_upload_filter; ++ return SUCCESS; ++} ++ ++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)) ++{ ++ sapi_module.upload_content_filter = upload_content_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) ++{ ++ sapi_module.post_upload_filter = post_upload_filter; ++ return SUCCESS; ++} ++ ++ + + SAPI_API int sapi_flush(TSRMLS_D) + { +diff -Nura php-4.4.2/main/SAPI.h hardening-patch-4.4.2-0.4.15/main/SAPI.h +--- php-4.4.2/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/SAPI.h 2006-09-05 20:30:33.000000000 +0200 +@@ -101,9 +101,10 @@ + char *current_user; + int current_user_length; + +- /* this is necessary for CLI module */ +- int argc; +- char **argv; ++ /* this is necessary for CLI module */ ++ int argc; ++ char **argv; ++ + } sapi_request_info; + + +@@ -177,6 +178,10 @@ + SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); + SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); + SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); + + SAPI_API int sapi_flush(TSRMLS_D); + SAPI_API struct stat *sapi_get_stat(TSRMLS_D); +@@ -238,8 +243,16 @@ + int (*get_target_uid)(uid_t * TSRMLS_DC); + int (*get_target_gid)(gid_t * TSRMLS_DC); + ++ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); ++ ++ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); ++ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); ++ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); ++ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); ++ + void (*ini_defaults)(HashTable *configuration_hash); + int phpinfo_as_text; ++ + }; + + +@@ -262,16 +275,27 @@ + + #define SAPI_DEFAULT_MIMETYPE "text/html" + #define SAPI_DEFAULT_CHARSET "" ++ ++#if HARDENING_PATCH ++#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" ++#else + #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION ++#endif + + #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) + #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) + + #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) ++#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) ++#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) ++#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) ++#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) ++#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) + + SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); + SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); + SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); ++SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter); + + #define STANDARD_SAPI_MODULE_PROPERTIES + +diff -Nura php-4.4.2/main/snprintf.c hardening-patch-4.4.2-0.4.15/main/snprintf.c +--- php-4.4.2/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/snprintf.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1014,7 +1014,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = cc; ++#endif + break; + + /* +diff -Nura php-4.4.2/main/spprintf.c hardening-patch-4.4.2-0.4.15/main/spprintf.c +--- php-4.4.2/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/spprintf.c 2006-09-05 20:30:33.000000000 +0200 +@@ -630,7 +630,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = xbuf->len; ++#endif + break; + + /* +diff -Nura php-4.4.2/main/streams.c hardening-patch-4.4.2-0.4.15/main/streams.c +--- php-4.4.2/main/streams.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/main/streams.c 2006-09-05 20:30:33.000000000 +0200 +@@ -20,7 +20,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: streams.c,v 1.125.2.100.2.2 2006/01/01 13:47:00 sniper Exp $ */ ++/* $Id: streams.c,v 1.125.2.100.2.3 2006/05/19 10:24:42 tony2001 Exp $ */ + + #define _GNU_SOURCE + #include "php.h" +@@ -445,7 +445,7 @@ + * charsets (for example) but still be able to provide them all as filters */ + PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, const char *filterparams, int filterparamslen, int persistent TSRMLS_DC) + { +- php_stream_filter_factory *factory; ++ php_stream_filter_factory *factory = NULL; + php_stream_filter *filter = NULL; + int n; + char *period; +diff -Nura php-4.4.2/php.ini-dist hardening-patch-4.4.2-0.4.15/php.ini-dist +--- php-4.4.2/php.ini-dist 2005-12-30 18:19:43.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/php.ini-dist 2006-09-05 20:30:33.000000000 +0200 +@@ -1114,6 +1114,209 @@ + ;exif.decode_jis_motorola = JIS + ;exif.decode_jis_intel = JIS + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-4.4.2/php.ini-recommended hardening-patch-4.4.2-0.4.15/php.ini-recommended +--- php-4.4.2/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/php.ini-recommended 2006-09-05 20:30:33.000000000 +0200 +@@ -1112,6 +1112,209 @@ + ;exif.decode_jis_motorola = JIS + ;exif.decode_jis_intel = JIS + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-4.4.2/README.input_filter hardening-patch-4.4.2-0.4.15/README.input_filter +--- php-4.4.2/README.input_filter 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/README.input_filter 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,193 @@ ++Input Filter Support ported from PHP 5 ++-------------------------------------- ++ ++XSS (Cross Site Scripting) hacks are becoming more and more prevalent, ++and can be quite difficult to prevent. Whenever you accept user data ++and somehow display this data back to users, you are likely vulnerable ++to XSS hacks. ++ ++The Input Filter support in PHP 5 is aimed at providing the framework ++through which a company-wide or site-wide security policy can be ++enforced. It is implemented as a SAPI hook and is called from the ++treat_data and post handler functions. To implement your own security ++policy you will need to write a standard PHP extension. ++ ++A simple implementation might look like the following. This stores the ++original raw user data and adds a my_get_raw() function while the normal ++$_POST, $_GET and $_COOKIE arrays are only populated with stripped ++data. In this simple example all I am doing is calling strip_tags() on ++the data. If register_globals is turned on, the default globals that ++are created will be stripped ($foo) while a $RAW_foo is created with the ++original user input. ++ ++ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) ++ zval *post_array; ++ zval *get_array; ++ zval *cookie_array; ++ZEND_END_MODULE_GLOBALS(my_input_filter) ++ ++#ifdef ZTS ++#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v) ++#else ++#define IF_G(v) (my_input_filter_globals.v) ++#endif ++ ++ZEND_DECLARE_MODULE_GLOBALS(my_input_filter) ++ ++function_entry my_input_filter_functions[] = { ++ PHP_FE(my_get_raw, NULL) ++ {NULL, NULL, NULL} ++}; ++ ++zend_module_entry my_input_filter_module_entry = { ++ STANDARD_MODULE_HEADER, ++ "my_input_filter", ++ my_input_filter_functions, ++ PHP_MINIT(my_input_filter), ++ PHP_MSHUTDOWN(my_input_filter), ++ NULL, ++ PHP_RSHUTDOWN(my_input_filter), ++ PHP_MINFO(my_input_filter), ++ "0.1", ++ STANDARD_MODULE_PROPERTIES ++}; ++ ++PHP_MINIT_FUNCTION(my_input_filter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL); ++ ++ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); ++ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); ++ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); ++ ++ sapi_register_input_filter(my_sapi_input_filter); ++ return SUCCESS; ++} ++ ++PHP_RSHUTDOWN_FUNCTION(my_input_filter) ++{ ++ if(IF_G(get_array)) { ++ zval_ptr_dtor(&IF_G(get_array)); ++ IF_G(get_array) = NULL; ++ } ++ if(IF_G(post_array)) { ++ zval_ptr_dtor(&IF_G(post_array)); ++ IF_G(post_array) = NULL; ++ } ++ if(IF_G(cookie_array)) { ++ zval_ptr_dtor(&IF_G(cookie_array)); ++ IF_G(cookie_array) = NULL; ++ } ++ return SUCCESS; ++} ++ ++PHP_MINFO_FUNCTION(my_input_filter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); ++ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $"); ++ php_info_print_table_end(); ++} ++ ++/* The filter handler. If you return 1 from it, then PHP also registers the ++ * (modified) variable. Returning 0 prevents PHP from registering the variable; ++ * you can use this if your filter already registers the variable under a ++ * different name, or if you just don't want the variable registered at all. */ ++SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter) ++{ ++ zval new_var; ++ zval *array_ptr = NULL; ++ char *raw_var; ++ int var_len; ++ ++ assert(*val != NULL); ++ ++ switch(arg) { ++ case PARSE_GET: ++ if(!IF_G(get_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(get_array) = array_ptr; ++ break; ++ case PARSE_POST: ++ if(!IF_G(post_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(post_array) = array_ptr; ++ break; ++ case PARSE_COOKIE: ++ if(!IF_G(cookie_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(cookie_array) = array_ptr; ++ break; ++ } ++ Z_STRLEN(new_var) = val_len; ++ Z_STRVAL(new_var) = estrndup(*val, val_len); ++ Z_TYPE(new_var) = IS_STRING; ++ ++ var_len = strlen(var); ++ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ ++ strcpy(raw_var, "RAW_"); ++ strlcat(raw_var,var,var_len+5); ++ ++ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC); ++ ++ php_strip_tags(*val, val_len, NULL, NULL, 0); ++ ++ *new_val_len = strlen(*val); ++ return 1; ++} ++ ++PHP_FUNCTION(my_get_raw) ++{ ++ long arg; ++ char *var; ++ int var_len; ++ zval **tmp; ++ zval *array_ptr = NULL; ++ HashTable *hash_ptr; ++ char *raw_var; ++ ++ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) { ++ return; ++ } ++ ++ switch(arg) { ++ case PARSE_GET: ++ array_ptr = IF_G(get_array); ++ break; ++ case PARSE_POST: ++ array_ptr = IF_G(post_array); ++ break; ++ case PARSE_COOKIE: ++ array_ptr = IF_G(post_array); ++ break; ++ } ++ ++ if(!array_ptr) RETURN_FALSE; ++ ++ /* ++ * I'm changing the variable name here because when running with register_globals on, ++ * the variable will end up in the global symbol table ++ */ ++ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ ++ strcpy(raw_var, "RAW_"); ++ strlcat(raw_var,var,var_len+5); ++ hash_ptr = HASH_OF(array_ptr); ++ ++ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) { ++ *return_value = **tmp; ++ zval_copy_ctor(return_value); ++ } else { ++ RETVAL_FALSE; ++ } ++ efree(raw_var); ++} ++ +diff -Nura php-4.4.2/run-tests.php hardening-patch-4.4.2-0.4.15/run-tests.php +--- php-4.4.2/run-tests.php 2006-01-01 14:46:48.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/run-tests.php 2006-09-05 20:30:33.000000000 +0200 +@@ -152,6 +152,10 @@ + 'error_reporting=2047', + 'display_errors=1', + 'log_errors=0', ++ 'hphp.executor.include.whitelist=cookietest', ++ 'hphp.log.syslog=0', ++ 'hphp.log.sapi=0', ++ 'hphp.log.script=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=1', +diff -Nura php-4.4.2/sapi/apache/mod_php4.c hardening-patch-4.4.2-0.4.15/sapi/apache/mod_php4.c +--- php-4.4.2/sapi/apache/mod_php4.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/sapi/apache/mod_php4.c 2006-09-05 20:30:33.000000000 +0200 +@@ -452,7 +452,7 @@ + sapi_apache_get_fd, + sapi_apache_force_http_10, + sapi_apache_get_target_uid, +- sapi_apache_get_target_gid ++ sapi_apache_get_target_gid, + }; + /* }}} */ + +@@ -898,7 +898,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component("PHP/" PHP_VERSION); ++#endif + } + } + #endif +diff -Nura php-4.4.2/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.2-0.4.15/sapi/apache2filter/sapi_apache2.c +--- php-4.4.2/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:30:33.000000000 +0200 +@@ -562,7 +562,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-4.4.2/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.2-0.4.15/sapi/apache2handler/sapi_apache2.c +--- php-4.4.2/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:30:33.000000000 +0200 +@@ -340,7 +340,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-4.4.2/sapi/cgi/cgi_main.c hardening-patch-4.4.2-0.4.15/sapi/cgi/cgi_main.c +--- php-4.4.2/sapi/cgi/cgi_main.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1432,11 +1432,19 @@ + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } ++#if HARDENING_PATCH ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif ++#else + #if ZEND_DEBUG + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #else + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #endif ++#endif + php_end_ob_buffers(1 TSRMLS_CC); + exit(0); + break; +diff -Nura php-4.4.2/sapi/cli/php_cli.c hardening-patch-4.4.2-0.4.15/sapi/cli/php_cli.c +--- php-4.4.2/sapi/cli/php_cli.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:30:33.000000000 +0200 +@@ -654,11 +654,19 @@ + if (php_request_startup(TSRMLS_C)==FAILURE) { + goto err; + } ++#if HARDENING_PATCH ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif ++#else + #if ZEND_DEBUG + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #else + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #endif ++#endif + php_end_ob_buffers(1 TSRMLS_CC); + exit_status=0; + goto out; +diff -Nura php-4.4.2/TSRM/TSRM.h hardening-patch-4.4.2-0.4.15/TSRM/TSRM.h +--- php-4.4.2/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200 ++++ hardening-patch-4.4.2-0.4.15/TSRM/TSRM.h 2006-09-05 20:30:33.000000000 +0200 +@@ -33,6 +33,13 @@ + # define TSRM_API + #endif + ++#if HARDENING_PATCH ++# if HAVE_REALPATH ++# undef realpath ++# define realpath php_realpath ++# endif ++#endif ++ + /* Only compile multi-threading functions if we're in ZTS mode */ + #ifdef ZTS + +@@ -84,6 +91,7 @@ + + #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts + ++ + #ifdef __cplusplus + extern "C" { + #endif +diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.c +--- php-4.4.2/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:30:33.000000000 +0200 +@@ -179,6 +179,178 @@ + return p; + } + ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved) ++{ ++ struct stat sb; ++ char *p, *q, *s; ++ size_t left_len, resolved_len; ++ unsigned symlinks; ++ int serrno, slen; ++ int is_dir = 1; ++ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; ++ ++ serrno = errno; ++ symlinks = 0; ++ if (path[0] == '/') { ++ resolved[0] = '/'; ++ resolved[1] = '\0'; ++ if (path[1] == '\0') ++ return (resolved); ++ resolved_len = 1; ++ left_len = strlcpy(left, path + 1, sizeof(left)); ++ } else { ++ if (getcwd(resolved, PATH_MAX) == NULL) { ++ strlcpy(resolved, ".", PATH_MAX); ++ return (NULL); ++ } ++ resolved_len = strlen(resolved); ++ left_len = strlcpy(left, path, sizeof(left)); ++ } ++ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ ++ /* ++ * Iterate over path components in `left'. ++ */ ++ while (left_len != 0) { ++ /* ++ * Extract the next path component and adjust `left' ++ * and its length. ++ */ ++ p = strchr(left, '/'); ++ s = p ? p : left + left_len; ++ if (s - left >= sizeof(next_token)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ memcpy(next_token, left, s - left); ++ next_token[s - left] = '\0'; ++ left_len -= s - left; ++ if (p != NULL) ++ memmove(left, s + 1, left_len + 1); ++ if (resolved[resolved_len - 1] != '/') { ++ if (resolved_len + 1 >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ resolved[resolved_len++] = '/'; ++ resolved[resolved_len] = '\0'; ++ } ++ if (next_token[0] == '\0') ++ continue; ++ else if (strcmp(next_token, ".") == 0) ++ continue; ++ else if (strcmp(next_token, "..") == 0) { ++ /* ++ * Strip the last path component except when we have ++ * single "/" ++ */ ++ if (!is_dir) { ++ errno = ENOENT; ++ return (NULL); ++ } ++ if (resolved_len > 1) { ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ continue; ++ } ++ ++ /* ++ * Append the next path component and lstat() it. If ++ * lstat() fails we still can return successfully if ++ * there are no more path components left. ++ */ ++ resolved_len = strlcat(resolved, next_token, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ if (lstat(resolved, &sb) != 0) { ++ if (errno == ENOENT) { ++ if (p == NULL) { ++ errno = serrno; ++ return (resolved); ++ } else ++ /* dirty hack to support a vanilla PHP feature */ ++ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { ++ resolved_len = strlcat(resolved, "/", PATH_MAX); ++ resolved_len = strlcat(resolved, left, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ errno = serrno; ++ return (resolved); ++ } ++ } ++ return (NULL); ++ } ++ if (S_ISLNK(sb.st_mode)) { ++ if (symlinks++ > MAXSYMLINKS) { ++ errno = ELOOP; ++ return (NULL); ++ } ++ slen = readlink(resolved, symlink, sizeof(symlink) - 1); ++ if (slen < 0) ++ return (NULL); ++ symlink[slen] = '\0'; ++ if (symlink[0] == '/') { ++ resolved[1] = 0; ++ resolved_len = 1; ++ } else if (resolved_len > 1) { ++ /* Strip the last path component. */ ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ ++ /* ++ * If there are any path components left, then ++ * append them to symlink. The result is placed ++ * in `left'. ++ */ ++ if (p != NULL) { ++ if (symlink[slen - 1] != '/') { ++ if (slen + 1 >= sizeof(symlink)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ symlink[slen] = '/'; ++ symlink[slen + 1] = 0; ++ } ++ left_len = strlcat(symlink, left, sizeof(left)); ++ if (left_len >= sizeof(left)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ } ++ left_len = strlcpy(left, symlink, sizeof(left)); ++ } else { ++ if (S_ISDIR(sb.st_mode)) { ++ is_dir = 1; ++ } else { ++ is_dir = 0; ++ } ++ } ++ } ++ ++ /* ++ * Remove trailing slash except when the resolved pathname ++ * is a single "/". ++ */ ++ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') ++ resolved[resolved_len - 1] = '\0'; ++ return (resolved); ++} ++#endif ++ + CWD_API void virtual_cwd_startup(void) + { + char cwd[MAXPATHLEN]; +@@ -300,8 +472,11 @@ + + if (path_length == 0) + return (0); +- if (path_length >= MAXPATHLEN) ++ if (path_length >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return (1); ++ } + + #if !defined(TSRM_WIN32) && !defined(NETWARE) + /* cwd_length can be 0 when getcwd() fails. +@@ -313,8 +488,9 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + } else { /* Concat current directory with relative path and then run realpath() on it */ +@@ -323,6 +499,8 @@ + + ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); + if (!tmp) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(ptr, state->cwd, state->cwd_length); +@@ -332,6 +510,8 @@ + ptr += path_length; + *ptr = '\0'; + if (strlen(tmp) >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + free(tmp); + return 1; + } +@@ -340,9 +520,10 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + free(tmp); +- return 1; */ ++ return 1; + } + } + free(tmp); +diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.h +--- php-4.4.2/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:30:33.000000000 +0200 +@@ -128,6 +128,22 @@ + + typedef int (*verify_path_func)(const cwd_state *); + ++#ifndef HAVE_STRLCPY ++CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); ++#undef strlcpy ++#define strlcpy php_strlcpy ++#endif ++ ++#ifndef HAVE_STRLCAT ++CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); ++#undef strlcat ++#define strlcat php_strlcat ++#endif ++ ++ ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved); ++#endif + CWD_API void virtual_cwd_startup(void); + CWD_API void virtual_cwd_shutdown(void); + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); +diff -Nura php-4.4.2/Zend/zend_alloc.c hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.c +--- php-4.4.2/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.c 2006-09-05 20:30:33.000000000 +0200 +@@ -56,6 +56,11 @@ + # define END_MAGIC_SIZE 0 + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++# define CANARY_SIZE sizeof(unsigned int) ++#else ++# define CANARY_SIZE 0 ++#endif + + # if MEMORY_LIMIT + # if ZEND_DEBUG +@@ -64,7 +69,15 @@ + #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) + # endif + +-#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ ++#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ ++ if (file) { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ ++ } else { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ ++ } \ ++ exit(1); \ ++ } \ ++ AG(allocated_memory) += rs;\ + if (AG(memory_limit)pNext; \ + } else { \ ++ if (p != p->pLast->pNext) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pLast->pNext = p->pNext; \ + } \ + if (p->pNext) { \ ++ if (p != p->pNext->pLast) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pNext->pLast = p->pLast; \ + } + +@@ -111,7 +132,7 @@ + p->pLast = (zend_mem_header *) NULL; + + #define DECLARE_CACHE_VARS() \ +- unsigned int real_size; \ ++ size_t real_size; \ + unsigned int cache_index + + #define REAL_SIZE(size) ((size+7) & ~0x7) +@@ -126,12 +147,22 @@ + + ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { +- zend_mem_header *p; ++ zend_mem_header *p = NULL; + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { ++ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); ++ exit(1); ++ } ++#endif + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + ++ if (size > INT_MAX || SIZE < size) { ++ goto emalloc_error; ++ } ++ + if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { + p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; + #if ZEND_DEBUG +@@ -147,6 +178,10 @@ + AG(cache_stats)[CACHE_INDEX][1]++; + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->cached = 0; + p->size = size; + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); +@@ -162,9 +197,11 @@ + AG(allocated_memory_peak) = AG(allocated_memory); + } + #endif +- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); + } + ++emalloc_error: ++ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (!p) { +@@ -192,7 +229,10 @@ + # endif + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif +- ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } +@@ -219,17 +259,36 @@ + return emalloc_rel(lval + offset); + } + } +- ++ ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); ++#endif + zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset); + return 0; + } + + ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++efree_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); ++ exit(1); ++ } ++ /* to catch double efree()s */ ++ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); ++ p->canary = 0; ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring", +@@ -274,6 +333,9 @@ + size_t _size = nmemb * size; + + if (nmemb && (_size/nmemb!=size)) { ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); ++#endif + fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); + #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID + kill(getpid(), SIGSEGV); +@@ -293,6 +355,9 @@ + + ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p; + zend_mem_header *orig; + DECLARE_CACHE_VARS(); +@@ -304,6 +369,16 @@ + + p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++erealloc_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); ++ exit(1); ++ } ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + void *new_p; +@@ -320,6 +395,13 @@ + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + + HANDLE_BLOCK_INTERRUPTIONS(); ++ ++ if (size > INT_MAX || SIZE < size) { ++ REMOVE_POINTER_FROM_LIST(p); ++ p = NULL; ++ goto erealloc_error; ++ } ++ + #if MEMORY_LIMIT + CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); + if (AG(allocated_memory) > AG(allocated_memory_peak)) { +@@ -327,7 +409,8 @@ + } + #endif + REMOVE_POINTER_FROM_LIST(p); +- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); ++erealloc_error: + if (!p) { + if (!allow_failure) { + fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); +@@ -349,6 +432,9 @@ + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + + HANDLE_UNBLOCK_INTERRUPTIONS(); +@@ -423,6 +509,10 @@ + { + AG(head) = NULL; + ++#if HARDENING_PATCH_MM_PROTECT ++ HG(canary_1) = zend_canary(); ++ HG(canary_2) = zend_canary(); ++#endif + #if MEMORY_LIMIT + AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ + AG(allocated_memory) = 0; +diff -Nura php-4.4.2/Zend/zend_alloc.h hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.h +--- php-4.4.2/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.h 2006-09-05 20:30:33.000000000 +0200 +@@ -32,6 +32,9 @@ + #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL + + typedef struct _zend_mem_header { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary; ++#endif + #if ZEND_DEBUG + long magic; + char *filename; +diff -Nura php-4.4.2/Zend/zend_builtin_functions.c hardening-patch-4.4.2-0.4.15/Zend/zend_builtin_functions.c +--- php-4.4.2/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:30:33.000000000 +0200 +@@ -49,6 +49,9 @@ + static ZEND_FUNCTION(crash); + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++static ZEND_FUNCTION(heap_overflow); ++#endif + static ZEND_FUNCTION(get_included_files); + static ZEND_FUNCTION(is_subclass_of); + static ZEND_FUNCTION(is_a); +@@ -101,6 +104,9 @@ + ZEND_FE(crash, NULL) + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ ZEND_FE(heap_overflow, NULL) ++#endif + ZEND_FE(get_included_files, NULL) + ZEND_FALIAS(get_required_files, get_included_files, NULL) + ZEND_FE(is_subclass_of, NULL) +@@ -805,6 +811,19 @@ + + #endif /* ZEND_DEBUG */ + ++ ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ZEND_FUNCTION(heap_overflow) ++{ ++ char *nowhere = emalloc(10); ++ ++ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); ++ ++ efree(nowhere); ++} ++#endif ++ ++ + /* {{{ proto array get_included_files(void) + Returns an array with the file names that were include_once()'d */ + ZEND_FUNCTION(get_included_files) +diff -Nura php-4.4.2/Zend/zend.c hardening-patch-4.4.2-0.4.15/Zend/zend.c +--- php-4.4.2/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend.c 2006-09-05 20:30:33.000000000 +0200 +@@ -53,6 +53,12 @@ + ZEND_API void (*zend_unblock_interruptions)(void); + ZEND_API void (*zend_ticks_function)(int ticks); + ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); ++#if HARDENING_PATCH ++ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + + void (*zend_on_timeout)(int seconds TSRMLS_DC); + +@@ -70,9 +76,391 @@ + return SUCCESS; + } + ++#if HARDENING_PATCH ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; ++ } else { ++ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_facility) = LOG_USER; ++ } else { ++ EG(hphp_log_syslog_facility) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_priority) = LOG_ALERT; ++ } else { ++ EG(hphp_log_syslog_priority) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_sapi) ++{ ++ if (!new_value) { ++ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; ++ } else { ++ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_script) ++{ ++ if (!new_value) { ++ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL); ++ } else { ++ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) ++{ ++ if (EG(hphp_log_scriptname)) { ++ pefree(EG(hphp_log_scriptname),1); ++ } ++ EG(hphp_log_scriptname) = NULL; ++ if (new_value) { ++ EG(hphp_log_scriptname) = pestrdup(new_value,1); ++ } ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_whitelist_destroy: ++ if (HG(include_whitelist)) { ++ zend_hash_destroy(HG(include_whitelist)); ++ pefree(HG(include_whitelist),1); ++ } ++ HG(include_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_whitelist_destroy; ++ } ++ ++ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_blacklist_destroy: ++ if (HG(include_blacklist)) { ++ zend_hash_destroy(HG(include_blacklist)); ++ pefree(HG(include_blacklist),1); ++ } ++ HG(include_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_blacklist_destroy; ++ } ++ ++ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_whitelist_destroy: ++ if (HG(eval_whitelist)) { ++ zend_hash_destroy(HG(eval_whitelist)); ++ pefree(HG(eval_whitelist),1); ++ } ++ HG(eval_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_whitelist_destroy; ++ } ++ ++ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_blacklist_destroy: ++ if (HG(eval_blacklist)) { ++ zend_hash_destroy(HG(eval_blacklist)); ++ pefree(HG(eval_blacklist), 1); ++ } ++ HG(eval_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_blacklist_destroy; ++ } ++ ++ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_whitelist_destroy: ++ if (HG(func_whitelist)) { ++ zend_hash_destroy(HG(func_whitelist)); ++ pefree(HG(func_whitelist),1); ++ } ++ HG(func_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_whitelist_destroy; ++ } ++ ++ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_blacklist_destroy: ++ if (HG(func_blacklist)) { ++ zend_hash_destroy(HG(func_blacklist)); ++ pefree(HG(func_blacklist),1); ++ } ++ HG(func_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_blacklist_destroy; ++ } ++ ++ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++#endif + + ZEND_INI_BEGIN() + ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) ++#if HARDENING_PATCH ++ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) ++ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) ++ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) ++ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) ++ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) ++ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) ++ 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) ++ ++ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) ++ ++ 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) ++ 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) ++ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) ++ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) ++#endif + ZEND_INI_END() + + +@@ -354,8 +742,12 @@ + zend_init_rsrc_plist(TSRMLS_C); + EG(lambda_count)=0; + EG(user_error_handler) = NULL; ++ EG(in_code_type) = 0; + EG(in_execution) = 0; + EG(current_execute_data) = NULL; ++#if HARDENING_PATCH ++ EG(hphp_log_scriptname) = NULL; ++#endif + } + + +@@ -420,6 +812,14 @@ + extern zend_scanner_globals language_scanner_globals; + #endif + ++ /* Set up Hardening-Patch utility functions first */ ++#if HARDENING_PATCH ++ zend_security_log = utility_functions->security_log_function; ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ zend_is_valid_include = utility_functions->is_valid_include; ++#endif ++ + #ifdef ZTS + ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + #else +@@ -619,6 +1019,7 @@ + } + CG(unclean_shutdown) = 1; + CG(in_compilation) = EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(current_execute_data) = NULL; + longjmp(EG(bailout), FAILURE); + } +diff -Nura php-4.4.2/Zend/zend_canary.c hardening-patch-4.4.2-0.4.15/Zend/zend_canary.c +--- php-4.4.2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_canary.c 2006-09-05 20:30:33.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ ++ ++#include "zend.h" ++ ++#include ++#include ++ ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++ZEND_API unsigned int zend_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.2/Zend/zend_compile.c hardening-patch-4.4.2-0.4.15/Zend/zend_compile.c +--- php-4.4.2/Zend/zend_compile.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_compile.c 2006-09-05 20:30:33.000000000 +0200 +@@ -768,6 +768,13 @@ + op_array.function_name = name; + op_array.arg_types = NULL; + op_array.return_reference = return_reference; ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array.created_by_eval = 1; ++ } else { ++ op_array.created_by_eval = 0; ++ } ++#endif + + if (is_method) { + if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { +diff -Nura php-4.4.2/Zend/zend_compile.h hardening-patch-4.4.2-0.4.15/Zend/zend_compile.h +--- php-4.4.2/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_compile.h 2006-09-05 20:30:33.000000000 +0200 +@@ -106,6 +106,9 @@ + char *filename; + + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; ++#if HARDENING_PATCH ++ zend_bool created_by_eval; ++#endif + }; + + +@@ -549,6 +552,7 @@ + #define ZEND_USER_FUNCTION 2 + #define ZEND_OVERLOADED_FUNCTION 3 + #define ZEND_EVAL_CODE 4 ++#define ZEND_SANDBOX_CODE 6 + + #define ZEND_INTERNAL_CLASS 1 + #define ZEND_USER_CLASS 2 +diff -Nura php-4.4.2/Zend/zend_constants.c hardening-patch-4.4.2-0.4.15/Zend/zend_constants.c +--- php-4.4.2/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_constants.c 2006-09-05 20:30:33.000000000 +0200 +@@ -111,6 +111,74 @@ + REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); + + REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); ++ ++ /* error levels */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); ++ /* facility: type of program logging the message */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NEWS ++ /* No LOG_NEWS on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ ++#endif ++#ifdef LOG_UUCP ++ /* No LOG_UUCP on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_CRON ++ /* apparently some systems don't have this one */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_AUTHPRIV ++ /* AIX doesn't have LOG_AUTHPRIV */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); ++#endif ++#if !defined(PHP_WIN32) && !defined(NETWARE) ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); ++#endif ++ /* options */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NOWAIT ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_PERROR ++ /* AIX doesn't have LOG_PERROR */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ ++#endif ++#endif + + /* true/false constants */ + { +diff -Nura php-4.4.2/Zend/zend_errors.h hardening-patch-4.4.2-0.4.15/Zend/zend_errors.h +--- php-4.4.2/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_errors.h 2006-09-05 20:30:33.000000000 +0200 +@@ -36,5 +36,18 @@ + #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) + #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) + ++#if HARDENING_PATCH ++#define S_MEMORY (1<<0L) ++#define S_VARS (1<<1L) ++#define S_FILES (1<<2L) ++#define S_INCLUDE (1<<3L) ++#define S_SQL (1<<4L) ++#define S_EXECUTOR (1<<5L) ++#define S_MAIL (1<<6L) ++#define S_MISC (1<<30L) ++#define S_INTERNAL (1<<29L) ++#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) ++#endif ++ + #endif /* ZEND_ERRORS_H */ + +diff -Nura php-4.4.2/Zend/zend_execute_API.c hardening-patch-4.4.2-0.4.15/Zend/zend_execute_API.c +--- php-4.4.2/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:30:33.000000000 +0200 +@@ -142,6 +142,7 @@ + EG(class_table) = CG(class_table); + + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + + zend_ptr_stack_init(&EG(argument_stack)); + +@@ -431,12 +432,14 @@ + zend_execute_data execute_data; + + /* Initialize execute_data */ ++ memset(&execute_data, 0, sizeof(execute_data)); + EX(fbc) = NULL; + EX(object).ptr = NULL; + EX(ce) = NULL; + EX(Ts) = NULL; + EX(op_array) = NULL; + EX(opline) = NULL; ++ EX(execute_depth) = 0; + + *retval_ptr_ptr = NULL; + +@@ -494,6 +497,39 @@ + zval_dtor(&function_name_copy); + return FAILURE; + } ++#if HARDENING_PATCH ++ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + zval_dtor(&function_name_copy); + + for (i=0; itype = type; + EG(return_value_ptr_ptr) = &local_retval_ptr; + EG(active_op_array) = new_op_array; + EG(no_extensions)=1; +@@ -673,6 +709,10 @@ + return retval; + } + ++ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++{ ++ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); ++} + + void execute_new_code(TSRMLS_D) + { +diff -Nura php-4.4.2/Zend/zend_execute.c hardening-patch-4.4.2-0.4.15/Zend/zend_execute.c +--- php-4.4.2/Zend/zend_execute.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_execute.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1042,6 +1042,7 @@ + zend_execute_data execute_data; + + /* Initialize execute_data */ ++ memset(&execute_data, 0, sizeof(execute_data)); + EX(fbc) = NULL; + EX(ce) = NULL; + EX(object).ptr = NULL; +@@ -1053,9 +1054,21 @@ + } + EX(prev_execute_data) = EG(current_execute_data); + EX(original_in_execution)=EG(in_execution); ++ EX(original_in_code_type)=EG(in_code_type); + + EG(current_execute_data) = &execute_data; + ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif ++ + EG(in_execution) = 1; + if (op_array->start_op) { + EX(opline) = op_array->start_op; +@@ -1087,6 +1100,19 @@ + } + } + ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif ++ + while (1) { + #ifdef ZEND_WIN32 + if (EG(timed_out)) { +@@ -1634,6 +1660,36 @@ + if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) { + zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val); + } ++#if HARDENING_PATCH ++ if (active_function_table == EG(function_table)) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++#endif ++ + zval_dtor(&tmp); + EX(fbc) = function; + overloaded_function_call_cont: +@@ -1649,6 +1705,35 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); + zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce)); + EX(object).ptr = NULL; +@@ -1821,6 +1906,7 @@ + efree(EX(Ts)); + } + EG(in_execution) = EX(original_in_execution); ++ EG(in_code_type) = EX(original_in_code_type); + EG(current_execute_data) = EX(prev_execute_data); + return; + } +@@ -2210,7 +2296,12 @@ + int dummy = 1; + zend_file_handle file_handle = {0}; + ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS ++#else + if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS ++#endif + && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { + + file_handle.filename = inc_filename->value.str.val; +@@ -2239,6 +2330,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -2381,7 +2477,7 @@ + if (EX(opline)->extended_value) { + array_ptr_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R); + if (array_ptr_ptr == NULL) { +- MAKE_STD_ZVAL(array_ptr); ++ ALLOC_INIT_ZVAL(array_ptr); + } else { + SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr); + array_ptr = *array_ptr_ptr; +diff -Nura php-4.4.2/Zend/zend_execute_globals.h hardening-patch-4.4.2-0.4.15/Zend/zend_execute_globals.h +--- php-4.4.2/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_execute_globals.h 2006-09-05 20:30:33.000000000 +0200 +@@ -60,6 +60,8 @@ + object_info object; + temp_variable *Ts; + zend_bool original_in_execution; ++ zend_uint original_in_code_type; ++ zend_uint execute_depth; + zend_op_array *op_array; + struct _zend_execute_data *prev_execute_data; + } zend_execute_data; +diff -Nura php-4.4.2/Zend/zend_extensions.c hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.c +--- php-4.4.2/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.c 2006-09-05 20:30:33.000000000 +0200 +@@ -54,23 +54,44 @@ + return FAILURE; + } + ++ /* check if module is compiled against Hardening-Patch */ ++ if (extension_version_info->zend_extension_api_no < 1000000000) { ++ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } ++ ++ ++ /* check if module is compiled against correct Hardening-Patch version */ ++ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { ++ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ extension_version_info->zend_extension_api_no, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } + + /* allow extension to proclaim compatibility with any Zend version */ +- 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)) { +- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { ++ 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)) { ++ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is outdated.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO); + DL_UNLOAD(handle); + return FAILURE; +- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { ++ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is newer.\n" + "Contact %s at %s for a later version of %s.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO, + new_extension->author, + new_extension->URL, +diff -Nura php-4.4.2/Zend/zend_extensions.h hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.h +--- php-4.4.2/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.h 2006-09-05 20:30:33.000000000 +0200 +@@ -23,6 +23,9 @@ + + #include "zend_compile.h" + ++/* Create own API version number for Hardening-Patch */ ++ ++#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805 + #define ZEND_EXTENSION_API_NO 20050606 + + typedef struct _zend_extension_version_info { +@@ -30,6 +33,7 @@ + char *required_zend_version; + unsigned char thread_safe; + unsigned char debug; ++ int real_zend_extension_api_no; + } zend_extension_version_info; + + +@@ -96,7 +100,7 @@ + + + #define ZEND_EXTENSION() \ +- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } ++ 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 } + + #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 + #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 +diff -Nura php-4.4.2/Zend/zend_globals.h hardening-patch-4.4.2-0.4.15/Zend/zend_globals.h +--- php-4.4.2/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_globals.h 2006-09-05 20:30:33.000000000 +0200 +@@ -163,6 +163,16 @@ + + int error_reporting; + int orig_error_reporting; ++#if HARDENING_PATCH ++ int hphp_log_syslog; ++ int hphp_log_syslog_facility; ++ int hphp_log_syslog_priority; ++ int hphp_log_sapi; ++ int hphp_log_script; ++ char *hphp_log_scriptname; ++ zend_bool hphp_log_use_x_forwarded_for; ++ long hphp_executor_max_depth; ++#endif + int exit_status; + + zend_op_array *active_op_array; +@@ -176,6 +186,7 @@ + int ticks_count; + + zend_bool in_execution; ++ zend_uint in_code_type; + zend_bool bailout_set; + zend_bool full_tables_cleanup; + +diff -Nura php-4.4.2/Zend/zend.h hardening-patch-4.4.2-0.4.15/Zend/zend.h +--- php-4.4.2/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend.h 2006-09-05 20:30:33.000000000 +0200 +@@ -274,9 +274,10 @@ + struct _zval_struct { + /* Variable information */ + zvalue_value value; /* value */ ++ zend_uint refcount; ++ zend_ushort flags; + zend_uchar type; /* active type */ + zend_uchar is_ref; +- zend_ushort refcount; + }; + + +@@ -337,6 +338,12 @@ + void (*ticks_function)(int ticks); + void (*on_timeout)(int seconds TSRMLS_DC); + zend_bool (*open_function)(const char *filename, struct _zend_file_handle *); ++#if HARDENING_PATCH ++ void (*security_log_function)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ int (*is_valid_include)(zval *z); ++#endif + } zend_utility_functions; + + +@@ -468,7 +475,16 @@ + extern ZEND_API void (*zend_ticks_function)(int ticks); + extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); + extern void (*zend_on_timeout)(int seconds TSRMLS_DC); ++#if HARDENING_PATCH ++extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++extern ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ZEND_API unsigned int zend_canary(void); ++#endif + + ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3); + +@@ -575,6 +591,11 @@ + + #define ZEND_MAX_RESERVED_RESOURCES 4 + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#include "php_syslog.h" ++#endif ++ + #endif /* ZEND_H */ + + /* +diff -Nura php-4.4.2/Zend/zend_hash.c hardening-patch-4.4.2-0.4.15/Zend/zend_hash.c +--- php-4.4.2/Zend/zend_hash.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_hash.c 2006-09-05 20:30:33.000000000 +0200 +@@ -26,6 +26,17 @@ + # include + #endif + ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int zend_hash_canary = 0x1234567; ++ zend_bool zend_hash_canary_inited = 0; ++#endif ++ ++#define CHECK_HASH_CANARY(hash) \ ++ if (zend_hash_canary != (hash)->canary) { \ ++ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ ++ exit(1); \ ++ } ++ + #define HANDLE_NUMERIC(key, length, func) { \ + register char *tmp=key; \ + \ +@@ -175,6 +186,9 @@ + { + uint i = 3; + Bucket **tmp; ++#if HARDENING_PATCH_HASH_PROTECT ++ TSRMLS_FETCH(); ++#endif + + SET_INCONSISTENT(HT_OK); + +@@ -184,6 +198,13 @@ + + ht->nTableSize = 1 << i; + ht->nTableMask = ht->nTableSize - 1; ++#if HARDENING_PATCH_HASH_PROTECT ++ if (zend_hash_canary_inited==0) { ++ zend_hash_canary = zend_canary(); ++ zend_hash_canary_inited = 1; ++ } ++ ht->canary = zend_hash_canary; ++#endif + ht->pDestructor = pDestructor; + ht->pListHead = NULL; + ht->pListTail = NULL; +@@ -259,6 +280,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -327,6 +351,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -402,6 +429,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -450,7 +480,7 @@ + IS_CONSISTENT(ht); + + if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ +- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); ++ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); + if (t) { + HANDLE_BLOCK_INTERRUPTIONS(); + ht->arBuckets = t; +@@ -460,6 +490,7 @@ + HANDLE_UNBLOCK_INTERRUPTIONS(); + return SUCCESS; + } ++ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); + return FAILURE; + } + return SUCCESS; +@@ -491,15 +522,17 @@ + IS_CONSISTENT(ht); + + if (flag == HASH_DEL_KEY) { +- HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, arKey, nKeyLength, idx, HASH_DEL_INDEX)); ++ HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, NULL, 0, idx, HASH_DEL_INDEX)); + h = zend_inline_hash_func(arKey, nKeyLength); + } + nIndex = h & ht->nTableMask; + + p = ht->arBuckets[nIndex]; + while (p != NULL) { +- if ((p->h == h) && ((p->nKeyLength == 0) || /* Numeric index */ +- ((p->nKeyLength == nKeyLength) && (!memcmp(p->arKey, arKey, nKeyLength))))) { ++ if ((p->h == h) ++ && (p->nKeyLength == nKeyLength) ++ && ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */ ++ || !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */ + HANDLE_BLOCK_INTERRUPTIONS(); + if (p == ht->arBuckets[nIndex]) { + ht->arBuckets[nIndex] = p->pNext; +@@ -524,6 +557,9 @@ + ht->pInternalPointer = p->pListNext; + } + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (!p->pDataPtr) { +@@ -553,6 +589,9 @@ + q = p; + p = p->pListNext; + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(q->pData); + } + if (!q->pDataPtr && q->pData) { +@@ -579,6 +618,9 @@ + q = p; + p = p->pListNext; + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(q->pData); + } + if (!q->pDataPtr && q->pData) { +@@ -608,6 +650,9 @@ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (!p->pDataPtr) { +diff -Nura php-4.4.2/Zend/zend_hash.h hardening-patch-4.4.2-0.4.15/Zend/zend_hash.h +--- php-4.4.2/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_hash.h 2006-09-05 20:30:33.000000000 +0200 +@@ -54,6 +54,9 @@ + } Bucket; + + typedef struct _hashtable { ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int canary; ++#endif + uint nTableSize; + uint nTableMask; + uint nNumOfElements; +diff -Nura php-4.4.2/Zend/zend_ini.c hardening-patch-4.4.2-0.4.15/Zend/zend_ini.c +--- php-4.4.2/Zend/zend_ini.c 2005-09-02 23:09:03.000000000 +0200 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_ini.c 2006-09-07 19:14:18.000000000 +0200 +@@ -256,7 +256,8 @@ + zend_ini_entry *ini_entry; + TSRMLS_FETCH(); + +- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { ++ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || ++ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifyable & ZEND_INI_USER) == 0)) { + return FAILURE; + } + +diff -Nura php-4.4.2/Zend/zend_ini.h hardening-patch-4.4.2-0.4.15/Zend/zend_ini.h +--- php-4.4.2/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_ini.h 2006-09-05 20:30:33.000000000 +0200 +@@ -174,6 +174,7 @@ + /* Standard message handlers */ + BEGIN_EXTERN_C() + ZEND_API ZEND_INI_MH(OnUpdateBool); ++#define OnUpdateLong OnUpdateInt + ZEND_API ZEND_INI_MH(OnUpdateInt); + ZEND_API ZEND_INI_MH(OnUpdateReal); + ZEND_API ZEND_INI_MH(OnUpdateString); +diff -Nura php-4.4.2/Zend/zend_language_scanner.l hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.l +--- php-4.4.2/Zend/zend_language_scanner.l 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:30:33.000000000 +0200 +@@ -393,6 +393,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-4.4.2/Zend/zend_language_scanner.c hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.c +--- php-4.4.2/Zend/zend_language_scanner.c 2006-01-12 19:24:28.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:30:33.000000000 +0200 +@@ -3036,6 +3036,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-4.4.2/Zend/zend_llist.c hardening-patch-4.4.2-0.4.15/Zend/zend_llist.c +--- php-4.4.2/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_llist.c 2006-09-05 20:30:33.000000000 +0200 +@@ -21,9 +21,49 @@ + #include "zend.h" + #include "zend_llist.h" + #include "zend_qsort.h" ++#include "zend_globals.h" ++ ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int zend_llist_canary_1 = 0x1234567; ++ unsigned int zend_llist_canary_2 = 0x1553425; ++ zend_bool zend_llist_canary_inited = 0; ++#endif ++ ++#define CHECK_LIST_CANARY(list) \ ++ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ ++ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ ++ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++#define CHECK_LISTELEMENT_CANARY(elem, list) \ ++ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ ++ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ ++ exit(1); \ ++ } ++ + + ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ ++ if (persistent) { ++ if (!zend_llist_canary_inited) { ++ /* do not change order to ensure thread safety */ ++ zend_llist_canary_1 = zend_canary(); ++ zend_llist_canary_2 = zend_canary(); ++ zend_llist_canary_inited = 1; ++ } ++ } else ++ if (!HG(ll_canary_inited)) { ++ HG(canary_3) = zend_canary(); ++ HG(canary_4) = zend_canary(); ++ HG(ll_canary_inited) = 1; ++ } ++ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); ++ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); ++#endif + l->head = NULL; + l->tail = NULL; + l->count = 0; +@@ -37,6 +77,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->prev = l->tail; + tmp->next = NULL; + if (l->tail) { +@@ -55,6 +100,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->next = l->head; + tmp->prev = NULL; + if (l->head) { +@@ -91,10 +141,20 @@ + zend_llist_element *current=l->head; + zend_llist_element *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (compare(current->data, element)) { + DEL_LLIST_ELEMENT(current, l); ++#if HARDENING_PATCH_LL_PROTECT ++ current->canary = 0; ++#endif + break; + } + current = next; +@@ -106,7 +166,14 @@ + { + zend_llist_element *current=l->head, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (l->dtor) { + l->dtor(current->data); +@@ -131,7 +198,14 @@ + zend_llist_element *old_tail; + void *data; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if ((old_tail = l->tail)) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(old_tail, l) ++#endif + if (l->tail->prev) { + l->tail->prev->next = NULL; + } +@@ -157,9 +231,16 @@ + { + zend_llist_element *ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(src) ++#endif + zend_llist_init(dst, src->size, src->dtor, src->persistent); + ptr = src->head; + while (ptr) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(ptr, src) ++#endif + zend_llist_add_element(dst, ptr->data); + ptr = ptr->next; + } +@@ -170,11 +251,21 @@ + { + zend_llist_element *element, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + element=l->head; + while (element) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + next = element->next; + if (func(element->data)) { + DEL_LLIST_ELEMENT(element, l); ++#if HARDENING_PATCH_LL_PROTECT ++ element->canary = 0; ++#endif + } + element = next; + } +@@ -185,7 +276,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data TSRMLS_CC); + } + } +@@ -197,6 +294,9 @@ + zend_llist_element **elements; + zend_llist_element *element, **ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + if (l->count <= 0) { + return; + } +@@ -206,6 +306,9 @@ + ptr = &elements[0]; + + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + *ptr++ = element; + } + +@@ -228,7 +331,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, arg TSRMLS_CC); + } + } +@@ -239,8 +348,14 @@ + zend_llist_element *element; + va_list args; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + va_start(args, num_args); + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, num_args, args TSRMLS_CC); + } + va_end(args); +@@ -249,6 +364,10 @@ + + ZEND_API int zend_llist_count(zend_llist *l) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + return l->count; + } + +@@ -256,8 +375,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->head; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -269,8 +395,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->tail; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -282,9 +415,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->next; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +@@ -296,9 +439,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->prev; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +diff -Nura php-4.4.2/Zend/zend_llist.h hardening-patch-4.4.2-0.4.15/Zend/zend_llist.h +--- php-4.4.2/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_llist.h 2006-09-05 20:30:33.000000000 +0200 +@@ -24,6 +24,9 @@ + #include + + typedef struct _zend_llist_element { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary, padding; ++#endif + struct _zend_llist_element *next; + struct _zend_llist_element *prev; + char data[1]; /* Needs to always be last in the struct */ +@@ -36,6 +39,9 @@ + typedef void (*llist_apply_func_t)(void * TSRMLS_DC); + + typedef struct _zend_llist { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_h; /* head */ ++#endif + zend_llist_element *head; + zend_llist_element *tail; + size_t size; +@@ -43,6 +49,9 @@ + llist_dtor_func_t dtor; + unsigned char persistent; + zend_llist_element *traverse_ptr; ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_t; /* tail */ ++#endif + } zend_llist; + + typedef zend_llist_element* zend_llist_position; +diff -Nura php-4.4.2/Zend/zend_modules.h hardening-patch-4.4.2-0.4.15/Zend/zend_modules.h +--- php-4.4.2/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_modules.h 2006-09-05 20:30:33.000000000 +0200 +@@ -34,6 +34,7 @@ + ZEND_API extern unsigned char second_arg_force_ref[]; + ZEND_API extern unsigned char third_arg_force_ref[]; + ++#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112 + #define ZEND_MODULE_API_NO 20020429 + #ifdef ZTS + #define USING_ZTS 1 +@@ -41,9 +42,9 @@ + #define USING_ZTS 0 + #endif + +-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS ++#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS + +-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 ++#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO + + #define STANDARD_MODULE_PROPERTIES \ + NULL, NULL, STANDARD_MODULE_PROPERTIES_EX +@@ -75,6 +76,7 @@ + unsigned char type; + void *handle; + int module_number; ++ unsigned int real_zend_api; + }; + + +diff -Nura php-4.4.2/Zend/zend_opcode.c hardening-patch-4.4.2-0.4.15/Zend/zend_opcode.c +--- php-4.4.2/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_opcode.c 2006-09-05 20:30:33.000000000 +0200 +@@ -88,6 +88,9 @@ + op_array->done_pass_two = 0; + + op_array->start_op = NULL; ++#if HARDENING_PATCH ++ op_array->created_by_eval = 0; ++#endif + + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); + } +diff -Nura php-4.4.2/Zend/zend_operators.c hardening-patch-4.4.2-0.4.15/Zend/zend_operators.c +--- php-4.4.2/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_operators.c 2006-09-05 20:30:33.000000000 +0200 +@@ -1604,6 +1604,20 @@ + return (op->value.lval ? 1 : 0); + } + ++ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) ++{ ++ register unsigned char *str = (unsigned char*)source; ++ register unsigned char *result = (unsigned char*)dest; ++ register unsigned char *end = str + length; ++ ++ while (str < end) { ++ *result++ = tolower((int)*str++); ++ } ++ *result = *end; ++ ++ return dest; ++} ++ + ZEND_API void zend_str_tolower(char *str, unsigned int length) + { + register char *p=str, *end=p+length; +diff -Nura php-4.4.2/Zend/zend_operators.h hardening-patch-4.4.2-0.4.15/Zend/zend_operators.h +--- php-4.4.2/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.2-0.4.15/Zend/zend_operators.h 2006-09-05 20:30:33.000000000 +0200 +@@ -174,6 +174,14 @@ + #endif + + ZEND_API void zend_str_tolower(char *str, unsigned int length); ++ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length); ++ ++static inline char * ++zend_str_tolower_dup(const char *source, unsigned int length) ++{ ++ return zend_str_tolower_copy((char *)emalloc(length+1), source, length); ++} ++ + ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2); + ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3); + ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2); diff --git a/0.4.15/hardening-patch-4.4.3-0.4.15.patch b/0.4.15/hardening-patch-4.4.3-0.4.15.patch new file mode 100644 index 0000000..017b2a0 --- /dev/null +++ b/0.4.15/hardening-patch-4.4.3-0.4.15.patch @@ -0,0 +1,8957 @@ +diff -Nura php-4.4.3/Changelog.hphp hardening-patch-4.4.3-0.4.15/Changelog.hphp +--- php-4.4.3/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Changelog.hphp 2006-09-07 19:32:48.000000000 +0200 +@@ -0,0 +1,61 @@ ++Changelog of the Hardening-Patch ++-------------------------------- ++ ++0.4.15 - 07. September 2006 ++ ++ PHP4: ++ [+] Fix for potential DOS in handling of include blacklists ++ ++ PHP4+5: ++ [+] Backported a fix for open_basedir problems with insanse PHP scripts ++ [+] Added a fix for ini_restore() PHP security vulnerability ++ ++0.4.14 - 11. August 2006 ++ ++ PHP4: ++ [+] Remove unecessary call to AC_BROKEN_REALPATH ++ ++ PHP5: ++ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant ++ ++ PHP4+5: ++ [+] Added a few PHP security fixes / see changelog.secfix for details ++ [+] Fixed the memory_limit protection for systems with different perdir memory_limits ++ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments ++ ++0.4.13 - 07. August 2006 ++ ++ PHP4+5: ++ [+] Added a fix for a compile problem on solaris due to missing strcasestr() ++ ++0.4.12 - 19. July 2006 ++ ++ PHP4: ++ [+] Added fixes from sf4 security patch / see changelog.secfix for details ++ ++ PHP5: ++ [+] Added fixes from sf5 security patch / see changelog.secfix for details ++ ++ PHP4+5: ++ [+] Added anti mail spam feature ++ [+] Speedup of zend_hash canary (clear/destroy) ++ [+] Added a fix for a DOS in the handling of URL blacklists ++ ++0.4.11 - 13. May 2006 ++ ++ PHP5: ++ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache ++ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 ++ ++ PHP4+5: ++ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories ++ ++ ++0.4.10 - 11. May 2006 ++ ++ PHP4: ++ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed ++ ++ PHP4+5: ++ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir ++ +diff -Nura php-4.4.3/Changelog.secfix hardening-patch-4.4.3-0.4.15/Changelog.secfix +--- php-4.4.3/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Changelog.secfix 2006-09-05 20:30:44.000000000 +0200 +@@ -0,0 +1,17 @@ ++Changelog of PHP 4.4.3 Security Fixes ++ ++Release 2 - 11. August 2006 ++ ++ [+] Added IMAP open_basedir/safe_mode check ++ [+] Added a upstream fix for previous ext/session fixes ++ [+] Added upstream fix to ext/socket ++ [+] Added sscanf() security fix ++ [+] Added fixes for handling of corrupt .gif files to gdlib ++ ++Release 1 - 4. August 2006 ++ ++ [+] Added a fix to disable CURLOPT_FOLLOWLOCATION while in safe_mode()/open_basedir ++ [+] Added a *working* wordwrap() fix ++ [+] Added code to make memory_limit work on 64bit systems ++ [+] Added a fix for an integer overflow in str_repeat() ++ +diff -Nura php-4.4.3/configure hardening-patch-4.4.3-0.4.15/configure +--- php-4.4.3/configure 2006-08-01 09:39:10.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/configure 2006-09-05 20:30:44.000000000 +0200 +@@ -402,6 +402,16 @@ + ac_default_prefix=/usr/local + # Any additions from configure.in: + ac_help="$ac_help ++ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." ++ac_help="$ac_help ++ --disable-hardening-patch-ll-protect Disable the Linked List protection." ++ac_help="$ac_help ++ --disable-hardening-patch-inc-protect Disable include/require protection." ++ac_help="$ac_help ++ --disable-hardening-patch-fmt-protect Disable format string protection." ++ac_help="$ac_help ++ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." ++ac_help="$ac_help + + SAPI modules: + " +@@ -854,6 +864,8 @@ + ac_help="$ac_help + --disable-tokenizer Disable tokenizer support" + ac_help="$ac_help ++ --disable-varfilter Disable Hardening-Patch's variable filter" ++ac_help="$ac_help + --enable-wddx Enable WDDX support." + ac_help="$ac_help + --disable-xml Disable XML support using bundled expat lib" +@@ -2942,6 +2954,157 @@ + + + ++# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. ++if test "${enable_hardening_patch_mm_protect+set}" = set; then ++ enableval="$enable_hardening_patch_mm_protect" ++ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. ++if test "${enable_hardening_patch_ll_protect+set}" = set; then ++ enableval="$enable_hardening_patch_ll_protect" ++ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. ++if test "${enable_hardening_patch_inc_protect+set}" = set; then ++ enableval="$enable_hardening_patch_inc_protect" ++ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. ++if test "${enable_hardening_patch_fmt_protect+set}" = set; then ++ enableval="$enable_hardening_patch_fmt_protect" ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. ++if test "${enable_hardening_patch_hash_protect+set}" = set; then ++ enableval="$enable_hardening_patch_hash_protect" ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++ ++fi ++ ++ ++echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 ++echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 ++echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 ++echo "configure:2733: checking whether to protect include/require statements" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect PHP Format String functions" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 ++ ++ ++cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH 1 ++EOF ++ ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 0 ++EOF ++ ++fi + + + +@@ -16017,6 +16180,62 @@ + fi + + ++ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 ++echo "configure:14928: checking whether realpath is broken" >&5 ++if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then ++ echo $ac_n "(cached) $ac_c" 1>&6 ++else ++ ++ if test "$cross_compiling" = yes; then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -fr conftest* ++ ++ ac_cv_broken_realpath=yes ++ ++fi ++rm -fr conftest* ++fi ++ ++ ++fi ++ ++echo "$ac_t""$ac_cv_broken_realpath" 1>&6 ++ if test "$ac_cv_broken_realpath" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 1 ++EOF ++ ++ else ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 0 ++EOF ++ ++ fi ++ ++ + echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 + echo "configure:16022: checking for declared timezone" >&5 + if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then +@@ -86718,7 +86937,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + cat >> confdefs.h <&6 ++echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 ++# Check whether --enable-varfilter or --disable-varfilter was given. ++if test "${enable_varfilter+set}" = set; then ++ enableval="$enable_varfilter" ++ PHP_VARFILTER=$enableval ++else ++ ++ PHP_VARFILTER=yes ++ ++ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then ++ PHP_VARFILTER=$PHP_ENABLE_ALL ++ fi ++ ++fi ++ ++ ++ ++ext_output="yes, shared" ++ext_shared=yes ++case $PHP_VARFILTER in ++shared,*) ++ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` ++ ;; ++shared) ++ PHP_VARFILTER=yes ++ ;; ++no) ++ ext_output=no ++ ext_shared=no ++ ;; ++*) ++ ext_output=yes ++ ext_shared=no ++ ;; ++esac ++ ++ ++ ++echo "$ac_t""$ext_output" 1>&6 ++ ++ ++ ++ ++if test "$PHP_VARFILTER" != "no"; then ++ cat >> confdefs.h <<\EOF ++#define HAVE_VARFILTER 1 ++EOF ++ ++ ++ ext_builddir=ext/varfilter ++ ext_srcdir=$abs_srcdir/ext/varfilter ++ ++ ac_extra= ++ ++ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then ++ ++ ++ ++ case ext/varfilter in ++ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; ++ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; ++ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; ++ esac ++ ++ ++ ++ b_c_pre=$php_c_pre ++ b_cxx_pre=$php_cxx_pre ++ b_c_meta=$php_c_meta ++ b_cxx_meta=$php_cxx_meta ++ b_c_post=$php_c_post ++ b_cxx_post=$php_cxx_post ++ b_lo=$php_lo ++ ++ ++ old_IFS=$IFS ++ for ac_src in varfilter.c; do ++ ++ IFS=. ++ set $ac_src ++ ac_obj=$1 ++ IFS=$old_IFS ++ ++ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" ++ ++ case $ac_src in ++ *.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" ;; ++ *.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" ;; ++ esac ++ ++ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 +@@ -104088,7 +104566,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + streams.c network.c php_open_temporary_file.c php_logos.c \ +- output.c memory_streams.c user_streams.c; do ++ output.c memory_streams.c user_streams.c hardening_patch.c; do + + IFS=. + set $ac_src +@@ -104273,7 +104751,7 @@ + zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ +- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do ++ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do + + IFS=. + set $ac_src +diff -Nura php-4.4.3/configure.in hardening-patch-4.4.3-0.4.15/configure.in +--- php-4.4.3/configure.in 2006-07-31 17:04:53.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/configure.in 2006-09-05 20:30:44.000000000 +0200 +@@ -247,7 +247,7 @@ + sinclude(Zend/acinclude.m4) + sinclude(Zend/Zend.m4) + sinclude(TSRM/tsrm.m4) +- ++sinclude(main/hardening_patch.m4) + + + divert(2) +@@ -621,6 +621,7 @@ + AC_FUNC_ALLOCA + dnl PHP_AC_BROKEN_SPRINTF + dnl PHP_AC_BROKEN_SNPRINTF ++dnl PHP_AC_BROKEN_REALPATH + PHP_DECLARED_TIMEZONE + PHP_TIME_R_TYPE + PHP_READDIR_R_TYPE +@@ -1260,7 +1261,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + streams.c network.c php_open_temporary_file.c php_logos.c \ +- output.c memory_streams.c user_streams.c) ++ output.c memory_streams.c user_streams.c hardening_patch.c) + PHP_ADD_SOURCES(/main, internal_functions.c,, sapi) + case $host_alias in + *netware*) +@@ -1281,7 +1282,7 @@ + zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ +- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c) ++ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c ) + + if test -r "$abs_srcdir/Zend/zend_objects.c"; then + PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c) +diff -Nura php-4.4.3/ext/curl/curl.c hardening-patch-4.4.3-0.4.15/ext/curl/curl.c +--- php-4.4.3/ext/curl/curl.c 2006-05-21 20:48:50.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/curl/curl.c 2006-09-05 20:30:44.000000000 +0200 +@@ -924,7 +924,6 @@ + case CURLOPT_FTPLISTONLY: + case CURLOPT_FTPAPPEND: + case CURLOPT_NETRC: +- case CURLOPT_FOLLOWLOCATION: + case CURLOPT_PUT: + #if CURLOPT_MUTE != 0 + case CURLOPT_MUTE: +@@ -961,6 +960,16 @@ + convert_to_long_ex(zvalue); + error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); + break; ++ case CURLOPT_FOLLOWLOCATION: ++ convert_to_long_ex(zvalue); ++ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ++ if (Z_LVAL_PP(zvalue) != 0) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set"); ++ RETURN_FALSE; ++ } ++ } ++ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); ++ break; + case CURLOPT_URL: + case CURLOPT_PROXY: + case CURLOPT_USERPWD: +diff -Nura php-4.4.3/ext/curl/curlstreams.c hardening-patch-4.4.3-0.4.15/ext/curl/curlstreams.c +--- php-4.4.3/ext/curl/curlstreams.c 2006-01-01 14:46:50.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/curl/curlstreams.c 2006-09-05 20:30:44.000000000 +0200 +@@ -297,7 +297,11 @@ + curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream); + + /* currently buggy (bug is in curl) */ +- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); ++ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ++ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); ++ } else { ++ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); ++ } + + curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr); + curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0); +diff -Nura php-4.4.3/ext/fbsql/php_fbsql.c hardening-patch-4.4.3-0.4.15/ext/fbsql/php_fbsql.c +--- php-4.4.3/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:30:44.000000000 +0200 +@@ -1797,8 +1797,24 @@ + } + else if (fbcmdErrorsFound(md)) + { ++#if HARDENING_PATCH ++ char* query_copy; ++ int i; ++#endif + FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); + char* emg = fbcemdAllErrorMessages(emd); ++#if HARDENING_PATCH ++ query_copy=estrdup(query_copy); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ free(emg); ++ fbcemdRelease(emd); ++ result = 0; ++ zend_bailout(); ++ } ++#endif + if (FB_SQL_G(generateWarnings)) + { + if (emg) +diff -Nura php-4.4.3/ext/gd/libgd/gd_gif_in.c hardening-patch-4.4.3-0.4.15/ext/gd/libgd/gd_gif_in.c +--- php-4.4.3/ext/gd/libgd/gd_gif_in.c 2006-05-08 16:04:39.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/gd/libgd/gd_gif_in.c 2006-09-05 20:30:44.000000000 +0200 +@@ -216,6 +216,12 @@ + if (!im) { + return 0; + } ++ ++ if (!im->colorsTotal) { ++ gdImageDestroy(im); ++ return 0; ++ } ++ + /* Check for open colors at the end, so + we can reduce colorsTotal and ultimately + BitsPerPixel */ +@@ -506,6 +512,19 @@ + int v; + int xpos = 0, ypos = 0, pass = 0; + int i; ++ ++ /* ++ ** Initialize the Compression routines ++ */ ++ if (! ReadOK(fd,&c,1)) { ++ return; ++ } ++ ++ if (c > MAX_LWZ_BITS) { ++ return; ++ } ++ ++ + /* Stash the color map into the image */ + for (i=0; (ired[i] = cmap[CM_RED][i]; +@@ -515,12 +534,7 @@ + } + /* Many (perhaps most) of these colors will remain marked open. */ + im->colorsTotal = gdMaxColors; +- /* +- ** Initialize the Compression routines +- */ +- if (! ReadOK(fd,&c,1)) { +- return; +- } ++ + if (LWZReadByte(fd, TRUE, c) < 0) { + return; + } +diff -Nura php-4.4.3/ext/gd/tests/bug38112.gif hardening-patch-4.4.3-0.4.15/ext/gd/tests/bug38112.gif +--- php-4.4.3/ext/gd/tests/bug38112.gif 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/gd/tests/bug38112.gif 2006-09-05 20:30:44.000000000 +0200 +@@ -0,0 +1,140 @@ ++GIF89a}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M ++ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuutt! NETSCAPE2.0!d,}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M ++ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuuttq]sH6U~F7Jػ|[rEwЫ*4;W(ƺj ++Ȗ֨_x֚hyvVyxc-%Bak(XF(yv aϑ@HZkhڊ'M )Zk[0K\G%y,l [6%F2 >ǾUI?6N>MhغCJ ++JmڶiIeʑ%~!T"2ZU ++禅^@-BAYVY0KTFXLs)rR+0l-BV%UrÜ Jmy@-QYŦm1%ΤOjvr3hm!1`0WDJj%To4Qə%)0 *Ƌ%LTt9sWKș#D(Qѧ_NGPHx#{ ++1He{"˥Z\U+Mf#HPB ++B}1wV$.[zsJ'MN("Os$R'D!EA=#L!`0[S6wL`AxPN* Q+9DŽ"X=R\20Z-ٕ hLRK 8R,QEX:$< ++@p&$ x d\ݵ@HyD5C*sY: ++ auc%l!F!Zr9BH  eP# Q ++!EG}Apk)lĞzZYn,A~*nY( ׌ƨ*1&r\gb*TS%~ZP}DÐhk;`BAkF.g- G!X` DD+8PA\0 ++";_BeI-ൂZ8A6 Mgv͚JG:Rױ` `څ,Ȁ-3bZ5A 7ÈR ++e!0/Jl!@tuACj< P>[[%^:uph ꀄ:`!XY, x/T†{33@46jX`!B0A/h^G) d{c4<J0q+*"ȼZPNaA,7;PHs7x1y 1@XTUnEX"$Q-jJM C@I܀ HD& :d" ++`G*`VgP`CXѰl3_ώ=𙛔f'}K1 F&`GFbL*0ف. @^0d';IPTd0|a˟*R6WpfF&UE_()=pOԻ [KS-Y&KG)$[UB%+Up/*1t5%[¡P ]y^"ZM8uX1Yb}C&mJP W9n2чzjTax9́,8R  Lp ++p"TUf %o,l(kPW$> ;Pp@ ++:>=#^db "Vxq?e+ﶓNCHK؁ ++l"?a @AOK*G:K!ƎƊ'8HB])ƞD?TVp \b1Fᰔ4ӨH7߹"mW~9 E.cM[F/W b׮WƤm335 PssP( TH;cyQr Đ'`1dS(m({frK Me D :  s%x 0' 3cSyp' ++vYao78yd0L zB-I qz=Cy0;9>d=`Fk^0@cƒ9Wpw03 ..@ ++)03f\@@阽 "o9 з l臙 S9gl e+c0S5_G0G9CZ@%P6E9@‖:=lD 03 i3EG0P!d05B#o 919ڐӣP:+WK*_' ++=ß5 &`~S vF= C8 1 sIp#PΖ@p̝X3WA`\=,ࢤT3 ++0l x@@ ++X m 0x茎 ++^qP鸪Epk Y8P0  oXS벎 Hc|i. +l?+\ I@ܐ   lѠ1/=0ݮv@O_n\ݾ@*֖-K ++Ќ g) : \ފ Nm^` h @_RK Z ++Mc5 a ΀ l0x > ? OVG c<^>N` -@`_R Pc@8ofmO?/)@T`r񒰻c^PHM VP{P, c0 ++UiDbb ++ Њ/\mbT]0#U(a0 ++Yij j25_Oߗ?`V{q mysm᮪t1OseXtk~> Q̖ەT;,tؗjzNUHYPIaSsZ*-)6:$NJHP>2Tšd2Z2^Q"XfRrS[p ./4:yd_Z[QP>4HTpwws>ȨNB!s7Q@ ,~G ocC\pC' /%_"RLDvDBK7;13nC}~dkTA  Ê@|3*A2L EA &D;rC2մ!E=a ++7ފSm#HOIC]y3RcorKXO$՚kD +zk#ˀ.ɂ" 7]{tL)[G-w -8E^ۂt@!0#őd ȉ#a"!"$C7 5B fN u&P~ 4 ex|%+փNE["W[(hALv9T0PaG#,?~ r&,Ra$\2љi\,Q3x惆EeVCѶI.CAh$,I%r9lA3)yws8uV`K(Oѭܭ m=Z8ڀ9}1? >)S\zA UV`d`h'57Za| 4_ҧ "blD4]h,PXnfAR"`@؉ ( R.@E4 m8B `m!J}CL np r6]aÞiF(DuB,q8aQrxceO@E`xa yM88(b f\6xE 6AD"r3_N!%(hu:D2I0ґ+4IJZh,@av{8 ++zs-Sqb!Ѕ I,?[:C.`n` @ b@Ϙ6JiJy387X͐t \KS ⴆ+ЇKAPEpP,s{ =eO|^"i;BJ#A9}TchX1qxD$Jno{DK\I2BQ ++?Bf-,6?VS@/B5=V@or ++umD0 %^ vs;DRja kF/vS>ܓ/X5?M+ H#lpH ++Hhwu 3;X+X} 9x!4 $ [uجg7)k08D1-bq@# ~#pacMF=a%9,nWF^|n7._6P0bw/#L!؄z]jj~ԕ_Uz`ЈFCXtI!d,կιǩUXuًȫȣdr*/>ç-Qȫ6AXIRbg *лۭΚʱțyۤsȑ炎ϯ운ΐë›랼ػࢮ柫ֳܐӢȜz;HPҩߟ^hkٟڧԢW^^nqq쮰ɭvzy7D@޹痛خHJ>zilTοȣĘþסϰHp?! OEQ2Zl%*D CII JMD% '>ɳ'Ot+JԪRDV"A|JJU!eC-[֠A4'V V]˶ ʔQLUZ$ ++,%+yռ5+&b!*. #2Ԗk<Bd+է')H]s!zѠ#TT Ÿ \9ViDK/sn ڵ+ z8zdb$ ,,DpJ >Vp:v Tn+M?b׿ gԒL7Ǝ6`2 Q\r, ^rtb+G $ZP3H86hc  hO+&LMp0BG刘XÄsM; g`lӎ)OL)h` }x$g d NCS1,M.#;: qTS©z~&X'|( B1nin&PB ,w\RB3*Ab¶ά`0 A|x!#IrW.fB8D`0 7`> l60 ++R # |ĻRRK-,.@8Ks7HPp hL/C ;|S, \J@^0 =QC&5/1VvD @ќ ? ++=0=G~"Jd[xm 5US! ,7D =| 1C6x(nB|*Mᆧ"!Ik,B+Ov݁Ag08?Km?LfJdL S0_,Ъ>PX ++ĥ'LO~:唑 eBiA,Ε?aKaWO*[(*G-`C8+TP0ZV: q&-,@MY>` 0 ۝$(5gD٪4<0G5!]0Ġ:"08P D>PX)UĀ @{ ++`uXwe`pu !w9Wɶf> Vǀ` -|XFטroi  !"MuP~oƚ5 } OL0&khnk}X ++ JP!D͸" ++@w `|wlوo tls{jmښ5igugLو&GPAř Z5H8v|EH"/,eG  Zz q@ ++` $ ++Pʉ Jn>#RzcPj?Z ` ZVpiC 500}z?i !| Z>==%X1k1 *=YFcT=SE `0((vN mQ;ziPYY+U1v fp0ԝ Н{P 0~ Q5`;|%μʵA ۻ{&ߪ0Xg Fc`NPό>IJR)Іhp@Q-0+sݚ 4f#L&,J ++0 t̆Z@1] [}K} @ ++in`*'` (geWf`0ˌ@g ++ uW͘ P,x- ++ƀWΓ[ˆ -b,i `?{  ++$p ix KA @`Гp݈ɻoSKPѱ=ؙjnDFS/dL$GG@, ++o FO4 ++ ߭4qݩݽ-4M00p ++,k p ++  ++ }0U02ߥ ++ ++Q_P˻Kr@m%fY  P =[Y՗  @ ; VJ@z, xݭ=^ބI,HC ++0 x PJNH*Pt q ++0j>\ڭ u -h *@Ϡ }XQ  ++@ 劮 _^ 6]i~ݞ;`p ,v P  ++R j 0^ h400uR "!`0 ^խuY @ 티 ޾ P߾z@8| ++y ++@5S~ > _nm{ ++n%  훀R H@8 L ++P[Dp'~`EɀV ++%P [ k  ++BLS? ^x! ++dPž_]0O%Udpp & ++jPP& y ++QY ++L0x]- _Qd =h S .> ppS@uk`bQ͏Ⱥyb6,\\ *eR#Y]PR叢:&}4)Dx>TPE- ++!kգ'iɱUp%!e&O ++J.3rϠTɲ̘4 F'OH FlSy@`ҭSh,W,DYDB`9I4FZ8[vK)WiIa Cpbő2m[Yٛg71& yȸE6TPcŴb)1*I^܊\;𞴌pk z FgyXt tl x .aDKJRJi7] Kd?"%21 4o>4@yF:nitx-MDeE1U|/1ы0jizܱBG ,)ďg&n@^|>>J!J`@`R\F9adH X N(>)Er9 "XÏ5@@MW 7Ƌ/@Xj֦HVXT ++f 5>‚qa|e@B ++)ָcK\c pj=E 9(bi|GtcU)=m8cYc>?ذd ++$\>PKreP& 45WL!v(`x?06W,=Qfy ++wB ++aM61 $`.ÎH`H vCjԏ^UjkX%k>f)= 0) X@fo^Jo-(e!ዖM߂{G%lܝayrH<#Lp e#H@EuBqtl/Ekd%]Gs#'>;LЂ(a 8d! w$;x `}R ++L~8 >f?# {8hD#d|%";XCB0~  ą1*l,5P_lYXyr*pz'b$|pEQ ++X@&mX0v` gFIr;F#$y-. ++Qz K(=/yUHMZ(>^s?sE0x84%{D@!KAtXk8 ++H }[)Bb>"G0*tPCE8hQ9xZ(Z# ++~H[Y2x`P?;@5BB*A0kF\2k4̃U}@7C@Z(\!W`x`opGxH:͢)Bp70#_a8CXd dDP;0/C(Gkdl`4 1Ss obX̃kFq?`TȪ8X ++--FILE-- ++ ++--EXPECTF-- ++Warning: imagecreatefromgif() [%s]: '%sbug38112.gif' is not a valid GIF file in %sbug38112.php on line %d +diff -Nura php-4.4.3/ext/imap/php_imap.c hardening-patch-4.4.3-0.4.15/ext/imap/php_imap.c +--- php-4.4.3/ext/imap/php_imap.c 2006-01-05 01:50:19.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/imap/php_imap.c 2006-09-05 20:30:44.000000000 +0200 +@@ -26,7 +26,7 @@ + | PHP 4.0 updates: Zeev Suraski | + +----------------------------------------------------------------------+ + */ +-/* $Id: php_imap.c,v 1.142.2.44.2.4 2006/01/05 00:50:19 iliaa Exp $ */ ++/* $Id: php_imap.c,v 1.142.2.44.2.5 2006/08/04 20:32:44 iliaa Exp $ */ + + #define IMAP41 + +@@ -731,6 +731,13 @@ + efree(IMAPG(imap_password)); + } + ++ /* local filename, need to perform open_basedir and safe_mode checks */ ++ if (Z_STRVAL_PP(mailbox)[0] != '{' && ++ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || ++ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { ++ RETURN_FALSE; ++ } ++ + IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); + IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); + +diff -Nura php-4.4.3/ext/mbstring/mbstring.c hardening-patch-4.4.3-0.4.15/ext/mbstring/mbstring.c +--- php-4.4.3/ext/mbstring/mbstring.c 2006-04-03 15:04:13.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/mbstring/mbstring.c 2006-09-05 20:30:44.000000000 +0200 +@@ -1500,6 +1500,7 @@ + char *strtok_buf = NULL, **val_list; + zval *array_ptr = (zval *) arg; + int n, num, val_len, *len_list; ++ unsigned int new_val_len; + enum mbfl_no_encoding from_encoding; + mbfl_string string, resvar, resval; + mbfl_encoding_detector *identd = NULL; +@@ -1622,8 +1623,14 @@ + val_len = len_list[n]; + } + n++; +- /* add variable to symbol table */ +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ /* we need val to be emalloc()ed */ ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ /* add variable to symbol table */ ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); ++ + if (convd != NULL){ + mbfl_string_clear(&resvar); + mbfl_string_clear(&resval); +diff -Nura php-4.4.3/ext/mysql/php_mysql.c hardening-patch-4.4.3-0.4.15/ext/mysql/php_mysql.c +--- php-4.4.3/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:30:44.000000000 +0200 +@@ -1218,6 +1218,8 @@ + { + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; ++ char *copy_query; ++ int i; + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); + +@@ -1268,6 +1270,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #else +@@ -1275,12 +1284,20 @@ + /* check possible error */ + if (MySG(trace_mode)){ + if (mysql_errno(&mysql->conn)){ +- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn)); ++ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #endif ++ + if(use_store == MYSQL_USE_RESULT) { + mysql_result=mysql_use_result(&mysql->conn); + } else { +diff -Nura php-4.4.3/ext/pgsql/pgsql.c hardening-patch-4.4.3-0.4.15/ext/pgsql/pgsql.c +--- php-4.4.3/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:30:44.000000000 +0200 +@@ -1001,10 +1001,28 @@ + case PGRES_EMPTY_QUERY: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: +- case PGRES_FATAL_ERROR: +- PHP_PQ_ERROR("Query failed: %s", pgsql); +- PQclear(pgsql_result); +- RETURN_FALSE; ++ case PGRES_FATAL_ERROR: ++ { ++#if HARDENING_PATCH ++ int i; ++ char *query_copy; ++#endif ++ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); ++ PQclear(pgsql_result); ++#if HARDENING_PATCH ++ query_copy = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ efree(msgbuf); ++ zend_bailout(); ++ } ++#endif ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); ++ efree(msgbuf); ++ RETURN_FALSE; ++ } + break; + case PGRES_COMMAND_OK: /* successful command that did not return rows */ + default: +diff -Nura php-4.4.3/ext/session/mod_files.c hardening-patch-4.4.3-0.4.15/ext/session/mod_files.c +--- php-4.4.3/ext/session/mod_files.c 2006-04-18 01:29:37.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/session/mod_files.c 2006-09-05 20:30:44.000000000 +0200 +@@ -16,7 +16,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: mod_files.c,v 1.83.2.9.2.3 2006/04/17 23:29:37 iliaa Exp $ */ ++/* $Id: mod_files.c,v 1.83.2.9.2.4 2006/08/08 14:57:04 iliaa Exp $ */ + + #include "php.h" + +@@ -368,7 +368,12 @@ + ps_files_close(data); + + if (VCWD_UNLINK(buf) == -1) { +- return FAILURE; ++ /* This is a little safety check for instances when we are dealing with a regenerated session ++ * that was not yet written to disk ++ */ ++ if (!VCWD_ACCESS(buf, F_OK)) { ++ return FAILURE; ++ } + } + } + +@@ -391,6 +396,34 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(files) ++{ ++ char buf[MAXPATHLEN]; ++ int fd; ++ PS_FILES_DATA; ++ ++ if (!ps_files_valid_key(key)) { ++ return FAILURE; ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { ++ return FAILURE; ++ } ++ ++ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600); ++ ++ if (fd != -1) { ++ close(fd); ++ return SUCCESS; ++ } ++ ++ return FAILURE; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-4.4.3/ext/session/mod_mm.c hardening-patch-4.4.3-0.4.15/ext/session/mod_mm.c +--- php-4.4.3/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/mod_mm.c 2006-09-05 20:30:44.000000000 +0200 +@@ -425,6 +425,42 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(mm) ++{ ++ PS_MM_DATA; ++ ps_sd *sd; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ } ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ mm_lock(data->mm, MM_LOCK_RD); ++ ++ sd = ps_sd_lookup(data, key, 0); ++ if (sd) { ++ mm_unlock(data->mm); ++ return SUCCESS; ++ } ++ ++ mm_unlock(data->mm); ++ ++ return FAILURE; ++} ++ + #endif + + /* +diff -Nura php-4.4.3/ext/session/mod_user.c hardening-patch-4.4.3-0.4.15/ext/session/mod_user.c +--- php-4.4.3/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/mod_user.c 2006-09-05 20:30:44.000000000 +0200 +@@ -23,7 +23,7 @@ + #include "mod_user.h" + + ps_module ps_mod_user = { +- PS_MOD(user) ++ PS_MOD_SID(user) + }; + + #define SESS_ZVAL_LONG(val, a) \ +@@ -174,6 +174,83 @@ + FINISH; + } + ++PS_CREATE_SID_FUNC(user) ++{ ++ int i; ++ char *val = NULL; ++ zval *retval; ++ ps_user *mdata = PS_GET_MOD_DATA(); ++ ++ if (!mdata) ++ return estrndup("", 0); ++ ++ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { ++ return php_session_create_id(mod_data, newlen TSRMLS_CC); ++ } ++ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); ++ ++ if (retval) { ++ if (Z_TYPE_P(retval) == IS_STRING) { ++ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); ++ } else { ++ val = estrndup("", 0); ++ } ++ zval_ptr_dtor(&retval); ++ } else { ++ val = estrndup("", 0); ++ } ++ ++ return val; ++} ++ ++static int ps_user_valid_key(const char *key TSRMLS_DC) ++{ ++ size_t len; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ ret = FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ ret = FAILURE; ++ ++ return ret; ++} ++ ++PS_VALIDATE_SID_FUNC(user) ++{ ++ zval *args[1]; ++ STDVARS; ++ ++ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { ++ return ps_user_valid_key(key TSRMLS_CC); ++ } ++ SESS_ZVAL_STRING(key, args[0]); ++ ++ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); ++ ++ if (retval) { ++ convert_to_long(retval); ++ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; ++ zval_ptr_dtor(&retval); ++ } ++ ++ return ret; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-4.4.3/ext/session/mod_user.h hardening-patch-4.4.3-0.4.15/ext/session/mod_user.h +--- php-4.4.3/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/mod_user.h 2006-09-05 20:30:44.000000000 +0200 +@@ -22,7 +22,7 @@ + #define MOD_USER_H + + typedef union { +- zval *names[6]; ++ zval *names[8]; + struct { + zval *ps_open; + zval *ps_close; +@@ -30,6 +30,8 @@ + zval *ps_write; + zval *ps_destroy; + zval *ps_gc; ++ zval *ps_create; ++ zval *ps_validate; + } name; + } ps_user; + +diff -Nura php-4.4.3/ext/session/php_session.h hardening-patch-4.4.3-0.4.15/ext/session/php_session.h +--- php-4.4.3/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/php_session.h 2006-09-05 20:30:44.000000000 +0200 +@@ -23,7 +23,7 @@ + + #include "ext/standard/php_var.h" + +-#define PHP_SESSION_API 20020330 ++#define PHP_SESSION_API 20051121 + + #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC + #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC +@@ -32,6 +32,7 @@ + #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC + #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC + #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC ++#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC + + /* default create id function */ + char *php_session_create_id(PS_CREATE_SID_ARGS); +@@ -45,6 +46,7 @@ + int (*s_destroy)(PS_DESTROY_ARGS); + int (*s_gc)(PS_GC_ARGS); + char *(*s_create_sid)(PS_CREATE_SID_ARGS); ++ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); + } ps_module; + + #define PS_GET_MOD_DATA() *mod_data +@@ -57,6 +59,7 @@ + #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) + #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) + #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) ++#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) + + #define PS_FUNCS(x) \ + PS_OPEN_FUNC(x); \ +@@ -65,11 +68,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID_FUNC(x) + + #define PS_MOD(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, php_session_create_id ++ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x + + /* SID enabled module handler definitions */ + #define PS_FUNCS_SID(x) \ +@@ -79,11 +83,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID(x) + + #define PS_MOD_SID(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, ps_create_sid_##x ++ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x + + typedef enum { + php_session_disabled, +@@ -120,6 +125,7 @@ + zend_bool use_only_cookies; + zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ ++ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + int send_cookie; + int define_sid; + } php_ps_globals; +diff -Nura php-4.4.3/ext/session/session.c hardening-patch-4.4.3-0.4.15/ext/session/session.c +--- php-4.4.3/ext/session/session.c 2006-05-19 00:16:27.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/session/session.c 2006-09-05 20:30:44.000000000 +0200 +@@ -17,7 +17,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: session.c,v 1.336.2.53.2.6 2006/05/18 22:16:27 helly Exp $ */ ++/* $Id: session.c,v 1.336.2.53.2.7 2006/08/01 08:33:13 tony2001 Exp $ */ + + #ifdef HAVE_CONFIG_H + #include "config.h" +@@ -155,6 +155,7 @@ + STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) ++ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals) +@@ -643,6 +644,15 @@ + return; + } + ++ /* If there is an ID, use session module to verify it */ ++ if (PS(id)) { ++ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ efree(PS(id)); ++ PS(id) = NULL; ++ PS(send_cookie) = 1; ++ } ++ } ++ + /* If there is no ID, use session module to create one */ + if (!PS(id)) + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); +@@ -1262,22 +1272,31 @@ + } + /* }}} */ + +-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) ++/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) + Sets user-level functions */ + PHP_FUNCTION(session_set_save_handler) + { +- zval **args[6]; +- int i; ++ zval **args[8]; ++ int i, numargs; + ps_user *mdata; + char *name; + ++ numargs = ZEND_NUM_ARGS(); ++ args[6] = NULL; ++ args[7] = NULL; ++ ++ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) ++ WRONG_PARAM_COUNT; + if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) + WRONG_PARAM_COUNT; + + if (PS(session_status) != php_session_none) + RETURN_FALSE; + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ continue; ++ } + if (!zend_is_callable(*args[i], 0, &name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); + efree(name); +@@ -1290,7 +1309,11 @@ + + mdata = emalloc(sizeof(*mdata)); + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ mdata->names[i] = NULL; ++ continue; ++ } + ZVAL_ADDREF(*args[i]); + mdata->names[i] = *args[i]; + } +@@ -1351,12 +1374,25 @@ + Update the current session id with a newly generated one. */ + PHP_FUNCTION(session_regenerate_id) + { ++ zend_bool del_ses = 0; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) { ++ WRONG_PARAM_COUNT; ++ } ++ + if (SG(headers_sent)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); + RETURN_FALSE; + } +- if (PS(session_status) == php_session_active) { +- if (PS(id)) efree(PS(id)); ++ ++ if (PS(session_status) == php_session_active) { ++ if (PS(id)) { ++ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed"); ++ RETURN_FALSE; ++ } ++ efree(PS(id)); ++ } + + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); + +@@ -1405,8 +1441,8 @@ + WRONG_PARAM_COUNT; + + if (ac == 1) { +- convert_to_long_ex(p_cache_expire); +- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); ++ convert_to_string_ex(p_cache_expire); ++ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + } + + RETVAL_LONG(old); +diff -Nura php-4.4.3/ext/session/tests/014.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/014.phpt +--- php-4.4.3/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:30:44.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.bug_compat_42=1 +diff -Nura php-4.4.3/ext/session/tests/015.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/015.phpt +--- php-4.4.3/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:30:44.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + arg_separator.output=& + session.name=PHPSESSID +diff -Nura php-4.4.3/ext/session/tests/018.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/018.phpt +--- php-4.4.3/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:30:44.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + session.name=PHPSESSID +diff -Nura php-4.4.3/ext/session/tests/020.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/020.phpt +--- php-4.4.3/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:30:44.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + arg_separator.output=& +diff -Nura php-4.4.3/ext/session/tests/021.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/021.phpt +--- php-4.4.3/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:30:44.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" +diff -Nura php-4.4.3/ext/session/tests/bug38377.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/bug38377.phpt +--- php-4.4.3/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:30:44.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++bug #38377 (session_destroy() gives warning after session_regenerate_id()) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECT-- ++Done +diff -Nura php-4.4.3/ext/sockets/sockets.c hardening-patch-4.4.3-0.4.15/ext/sockets/sockets.c +--- php-4.4.3/ext/sockets/sockets.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/sockets/sockets.c 2006-09-05 20:30:44.000000000 +0200 +@@ -19,7 +19,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: sockets.c,v 1.125.2.29.2.3 2006/01/01 13:46:56 sniper Exp $ */ ++/* $Id: sockets.c,v 1.125.2.29.2.6 2006/08/01 12:04:14 tony2001 Exp $ */ + + #ifdef HAVE_CONFIG_H + #include "config.h" +@@ -515,6 +515,7 @@ + int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, SOCKET *max_fd TSRMLS_DC) { + zval **element; + php_socket *php_sock; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -529,9 +530,10 @@ + if (php_sock->bsd_socket > *max_fd) { + *max_fd = php_sock->bsd_socket; + } ++ num++; + } + +- return 1; ++ return num ? 1 : 0; + } + + int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) { +@@ -539,6 +541,8 @@ + zval **dest_element; + php_socket *php_sock; + HashTable *new_hash; ++ int num = 0; ++ + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + + ALLOC_HASHTABLE(new_hash); +@@ -555,6 +559,7 @@ + zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); + if (dest_element) zval_add_ref(dest_element); + } ++ num++; + } + + /* Destroy old array, add new one */ +@@ -564,7 +569,7 @@ + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(sock_array) = new_hash; + +- return 1; ++ return num ? 1 : 0; + } + + +diff -Nura php-4.4.3/ext/standard/array.c hardening-patch-4.4.3-0.4.15/ext/standard/array.c +--- php-4.4.3/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/array.c 2006-09-05 20:30:44.000000000 +0200 +@@ -1162,6 +1162,32 @@ + } + } + } ++ ++ if (var_name[0] == 'H') { ++ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_FILES")==0)|| ++ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { ++ return 0; ++ } ++ } else if (var_name[0] == '_') { ++ if ((strcmp(var_name, "_COOKIE")==0)|| ++ (strcmp(var_name, "_ENV")==0)|| ++ (strcmp(var_name, "_FILES")==0)|| ++ (strcmp(var_name, "_GET")==0)|| ++ (strcmp(var_name, "_POST")==0)|| ++ (strcmp(var_name, "_REQUEST")==0)|| ++ (strcmp(var_name, "_SESSION")==0)|| ++ (strcmp(var_name, "_SERVER")==0)) { ++ return 0; ++ } ++ } else if (strcmp(var_name, "GLOBALS")==0) { ++ return 0; ++ } + + return 1; + } +diff -Nura php-4.4.3/ext/standard/basic_functions.c hardening-patch-4.4.3-0.4.15/ext/standard/basic_functions.c +--- php-4.4.3/ext/standard/basic_functions.c 2006-06-29 00:09:09.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:35:02.000000000 +0200 +@@ -107,12 +107,14 @@ + typedef struct _php_shutdown_function_entry { + zval **arguments; + int arg_count; ++ zend_bool created_by_eval; + } php_shutdown_function_entry; + + typedef struct _user_tick_function_entry { + zval **arguments; + int arg_count; + int calling; ++ zend_bool created_by_eval; + } user_tick_function_entry; + + /* some prototypes for local functions */ +@@ -295,6 +297,8 @@ + PHP_FE(get_html_translation_table, NULL) + PHP_FE(sha1, NULL) + PHP_FE(sha1_file, NULL) ++ PHP_FE(sha256, NULL) ++ PHP_FE(sha256_file, NULL) + PHP_NAMED_FE(md5,php_if_md5, NULL) + PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) + PHP_NAMED_FE(crc32,php_if_crc32, NULL) +@@ -676,7 +680,7 @@ + PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) + + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +- PHP_FE(realpath, NULL) ++ PHP_STATIC_FE("realpath", zif_real_path, NULL) + #endif + + #ifdef HAVE_FNMATCH +@@ -2101,6 +2105,13 @@ + { + zval retval; + char *function_name = NULL; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (shutdown_function_entry->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { + php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); +@@ -2116,6 +2127,9 @@ + if (function_name) { + efree(function_name); + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + return 0; + } + +@@ -2123,6 +2137,13 @@ + { + zval retval; + zval *function = tick_fe->arguments[0]; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (tick_fe->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + /* Prevent reentrant calls to the same user ticks function */ + if (! tick_fe->calling) { +@@ -2154,6 +2175,9 @@ + + tick_fe->calling = 0; + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + } + + static void run_user_tick_functions(int tick_count) +@@ -2222,6 +2246,13 @@ + efree(shutdown_function_entry.arguments); + RETURN_FALSE; + } ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ shutdown_function_entry.created_by_eval = 1; ++ } else { ++ shutdown_function_entry.created_by_eval = 0; ++ } ++#endif + + /* Prevent entering of anything but valid callback (syntax check only!) */ + if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { +@@ -2503,6 +2534,15 @@ + + convert_to_string_ex(varname); + ++ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ ++ if (PG(safe_mode)) { ++ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || ++ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || ++ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { ++ RETURN_FALSE; ++ } ++ } ++ + zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); + } + /* }}} */ +@@ -2759,6 +2799,13 @@ + } + + tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ tick_fe.created_by_eval = 1; ++ } else { ++ tick_fe.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { + efree(tick_fe.arguments); +@@ -3057,6 +3104,35 @@ + new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); + } + ++ if (new_key[0] == 'H') { ++ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_FILES")==0)|| ++ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (new_key[0] == '_') { ++ if ((strcmp(new_key, "_COOKIE")==0)|| ++ (strcmp(new_key, "_ENV")==0)|| ++ (strcmp(new_key, "_FILES")==0)|| ++ (strcmp(new_key, "_GET")==0)|| ++ (strcmp(new_key, "_POST")==0)|| ++ (strcmp(new_key, "_REQUEST")==0)|| ++ (strcmp(new_key, "_SESSION")==0)|| ++ (strcmp(new_key, "_SERVER")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (strcmp(new_key, "GLOBALS")==0) { ++ efree(new_key); ++ return 0; ++ } ++ + zend_hash_del(&EG(symbol_table), new_key, new_key_len); + ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); + +diff -Nura php-4.4.3/ext/standard/config.m4 hardening-patch-4.4.3-0.4.15/ext/standard/config.m4 +--- php-4.4.3/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/config.m4 2006-09-05 20:30:45.000000000 +0200 +@@ -203,7 +203,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) + ]) +@@ -419,6 +419,6 @@ + url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ + http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ +- var_unserializer.c ftok.c aggregation.c sha1.c ) ++ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ) + + PHP_ADD_MAKEFILE_FRAGMENT +diff -Nura php-4.4.3/ext/standard/crypt_blowfish.c hardening-patch-4.4.3-0.4.15/ext/standard/crypt_blowfish.c +--- php-4.4.3/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,748 @@ ++/* ++ * This code comes from John the Ripper password cracker, with reentrant ++ * and crypt(3) interfaces added, but optimizations specific to password ++ * cracking removed. ++ * ++ * Written by Solar Designer in 1998-2002 and ++ * placed in the public domain. ++ * ++ * There's absolutely no warranty. ++ * ++ * It is my intent that you should be able to use this on your system, ++ * as a part of a software package, or anywhere else to improve security, ++ * ensure compatibility, or for any other purpose. I would appreciate ++ * it if you give credit where it is due and keep your modifications in ++ * the public domain as well, but I don't require that in order to let ++ * you place this code and any modifications you make under a license ++ * of your choice. ++ * ++ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) ++ * by Niels Provos , and uses some of his ++ * ideas. The password hashing algorithm was designed by David Mazieres ++ * . ++ * ++ * There's a paper on the algorithm that explains its design decisions: ++ * ++ * http://www.usenix.org/events/usenix99/provos.html ++ * ++ * Some of the tricks in BF_ROUND might be inspired by Eric Young's ++ * Blowfish library (I can't be sure if I would think of something if I ++ * hadn't seen his code). ++ */ ++ ++#include ++ ++#include ++#ifndef __set_errno ++#define __set_errno(val) errno = (val) ++#endif ++ ++#undef __CONST ++#ifdef __GNUC__ ++#define __CONST __const ++#else ++#define __CONST ++#endif ++ ++#ifdef __i386__ ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#elif defined(__alpha__) || defined(__hppa__) ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#else ++#define BF_ASM 0 ++#define BF_SCALE 0 ++#endif ++ ++typedef unsigned int BF_word; ++ ++/* Number of Blowfish rounds, this is also hardcoded into a few places */ ++#define BF_N 16 ++ ++typedef BF_word BF_key[BF_N + 2]; ++ ++typedef struct { ++ BF_word S[4][0x100]; ++ BF_key P; ++} BF_ctx; ++ ++/* ++ * Magic IV for 64 Blowfish encryptions that we do at the end. ++ * The string is "OrpheanBeholderScryDoubt" on big-endian. ++ */ ++static BF_word BF_magic_w[6] = { ++ 0x4F727068, 0x65616E42, 0x65686F6C, ++ 0x64657253, 0x63727944, 0x6F756274 ++}; ++ ++/* ++ * P-box and S-box tables initialized with digits of Pi. ++ */ ++static BF_ctx BF_init_state = { ++ { ++ { ++ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, ++ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, ++ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, ++ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, ++ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, ++ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, ++ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, ++ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, ++ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, ++ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, ++ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, ++ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, ++ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, ++ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, ++ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, ++ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, ++ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, ++ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, ++ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, ++ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, ++ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, ++ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, ++ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, ++ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, ++ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, ++ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, ++ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, ++ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, ++ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, ++ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, ++ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, ++ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, ++ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, ++ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, ++ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, ++ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, ++ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, ++ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, ++ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, ++ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, ++ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, ++ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, ++ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, ++ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, ++ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, ++ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, ++ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, ++ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, ++ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, ++ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, ++ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, ++ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, ++ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, ++ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, ++ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, ++ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, ++ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, ++ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, ++ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, ++ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, ++ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, ++ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, ++ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, ++ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a ++ }, { ++ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, ++ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, ++ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, ++ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, ++ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, ++ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, ++ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, ++ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, ++ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, ++ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, ++ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, ++ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, ++ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, ++ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, ++ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, ++ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, ++ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, ++ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, ++ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, ++ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, ++ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, ++ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, ++ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, ++ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, ++ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, ++ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, ++ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, ++ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, ++ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, ++ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, ++ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, ++ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, ++ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, ++ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, ++ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, ++ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, ++ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, ++ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, ++ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, ++ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, ++ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, ++ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, ++ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, ++ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, ++ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, ++ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, ++ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, ++ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, ++ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, ++ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, ++ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, ++ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, ++ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, ++ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, ++ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, ++ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, ++ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, ++ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, ++ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, ++ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, ++ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, ++ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, ++ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, ++ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 ++ }, { ++ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, ++ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, ++ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, ++ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, ++ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, ++ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, ++ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, ++ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, ++ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, ++ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, ++ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, ++ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, ++ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, ++ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, ++ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, ++ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, ++ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, ++ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, ++ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, ++ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, ++ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, ++ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, ++ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, ++ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, ++ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, ++ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, ++ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, ++ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, ++ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, ++ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, ++ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, ++ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, ++ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, ++ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, ++ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, ++ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, ++ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, ++ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, ++ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, ++ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, ++ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, ++ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, ++ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, ++ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, ++ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, ++ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, ++ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, ++ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, ++ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, ++ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, ++ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, ++ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, ++ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, ++ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, ++ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, ++ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, ++ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, ++ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, ++ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, ++ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, ++ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, ++ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, ++ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, ++ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 ++ }, { ++ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, ++ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, ++ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, ++ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, ++ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, ++ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, ++ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, ++ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, ++ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, ++ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, ++ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, ++ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, ++ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, ++ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, ++ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, ++ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, ++ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, ++ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, ++ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, ++ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, ++ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, ++ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, ++ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, ++ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, ++ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, ++ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, ++ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, ++ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, ++ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, ++ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, ++ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, ++ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, ++ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, ++ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, ++ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, ++ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, ++ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, ++ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, ++ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, ++ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, ++ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, ++ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, ++ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, ++ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, ++ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, ++ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, ++ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, ++ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, ++ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, ++ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, ++ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, ++ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, ++ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, ++ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, ++ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, ++ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, ++ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, ++ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, ++ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, ++ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, ++ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, ++ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, ++ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, ++ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 ++ } ++ }, { ++ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, ++ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, ++ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, ++ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, ++ 0x9216d5d9, 0x8979fb1b ++ } ++}; ++ ++static unsigned char BF_itoa64[64 + 1] = ++ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ++ ++static unsigned char BF_atoi64[0x60] = { ++ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, ++ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, ++ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, ++ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, ++ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 ++}; ++ ++/* ++ * This may be optimized out if built with function inlining and no BF_ASM. ++ */ ++static void clean(void *data, int size) ++{ ++#if BF_ASM ++ extern void _BF_clean(void *data); ++#endif ++ memset(data, 0, size); ++#if BF_ASM ++ _BF_clean(data); ++#endif ++} ++ ++#define BF_safe_atoi64(dst, src) \ ++{ \ ++ tmp = (unsigned char)(src); \ ++ if (tmp == '$') break; \ ++ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ ++ tmp = BF_atoi64[tmp]; \ ++ if (tmp > 63) return -1; \ ++ (dst) = tmp; \ ++} ++ ++static int BF_decode(BF_word *dst, __CONST char *src, int size) ++{ ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned char *end = dptr + size; ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned int tmp, c1, c2, c3, c4; ++ ++ do { ++ BF_safe_atoi64(c1, *sptr++); ++ BF_safe_atoi64(c2, *sptr++); ++ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c3, *sptr++); ++ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c4, *sptr++); ++ *dptr++ = ((c3 & 0x03) << 6) | c4; ++ } while (dptr < end); ++ ++ while (dptr < end) ++ *dptr++ = 0; ++ ++ return 0; ++} ++ ++static void BF_encode(char *dst, __CONST BF_word *src, int size) ++{ ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned char *end = sptr + size; ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned int c1, c2; ++ ++ do { ++ c1 = *sptr++; ++ *dptr++ = BF_itoa64[c1 >> 2]; ++ c1 = (c1 & 0x03) << 4; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 4; ++ *dptr++ = BF_itoa64[c1]; ++ c1 = (c2 & 0x0f) << 2; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 6; ++ *dptr++ = BF_itoa64[c1]; ++ *dptr++ = BF_itoa64[c2 & 0x3f]; ++ } while (sptr < end); ++} ++ ++static void BF_swap(BF_word *x, int count) ++{ ++ static int endianness_check = 1; ++ char *is_little_endian = (char *)&endianness_check; ++ BF_word tmp; ++ ++ if (*is_little_endian) ++ do { ++ tmp = *x; ++ tmp = (tmp << 16) | (tmp >> 16); ++ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); ++ } while (--count); ++} ++ ++#if BF_SCALE ++/* Architectures which can shift addresses left by 2 bits with no extra cost */ ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp2 = L >> 8; \ ++ tmp2 &= 0xFF; \ ++ tmp3 = L >> 16; \ ++ tmp3 &= 0xFF; \ ++ tmp4 = L >> 24; \ ++ tmp1 = data.ctx.S[3][tmp1]; \ ++ tmp2 = data.ctx.S[2][tmp2]; \ ++ tmp3 = data.ctx.S[1][tmp3]; \ ++ tmp3 += data.ctx.S[0][tmp4]; \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#else ++/* Architectures with no complicated addressing modes supported */ ++#define BF_INDEX(S, i) \ ++ (*((BF_word *)(((unsigned char *)S) + (i)))) ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp1 <<= 2; \ ++ tmp2 = L >> 6; \ ++ tmp2 &= 0x3FC; \ ++ tmp3 = L >> 14; \ ++ tmp3 &= 0x3FC; \ ++ tmp4 = L >> 22; \ ++ tmp4 &= 0x3FC; \ ++ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ ++ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ ++ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ ++ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#endif ++ ++/* ++ * Encrypt one block, BF_N is hardcoded here. ++ */ ++#define BF_ENCRYPT \ ++ L ^= data.ctx.P[0]; \ ++ BF_ROUND(L, R, 0); \ ++ BF_ROUND(R, L, 1); \ ++ BF_ROUND(L, R, 2); \ ++ BF_ROUND(R, L, 3); \ ++ BF_ROUND(L, R, 4); \ ++ BF_ROUND(R, L, 5); \ ++ BF_ROUND(L, R, 6); \ ++ BF_ROUND(R, L, 7); \ ++ BF_ROUND(L, R, 8); \ ++ BF_ROUND(R, L, 9); \ ++ BF_ROUND(L, R, 10); \ ++ BF_ROUND(R, L, 11); \ ++ BF_ROUND(L, R, 12); \ ++ BF_ROUND(R, L, 13); \ ++ BF_ROUND(L, R, 14); \ ++ BF_ROUND(R, L, 15); \ ++ tmp4 = R; \ ++ R = L; \ ++ L = tmp4 ^ data.ctx.P[BF_N + 1]; ++ ++#if BF_ASM ++#define BF_body() \ ++ _BF_body_r(&data.ctx); ++#else ++#define BF_body() \ ++ L = R = 0; \ ++ ptr = data.ctx.P; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.P[BF_N + 2]); \ ++\ ++ ptr = data.ctx.S[0]; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.S[3][0xFF]); ++#endif ++ ++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) ++{ ++ __CONST char *ptr = key; ++ int i, j; ++ BF_word tmp; ++ ++ for (i = 0; i < BF_N + 2; i++) { ++ tmp = 0; ++ for (j = 0; j < 4; j++) { ++ tmp <<= 8; ++ tmp |= *ptr; ++ ++ if (!*ptr) ptr = key; else ptr++; ++ } ++ ++ expanded[i] = tmp; ++ initial[i] = BF_init_state.P[i] ^ tmp; ++ } ++} ++ ++char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, ++ char *output, int size) ++{ ++#if BF_ASM ++ extern void _BF_body_r(BF_ctx *ctx); ++#endif ++ struct { ++ BF_ctx ctx; ++ BF_key expanded_key; ++ union { ++ BF_word salt[4]; ++ BF_word output[6]; ++ } binary; ++ } data; ++ BF_word L, R; ++ BF_word tmp1, tmp2, tmp3, tmp4; ++ BF_word *ptr; ++ BF_word count; ++ int i; ++ ++ if (size < 7 + 22 + 31 + 1) { ++ __set_errno(ERANGE); ++ return NULL; ++ } ++ ++ if (setting[0] != '$' || ++ setting[1] != '2' || ++ setting[2] != 'a' || ++ setting[3] != '$' || ++ setting[4] < '0' || setting[4] > '3' || ++ setting[5] < '0' || setting[5] > '9' || ++ setting[6] != '$') { ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); ++ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { ++ clean(data.binary.salt, sizeof(data.binary.salt)); ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ BF_swap(data.binary.salt, 4); ++ ++ BF_set_key(key, data.expanded_key, data.ctx.P); ++ ++ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); ++ ++ L = R = 0; ++ for (i = 0; i < BF_N + 2; i += 2) { ++ L ^= data.binary.salt[i & 2]; ++ R ^= data.binary.salt[(i & 2) + 1]; ++ BF_ENCRYPT; ++ data.ctx.P[i] = L; ++ data.ctx.P[i + 1] = R; ++ } ++ ++ ptr = data.ctx.S[0]; ++ do { ++ ptr += 4; ++ L ^= data.binary.salt[(BF_N + 2) & 3]; ++ R ^= data.binary.salt[(BF_N + 3) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 4) = L; ++ *(ptr - 3) = R; ++ ++ L ^= data.binary.salt[(BF_N + 4) & 3]; ++ R ^= data.binary.salt[(BF_N + 5) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 2) = L; ++ *(ptr - 1) = R; ++ } while (ptr < &data.ctx.S[3][0xFF]); ++ ++ do { ++ data.ctx.P[0] ^= data.expanded_key[0]; ++ data.ctx.P[1] ^= data.expanded_key[1]; ++ data.ctx.P[2] ^= data.expanded_key[2]; ++ data.ctx.P[3] ^= data.expanded_key[3]; ++ data.ctx.P[4] ^= data.expanded_key[4]; ++ data.ctx.P[5] ^= data.expanded_key[5]; ++ data.ctx.P[6] ^= data.expanded_key[6]; ++ data.ctx.P[7] ^= data.expanded_key[7]; ++ data.ctx.P[8] ^= data.expanded_key[8]; ++ data.ctx.P[9] ^= data.expanded_key[9]; ++ data.ctx.P[10] ^= data.expanded_key[10]; ++ data.ctx.P[11] ^= data.expanded_key[11]; ++ data.ctx.P[12] ^= data.expanded_key[12]; ++ data.ctx.P[13] ^= data.expanded_key[13]; ++ data.ctx.P[14] ^= data.expanded_key[14]; ++ data.ctx.P[15] ^= data.expanded_key[15]; ++ data.ctx.P[16] ^= data.expanded_key[16]; ++ data.ctx.P[17] ^= data.expanded_key[17]; ++ ++ BF_body(); ++ ++ tmp1 = data.binary.salt[0]; ++ tmp2 = data.binary.salt[1]; ++ tmp3 = data.binary.salt[2]; ++ tmp4 = data.binary.salt[3]; ++ data.ctx.P[0] ^= tmp1; ++ data.ctx.P[1] ^= tmp2; ++ data.ctx.P[2] ^= tmp3; ++ data.ctx.P[3] ^= tmp4; ++ data.ctx.P[4] ^= tmp1; ++ data.ctx.P[5] ^= tmp2; ++ data.ctx.P[6] ^= tmp3; ++ data.ctx.P[7] ^= tmp4; ++ data.ctx.P[8] ^= tmp1; ++ data.ctx.P[9] ^= tmp2; ++ data.ctx.P[10] ^= tmp3; ++ data.ctx.P[11] ^= tmp4; ++ data.ctx.P[12] ^= tmp1; ++ data.ctx.P[13] ^= tmp2; ++ data.ctx.P[14] ^= tmp3; ++ data.ctx.P[15] ^= tmp4; ++ data.ctx.P[16] ^= tmp1; ++ data.ctx.P[17] ^= tmp2; ++ ++ BF_body(); ++ } while (--count); ++ ++ for (i = 0; i < 6; i += 2) { ++ L = BF_magic_w[i]; ++ R = BF_magic_w[i + 1]; ++ ++ count = 64; ++ do { ++ BF_ENCRYPT; ++ } while (--count); ++ ++ data.binary.output[i] = L; ++ data.binary.output[i + 1] = R; ++ } ++ ++ memcpy(output, setting, 7 + 22 - 1); ++ output[7 + 22 - 1] = BF_itoa64[(int) ++ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; ++ ++/* This has to be bug-compatible with the original implementation, so ++ * only encode 23 of the 24 bytes. :-) */ ++ BF_swap(data.binary.output, 6); ++ BF_encode(&output[7 + 22], data.binary.output, 23); ++ output[7 + 22 + 31] = '\0'; ++ ++/* Overwrite the most obvious sensitive data we have on the stack. Note ++ * that this does not guarantee there's no sensitive data left on the ++ * stack and/or in registers; I'm not aware of portable code that does. */ ++ clean(&data, sizeof(data)); ++ ++ return output; ++} ++ ++char *_crypt_gensalt_blowfish_rn(unsigned long count, ++ __CONST char *input, int size, char *output, int output_size) ++{ ++ if (size < 16 || output_size < 7 + 22 + 1 || ++ (count && (count < 4 || count > 31))) { ++ if (output_size > 0) output[0] = '\0'; ++ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); ++ return NULL; ++ } ++ ++ if (!count) count = 5; ++ ++ output[0] = '$'; ++ output[1] = '2'; ++ output[2] = 'a'; ++ output[3] = '$'; ++ output[4] = '0' + count / 10; ++ output[5] = '0' + count % 10; ++ output[6] = '$'; ++ ++ BF_encode(&output[7], (BF_word *)input, 16); ++ output[7 + 22] = '\0'; ++ ++ return output; ++} +diff -Nura php-4.4.3/ext/standard/crypt.c hardening-patch-4.4.3-0.4.15/ext/standard/crypt.c +--- php-4.4.3/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/crypt.c 2006-09-05 20:30:45.000000000 +0200 +@@ -100,6 +100,8 @@ + return SUCCESS; + } + ++char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); ++char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); + + static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +@@ -135,7 +137,14 @@ + + /* The automatic salt generation only covers standard DES and md5-crypt */ + if(!*salt) { +-#if PHP_MD5_CRYPT ++#if PHP_BLOWFISH_CRYPT ++ char randat[16]; ++ int i; ++ ++ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; ++ ++ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); ++#elif PHP_MD5_CRYPT + strcpy(salt, "$1$"); + php_to64(&salt[3], PHP_CRYPT_RAND, 4); + php_to64(&salt[7], PHP_CRYPT_RAND, 4); +@@ -145,8 +154,24 @@ + salt[2] = '\0'; + #endif + } +- +- RETVAL_STRING(crypt(str, salt), 1); ++ ++ if (salt[0] == '$' && ++ salt[1] == '2' && ++ salt[2] == 'a' && ++ salt[3] == '$' && ++ salt[4] >= '0' && salt[4] <= '3' && ++ salt[5] >= '0' && salt[5] <= '9' && ++ salt[6] == '$') { ++ ++ char output[PHP_MAX_SALT_LEN+1]; ++ ++ output[0] = 0; ++ _crypt_blowfish_rn(str, salt, output, sizeof(output)); ++ RETVAL_STRING(output, 1); ++ ++ } else { ++ RETVAL_STRING(crypt(str, salt), 1); ++ } + } + /* }}} */ + #endif +diff -Nura php-4.4.3/ext/standard/dl.c hardening-patch-4.4.3-0.4.15/ext/standard/dl.c +--- php-4.4.3/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/dl.c 2006-09-05 20:30:45.000000000 +0200 +@@ -160,8 +160,35 @@ + RETURN_FALSE; + } + module_entry = get_module(); ++ ++ /* check if Hardening-Patch is installed */ ++ if (module_entry->zend_api < 1000000000) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ ++ /* check if correct Hardening-Patch is installed */ ++ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ + if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) +- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { ++ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { + /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ + struct pre_4_1_0_module_entry { + char *name; +@@ -195,7 +222,7 @@ + zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; + } else { + name = module_entry->name; +- zend_api = module_entry->zend_api; ++ zend_api = module_entry->real_zend_api; + zend_debug = module_entry->zend_debug; + zts = module_entry->zts; + } +diff -Nura php-4.4.3/ext/standard/file.c hardening-patch-4.4.3-0.4.15/ext/standard/file.c +--- php-4.4.3/ext/standard/file.c 2006-04-14 19:46:59.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/file.c 2006-09-05 20:30:45.000000000 +0200 +@@ -2527,7 +2527,7 @@ + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) + /* {{{ proto string realpath(string path) + Return the resolved path */ +-PHP_FUNCTION(realpath) ++PHP_FUNCTION(real_path) + { + zval **path; + char resolved_path_buff[MAXPATHLEN]; +diff -Nura php-4.4.3/ext/standard/file.h hardening-patch-4.4.3-0.4.15/ext/standard/file.h +--- php-4.4.3/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/file.h 2006-09-05 20:30:45.000000000 +0200 +@@ -64,7 +64,7 @@ + PHP_FUNCTION(fd_set); + PHP_FUNCTION(fd_isset); + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +-PHP_FUNCTION(realpath); ++PHP_FUNCTION(real_path); + #endif + #ifdef HAVE_FNMATCH + PHP_FUNCTION(fnmatch); +diff -Nura php-4.4.3/ext/standard/head.c hardening-patch-4.4.3-0.4.15/ext/standard/head.c +--- php-4.4.3/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/head.c 2006-09-05 20:30:45.000000000 +0200 +@@ -44,7 +44,7 @@ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, + &ctr.line_len, &rep, &ctr.response_code) == FAILURE) + return; +- ++ + sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); + } + /* }}} */ +diff -Nura php-4.4.3/ext/standard/mail.c hardening-patch-4.4.3-0.4.15/ext/standard/mail.c +--- php-4.4.3/ext/standard/mail.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/mail.c 2006-09-05 20:30:45.000000000 +0200 +@@ -78,6 +78,25 @@ + } + /* }}} */ + ++/* {{{ hphp_strcasestr */ ++char *hphp_strcasestr(char *haystack, char *needle) ++{ ++ unsigned char *t, *h, *n; ++ ++ h = (unsigned char *) haystack; ++conts: ++ while (*h) { ++ n = (unsigned char *) needle; ++ for (t=h++; *n && *h; t++, n++) { ++ if (toupper(*t) != toupper(*n)) goto conts; ++ } ++ return ((char*)h-1); ++ } ++ ++ return (NULL); ++} ++/* }}} */ ++ + /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) + Send an email message */ + PHP_FUNCTION(mail) +@@ -103,6 +122,44 @@ + return; + } + ++ if (HG(hphp_mailprotect) > 0) { ++ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { ++ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ /* check for spam attempts with buggy webforms */ ++ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (HG(hphp_mailprotect) > 1) { ++ /* search for to, cc or bcc headers */ ++ if (headers_len > 0 && headers != NULL) { ++ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { ++ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { ++ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { ++ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ } ++ } ++ } ++ + if (to_len > 0) { + to_r = estrndup(to, to_len); + for (; to_len; to_len--) { +diff -Nura php-4.4.3/ext/standard/php_standard.h hardening-patch-4.4.3-0.4.15/ext/standard/php_standard.h +--- php-4.4.3/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/php_standard.h 2006-09-05 20:30:45.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "php_mail.h" + #include "md5.h" + #include "sha1.h" ++#include "sha256.h" + #include "html.h" + #include "exec.h" + #include "file.h" +diff -Nura php-4.4.3/ext/standard/scanf.c hardening-patch-4.4.3-0.4.15/ext/standard/scanf.c +--- php-4.4.3/ext/standard/scanf.c 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/scanf.c 2006-09-05 20:30:45.000000000 +0200 +@@ -16,7 +16,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: scanf.c,v 1.16.4.9.2.1 2006/01/01 13:46:58 sniper Exp $ */ ++/* $Id: scanf.c,v 1.16.4.9.2.2 2006/08/04 11:59:50 tony2001 Exp $ */ + + /* + scanf.c -- +@@ -732,7 +732,7 @@ + if (*end == '$') { + format = end+1; + ch = format++; +- objIndex = varStart + value; ++ objIndex = varStart + value - 1; + } + } + +@@ -762,8 +762,10 @@ + switch (*ch) { + case 'n': + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { +- current = args[objIndex++]; ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { ++ current = args[objIndex++]; + zval_dtor( *current ); + ZVAL_LONG( *current, (long)(string - baseString) ); + } else { +@@ -883,8 +885,10 @@ + } + } + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { +- current = args[objIndex++]; ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { ++ current = args[objIndex++]; + zval_dtor( *current ); + ZVAL_STRINGL( *current, string, end-string, 1); + } else { +@@ -922,7 +926,9 @@ + goto done; + } + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + zval_dtor( *current ); + ZVAL_STRINGL( *current, string, end-string, 1); +@@ -1079,8 +1085,10 @@ + value = (int) (*fn)(buf, NULL, base); + if ((flags & SCAN_UNSIGNED) && (value < 0)) { + sprintf(buf, "%u", value); /* INTL: ISO digit */ +- if (numVars) { +- /* change passed value type to string */ ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { ++ /* change passed value type to string */ + current = args[objIndex++]; + convert_to_string( *current ); + ZVAL_STRING( *current, buf, 1 ); +@@ -1088,7 +1096,9 @@ + add_index_string(*return_value, objIndex++, buf, 1); + } + } else { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + convert_to_long( *current ); + Z_LVAL(**current) = value; +@@ -1196,7 +1206,9 @@ + double dvalue; + *end = '\0'; + dvalue = zend_strtod(buf, NULL); +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + convert_to_double( *current ); + Z_DVAL_PP( current ) = dvalue; +diff -Nura php-4.4.3/ext/standard/sha256.c hardening-patch-4.4.3-0.4.15/ext/standard/sha256.c +--- php-4.4.3/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/sha256.c 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,398 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ ++ ++#include ++#include "php.h" ++ ++/* This code is heavily based on the PHP md5/sha1 implementations */ ++ ++#include "sha256.h" ++ ++PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ sprintf(sha256str, "%02x", digest[i]); ++ sha256str += 2; ++ } ++ ++ *sha256str = '\0'; ++} ++ ++/* {{{ proto string sha256(string str [, bool raw_output]) ++ Calculate the sha256 hash of a string */ ++PHP_FUNCTION(sha256) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ PHP_SHA256_CTX context; ++ unsigned char digest[32]; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ sha256str[0] = '\0'; ++ PHP_SHA256Init(&context); ++ PHP_SHA256Update(&context, arg, arg_len); ++ PHP_SHA256Final(digest, &context); ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++ ++} ++ ++/* }}} */ ++ ++/* {{{ proto string sha256_file(string filename [, bool raw_output]) ++ Calculate the sha256 hash of given filename */ ++PHP_FUNCTION(sha256_file) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ unsigned char buf[1024]; ++ unsigned char digest[32]; ++ PHP_SHA256_CTX context; ++ int n; ++ FILE *fp; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { ++ RETURN_FALSE; ++ } ++ ++ if (php_check_open_basedir(arg TSRMLS_CC)) { ++ RETURN_FALSE; ++ } ++ ++ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); ++ RETURN_FALSE; ++ } ++ ++ PHP_SHA256Init(&context); ++ ++ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { ++ PHP_SHA256Update(&context, buf, n); ++ } ++ ++ PHP_SHA256Final(digest, &context); ++ ++ if (ferror(fp)) { ++ fclose(fp); ++ RETURN_FALSE; ++ } ++ ++ fclose(fp); ++ ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++} ++/* }}} */ ++ ++ ++static void SHA256Transform(php_uint32[8], const unsigned char[64]); ++static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); ++static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); ++ ++static unsigned char PADDING[64] = ++{ ++ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++/* F, G, H and I are basic SHA256 functions. ++ */ ++#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) ++#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) ++#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) ++#define I(x, y, z) (((x) & (y)) | ((~x) & z)) ++ ++/* ROTATE_RIGHT rotates x right n bits. ++ */ ++#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) ++ ++/* W[i] ++ */ ++#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ ++ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ ++ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) ++ ++/* ROUND function of sha256 ++ */ ++ ++#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ ++ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ ++ (h) = F((a)) + G((a), (b), (c)) + t1; \ ++ (d) += t1; \ ++ } ++ ++ ++/* {{{ PHP_SHA256Init ++ * SHA256 initialization. Begins an SHA256 operation, writing a new context. ++ */ ++PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context) ++{ ++ context->count[0] = context->count[1] = 0; ++ /* Load magic initialization constants. ++ */ ++ context->state[0] = 0x6a09e667; ++ context->state[1] = 0xbb67ae85; ++ context->state[2] = 0x3c6ef372; ++ context->state[3] = 0xa54ff53a; ++ context->state[4] = 0x510e527f; ++ context->state[5] = 0x9b05688c; ++ context->state[6] = 0x1f83d9ab; ++ context->state[7] = 0x5be0cd19; ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Update ++ SHA256 block update operation. Continues an SHA256 message-digest ++ operation, processing another message block, and updating the ++ context. ++ */ ++PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, ++ unsigned int inputLen) ++{ ++ unsigned int i, index, partLen; ++ ++ /* Compute number of bytes mod 64 */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ++ ++ /* Update number of bits */ ++ if ((context->count[0] += ((php_uint32) inputLen << 3)) ++ < ((php_uint32) inputLen << 3)) ++ context->count[1]++; ++ context->count[1] += ((php_uint32) inputLen >> 29); ++ ++ partLen = 64 - index; ++ ++ /* Transform as many times as possible. ++ */ ++ if (inputLen >= partLen) { ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ++ SHA256Transform(context->state, context->buffer); ++ ++ for (i = partLen; i + 63 < inputLen; i += 64) ++ SHA256Transform(context->state, &input[i]); ++ ++ index = 0; ++ } else ++ i = 0; ++ ++ /* Buffer remaining input */ ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], ++ inputLen - i); ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Final ++ SHA256 finalization. Ends an SHA256 message-digest operation, writing the ++ the message digest and zeroizing the context. ++ */ ++PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) ++{ ++ unsigned char bits[8]; ++ unsigned int index, padLen; ++ ++ /* Save number of bits */ ++ bits[7] = context->count[0] & 0xFF; ++ bits[6] = (context->count[0] >> 8) & 0xFF; ++ bits[5] = (context->count[0] >> 16) & 0xFF; ++ bits[4] = (context->count[0] >> 24) & 0xFF; ++ bits[3] = context->count[1] & 0xFF; ++ bits[2] = (context->count[1] >> 8) & 0xFF; ++ bits[1] = (context->count[1] >> 16) & 0xFF; ++ bits[0] = (context->count[1] >> 24) & 0xFF; ++ ++ /* Pad out to 56 mod 64. ++ */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ++ padLen = (index < 56) ? (56 - index) : (120 - index); ++ PHP_SHA256Update(context, PADDING, padLen); ++ ++ /* Append length (before padding) */ ++ PHP_SHA256Update(context, bits, 8); ++ ++ /* Store state in digest */ ++ SHA256Encode(digest, context->state, 32); ++ ++ /* Zeroize sensitive information. ++ */ ++ memset((unsigned char*) context, 0, sizeof(*context)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Transform ++ * SHA256 basic transformation. Transforms state based on block. ++ */ ++static void SHA256Transform(state, block) ++php_uint32 state[8]; ++const unsigned char block[64]; ++{ ++ php_uint32 a = state[0], b = state[1], c = state[2]; ++ php_uint32 d = state[3], e = state[4], f = state[5]; ++ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; ++ ++ SHA256Decode(x, block, 64); ++ ++ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) ++ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) ++ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) ++ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) ++ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) ++ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) ++ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) ++ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) ++ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) ++ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) ++ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) ++ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) ++ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) ++ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) ++ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) ++ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) ++ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) ++ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) ++ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) ++ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) ++ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) ++ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) ++ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) ++ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) ++ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) ++ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) ++ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) ++ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) ++ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) ++ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) ++ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) ++ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) ++ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) ++ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) ++ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) ++ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) ++ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) ++ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) ++ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) ++ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) ++ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) ++ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) ++ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) ++ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) ++ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) ++ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) ++ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) ++ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) ++ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) ++ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) ++ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) ++ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) ++ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) ++ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) ++ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) ++ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) ++ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) ++ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) ++ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) ++ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) ++ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) ++ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) ++ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) ++ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) ++ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ state[5] += f; ++ state[6] += g; ++ state[7] += h; ++ ++ /* Zeroize sensitive information. */ ++ memset((unsigned char*) x, 0, sizeof(x)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Encode ++ Encodes input (php_uint32) into output (unsigned char). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Encode(output, input, len) ++unsigned char *output; ++php_uint32 *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) { ++ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); ++ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); ++ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); ++ output[j + 3] = (unsigned char) (input[i] & 0xff); ++ } ++} ++/* }}} */ ++ ++/* {{{ SHA256Decode ++ Decodes input (unsigned char) into output (php_uint32). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Decode(output, input, len) ++php_uint32 *output; ++const unsigned char *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) ++ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | ++ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.3/ext/standard/sha256.h hardening-patch-4.4.3-0.4.15/ext/standard/sha256.h +--- php-4.4.3/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/sha256.h 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ ++ ++#ifndef SHA256_H ++#define SHA256_H ++ ++#include "ext/standard/basic_functions.h" ++ ++/* SHA1 context. */ ++typedef struct { ++ php_uint32 state[8]; /* state (ABCD) */ ++ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ++ unsigned char buffer[64]; /* input buffer */ ++} PHP_SHA256_CTX; ++ ++PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *); ++PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); ++PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); ++ ++PHP_FUNCTION(sha256); ++PHP_FUNCTION(sha256_file); ++ ++#endif +diff -Nura php-4.4.3/ext/standard/string.c hardening-patch-4.4.3-0.4.15/ext/standard/string.c +--- php-4.4.3/ext/standard/string.c 2006-05-19 12:20:44.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/string.c 2006-09-05 20:30:45.000000000 +0200 +@@ -628,7 +628,8 @@ + { + const char *text, *breakchar = "\n"; + char *newtext; +- int textlen, breakcharlen = 1, newtextlen, alloced, chk; ++ int textlen, breakcharlen = 1, newtextlen, chk; ++ size_t alloced; + long current = 0, laststart = 0, lastspace = 0; + long linelength = 75; + zend_bool docut = 0; +@@ -3518,7 +3519,7 @@ + zval **input_str; /* Input string */ + zval **mult; /* Multiplier */ + char *result; /* Resulting string */ +- int result_len; /* Length of the resulting string */ ++ size_t result_len; /* Length of the resulting string */ + + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { + WRONG_PARAM_COUNT; +@@ -3543,11 +3544,7 @@ + + /* Initialize the result string */ + result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); +- if (result_len < 1) { +- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes"); +- RETURN_FALSE; +- } +- result = (char *)emalloc(result_len + 1); ++ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1); + + /* Heavy optimization for situations where input string is 1 byte long */ + if (Z_STRLEN_PP(input_str) == 1) { +diff -Nura php-4.4.3/ext/standard/syslog.c hardening-patch-4.4.3-0.4.15/ext/standard/syslog.c +--- php-4.4.3/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/syslog.c 2006-09-05 20:30:45.000000000 +0200 +@@ -42,6 +42,8 @@ + */ + PHP_MINIT_FUNCTION(syslog) + { ++ ++#if !HARDENING_PATCH + /* error levels */ + REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ + REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ +@@ -97,7 +99,7 @@ + /* AIX doesn't have LOG_PERROR */ + REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ + #endif +- ++#endif + return SUCCESS; + } + /* }}} */ +diff -Nura php-4.4.3/ext/standard/tests/strings/bug38322.phpt hardening-patch-4.4.3-0.4.15/ext/standard/tests/strings/bug38322.phpt +--- php-4.4.3/ext/standard/tests/strings/bug38322.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/standard/tests/strings/bug38322.phpt 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++Bug #38322 (reading past array in sscanf() leads to segfault/arbitary code execution) ++--FILE-- ++ ++--EXPECTF-- ++int(1) ++Done +diff -Nura php-4.4.3/ext/varfilter/config.m4 hardening-patch-4.4.3-0.4.15/ext/varfilter/config.m4 +--- php-4.4.3/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/varfilter/config.m4 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,11 @@ ++dnl ++dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++dnl ++ ++PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, ++[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) ++ ++if test "$PHP_VARFILTER" != "no"; then ++ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) ++ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) ++fi +diff -Nura php-4.4.3/ext/varfilter/CREDITS hardening-patch-4.4.3-0.4.15/ext/varfilter/CREDITS +--- php-4.4.3/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,2 @@ ++varfilter ++Stefan Esser +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-4.4.3/ext/varfilter/php_varfilter.h hardening-patch-4.4.3-0.4.15/ext/varfilter/php_varfilter.h +--- php-4.4.3/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,144 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifndef PHP_VARFILTER_H ++#define PHP_VARFILTER_H ++ ++extern zend_module_entry varfilter_module_entry; ++#define phpext_varfilter_ptr &varfilter_module_entry ++ ++#ifdef PHP_WIN32 ++#define PHP_VARFILTER_API __declspec(dllexport) ++#else ++#define PHP_VARFILTER_API ++#endif ++ ++#ifdef ZTS ++#include "TSRM.h" ++#endif ++ ++#include "SAPI.h" ++ ++#include "php_variables.h" ++ ++#ifdef ZEND_ENGINE_2 ++#define HASH_HTTP_GET_VARS 0x2095733f ++#define HASH_HTTP_POST_VARS 0xbfee1265 ++#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 ++#define HASH_HTTP_ENV_VARS 0x1fe186a8 ++#define HASH_HTTP_SERVER_VARS 0xc987afd6 ++#define HASH_HTTP_SESSION_VARS 0x7aba0d43 ++#define HASH_HTTP_POST_FILES 0x98eb1ddc ++#define HASH_HTTP_RAW_POST_DATA 0xdd633fec ++#else ++#define HASH_HTTP_GET_VARS 0x8d8645bd ++#define HASH_HTTP_POST_VARS 0x7c699bf3 ++#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f ++#define HASH_HTTP_ENV_VARS 0x84da3016 ++#define HASH_HTTP_SERVER_VARS 0x6dbf964e ++#define HASH_HTTP_SESSION_VARS 0x322906f5 ++#define HASH_HTTP_POST_FILES 0xe4e4ce70 ++#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e ++#endif ++ ++PHP_MINIT_FUNCTION(varfilter); ++PHP_MSHUTDOWN_FUNCTION(varfilter); ++PHP_RINIT_FUNCTION(varfilter); ++PHP_RSHUTDOWN_FUNCTION(varfilter); ++PHP_MINFO_FUNCTION(varfilter); ++ ++ ++ZEND_BEGIN_MODULE_GLOBALS(varfilter) ++/* request variables */ ++ long max_request_variables; ++ long cur_request_variables; ++ long max_varname_length; ++ long max_totalname_length; ++ long max_value_length; ++ long max_array_depth; ++ long max_array_index_length; ++ zend_bool disallow_nul; ++/* cookie variables */ ++ long max_cookie_vars; ++ long cur_cookie_vars; ++ long max_cookie_name_length; ++ long max_cookie_totalname_length; ++ long max_cookie_value_length; ++ long max_cookie_array_depth; ++ long max_cookie_array_index_length; ++ zend_bool disallow_cookie_nul; ++/* get variables */ ++ long max_get_vars; ++ long cur_get_vars; ++ long max_get_name_length; ++ long max_get_totalname_length; ++ long max_get_value_length; ++ long max_get_array_depth; ++ long max_get_array_index_length; ++ zend_bool disallow_get_nul; ++/* post variables */ ++ long max_post_vars; ++ long cur_post_vars; ++ long max_post_name_length; ++ long max_post_totalname_length; ++ long max_post_value_length; ++ long max_post_array_depth; ++ long max_post_array_index_length; ++ zend_bool disallow_post_nul; ++/* fileupload */ ++ long max_uploads; ++ long cur_uploads; ++ zend_bool disallow_elf_files; ++ char *verification_script; ++ ++ zend_bool no_more_variables; ++ zend_bool no_more_get_variables; ++ zend_bool no_more_post_variables; ++ zend_bool no_more_cookie_variables; ++ zend_bool no_more_uploads; ++ ++ZEND_END_MODULE_GLOBALS(varfilter) ++ ++ ++#ifdef ZTS ++#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) ++#else ++#define VARFILTER_G(v) (varfilter_globals.v) ++#endif ++ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); ++SAPI_TREAT_DATA_FUNC(varfilter_treat_data); ++ ++ ++ ++#endif /* PHP_VARFILTER_H */ ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: t ++ * End: ++ */ +diff -Nura php-4.4.3/ext/varfilter/varfilter.c hardening-patch-4.4.3-0.4.15/ext/varfilter/varfilter.c +--- php-4.4.3/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:50:05.000000000 +0200 +@@ -0,0 +1,915 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "php.h" ++#include "php_ini.h" ++#include "ext/standard/info.h" ++#include "php_varfilter.h" ++#include "hardening_patch.h" ++ ++ZEND_DECLARE_MODULE_GLOBALS(varfilter) ++ ++/* True global resources - no need for thread safety here */ ++static int le_varfilter; ++ ++static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; ++static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; ++static zend_bool hooked = 0; ++ ++/* {{{ varfilter_module_entry ++ */ ++zend_module_entry varfilter_module_entry = { ++#if ZEND_MODULE_API_NO >= 20010901 ++ STANDARD_MODULE_HEADER, ++#endif ++ "varfilter", ++ NULL, ++ PHP_MINIT(varfilter), ++ PHP_MSHUTDOWN(varfilter), ++ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ ++ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ ++ PHP_MINFO(varfilter), ++#if ZEND_MODULE_API_NO >= 20010901 ++ "0.4.15", /* Replace with version number for your extension */ ++#endif ++ STANDARD_MODULE_PROPERTIES ++}; ++/* }}} */ ++ ++#ifdef COMPILE_DL_VARFILTER ++ZEND_GET_MODULE(varfilter) ++#endif ++ ++/* {{{ PHP_INI ++ */ ++PHP_INI_BEGIN() ++ /* for backward compatibility */ ++ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) ++ ++ ++PHP_INI_END() ++/* }}} */ ++ ++/* {{{ php_varfilter_init_globals ++ */ ++static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) ++{ ++ varfilter_globals->max_request_variables = 200; ++ varfilter_globals->max_varname_length = 64; ++ varfilter_globals->max_value_length = 10000; ++ varfilter_globals->max_array_depth = 100; ++ varfilter_globals->max_totalname_length = 256; ++ varfilter_globals->max_array_index_length = 64; ++ varfilter_globals->disallow_nul = 1; ++ ++ varfilter_globals->max_cookie_vars = 100; ++ varfilter_globals->max_cookie_name_length = 64; ++ varfilter_globals->max_cookie_totalname_length = 256; ++ varfilter_globals->max_cookie_value_length = 10000; ++ varfilter_globals->max_cookie_array_depth = 100; ++ varfilter_globals->max_cookie_array_index_length = 64; ++ varfilter_globals->disallow_cookie_nul = 1; ++ ++ varfilter_globals->max_get_vars = 100; ++ varfilter_globals->max_get_name_length = 64; ++ varfilter_globals->max_get_totalname_length = 256; ++ varfilter_globals->max_get_value_length = 512; ++ varfilter_globals->max_get_array_depth = 50; ++ varfilter_globals->max_get_array_index_length = 64; ++ varfilter_globals->disallow_get_nul = 1; ++ ++ varfilter_globals->max_post_vars = 200; ++ varfilter_globals->max_post_name_length = 64; ++ varfilter_globals->max_post_totalname_length = 256; ++ varfilter_globals->max_post_value_length = 65000; ++ varfilter_globals->max_post_array_depth = 100; ++ varfilter_globals->max_post_array_index_length = 64; ++ varfilter_globals->disallow_post_nul = 1; ++ ++ varfilter_globals->max_uploads = 25; ++ varfilter_globals->disallow_elf_files = 1; ++ varfilter_globals->verification_script = NULL; ++ ++ varfilter_globals->no_more_variables = 0; ++ varfilter_globals->no_more_get_variables = 0; ++ varfilter_globals->no_more_post_variables = 0; ++ varfilter_globals->no_more_cookie_variables = 0; ++ varfilter_globals->no_more_uploads = 0; ++ ++ varfilter_globals->cur_request_variables = 0; ++ varfilter_globals->cur_get_vars = 0; ++ varfilter_globals->cur_post_vars = 0; ++ varfilter_globals->cur_cookie_vars = 0; ++ ++ varfilter_globals->cur_uploads = 0; ++ ++} ++/* }}} */ ++ ++ ++void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) ++{ ++ HashTable *svars; ++ int retval, failure=0; ++ ++ orig_register_server_variables(track_vars_array TSRMLS_CC); ++ ++ svars = Z_ARRVAL_P(track_vars_array); ++ ++ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ ++ if (failure) { ++ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); ++ } ++} ++ ++int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) ++{ ++ int retval = SAPI_HEADER_ADD, i; ++ char *tmp; ++ ++ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { ++ ++ tmp = sapi_header->header; ++ for (i=0; iheader_len; i++, tmp++) { ++ if (tmp[0] == 0) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); ++ sapi_header->header_len = i; ++ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); ++ sapi_header->header_len = i; ++ tmp[0] = 0; ++ } ++ } ++ } ++ ++ if (orig_header_handler) { ++ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); ++ } ++ ++ return retval; ++} ++ ++/* {{{ PHP_MINIT_FUNCTION ++ */ ++PHP_MINIT_FUNCTION(varfilter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); ++ REGISTER_INI_ENTRIES(); ++ ++ if (!hooked) { ++ void *temp; ++ hooked = 1; ++ ++ temp = (void *)sapi_module.register_server_variables; ++ if (temp != varfilter_register_server_variables) { ++ orig_register_server_variables = temp; ++ } ++ temp = (void *)sapi_module.header_handler; ++ if (temp != varfilter_header_handler) { ++ orig_header_handler = temp; ++ } ++ } ++ ++ sapi_register_input_filter(varfilter_input_filter); ++ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); ++ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); ++ sapi_register_upload_content_filter(varfilter_upload_content_filter); ++ sapi_register_post_upload_filter(varfilter_post_upload_filter); ++ ++ sapi_module.header_handler = varfilter_header_handler; ++ sapi_module.register_server_variables = varfilter_register_server_variables; ++ ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MSHUTDOWN_FUNCTION ++ */ ++PHP_MSHUTDOWN_FUNCTION(varfilter) ++{ ++ UNREGISTER_INI_ENTRIES(); ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request start */ ++/* {{{ PHP_RINIT_FUNCTION ++ */ ++PHP_RINIT_FUNCTION(varfilter) ++{ ++ VARFILTER_G(cur_request_variables) = 0; ++ VARFILTER_G(cur_get_vars) = 0; ++ VARFILTER_G(cur_post_vars) = 0; ++ VARFILTER_G(cur_cookie_vars) = 0; ++ ++ VARFILTER_G(cur_uploads) = 0; ++ ++ VARFILTER_G(no_more_variables) = 0; ++ VARFILTER_G(no_more_get_variables) = 0; ++ VARFILTER_G(no_more_post_variables) = 0; ++ VARFILTER_G(no_more_cookie_variables) = 0; ++ VARFILTER_G(no_more_uploads) = 0; ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request end */ ++/* {{{ PHP_RSHUTDOWN_FUNCTION ++ */ ++PHP_RSHUTDOWN_FUNCTION(varfilter) ++{ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MINFO_FUNCTION ++ */ ++PHP_MINFO_FUNCTION(varfilter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); ++ php_info_print_table_end(); ++ ++ DISPLAY_INI_ENTRIES(); ++} ++/* }}} */ ++ ++/* {{{ normalize_varname ++ */ ++static void normalize_varname(char *varname) ++{ ++ char *s=varname, *index=NULL, *indexend=NULL, *p; ++ ++ /* overjump leading space */ ++ while (*s == ' ') { ++ s++; ++ } ++ ++ /* and remove it */ ++ if (s != varname) { ++ memmove(varname, s, strlen(s)+1); ++ } ++ ++ for (p=varname; *p && *p != '['; p++) { ++ switch(*p) { ++ case ' ': ++ case '.': ++ *p='_'; ++ break; ++ } ++ } ++ ++ /* find index */ ++ index = strchr(varname, '['); ++ if (index) { ++ index++; ++ s=index; ++ } else { ++ return; ++ } ++ ++ /* done? */ ++ while (index) { ++ ++ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { ++ index++; ++ } ++ indexend = strchr(index, ']'); ++ indexend = indexend ? indexend + 1 : index + strlen(index); ++ ++ if (s != index) { ++ memmove(s, index, strlen(index)+1); ++ s += indexend-index; ++ } else { ++ s = indexend; ++ } ++ ++ if (*s == '[') { ++ s++; ++ index = s; ++ } else { ++ index = NULL; ++ } ++ } ++ *s++='\0'; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC ++ */ ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) ++{ ++ char *index, *prev_index = NULL, *var; ++ unsigned int var_len, total_len, depth = 0; ++ ++ var = estrdup(varname); ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); ++ ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; ++ break; ++ } ++ ++ efree(var); ++ return SUCCESS; ++protected_varname2: ++ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); ++return_failure: ++ efree(var); ++ return FAILURE; ++} ++/* }}} */ ++ ++/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC ++ */ ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) ++{ ++ /* Drop if no more variables flag is set */ ++ if (VARFILTER_G(no_more_uploads)) { ++ return FAILURE; ++ } ++ /* Drop this fileupload if the limit is reached */ ++ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { ++ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); ++ VARFILTER_G(no_more_uploads) = 1; ++ return FAILURE; ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC ++ */ ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) ++{ ++ ++ if (VARFILTER_G(disallow_elf_files)) { ++ ++ if (offset == 0 && buffer_len > 10) { ++ ++ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { ++ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); ++ return FAILURE; ++ } ++ } ++ ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC ++ */ ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) ++{ ++ int retval = SUCCESS; ++ ++ if (VARFILTER_G(verification_script)) { ++ char cmd[8192]; ++ FILE *in; ++ int first=1; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); ++ return FAILURE; ++ } ++ ++ retval = FAILURE; ++ ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ if (first) { ++ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; ++ first = 0; ++ } ++ } ++ pclose(in); ++ } ++ ++ if (retval != SUCCESS) { ++ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); ++ return FAILURE; ++ } ++ ++ VARFILTER_G(cur_uploads)++; ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_INPUT_FILTER_FUNC ++ */ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) ++{ ++ char *index, *prev_index = NULL; ++ unsigned int var_len, total_len, depth = 0; ++ ++ /* Drop this variable if the limit was reached */ ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(no_more_get_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(no_more_post_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(no_more_cookie_variables)) { ++ return 0; ++ } ++ break; ++ default: /* we do not want to protect parse_str() and friends */ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ return 1; ++ } ++ if (VARFILTER_G(no_more_variables)) { ++ return 0; ++ } ++ ++ /* Drop this variable if the limit is now reached */ ++ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { ++ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_variables) = 1; ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { ++ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_get_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { ++ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_cookie_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { ++ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_post_variables) = 1; ++ return 0; ++ } ++ break; ++ } ++ ++ ++ /* Drop this variable if it exceeds the value length limit */ ++ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { ++ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { ++ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { ++ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { ++ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { ++ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { ++ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Check if variable value is truncated by a \0 */ ++ ++ if (val && *val && val_len != strlen(*val)) { ++ ++ if (VARFILTER_G(disallow_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(disallow_get_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(disallow_cookie_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(disallow_post_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ } ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname; ++ break; ++ } ++ ++ /* Okay let PHP register this variable */ ++ VARFILTER_G(cur_request_variables)++; ++ switch (arg) { ++ case PARSE_GET: ++ VARFILTER_G(cur_get_vars)++; ++ break; ++ case PARSE_COOKIE: ++ VARFILTER_G(cur_cookie_vars)++; ++ break; ++ case PARSE_POST: ++ VARFILTER_G(cur_post_vars)++; ++ break; ++ } ++ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ ++ return 1; ++protected_varname: ++ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); ++ return 0; ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: noet sw=4 ts=4 fdm=marker ++ * vim<600: noet sw=4 ts=4 ++ */ ++ ++ +diff -Nura php-4.4.3/main/fopen_wrappers.c hardening-patch-4.4.3-0.4.15/main/fopen_wrappers.c +--- php-4.4.3/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:34.000000000 +0200 +@@ -106,7 +106,10 @@ + } + + /* Resolve the real path into resolved_name */ +- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { ++ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { ++ return -2; ++ } ++ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { + /* Handler for basedirs that end with a / */ + resolved_basedir_len = strlen(resolved_basedir); + if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { +@@ -116,14 +119,20 @@ + } + } + ++ resolved_name_len = strlen(resolved_name); + if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { +- resolved_name_len = strlen(resolved_name); + if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { + resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; + resolved_name[++resolved_name_len] = '\0'; + } + } + ++ if (resolved_name_len == resolved_basedir_len - 1) { ++ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { ++ resolved_basedir_len--; ++ } ++ } ++ + /* Check the path */ + #ifdef PHP_WIN32 + if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { +@@ -137,7 +146,7 @@ + } + } else { + /* Unable to resolve the real path, return -1 */ +- return -1; ++ return -3; + } + } + /* }}} */ +@@ -156,22 +165,44 @@ + char *pathbuf; + char *ptr; + char *end; ++ char path_copy[MAXPATHLEN]; ++ int path_len; ++ ++ /* Special case path ends with a trailing slash */ ++ path_len = strlen(path); ++ if (path_len >= MAXPATHLEN) { ++ errno = EPERM; /* we deny permission to open it */ ++ return -1; ++ } ++ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { ++ memcpy(path_copy, path, path_len+1); ++ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; ++ path_copy[path_len] = '\0'; ++ path = (const char *)&path_copy; ++ } + + pathbuf = estrdup(PG(open_basedir)); + + ptr = pathbuf; + + while (ptr && *ptr) { ++ int res; + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end != NULL) { + *end = '\0'; + end++; + } + +- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { ++ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); ++ if (res == 0) { + efree(pathbuf); + return 0; + } ++ if (res == -2) { ++ efree(pathbuf); ++ errno = EPERM; ++ return -1; ++ } + + ptr = end; + } +diff -Nura php-4.4.3/main/hardened_globals.h hardening-patch-4.4.3-0.4.15/main/hardened_globals.h +--- php-4.4.3/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/hardened_globals.h 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENED_GLOBALS_H ++#define HARDENED_GLOBALS_H ++ ++typedef struct _hardened_globals hardened_globals_struct; ++ ++#ifdef ZTS ++# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) ++extern int hardened_globals_id; ++#else ++# define HG(v) (hardened_globals.v) ++extern struct _hardened_globals hardened_globals; ++#endif ++ ++ ++struct _hardened_globals { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_1; ++ unsigned int canary_2; ++#endif ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_3; ++ unsigned int canary_4; ++ unsigned int ll_canary_inited; ++#endif ++ zend_bool hphp_sql_bailout_on_error; ++ zend_bool hphp_multiheader; ++ unsigned long hphp_mailprotect; ++ long hard_memory_limit; ++ HashTable *eval_whitelist; ++ HashTable *eval_blacklist; ++ HashTable *func_whitelist; ++ HashTable *func_blacklist; ++ HashTable *include_whitelist; ++ HashTable *include_blacklist; ++ unsigned int dummy; ++}; ++ ++ ++#endif /* HARDENED_GLOBALS_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-4.4.3/main/hardening_patch.c hardening-patch-4.4.3-0.4.15/main/hardening_patch.c +--- php-4.4.3/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/hardening_patch.c 2006-09-07 18:48:07.000000000 +0200 +@@ -0,0 +1,430 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ ++ ++#include "php.h" ++ ++#include ++#include ++ ++#if HAVE_UNISTD_H ++#include ++#endif ++#include "SAPI.h" ++#include "php_globals.h" ++ ++#if HARDENING_PATCH ++ ++#ifdef HAVE_SYS_SOCKET_H ++#include ++#endif ++ ++#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) ++#undef AF_UNIX ++#endif ++ ++#if defined(AF_UNIX) ++#include ++#endif ++ ++#define SYSLOG_PATH "/dev/log" ++ ++#include "snprintf.h" ++ ++#include "hardening_patch.h" ++ ++#ifdef ZTS ++#include "hardened_globals.h" ++int hardened_globals_id; ++#else ++struct _hardened_globals hardened_globals; ++#endif ++ ++static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) ++{ ++ memset(hardened_globals, 0, sizeof(*hardened_globals)); ++} ++ ++ ++PHPAPI void hardened_startup() ++{ ++#ifdef ZTS ++ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); ++#else ++ hardened_globals_ctor(&hardened_globals TSRMLS_CC); ++#endif ++} ++ ++PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) ++{ ++ HG(canary_1) = php_canary(); ++ HG(canary_2) = php_canary(); ++} ++ ++char *loglevel2string(int loglevel) ++{ ++ switch (loglevel) { ++ case S_FILES: ++ return "FILES"; ++ case S_INCLUDE: ++ return "INCLUDE"; ++ case S_MEMORY: ++ return "MEMORY"; ++ case S_MISC: ++ return "MISC"; ++ case S_SQL: ++ return "SQL"; ++ case S_EXECUTOR: ++ return "EXECUTOR"; ++ case S_VARS: ++ return "VARS"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++PHPAPI void php_security_log(int loglevel, char *fmt, ...) ++{ ++#if defined(AF_UNIX) ++ int s, r, i=0; ++ struct sockaddr_un saun; ++ char buf[4096+64]; ++ char error[4096+100]; ++ char *ip_address; ++ char *fname; ++ int lineno; ++ va_list ap; ++ TSRMLS_FETCH(); ++ ++ if (EG(hphp_log_use_x_forwarded_for)) { ++ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "X-FORWARDED-FOR not set"; ++ } ++ } else { ++ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "REMOTE_ADDR not set"; ++ } ++ } ++ ++ ++ va_start(ap, fmt); ++ ap_php_vsnprintf(error, sizeof(error), fmt, ap); ++ va_end(ap); ++ while (error[i]) { ++ if (error[i] < 32) error[i] = '.'; ++ i++; ++ } ++ ++ if (zend_is_executing(TSRMLS_C)) { ++ lineno = zend_get_executed_lineno(TSRMLS_C); ++ fname = zend_get_executed_filename(TSRMLS_C); ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); ++ } else { ++ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); ++ if (fname==NULL) { ++ fname = "unknown"; ++ } ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); ++ } ++ ++ /* Syslog-Logging disabled? */ ++ if ((EG(hphp_log_syslog) & loglevel)==0) { ++ goto log_sapi; ++ } ++ ++ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); ++ ++ s = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ s = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ goto log_sapi; ++ } ++ } ++ send(s, error, strlen(error), 0); ++ ++ close(s); ++ ++log_sapi: ++ /* SAPI Logging activated? */ ++ if ((EG(hphp_log_sapi) & loglevel)!=0) { ++ sapi_module.log_message(buf); ++ } ++ ++log_script: ++ /* script logging activaed? */ ++ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { ++ char cmd[8192], *cmdpos, *bufpos; ++ FILE *in; ++ int space; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); ++ space = sizeof(cmd) - strlen(cmd); ++ cmdpos = cmd + strlen(cmd); ++ bufpos = buf; ++ if (space <= 1) return; ++ while (space > 2 && *bufpos) { ++ if (*bufpos == '\'') { ++ if (space<=5) break; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\\'; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\''; ++ bufpos++; ++ space-=4; ++ } else { ++ *cmdpos++ = *bufpos++; ++ space--; ++ } ++ } ++ *cmdpos++ = '\''; ++ *cmdpos = 0; ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); ++ return; ++ } ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ } ++ pclose(in); ++ } ++ ++#endif ++} ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++PHPAPI unsigned int php_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++ ++PHPAPI int php_is_valid_include(zval *z) ++{ ++ char *filename; ++ int len, i; ++ TSRMLS_FETCH(); ++ ++ /* must be of type string */ ++ if (z->type != IS_STRING || z->value.str.val == NULL) { ++ return (0); ++ } ++ ++ /* short cut */ ++ filename = z->value.str.val; ++ len = z->value.str.len; ++ ++ /* 1. must be shorter than MAXPATHLEN */ ++ if (len > MAXPATHLEN) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 2. must not be cutted */ ++ if (len != strlen(filename)) { ++ char *fname = estrndup(filename, len); ++ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ ++ if (strstr(filename, "://")) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ ++ /* no black or whitelist then disallow all */ ++ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* whitelist is stronger than blacklist */ ++ if (HG(include_whitelist)) { ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ zend_bool isOk = 0; ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_whitelist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ isOk = 1; ++ break; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_whitelist)); ++ } while (1); ++ ++ /* not found in whitelist */ ++ if (!isOk) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); ++ efree(fname); ++ return 0; ++ } ++ ++ s = h + 3; ++ } while (1); ++ } else { ++ /* okay then handle the blacklist */ ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_blacklist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); ++ efree(fname); ++ return 0; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_blacklist)); ++ } while (1); ++ ++ s = h + 3; ++ } while (1); ++ } ++ ++ efree(fname); ++ } ++ ++ /* 4. must not be an uploaded file */ ++ if (SG(rfc1867_uploaded_files)) { ++ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { ++ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); ++ return (0); ++ } ++ } ++ ++ /* passed all tests */ ++ return (1); ++} ++ ++#endif ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.3/main/hardening_patch.h hardening-patch-4.4.3-0.4.15/main/hardening_patch.h +--- php-4.4.3/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/hardening_patch.h 2006-09-07 18:50:14.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENING_PATCH_H ++#define HARDENING_PATCH_H ++ ++#include "zend.h" ++ ++#if HARDENING_PATCH ++PHPAPI void php_security_log(int loglevel, char *fmt, ...); ++PHPAPI void hardened_startup(); ++#define HARDENING_PATCH_VERSION "0.4.15" ++ ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++PHPAPI unsigned int php_canary(); ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++PHPAPI int php_is_valid_include(zval *z); ++#endif ++ ++#endif /* HARDENING_PATCH_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-4.4.3/main/hardening_patch.m4 hardening-patch-4.4.3-0.4.15/main/hardening_patch.m4 +--- php-4.4.3/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/hardening_patch.m4 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,95 @@ ++dnl ++dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ ++dnl ++dnl This file contains Hardening Patch for PHP specific autoconf functions. ++dnl ++ ++AC_ARG_ENABLE(hardening-patch-mm-protect, ++[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-ll-protect, ++[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-inc-protect, ++[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-fmt-protect, ++[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-hash-protect, ++[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++]) ++ ++AC_MSG_CHECKING(whether to protect the Zend Memory Manager) ++AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the Zend Linked Lists) ++AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect include/require statements) ++AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect PHP Format String functions) ++AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) ++AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) ++ ++ ++AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) ++fi ++ +diff -Nura php-4.4.3/main/main.c hardening-patch-4.4.3-0.4.15/main/main.c +--- php-4.4.3/main/main.c 2006-05-19 00:36:14.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/main/main.c 2006-09-05 20:30:45.000000000 +0200 +@@ -92,6 +92,10 @@ + PHPAPI int core_globals_id; + #endif + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#endif ++ + #define ERROR_BUF_LEN 1024 + + typedef struct { +@@ -142,17 +146,39 @@ + */ + static PHP_INI_MH(OnChangeMemoryLimit) + { ++#if HARDENING_PATCH ++ long hard_memory_limit = 1<<30; ++ ++ if (stage == ZEND_INI_STAGE_RUNTIME) { ++ if (HG(hard_memory_limit) == 0) { ++ HG(hard_memory_limit) = PG(memory_limit); ++ } ++ hard_memory_limit = HG(hard_memory_limit); ++ } else { ++ HG(hard_memory_limit) = 0; ++ } ++#endif + if (new_value) { + PG(memory_limit) = zend_atoi(new_value, new_value_length); ++#if HARDENING_PATCH ++ if (PG(memory_limit) > hard_memory_limit) { ++ PG(memory_limit) = hard_memory_limit; ++ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); ++ return FAILURE; ++ } ++#endif + } else { ++#if HARDENING_PATCH ++ PG(memory_limit) = hard_memory_limit; ++#else + PG(memory_limit) = 1<<30; /* effectively, no limit */ ++#endif + } + return zend_set_memory_limit(PG(memory_limit)); + } + /* }}} */ + #endif + +- + /* {{{ php_disable_functions + */ + static void php_disable_functions(TSRMLS_D) +@@ -1008,6 +1034,9 @@ + + zend_try { + shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); ++#if HARDENING_PATCH ++ hardened_clear_mm_canaries(TSRMLS_C); ++#endif + } zend_end_try(); + + zend_try { +@@ -1098,6 +1127,10 @@ + tsrm_ls = ts_resource(0); + #endif + ++#if HARDENING_PATCH ++ hardened_startup(); ++#endif ++ + sapi_initialize_empty_request(TSRMLS_C); + sapi_activate(TSRMLS_C); + +@@ -1109,6 +1142,12 @@ + + php_output_startup(); + ++#if HARDENING_PATCH_INC_PROTECT ++ zuf.is_valid_include = php_is_valid_include; ++#endif ++#if HARDENING_PATCH ++ zuf.security_log_function = php_security_log; ++#endif + zuf.error_function = php_error_cb; + zuf.printf_function = php_printf; + zuf.write_function = php_body_write_wrapper; +@@ -1210,6 +1249,10 @@ + REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS); + 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); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); ++#endif + REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); +@@ -1317,7 +1360,7 @@ + */ + static inline void php_register_server_variables(TSRMLS_D) + { +- zval *array_ptr=NULL; ++ zval *array_ptr=NULL, *vptr; + + ALLOC_ZVAL(array_ptr); + array_init(array_ptr); +diff -Nura php-4.4.3/main/php_config.h.in hardening-patch-4.4.3-0.4.15/main/php_config.h.in +--- php-4.4.3/main/php_config.h.in 2006-08-01 09:39:13.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/main/php_config.h.in 2006-09-05 20:30:45.000000000 +0200 +@@ -1,4 +1,4 @@ +-/* main/php_config.h.in. Generated automatically from configure.in by autoheader. */ ++/* main/php_config.h.in. Generated automatically from configure.in by autoheader 2.13. */ + /* Leave this file alone */ + #define ZEND_API + #define ZEND_DLEXPORT +@@ -865,6 +865,39 @@ + /* Enabling BIND8 compatibility for Panther */ + #undef BIND_8_COMPAT + ++/* Hardening-Patch */ ++#undef HARDENING_PATCH ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ + /* Whether you have AOLserver */ + #undef HAVE_AOLSERVER + +@@ -1148,6 +1181,12 @@ + /* Define if you have the getaddrinfo function */ + #undef HAVE_GETADDRINFO + ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ + /* Whether system headers declare timezone */ + #undef HAVE_DECLARED_TIMEZONE + +diff -Nura php-4.4.3/main/php_content_types.c hardening-patch-4.4.3-0.4.15/main/php_content_types.c +--- php-4.4.3/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/php_content_types.c 2006-09-05 20:30:45.000000000 +0200 +@@ -77,6 +77,7 @@ + sapi_register_post_entries(php_post_entries); + sapi_register_default_post_reader(php_default_post_reader); + sapi_register_treat_data(php_default_treat_data); ++ sapi_register_input_filter(php_default_input_filter); + return SUCCESS; + } + /* }}} */ +diff -Nura php-4.4.3/main/php.h hardening-patch-4.4.3-0.4.15/main/php.h +--- php-4.4.3/main/php.h 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/php.h 2006-09-05 20:30:45.000000000 +0200 +@@ -35,11 +35,19 @@ + #include "zend_qsort.h" + #include "php_compat.h" + ++ + #include "zend_API.h" + + #undef sprintf + #define sprintf php_sprintf + ++#if HARDENING_PATCH ++#if HAVE_REALPATH ++#undef realpath ++#define realpath php_realpath ++#endif ++#endif ++ + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ + #undef PHP_DEBUG + #define PHP_DEBUG ZEND_DEBUG +@@ -409,6 +417,10 @@ + #endif + #endif /* !XtOffsetOf */ + ++#if HARDENING_PATCH ++#include "hardening_patch.h" ++#endif ++ + #endif + + /* +diff -Nura php-4.4.3/main/php_variables.c hardening-patch-4.4.3-0.4.15/main/php_variables.c +--- php-4.4.3/main/php_variables.c 2006-02-13 13:19:10.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/php_variables.c 2006-09-05 20:30:45.000000000 +0200 +@@ -238,17 +238,28 @@ + while (var) { + val = strchr(var, '='); + if (val) { /* have a value */ +- int val_len; ++ unsigned int val_len, new_val_len; + + *val++ = '\0'; + php_url_decode(var, strlen(var)); + val_len = php_url_decode(val, strlen(val)); +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } + var = php_strtok_r(NULL, "&", &strtok_buf); + } + } + ++SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) ++{ ++ /* TODO: check .ini setting here and apply user-defined input filter */ ++ *new_val_len = val_len; ++ return 1; ++} ++ + SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) + { + char *res = NULL, *var, *val, *separator=NULL; +@@ -326,15 +337,26 @@ + while (var) { + val = strchr(var, '='); + if (val) { /* have a value */ +- int val_len; ++ unsigned int val_len, new_val_len; + + *val++ = '\0'; + php_url_decode(var, strlen(var)); + val_len = php_url_decode(val, strlen(val)); +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } else { ++ unsigned int val_len, new_val_len; ++ + php_url_decode(var, strlen(var)); +- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC); ++ val_len = 0; ++ val = estrndup("", 0); ++ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } + var = php_strtok_r(NULL, separator, &strtok_buf); + } +diff -Nura php-4.4.3/main/php_version.h hardening-patch-4.4.3-0.4.15/main/php_version.h +--- php-4.4.3/main/php_version.h 2006-07-31 17:04:54.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/main/php_version.h 2006-09-05 20:30:45.000000000 +0200 +@@ -2,6 +2,6 @@ + /* edit configure.in to change version number */ + #define PHP_MAJOR_VERSION 4 + #define PHP_MINOR_VERSION 4 +-#define PHP_RELEASE_VERSION 3 +-#define PHP_EXTRA_VERSION "" +-#define PHP_VERSION "4.4.3" ++#define PHP_RELEASE_VERSION 4 ++#define PHP_EXTRA_VERSION "-dev" ++#define PHP_VERSION "4.4.4-dev" +diff -Nura php-4.4.3/main/rfc1867.c hardening-patch-4.4.3-0.4.15/main/rfc1867.c +--- php-4.4.3/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/rfc1867.c 2006-09-05 20:30:45.000000000 +0200 +@@ -128,6 +128,8 @@ + #define UPLOAD_ERROR_D 4 /* No file uploaded */ + #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ + #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ ++#define UPLOAD_ERROR_X 99 /* Filter forbids upload */ ++ + + void php_rfc1867_register_constants(TSRMLS_D) + { +@@ -138,6 +140,7 @@ + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); + } + + static void normalize_protected_variable(char *varname TSRMLS_DC) +@@ -849,6 +852,7 @@ + char buff[FILLUNIT]; + char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; + int blen=0, wlen=0; ++ unsigned long offset; + + zend_llist_clean(&header); + +@@ -897,21 +901,24 @@ + if (!filename && param) { + + char *value = multipart_buffer_read_body(mbuff TSRMLS_CC); ++ unsigned int new_val_len; /* Dummy variable */ + + if (!value) { + value = estrdup(""); + } + ++ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) { + #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) +- if (php_mb_encoding_translation(TSRMLS_C)) { +- php_mb_gpc_stack_variable(param, value, &val_list, &len_list, +- &num_vars, &num_vars_max TSRMLS_CC); +- } else { +- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); +- } ++ if (php_mb_encoding_translation(TSRMLS_C)) { ++ php_mb_gpc_stack_variable(param, value, &val_list, &len_list, ++ &num_vars, &num_vars_max TSRMLS_CC); ++ } else { ++ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); ++ } + #else +- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); ++ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); + #endif ++ } + if (!strcasecmp(param, "MAX_FILE_SIZE")) { + max_file_size = atol(value); + } +@@ -963,7 +970,11 @@ + tmp++; + } + } +- ++ ++ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { ++ skip_upload = 1; ++ } ++ + total_bytes = cancel_upload = 0; + + if (!skip_upload) { +@@ -987,6 +998,11 @@ + cancel_upload = UPLOAD_ERROR_D; + } + ++ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ ++ offset = 0; + end = 0; + while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) + { +@@ -997,6 +1013,11 @@ + sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); + cancel_upload = UPLOAD_ERROR_B; + } else if (blen > 0) { ++ ++ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + wlen = write(fd, buff, blen); + + if (wlen < blen) { +@@ -1004,6 +1025,7 @@ + cancel_upload = UPLOAD_ERROR_F; + } else { + total_bytes += wlen; ++ offset += wlen; + } + } + } +@@ -1025,6 +1047,10 @@ + } + #endif + ++ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + if (cancel_upload) { + if (temp_filename) { + if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ +diff -Nura php-4.4.3/main/SAPI.c hardening-patch-4.4.3-0.4.15/main/SAPI.c +--- php-4.4.3/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/SAPI.c 2006-09-05 20:30:45.000000000 +0200 +@@ -854,6 +854,37 @@ + return SUCCESS; + } + ++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)) ++{ ++ sapi_module.input_filter = input_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) ++{ ++ sapi_module.upload_varname_filter = upload_varname_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) ++{ ++ sapi_module.pre_upload_filter = pre_upload_filter; ++ return SUCCESS; ++} ++ ++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)) ++{ ++ sapi_module.upload_content_filter = upload_content_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) ++{ ++ sapi_module.post_upload_filter = post_upload_filter; ++ return SUCCESS; ++} ++ ++ + + SAPI_API int sapi_flush(TSRMLS_D) + { +diff -Nura php-4.4.3/main/SAPI.h hardening-patch-4.4.3-0.4.15/main/SAPI.h +--- php-4.4.3/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/SAPI.h 2006-09-05 20:30:45.000000000 +0200 +@@ -101,9 +101,10 @@ + char *current_user; + int current_user_length; + +- /* this is necessary for CLI module */ +- int argc; +- char **argv; ++ /* this is necessary for CLI module */ ++ int argc; ++ char **argv; ++ + } sapi_request_info; + + +@@ -177,6 +178,10 @@ + SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); + SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); + SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); + + SAPI_API int sapi_flush(TSRMLS_D); + SAPI_API struct stat *sapi_get_stat(TSRMLS_D); +@@ -238,8 +243,16 @@ + int (*get_target_uid)(uid_t * TSRMLS_DC); + int (*get_target_gid)(gid_t * TSRMLS_DC); + ++ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); ++ ++ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); ++ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); ++ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); ++ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); ++ + void (*ini_defaults)(HashTable *configuration_hash); + int phpinfo_as_text; ++ + }; + + +@@ -262,16 +275,27 @@ + + #define SAPI_DEFAULT_MIMETYPE "text/html" + #define SAPI_DEFAULT_CHARSET "" ++ ++#if HARDENING_PATCH ++#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" ++#else + #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION ++#endif + + #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) + #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) + + #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) ++#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) ++#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) ++#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) ++#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) ++#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) + + SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); + SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); + SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); ++SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter); + + #define STANDARD_SAPI_MODULE_PROPERTIES + +diff -Nura php-4.4.3/main/snprintf.c hardening-patch-4.4.3-0.4.15/main/snprintf.c +--- php-4.4.3/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/snprintf.c 2006-09-05 20:30:45.000000000 +0200 +@@ -1014,7 +1014,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = cc; ++#endif + break; + + /* +diff -Nura php-4.4.3/main/spprintf.c hardening-patch-4.4.3-0.4.15/main/spprintf.c +--- php-4.4.3/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/main/spprintf.c 2006-09-05 20:30:45.000000000 +0200 +@@ -630,7 +630,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = xbuf->len; ++#endif + break; + + /* +diff -Nura php-4.4.3/php.ini-dist hardening-patch-4.4.3-0.4.15/php.ini-dist +--- php-4.4.3/php.ini-dist 2005-12-30 18:19:43.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/php.ini-dist 2006-09-05 20:30:45.000000000 +0200 +@@ -1114,6 +1114,209 @@ + ;exif.decode_jis_motorola = JIS + ;exif.decode_jis_intel = JIS + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-4.4.3/php.ini-recommended hardening-patch-4.4.3-0.4.15/php.ini-recommended +--- php-4.4.3/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/php.ini-recommended 2006-09-05 20:30:45.000000000 +0200 +@@ -1112,6 +1112,209 @@ + ;exif.decode_jis_motorola = JIS + ;exif.decode_jis_intel = JIS + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-4.4.3/README.input_filter hardening-patch-4.4.3-0.4.15/README.input_filter +--- php-4.4.3/README.input_filter 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/README.input_filter 2006-09-05 20:30:45.000000000 +0200 +@@ -0,0 +1,193 @@ ++Input Filter Support ported from PHP 5 ++-------------------------------------- ++ ++XSS (Cross Site Scripting) hacks are becoming more and more prevalent, ++and can be quite difficult to prevent. Whenever you accept user data ++and somehow display this data back to users, you are likely vulnerable ++to XSS hacks. ++ ++The Input Filter support in PHP 5 is aimed at providing the framework ++through which a company-wide or site-wide security policy can be ++enforced. It is implemented as a SAPI hook and is called from the ++treat_data and post handler functions. To implement your own security ++policy you will need to write a standard PHP extension. ++ ++A simple implementation might look like the following. This stores the ++original raw user data and adds a my_get_raw() function while the normal ++$_POST, $_GET and $_COOKIE arrays are only populated with stripped ++data. In this simple example all I am doing is calling strip_tags() on ++the data. If register_globals is turned on, the default globals that ++are created will be stripped ($foo) while a $RAW_foo is created with the ++original user input. ++ ++ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) ++ zval *post_array; ++ zval *get_array; ++ zval *cookie_array; ++ZEND_END_MODULE_GLOBALS(my_input_filter) ++ ++#ifdef ZTS ++#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v) ++#else ++#define IF_G(v) (my_input_filter_globals.v) ++#endif ++ ++ZEND_DECLARE_MODULE_GLOBALS(my_input_filter) ++ ++function_entry my_input_filter_functions[] = { ++ PHP_FE(my_get_raw, NULL) ++ {NULL, NULL, NULL} ++}; ++ ++zend_module_entry my_input_filter_module_entry = { ++ STANDARD_MODULE_HEADER, ++ "my_input_filter", ++ my_input_filter_functions, ++ PHP_MINIT(my_input_filter), ++ PHP_MSHUTDOWN(my_input_filter), ++ NULL, ++ PHP_RSHUTDOWN(my_input_filter), ++ PHP_MINFO(my_input_filter), ++ "0.1", ++ STANDARD_MODULE_PROPERTIES ++}; ++ ++PHP_MINIT_FUNCTION(my_input_filter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL); ++ ++ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); ++ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); ++ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); ++ ++ sapi_register_input_filter(my_sapi_input_filter); ++ return SUCCESS; ++} ++ ++PHP_RSHUTDOWN_FUNCTION(my_input_filter) ++{ ++ if(IF_G(get_array)) { ++ zval_ptr_dtor(&IF_G(get_array)); ++ IF_G(get_array) = NULL; ++ } ++ if(IF_G(post_array)) { ++ zval_ptr_dtor(&IF_G(post_array)); ++ IF_G(post_array) = NULL; ++ } ++ if(IF_G(cookie_array)) { ++ zval_ptr_dtor(&IF_G(cookie_array)); ++ IF_G(cookie_array) = NULL; ++ } ++ return SUCCESS; ++} ++ ++PHP_MINFO_FUNCTION(my_input_filter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); ++ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $"); ++ php_info_print_table_end(); ++} ++ ++/* The filter handler. If you return 1 from it, then PHP also registers the ++ * (modified) variable. Returning 0 prevents PHP from registering the variable; ++ * you can use this if your filter already registers the variable under a ++ * different name, or if you just don't want the variable registered at all. */ ++SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter) ++{ ++ zval new_var; ++ zval *array_ptr = NULL; ++ char *raw_var; ++ int var_len; ++ ++ assert(*val != NULL); ++ ++ switch(arg) { ++ case PARSE_GET: ++ if(!IF_G(get_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(get_array) = array_ptr; ++ break; ++ case PARSE_POST: ++ if(!IF_G(post_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(post_array) = array_ptr; ++ break; ++ case PARSE_COOKIE: ++ if(!IF_G(cookie_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(cookie_array) = array_ptr; ++ break; ++ } ++ Z_STRLEN(new_var) = val_len; ++ Z_STRVAL(new_var) = estrndup(*val, val_len); ++ Z_TYPE(new_var) = IS_STRING; ++ ++ var_len = strlen(var); ++ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ ++ strcpy(raw_var, "RAW_"); ++ strlcat(raw_var,var,var_len+5); ++ ++ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC); ++ ++ php_strip_tags(*val, val_len, NULL, NULL, 0); ++ ++ *new_val_len = strlen(*val); ++ return 1; ++} ++ ++PHP_FUNCTION(my_get_raw) ++{ ++ long arg; ++ char *var; ++ int var_len; ++ zval **tmp; ++ zval *array_ptr = NULL; ++ HashTable *hash_ptr; ++ char *raw_var; ++ ++ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) { ++ return; ++ } ++ ++ switch(arg) { ++ case PARSE_GET: ++ array_ptr = IF_G(get_array); ++ break; ++ case PARSE_POST: ++ array_ptr = IF_G(post_array); ++ break; ++ case PARSE_COOKIE: ++ array_ptr = IF_G(post_array); ++ break; ++ } ++ ++ if(!array_ptr) RETURN_FALSE; ++ ++ /* ++ * I'm changing the variable name here because when running with register_globals on, ++ * the variable will end up in the global symbol table ++ */ ++ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ ++ strcpy(raw_var, "RAW_"); ++ strlcat(raw_var,var,var_len+5); ++ hash_ptr = HASH_OF(array_ptr); ++ ++ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) { ++ *return_value = **tmp; ++ zval_copy_ctor(return_value); ++ } else { ++ RETVAL_FALSE; ++ } ++ efree(raw_var); ++} ++ +diff -Nura php-4.4.3/run-tests.php hardening-patch-4.4.3-0.4.15/run-tests.php +--- php-4.4.3/run-tests.php 2006-01-18 18:59:41.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/run-tests.php 2006-09-05 20:30:45.000000000 +0200 +@@ -152,6 +152,10 @@ + 'error_reporting=2047', + 'display_errors=1', + 'log_errors=0', ++ 'hphp.executor.include.whitelist=cookietest', ++ 'hphp.log.syslog=0', ++ 'hphp.log.sapi=0', ++ 'hphp.log.script=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=1', +diff -Nura php-4.4.3/sapi/apache/mod_php4.c hardening-patch-4.4.3-0.4.15/sapi/apache/mod_php4.c +--- php-4.4.3/sapi/apache/mod_php4.c 2006-05-13 23:42:14.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/sapi/apache/mod_php4.c 2006-09-05 20:30:45.000000000 +0200 +@@ -451,7 +451,7 @@ + sapi_apache_get_fd, + sapi_apache_force_http_10, + sapi_apache_get_target_uid, +- sapi_apache_get_target_gid ++ sapi_apache_get_target_gid, + }; + /* }}} */ + +@@ -897,7 +897,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component("PHP/" PHP_VERSION); ++#endif + } + } + #endif +diff -Nura php-4.4.3/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.3-0.4.15/sapi/apache2filter/sapi_apache2.c +--- php-4.4.3/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:30:45.000000000 +0200 +@@ -562,7 +562,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-4.4.3/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.3-0.4.15/sapi/apache2handler/sapi_apache2.c +--- php-4.4.3/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:30:45.000000000 +0200 +@@ -340,7 +340,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-4.4.3/sapi/cgi/cgi_main.c hardening-patch-4.4.3-0.4.15/sapi/cgi/cgi_main.c +--- php-4.4.3/sapi/cgi/cgi_main.c 2006-02-22 16:11:53.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:30:46.000000000 +0200 +@@ -1435,11 +1435,19 @@ + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } ++#if HARDENING_PATCH ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif ++#else + #if ZEND_DEBUG + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #else + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #endif ++#endif + php_end_ob_buffers(1 TSRMLS_CC); + exit(0); + break; +diff -Nura php-4.4.3/sapi/cli/php_cli.c hardening-patch-4.4.3-0.4.15/sapi/cli/php_cli.c +--- php-4.4.3/sapi/cli/php_cli.c 2006-05-18 22:33:46.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:30:46.000000000 +0200 +@@ -656,11 +656,19 @@ + if (php_request_startup(TSRMLS_C)==FAILURE) { + goto err; + } ++#if HARDENING_PATCH ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif ++#else + #if ZEND_DEBUG + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #else + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #endif ++#endif + php_end_ob_buffers(1 TSRMLS_CC); + exit_status=0; + goto out; +diff -Nura php-4.4.3/tests/lang/bug35239.phpt hardening-patch-4.4.3-0.4.15/tests/lang/bug35239.phpt +--- php-4.4.3/tests/lang/bug35239.phpt 2006-05-19 13:17:53.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/tests/lang/bug35239.phpt 2006-09-05 20:30:46.000000000 +0200 +@@ -10,16 +10,16 @@ + $a->x0->y0 = 'b'; + var_dump($a); + $a->x0->y1 = "ok\n"; +-echo $a->x0; ++var_dump($a->x0); + ?> + --EXPECT-- +-object(stdClass)#1 (1) { ++object(stdClass)(1) { + ["x0"]=> +- &object(stdClass)#2 (3) { ++ &object(stdClass)(3) { + ["y0"]=> + string(1) "b" + ["y1"]=> +- &object(stdClass)#2 (3) { ++ &object(stdClass)(3) { + ["y0"]=> + string(1) "b" + ["y1"]=> +@@ -28,7 +28,7 @@ + *RECURSION* + } + ["y2"]=> +- &object(stdClass)#2 (3) { ++ &object(stdClass)(3) { + ["y0"]=> + string(1) "b" + ["y1"]=> +@@ -38,4 +38,4 @@ + } + } + } +-ok ++string(2) "ok" +diff -Nura php-4.4.3/TSRM/TSRM.h hardening-patch-4.4.3-0.4.15/TSRM/TSRM.h +--- php-4.4.3/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/TSRM/TSRM.h 2006-09-05 20:30:46.000000000 +0200 +@@ -33,6 +33,13 @@ + # define TSRM_API + #endif + ++#if HARDENING_PATCH ++# if HAVE_REALPATH ++# undef realpath ++# define realpath php_realpath ++# endif ++#endif ++ + /* Only compile multi-threading functions if we're in ZTS mode */ + #ifdef ZTS + +@@ -84,6 +91,7 @@ + + #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts + ++ + #ifdef __cplusplus + extern "C" { + #endif +diff -Nura php-4.4.3/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.c +--- php-4.4.3/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:30:46.000000000 +0200 +@@ -179,6 +179,178 @@ + return p; + } + ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved) ++{ ++ struct stat sb; ++ char *p, *q, *s; ++ size_t left_len, resolved_len; ++ unsigned symlinks; ++ int serrno, slen; ++ int is_dir = 1; ++ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; ++ ++ serrno = errno; ++ symlinks = 0; ++ if (path[0] == '/') { ++ resolved[0] = '/'; ++ resolved[1] = '\0'; ++ if (path[1] == '\0') ++ return (resolved); ++ resolved_len = 1; ++ left_len = strlcpy(left, path + 1, sizeof(left)); ++ } else { ++ if (getcwd(resolved, PATH_MAX) == NULL) { ++ strlcpy(resolved, ".", PATH_MAX); ++ return (NULL); ++ } ++ resolved_len = strlen(resolved); ++ left_len = strlcpy(left, path, sizeof(left)); ++ } ++ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ ++ /* ++ * Iterate over path components in `left'. ++ */ ++ while (left_len != 0) { ++ /* ++ * Extract the next path component and adjust `left' ++ * and its length. ++ */ ++ p = strchr(left, '/'); ++ s = p ? p : left + left_len; ++ if (s - left >= sizeof(next_token)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ memcpy(next_token, left, s - left); ++ next_token[s - left] = '\0'; ++ left_len -= s - left; ++ if (p != NULL) ++ memmove(left, s + 1, left_len + 1); ++ if (resolved[resolved_len - 1] != '/') { ++ if (resolved_len + 1 >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ resolved[resolved_len++] = '/'; ++ resolved[resolved_len] = '\0'; ++ } ++ if (next_token[0] == '\0') ++ continue; ++ else if (strcmp(next_token, ".") == 0) ++ continue; ++ else if (strcmp(next_token, "..") == 0) { ++ /* ++ * Strip the last path component except when we have ++ * single "/" ++ */ ++ if (!is_dir) { ++ errno = ENOENT; ++ return (NULL); ++ } ++ if (resolved_len > 1) { ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ continue; ++ } ++ ++ /* ++ * Append the next path component and lstat() it. If ++ * lstat() fails we still can return successfully if ++ * there are no more path components left. ++ */ ++ resolved_len = strlcat(resolved, next_token, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ if (lstat(resolved, &sb) != 0) { ++ if (errno == ENOENT) { ++ if (p == NULL) { ++ errno = serrno; ++ return (resolved); ++ } else ++ /* dirty hack to support a vanilla PHP feature */ ++ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { ++ resolved_len = strlcat(resolved, "/", PATH_MAX); ++ resolved_len = strlcat(resolved, left, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ errno = serrno; ++ return (resolved); ++ } ++ } ++ return (NULL); ++ } ++ if (S_ISLNK(sb.st_mode)) { ++ if (symlinks++ > MAXSYMLINKS) { ++ errno = ELOOP; ++ return (NULL); ++ } ++ slen = readlink(resolved, symlink, sizeof(symlink) - 1); ++ if (slen < 0) ++ return (NULL); ++ symlink[slen] = '\0'; ++ if (symlink[0] == '/') { ++ resolved[1] = 0; ++ resolved_len = 1; ++ } else if (resolved_len > 1) { ++ /* Strip the last path component. */ ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ ++ /* ++ * If there are any path components left, then ++ * append them to symlink. The result is placed ++ * in `left'. ++ */ ++ if (p != NULL) { ++ if (symlink[slen - 1] != '/') { ++ if (slen + 1 >= sizeof(symlink)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ symlink[slen] = '/'; ++ symlink[slen + 1] = 0; ++ } ++ left_len = strlcat(symlink, left, sizeof(left)); ++ if (left_len >= sizeof(left)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ } ++ left_len = strlcpy(left, symlink, sizeof(left)); ++ } else { ++ if (S_ISDIR(sb.st_mode)) { ++ is_dir = 1; ++ } else { ++ is_dir = 0; ++ } ++ } ++ } ++ ++ /* ++ * Remove trailing slash except when the resolved pathname ++ * is a single "/". ++ */ ++ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') ++ resolved[resolved_len - 1] = '\0'; ++ return (resolved); ++} ++#endif ++ + CWD_API void virtual_cwd_startup(void) + { + char cwd[MAXPATHLEN]; +@@ -300,8 +472,11 @@ + + if (path_length == 0) + return (0); +- if (path_length >= MAXPATHLEN) ++ if (path_length >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return (1); ++ } + + #if !defined(TSRM_WIN32) && !defined(NETWARE) + /* cwd_length can be 0 when getcwd() fails. +@@ -313,8 +488,9 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + } else { /* Concat current directory with relative path and then run realpath() on it */ +@@ -323,6 +499,8 @@ + + ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); + if (!tmp) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(ptr, state->cwd, state->cwd_length); +@@ -332,6 +510,8 @@ + ptr += path_length; + *ptr = '\0'; + if (strlen(tmp) >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + free(tmp); + return 1; + } +@@ -340,9 +520,10 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + free(tmp); +- return 1; */ ++ return 1; + } + } + free(tmp); +diff -Nura php-4.4.3/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.h +--- php-4.4.3/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:30:46.000000000 +0200 +@@ -128,6 +128,22 @@ + + typedef int (*verify_path_func)(const cwd_state *); + ++#ifndef HAVE_STRLCPY ++CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); ++#undef strlcpy ++#define strlcpy php_strlcpy ++#endif ++ ++#ifndef HAVE_STRLCAT ++CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); ++#undef strlcat ++#define strlcat php_strlcat ++#endif ++ ++ ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved); ++#endif + CWD_API void virtual_cwd_startup(void); + CWD_API void virtual_cwd_shutdown(void); + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); +diff -Nura php-4.4.3/Zend/zend_alloc.c hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.c +--- php-4.4.3/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.c 2006-09-05 20:30:46.000000000 +0200 +@@ -56,6 +56,11 @@ + # define END_MAGIC_SIZE 0 + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++# define CANARY_SIZE sizeof(unsigned int) ++#else ++# define CANARY_SIZE 0 ++#endif + + # if MEMORY_LIMIT + # if ZEND_DEBUG +@@ -64,7 +69,15 @@ + #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) + # endif + +-#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ ++#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ ++ if (file) { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ ++ } else { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ ++ } \ ++ exit(1); \ ++ } \ ++ AG(allocated_memory) += rs;\ + if (AG(memory_limit)pNext; \ + } else { \ ++ if (p != p->pLast->pNext) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pLast->pNext = p->pNext; \ + } \ + if (p->pNext) { \ ++ if (p != p->pNext->pLast) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pNext->pLast = p->pLast; \ + } + +@@ -111,7 +132,7 @@ + p->pLast = (zend_mem_header *) NULL; + + #define DECLARE_CACHE_VARS() \ +- unsigned int real_size; \ ++ size_t real_size; \ + unsigned int cache_index + + #define REAL_SIZE(size) ((size+7) & ~0x7) +@@ -126,12 +147,22 @@ + + ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { +- zend_mem_header *p; ++ zend_mem_header *p = NULL; + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { ++ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); ++ exit(1); ++ } ++#endif + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + ++ if (size > INT_MAX || SIZE < size) { ++ goto emalloc_error; ++ } ++ + if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { + p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; + #if ZEND_DEBUG +@@ -147,6 +178,10 @@ + AG(cache_stats)[CACHE_INDEX][1]++; + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->cached = 0; + p->size = size; + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); +@@ -162,9 +197,11 @@ + AG(allocated_memory_peak) = AG(allocated_memory); + } + #endif +- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); + } + ++emalloc_error: ++ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (!p) { +@@ -192,7 +229,10 @@ + # endif + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif +- ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } +@@ -219,17 +259,36 @@ + return emalloc_rel(lval + offset); + } + } +- ++ ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); ++#endif + zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset); + return 0; + } + + ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++efree_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); ++ exit(1); ++ } ++ /* to catch double efree()s */ ++ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); ++ p->canary = 0; ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring", +@@ -274,6 +333,9 @@ + size_t _size = nmemb * size; + + if (nmemb && (_size/nmemb!=size)) { ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); ++#endif + fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); + #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID + kill(getpid(), SIGSEGV); +@@ -293,6 +355,9 @@ + + ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p; + zend_mem_header *orig; + DECLARE_CACHE_VARS(); +@@ -304,6 +369,16 @@ + + p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++erealloc_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); ++ exit(1); ++ } ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + void *new_p; +@@ -320,6 +395,13 @@ + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + + HANDLE_BLOCK_INTERRUPTIONS(); ++ ++ if (size > INT_MAX || SIZE < size) { ++ REMOVE_POINTER_FROM_LIST(p); ++ p = NULL; ++ goto erealloc_error; ++ } ++ + #if MEMORY_LIMIT + CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); + if (AG(allocated_memory) > AG(allocated_memory_peak)) { +@@ -327,7 +409,8 @@ + } + #endif + REMOVE_POINTER_FROM_LIST(p); +- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); ++erealloc_error: + if (!p) { + if (!allow_failure) { + fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); +@@ -349,6 +432,9 @@ + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + + HANDLE_UNBLOCK_INTERRUPTIONS(); +@@ -423,6 +509,10 @@ + { + AG(head) = NULL; + ++#if HARDENING_PATCH_MM_PROTECT ++ HG(canary_1) = zend_canary(); ++ HG(canary_2) = zend_canary(); ++#endif + #if MEMORY_LIMIT + AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ + AG(allocated_memory) = 0; +diff -Nura php-4.4.3/Zend/zend_alloc.h hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.h +--- php-4.4.3/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.h 2006-09-05 20:30:46.000000000 +0200 +@@ -32,6 +32,9 @@ + #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL + + typedef struct _zend_mem_header { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary; ++#endif + #if ZEND_DEBUG + long magic; + char *filename; +diff -Nura php-4.4.3/Zend/zend_builtin_functions.c hardening-patch-4.4.3-0.4.15/Zend/zend_builtin_functions.c +--- php-4.4.3/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:30:46.000000000 +0200 +@@ -49,6 +49,9 @@ + static ZEND_FUNCTION(crash); + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++static ZEND_FUNCTION(heap_overflow); ++#endif + static ZEND_FUNCTION(get_included_files); + static ZEND_FUNCTION(is_subclass_of); + static ZEND_FUNCTION(is_a); +@@ -101,6 +104,9 @@ + ZEND_FE(crash, NULL) + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ ZEND_FE(heap_overflow, NULL) ++#endif + ZEND_FE(get_included_files, NULL) + ZEND_FALIAS(get_required_files, get_included_files, NULL) + ZEND_FE(is_subclass_of, NULL) +@@ -805,6 +811,19 @@ + + #endif /* ZEND_DEBUG */ + ++ ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ZEND_FUNCTION(heap_overflow) ++{ ++ char *nowhere = emalloc(10); ++ ++ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); ++ ++ efree(nowhere); ++} ++#endif ++ ++ + /* {{{ proto array get_included_files(void) + Returns an array with the file names that were include_once()'d */ + ZEND_FUNCTION(get_included_files) +diff -Nura php-4.4.3/Zend/zend.c hardening-patch-4.4.3-0.4.15/Zend/zend.c +--- php-4.4.3/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend.c 2006-09-05 20:30:46.000000000 +0200 +@@ -53,6 +53,12 @@ + ZEND_API void (*zend_unblock_interruptions)(void); + ZEND_API void (*zend_ticks_function)(int ticks); + ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); ++#if HARDENING_PATCH ++ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + + void (*zend_on_timeout)(int seconds TSRMLS_DC); + +@@ -70,9 +76,391 @@ + return SUCCESS; + } + ++#if HARDENING_PATCH ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; ++ } else { ++ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_facility) = LOG_USER; ++ } else { ++ EG(hphp_log_syslog_facility) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_priority) = LOG_ALERT; ++ } else { ++ EG(hphp_log_syslog_priority) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_sapi) ++{ ++ if (!new_value) { ++ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; ++ } else { ++ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_script) ++{ ++ if (!new_value) { ++ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL); ++ } else { ++ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) ++{ ++ if (EG(hphp_log_scriptname)) { ++ pefree(EG(hphp_log_scriptname),1); ++ } ++ EG(hphp_log_scriptname) = NULL; ++ if (new_value) { ++ EG(hphp_log_scriptname) = pestrdup(new_value,1); ++ } ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_whitelist_destroy: ++ if (HG(include_whitelist)) { ++ zend_hash_destroy(HG(include_whitelist)); ++ pefree(HG(include_whitelist),1); ++ } ++ HG(include_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_whitelist_destroy; ++ } ++ ++ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_blacklist_destroy: ++ if (HG(include_blacklist)) { ++ zend_hash_destroy(HG(include_blacklist)); ++ pefree(HG(include_blacklist),1); ++ } ++ HG(include_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_blacklist_destroy; ++ } ++ ++ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_whitelist_destroy: ++ if (HG(eval_whitelist)) { ++ zend_hash_destroy(HG(eval_whitelist)); ++ pefree(HG(eval_whitelist),1); ++ } ++ HG(eval_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_whitelist_destroy; ++ } ++ ++ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_blacklist_destroy: ++ if (HG(eval_blacklist)) { ++ zend_hash_destroy(HG(eval_blacklist)); ++ pefree(HG(eval_blacklist), 1); ++ } ++ HG(eval_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_blacklist_destroy; ++ } ++ ++ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_whitelist_destroy: ++ if (HG(func_whitelist)) { ++ zend_hash_destroy(HG(func_whitelist)); ++ pefree(HG(func_whitelist),1); ++ } ++ HG(func_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_whitelist_destroy; ++ } ++ ++ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_blacklist_destroy: ++ if (HG(func_blacklist)) { ++ zend_hash_destroy(HG(func_blacklist)); ++ pefree(HG(func_blacklist),1); ++ } ++ HG(func_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_blacklist_destroy; ++ } ++ ++ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++#endif + + ZEND_INI_BEGIN() + ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) ++#if HARDENING_PATCH ++ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) ++ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) ++ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) ++ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) ++ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) ++ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) ++ 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) ++ ++ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) ++ ++ 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) ++ 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) ++ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) ++ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) ++#endif + ZEND_INI_END() + + +@@ -354,8 +742,12 @@ + zend_init_rsrc_plist(TSRMLS_C); + EG(lambda_count)=0; + EG(user_error_handler) = NULL; ++ EG(in_code_type) = 0; + EG(in_execution) = 0; + EG(current_execute_data) = NULL; ++#if HARDENING_PATCH ++ EG(hphp_log_scriptname) = NULL; ++#endif + } + + +@@ -420,6 +812,14 @@ + extern zend_scanner_globals language_scanner_globals; + #endif + ++ /* Set up Hardening-Patch utility functions first */ ++#if HARDENING_PATCH ++ zend_security_log = utility_functions->security_log_function; ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ zend_is_valid_include = utility_functions->is_valid_include; ++#endif ++ + #ifdef ZTS + ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + #else +@@ -619,6 +1019,7 @@ + } + CG(unclean_shutdown) = 1; + CG(in_compilation) = EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(current_execute_data) = NULL; + longjmp(EG(bailout), FAILURE); + } +diff -Nura php-4.4.3/Zend/zend_canary.c hardening-patch-4.4.3-0.4.15/Zend/zend_canary.c +--- php-4.4.3/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_canary.c 2006-09-05 20:30:46.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ ++ ++#include "zend.h" ++ ++#include ++#include ++ ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++ZEND_API unsigned int zend_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.3/Zend/zend_compile.c hardening-patch-4.4.3-0.4.15/Zend/zend_compile.c +--- php-4.4.3/Zend/zend_compile.c 2006-02-23 19:07:16.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_compile.c 2006-09-05 20:30:46.000000000 +0200 +@@ -768,6 +768,13 @@ + op_array.function_name = name; + op_array.arg_types = NULL; + op_array.return_reference = return_reference; ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array.created_by_eval = 1; ++ } else { ++ op_array.created_by_eval = 0; ++ } ++#endif + + if (is_method) { + if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { +diff -Nura php-4.4.3/Zend/zend_compile.h hardening-patch-4.4.3-0.4.15/Zend/zend_compile.h +--- php-4.4.3/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_compile.h 2006-09-05 20:30:46.000000000 +0200 +@@ -106,6 +106,9 @@ + char *filename; + + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; ++#if HARDENING_PATCH ++ zend_bool created_by_eval; ++#endif + }; + + +@@ -549,6 +552,7 @@ + #define ZEND_USER_FUNCTION 2 + #define ZEND_OVERLOADED_FUNCTION 3 + #define ZEND_EVAL_CODE 4 ++#define ZEND_SANDBOX_CODE 6 + + #define ZEND_INTERNAL_CLASS 1 + #define ZEND_USER_CLASS 2 +diff -Nura php-4.4.3/Zend/zend_constants.c hardening-patch-4.4.3-0.4.15/Zend/zend_constants.c +--- php-4.4.3/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_constants.c 2006-09-05 20:30:46.000000000 +0200 +@@ -111,6 +111,74 @@ + REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); + + REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); ++ ++ /* error levels */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); ++ /* facility: type of program logging the message */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NEWS ++ /* No LOG_NEWS on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ ++#endif ++#ifdef LOG_UUCP ++ /* No LOG_UUCP on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_CRON ++ /* apparently some systems don't have this one */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_AUTHPRIV ++ /* AIX doesn't have LOG_AUTHPRIV */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); ++#endif ++#if !defined(PHP_WIN32) && !defined(NETWARE) ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); ++#endif ++ /* options */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NOWAIT ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_PERROR ++ /* AIX doesn't have LOG_PERROR */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ ++#endif ++#endif + + /* true/false constants */ + { +diff -Nura php-4.4.3/Zend/zend_errors.h hardening-patch-4.4.3-0.4.15/Zend/zend_errors.h +--- php-4.4.3/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_errors.h 2006-09-05 20:30:46.000000000 +0200 +@@ -36,5 +36,18 @@ + #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) + #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) + ++#if HARDENING_PATCH ++#define S_MEMORY (1<<0L) ++#define S_VARS (1<<1L) ++#define S_FILES (1<<2L) ++#define S_INCLUDE (1<<3L) ++#define S_SQL (1<<4L) ++#define S_EXECUTOR (1<<5L) ++#define S_MAIL (1<<6L) ++#define S_MISC (1<<30L) ++#define S_INTERNAL (1<<29L) ++#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) ++#endif ++ + #endif /* ZEND_ERRORS_H */ + +diff -Nura php-4.4.3/Zend/zend_execute_API.c hardening-patch-4.4.3-0.4.15/Zend/zend_execute_API.c +--- php-4.4.3/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:30:46.000000000 +0200 +@@ -142,6 +142,7 @@ + EG(class_table) = CG(class_table); + + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + + zend_ptr_stack_init(&EG(argument_stack)); + +@@ -431,12 +432,14 @@ + zend_execute_data execute_data; + + /* Initialize execute_data */ ++ memset(&execute_data, 0, sizeof(execute_data)); + EX(fbc) = NULL; + EX(object).ptr = NULL; + EX(ce) = NULL; + EX(Ts) = NULL; + EX(op_array) = NULL; + EX(opline) = NULL; ++ EX(execute_depth) = 0; + + *retval_ptr_ptr = NULL; + +@@ -494,6 +497,39 @@ + zval_dtor(&function_name_copy); + return FAILURE; + } ++#if HARDENING_PATCH ++ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + zval_dtor(&function_name_copy); + + for (i=0; itype = type; + EG(return_value_ptr_ptr) = &local_retval_ptr; + EG(active_op_array) = new_op_array; + EG(no_extensions)=1; +@@ -673,6 +709,10 @@ + return retval; + } + ++ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++{ ++ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); ++} + + void execute_new_code(TSRMLS_D) + { +diff -Nura php-4.4.3/Zend/zend_execute.c hardening-patch-4.4.3-0.4.15/Zend/zend_execute.c +--- php-4.4.3/Zend/zend_execute.c 2006-04-13 08:16:42.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_execute.c 2006-09-05 20:30:46.000000000 +0200 +@@ -1042,6 +1042,7 @@ + zend_execute_data execute_data; + + /* Initialize execute_data */ ++ memset(&execute_data, 0, sizeof(execute_data)); + EX(fbc) = NULL; + EX(ce) = NULL; + EX(object).ptr = NULL; +@@ -1053,9 +1054,21 @@ + } + EX(prev_execute_data) = EG(current_execute_data); + EX(original_in_execution)=EG(in_execution); ++ EX(original_in_code_type)=EG(in_code_type); + + EG(current_execute_data) = &execute_data; + ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif ++ + EG(in_execution) = 1; + if (op_array->start_op) { + EX(opline) = op_array->start_op; +@@ -1087,6 +1100,19 @@ + } + } + ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif ++ + while (1) { + #ifdef ZEND_WIN32 + if (EG(timed_out)) { +@@ -1634,6 +1660,36 @@ + if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) { + zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val); + } ++#if HARDENING_PATCH ++ if (active_function_table == EG(function_table)) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++#endif ++ + zval_dtor(&tmp); + EX(fbc) = function; + overloaded_function_call_cont: +@@ -1649,6 +1705,35 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); + zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce)); + EX(object).ptr = NULL; +@@ -1821,6 +1906,7 @@ + efree(EX(Ts)); + } + EG(in_execution) = EX(original_in_execution); ++ EG(in_code_type) = EX(original_in_code_type); + EG(current_execute_data) = EX(prev_execute_data); + return; + } +@@ -2210,7 +2296,12 @@ + int dummy = 1; + zend_file_handle file_handle = {0}; + ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS ++#else + if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS ++#endif + && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { + + file_handle.filename = inc_filename->value.str.val; +@@ -2239,6 +2330,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -2381,7 +2477,7 @@ + if (EX(opline)->extended_value) { + array_ptr_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R); + if (array_ptr_ptr == NULL) { +- MAKE_STD_ZVAL(array_ptr); ++ ALLOC_INIT_ZVAL(array_ptr); + } else { + SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr); + array_ptr = *array_ptr_ptr; +diff -Nura php-4.4.3/Zend/zend_execute_globals.h hardening-patch-4.4.3-0.4.15/Zend/zend_execute_globals.h +--- php-4.4.3/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_execute_globals.h 2006-09-05 20:30:46.000000000 +0200 +@@ -60,6 +60,8 @@ + object_info object; + temp_variable *Ts; + zend_bool original_in_execution; ++ zend_uint original_in_code_type; ++ zend_uint execute_depth; + zend_op_array *op_array; + struct _zend_execute_data *prev_execute_data; + } zend_execute_data; +diff -Nura php-4.4.3/Zend/zend_extensions.c hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.c +--- php-4.4.3/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.c 2006-09-05 20:30:46.000000000 +0200 +@@ -54,23 +54,44 @@ + return FAILURE; + } + ++ /* check if module is compiled against Hardening-Patch */ ++ if (extension_version_info->zend_extension_api_no < 1000000000) { ++ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } ++ ++ ++ /* check if module is compiled against correct Hardening-Patch version */ ++ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { ++ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ extension_version_info->zend_extension_api_no, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } + + /* allow extension to proclaim compatibility with any Zend version */ +- 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)) { +- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { ++ 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)) { ++ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is outdated.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO); + DL_UNLOAD(handle); + return FAILURE; +- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { ++ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is newer.\n" + "Contact %s at %s for a later version of %s.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO, + new_extension->author, + new_extension->URL, +diff -Nura php-4.4.3/Zend/zend_extensions.h hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.h +--- php-4.4.3/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.h 2006-09-05 20:30:46.000000000 +0200 +@@ -23,6 +23,9 @@ + + #include "zend_compile.h" + ++/* Create own API version number for Hardening-Patch */ ++ ++#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805 + #define ZEND_EXTENSION_API_NO 20050606 + + typedef struct _zend_extension_version_info { +@@ -30,6 +33,7 @@ + char *required_zend_version; + unsigned char thread_safe; + unsigned char debug; ++ int real_zend_extension_api_no; + } zend_extension_version_info; + + +@@ -96,7 +100,7 @@ + + + #define ZEND_EXTENSION() \ +- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } ++ 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 } + + #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 + #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 +diff -Nura php-4.4.3/Zend/zend_globals.h hardening-patch-4.4.3-0.4.15/Zend/zend_globals.h +--- php-4.4.3/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_globals.h 2006-09-05 20:30:46.000000000 +0200 +@@ -163,6 +163,16 @@ + + int error_reporting; + int orig_error_reporting; ++#if HARDENING_PATCH ++ int hphp_log_syslog; ++ int hphp_log_syslog_facility; ++ int hphp_log_syslog_priority; ++ int hphp_log_sapi; ++ int hphp_log_script; ++ char *hphp_log_scriptname; ++ zend_bool hphp_log_use_x_forwarded_for; ++ long hphp_executor_max_depth; ++#endif + int exit_status; + + zend_op_array *active_op_array; +@@ -176,6 +186,7 @@ + int ticks_count; + + zend_bool in_execution; ++ zend_uint in_code_type; + zend_bool bailout_set; + zend_bool full_tables_cleanup; + +diff -Nura php-4.4.3/Zend/zend.h hardening-patch-4.4.3-0.4.15/Zend/zend.h +--- php-4.4.3/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend.h 2006-09-05 20:30:46.000000000 +0200 +@@ -274,9 +274,10 @@ + struct _zval_struct { + /* Variable information */ + zvalue_value value; /* value */ ++ zend_uint refcount; ++ zend_ushort flags; + zend_uchar type; /* active type */ + zend_uchar is_ref; +- zend_ushort refcount; + }; + + +@@ -337,6 +338,12 @@ + void (*ticks_function)(int ticks); + void (*on_timeout)(int seconds TSRMLS_DC); + zend_bool (*open_function)(const char *filename, struct _zend_file_handle *); ++#if HARDENING_PATCH ++ void (*security_log_function)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ int (*is_valid_include)(zval *z); ++#endif + } zend_utility_functions; + + +@@ -468,7 +475,16 @@ + extern ZEND_API void (*zend_ticks_function)(int ticks); + extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); + extern void (*zend_on_timeout)(int seconds TSRMLS_DC); ++#if HARDENING_PATCH ++extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++extern ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ZEND_API unsigned int zend_canary(void); ++#endif + + ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3); + +@@ -575,6 +591,11 @@ + + #define ZEND_MAX_RESERVED_RESOURCES 4 + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#include "php_syslog.h" ++#endif ++ + #endif /* ZEND_H */ + + /* +diff -Nura php-4.4.3/Zend/zend_hash.c hardening-patch-4.4.3-0.4.15/Zend/zend_hash.c +--- php-4.4.3/Zend/zend_hash.c 2006-02-01 10:11:55.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_hash.c 2006-09-05 20:30:46.000000000 +0200 +@@ -26,6 +26,17 @@ + # include + #endif + ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int zend_hash_canary = 0x1234567; ++ zend_bool zend_hash_canary_inited = 0; ++#endif ++ ++#define CHECK_HASH_CANARY(hash) \ ++ if (zend_hash_canary != (hash)->canary) { \ ++ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ ++ exit(1); \ ++ } ++ + #define HANDLE_NUMERIC(key, length, func) { \ + register char *tmp=key; \ + \ +@@ -175,6 +186,9 @@ + { + uint i = 3; + Bucket **tmp; ++#if HARDENING_PATCH_HASH_PROTECT ++ TSRMLS_FETCH(); ++#endif + + SET_INCONSISTENT(HT_OK); + +@@ -184,6 +198,13 @@ + + ht->nTableSize = 1 << i; + ht->nTableMask = ht->nTableSize - 1; ++#if HARDENING_PATCH_HASH_PROTECT ++ if (zend_hash_canary_inited==0) { ++ zend_hash_canary = zend_canary(); ++ zend_hash_canary_inited = 1; ++ } ++ ht->canary = zend_hash_canary; ++#endif + ht->pDestructor = pDestructor; + ht->pListHead = NULL; + ht->pListTail = NULL; +@@ -259,6 +280,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -327,6 +351,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -402,6 +429,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -450,7 +480,7 @@ + IS_CONSISTENT(ht); + + if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ +- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); ++ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); + if (t) { + HANDLE_BLOCK_INTERRUPTIONS(); + ht->arBuckets = t; +@@ -460,6 +490,7 @@ + HANDLE_UNBLOCK_INTERRUPTIONS(); + return SUCCESS; + } ++ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); + return FAILURE; + } + return SUCCESS; +@@ -526,6 +557,9 @@ + ht->pInternalPointer = p->pListNext; + } + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (!p->pDataPtr) { +@@ -555,6 +589,9 @@ + q = p; + p = p->pListNext; + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(q->pData); + } + if (!q->pDataPtr && q->pData) { +@@ -581,6 +618,9 @@ + q = p; + p = p->pListNext; + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(q->pData); + } + if (!q->pDataPtr && q->pData) { +@@ -610,6 +650,9 @@ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (!p->pDataPtr) { +diff -Nura php-4.4.3/Zend/zend_hash.h hardening-patch-4.4.3-0.4.15/Zend/zend_hash.h +--- php-4.4.3/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_hash.h 2006-09-05 20:30:46.000000000 +0200 +@@ -54,6 +54,9 @@ + } Bucket; + + typedef struct _hashtable { ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int canary; ++#endif + uint nTableSize; + uint nTableMask; + uint nNumOfElements; +diff -Nura php-4.4.3/Zend/zend_ini.c hardening-patch-4.4.3-0.4.15/Zend/zend_ini.c +--- php-4.4.3/Zend/zend_ini.c 2005-09-02 23:09:03.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:56.000000000 +0200 +@@ -256,7 +256,8 @@ + zend_ini_entry *ini_entry; + TSRMLS_FETCH(); + +- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { ++ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || ++ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifyable & ZEND_INI_USER) == 0)) { + return FAILURE; + } + +diff -Nura php-4.4.3/Zend/zend_ini.h hardening-patch-4.4.3-0.4.15/Zend/zend_ini.h +--- php-4.4.3/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_ini.h 2006-09-05 20:30:46.000000000 +0200 +@@ -174,6 +174,7 @@ + /* Standard message handlers */ + BEGIN_EXTERN_C() + ZEND_API ZEND_INI_MH(OnUpdateBool); ++#define OnUpdateLong OnUpdateInt + ZEND_API ZEND_INI_MH(OnUpdateInt); + ZEND_API ZEND_INI_MH(OnUpdateReal); + ZEND_API ZEND_INI_MH(OnUpdateString); +diff -Nura php-4.4.3/Zend/zend_language_scanner.l hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.l +--- php-4.4.3/Zend/zend_language_scanner.l 2006-04-13 15:52:24.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:30:46.000000000 +0200 +@@ -393,6 +393,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-4.4.3/Zend/zend_language_scanner.c hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.c +--- php-4.4.3/Zend/zend_language_scanner.c 2006-08-01 09:39:14.000000000 +0200 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:30:46.000000000 +0200 +@@ -3036,6 +3036,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-4.4.3/Zend/zend_llist.c hardening-patch-4.4.3-0.4.15/Zend/zend_llist.c +--- php-4.4.3/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_llist.c 2006-09-05 20:30:46.000000000 +0200 +@@ -21,9 +21,49 @@ + #include "zend.h" + #include "zend_llist.h" + #include "zend_qsort.h" ++#include "zend_globals.h" ++ ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int zend_llist_canary_1 = 0x1234567; ++ unsigned int zend_llist_canary_2 = 0x1553425; ++ zend_bool zend_llist_canary_inited = 0; ++#endif ++ ++#define CHECK_LIST_CANARY(list) \ ++ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ ++ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ ++ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++#define CHECK_LISTELEMENT_CANARY(elem, list) \ ++ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ ++ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ ++ exit(1); \ ++ } ++ + + ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ ++ if (persistent) { ++ if (!zend_llist_canary_inited) { ++ /* do not change order to ensure thread safety */ ++ zend_llist_canary_1 = zend_canary(); ++ zend_llist_canary_2 = zend_canary(); ++ zend_llist_canary_inited = 1; ++ } ++ } else ++ if (!HG(ll_canary_inited)) { ++ HG(canary_3) = zend_canary(); ++ HG(canary_4) = zend_canary(); ++ HG(ll_canary_inited) = 1; ++ } ++ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); ++ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); ++#endif + l->head = NULL; + l->tail = NULL; + l->count = 0; +@@ -37,6 +77,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->prev = l->tail; + tmp->next = NULL; + if (l->tail) { +@@ -55,6 +100,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->next = l->head; + tmp->prev = NULL; + if (l->head) { +@@ -91,10 +141,20 @@ + zend_llist_element *current=l->head; + zend_llist_element *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (compare(current->data, element)) { + DEL_LLIST_ELEMENT(current, l); ++#if HARDENING_PATCH_LL_PROTECT ++ current->canary = 0; ++#endif + break; + } + current = next; +@@ -106,7 +166,14 @@ + { + zend_llist_element *current=l->head, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (l->dtor) { + l->dtor(current->data); +@@ -131,7 +198,14 @@ + zend_llist_element *old_tail; + void *data; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if ((old_tail = l->tail)) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(old_tail, l) ++#endif + if (l->tail->prev) { + l->tail->prev->next = NULL; + } +@@ -157,9 +231,16 @@ + { + zend_llist_element *ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(src) ++#endif + zend_llist_init(dst, src->size, src->dtor, src->persistent); + ptr = src->head; + while (ptr) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(ptr, src) ++#endif + zend_llist_add_element(dst, ptr->data); + ptr = ptr->next; + } +@@ -170,11 +251,21 @@ + { + zend_llist_element *element, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + element=l->head; + while (element) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + next = element->next; + if (func(element->data)) { + DEL_LLIST_ELEMENT(element, l); ++#if HARDENING_PATCH_LL_PROTECT ++ element->canary = 0; ++#endif + } + element = next; + } +@@ -185,7 +276,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data TSRMLS_CC); + } + } +@@ -197,6 +294,9 @@ + zend_llist_element **elements; + zend_llist_element *element, **ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + if (l->count <= 0) { + return; + } +@@ -206,6 +306,9 @@ + ptr = &elements[0]; + + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + *ptr++ = element; + } + +@@ -228,7 +331,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, arg TSRMLS_CC); + } + } +@@ -239,8 +348,14 @@ + zend_llist_element *element; + va_list args; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + va_start(args, num_args); + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, num_args, args TSRMLS_CC); + } + va_end(args); +@@ -249,6 +364,10 @@ + + ZEND_API int zend_llist_count(zend_llist *l) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + return l->count; + } + +@@ -256,8 +375,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->head; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -269,8 +395,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->tail; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -282,9 +415,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->next; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +@@ -296,9 +439,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->prev; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +diff -Nura php-4.4.3/Zend/zend_llist.h hardening-patch-4.4.3-0.4.15/Zend/zend_llist.h +--- php-4.4.3/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_llist.h 2006-09-05 20:30:46.000000000 +0200 +@@ -24,6 +24,9 @@ + #include + + typedef struct _zend_llist_element { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary, padding; ++#endif + struct _zend_llist_element *next; + struct _zend_llist_element *prev; + char data[1]; /* Needs to always be last in the struct */ +@@ -36,6 +39,9 @@ + typedef void (*llist_apply_func_t)(void * TSRMLS_DC); + + typedef struct _zend_llist { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_h; /* head */ ++#endif + zend_llist_element *head; + zend_llist_element *tail; + size_t size; +@@ -43,6 +49,9 @@ + llist_dtor_func_t dtor; + unsigned char persistent; + zend_llist_element *traverse_ptr; ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_t; /* tail */ ++#endif + } zend_llist; + + typedef zend_llist_element* zend_llist_position; +diff -Nura php-4.4.3/Zend/zend_modules.h hardening-patch-4.4.3-0.4.15/Zend/zend_modules.h +--- php-4.4.3/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_modules.h 2006-09-05 20:30:46.000000000 +0200 +@@ -34,6 +34,7 @@ + ZEND_API extern unsigned char second_arg_force_ref[]; + ZEND_API extern unsigned char third_arg_force_ref[]; + ++#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112 + #define ZEND_MODULE_API_NO 20020429 + #ifdef ZTS + #define USING_ZTS 1 +@@ -41,9 +42,9 @@ + #define USING_ZTS 0 + #endif + +-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS ++#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS + +-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 ++#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO + + #define STANDARD_MODULE_PROPERTIES \ + NULL, NULL, STANDARD_MODULE_PROPERTIES_EX +@@ -75,6 +76,7 @@ + unsigned char type; + void *handle; + int module_number; ++ unsigned int real_zend_api; + }; + + +diff -Nura php-4.4.3/Zend/zend_opcode.c hardening-patch-4.4.3-0.4.15/Zend/zend_opcode.c +--- php-4.4.3/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_opcode.c 2006-09-05 20:30:46.000000000 +0200 +@@ -88,6 +88,9 @@ + op_array->done_pass_two = 0; + + op_array->start_op = NULL; ++#if HARDENING_PATCH ++ op_array->created_by_eval = 0; ++#endif + + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); + } +diff -Nura php-4.4.3/Zend/zend_operators.c hardening-patch-4.4.3-0.4.15/Zend/zend_operators.c +--- php-4.4.3/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_operators.c 2006-09-05 20:30:46.000000000 +0200 +@@ -1604,6 +1604,20 @@ + return (op->value.lval ? 1 : 0); + } + ++ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) ++{ ++ register unsigned char *str = (unsigned char*)source; ++ register unsigned char *result = (unsigned char*)dest; ++ register unsigned char *end = str + length; ++ ++ while (str < end) { ++ *result++ = tolower((int)*str++); ++ } ++ *result = *end; ++ ++ return dest; ++} ++ + ZEND_API void zend_str_tolower(char *str, unsigned int length) + { + register char *p=str, *end=p+length; +diff -Nura php-4.4.3/Zend/zend_operators.h hardening-patch-4.4.3-0.4.15/Zend/zend_operators.h +--- php-4.4.3/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.3-0.4.15/Zend/zend_operators.h 2006-09-05 20:30:46.000000000 +0200 +@@ -174,6 +174,14 @@ + #endif + + ZEND_API void zend_str_tolower(char *str, unsigned int length); ++ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length); ++ ++static inline char * ++zend_str_tolower_dup(const char *source, unsigned int length) ++{ ++ return zend_str_tolower_copy((char *)emalloc(length+1), source, length); ++} ++ + ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2); + ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3); + ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2); diff --git a/0.4.15/hardening-patch-4.4.4-0.4.15.patch b/0.4.15/hardening-patch-4.4.4-0.4.15.patch new file mode 100644 index 0000000..c0208f6 --- /dev/null +++ b/0.4.15/hardening-patch-4.4.4-0.4.15.patch @@ -0,0 +1,8300 @@ +diff -Nura php-4.4.4/Changelog.hphp hardening-patch-4.4.4-0.4.15/Changelog.hphp +--- php-4.4.4/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Changelog.hphp 2006-09-07 19:32:38.000000000 +0200 +@@ -0,0 +1,61 @@ ++Changelog of the Hardening-Patch ++-------------------------------- ++ ++0.4.15 - 07. September 2006 ++ ++ PHP4: ++ [+] Fix for potential DOS in handling of include blacklists ++ ++ PHP4+5: ++ [+] Backported a fix for open_basedir problems with insanse PHP scripts ++ [+] Added a fix for ini_restore() PHP security vulnerability ++ ++0.4.14 - 11. August 2006 ++ ++ PHP4: ++ [+] Remove unecessary call to AC_BROKEN_REALPATH ++ ++ PHP5: ++ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant ++ ++ PHP4+5: ++ [+] Added a few PHP security fixes / see changelog.secfix for details ++ [+] Fixed the memory_limit protection for systems with different perdir memory_limits ++ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments ++ ++0.4.13 - 07. August 2006 ++ ++ PHP4+5: ++ [+] Added a fix for a compile problem on solaris due to missing strcasestr() ++ ++0.4.12 - 19. July 2006 ++ ++ PHP4: ++ [+] Added fixes from sf4 security patch / see changelog.secfix for details ++ ++ PHP5: ++ [+] Added fixes from sf5 security patch / see changelog.secfix for details ++ ++ PHP4+5: ++ [+] Added anti mail spam feature ++ [+] Speedup of zend_hash canary (clear/destroy) ++ [+] Added a fix for a DOS in the handling of URL blacklists ++ ++0.4.11 - 13. May 2006 ++ ++ PHP5: ++ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache ++ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 ++ ++ PHP4+5: ++ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories ++ ++ ++0.4.10 - 11. May 2006 ++ ++ PHP4: ++ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed ++ ++ PHP4+5: ++ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir ++ +diff -Nura php-4.4.4/Changelog.secfix hardening-patch-4.4.4-0.4.15/Changelog.secfix +--- php-4.4.4/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Changelog.secfix 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,17 @@ ++Changelog of PHP 4.4.3 Security Fixes ++ ++Release 2 - 11. August 2006 ++ ++ [+] Added IMAP open_basedir/safe_mode check ++ [+] Added a upstream fix for previous ext/session fixes ++ [+] Added upstream fix to ext/socket ++ [+] Added sscanf() security fix ++ [+] Added fixes for handling of corrupt .gif files to gdlib ++ ++Release 1 - 4. August 2006 ++ ++ [+] Added a fix to disable CURLOPT_FOLLOWLOCATION while in safe_mode()/open_basedir ++ [+] Added a *working* wordwrap() fix ++ [+] Added code to make memory_limit work on 64bit systems ++ [+] Added a fix for an integer overflow in str_repeat() ++ +diff -Nura php-4.4.4/configure hardening-patch-4.4.4-0.4.15/configure +--- php-4.4.4/configure 2006-08-15 14:01:18.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/configure 2006-09-05 20:30:51.000000000 +0200 +@@ -402,6 +402,16 @@ + ac_default_prefix=/usr/local + # Any additions from configure.in: + ac_help="$ac_help ++ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." ++ac_help="$ac_help ++ --disable-hardening-patch-ll-protect Disable the Linked List protection." ++ac_help="$ac_help ++ --disable-hardening-patch-inc-protect Disable include/require protection." ++ac_help="$ac_help ++ --disable-hardening-patch-fmt-protect Disable format string protection." ++ac_help="$ac_help ++ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." ++ac_help="$ac_help + + SAPI modules: + " +@@ -854,6 +864,8 @@ + ac_help="$ac_help + --disable-tokenizer Disable tokenizer support" + ac_help="$ac_help ++ --disable-varfilter Disable Hardening-Patch's variable filter" ++ac_help="$ac_help + --enable-wddx Enable WDDX support." + ac_help="$ac_help + --disable-xml Disable XML support using bundled expat lib" +@@ -2942,6 +2954,157 @@ + + + ++# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. ++if test "${enable_hardening_patch_mm_protect+set}" = set; then ++ enableval="$enable_hardening_patch_mm_protect" ++ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. ++if test "${enable_hardening_patch_ll_protect+set}" = set; then ++ enableval="$enable_hardening_patch_ll_protect" ++ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. ++if test "${enable_hardening_patch_inc_protect+set}" = set; then ++ enableval="$enable_hardening_patch_inc_protect" ++ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. ++if test "${enable_hardening_patch_fmt_protect+set}" = set; then ++ enableval="$enable_hardening_patch_fmt_protect" ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. ++if test "${enable_hardening_patch_hash_protect+set}" = set; then ++ enableval="$enable_hardening_patch_hash_protect" ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++ ++fi ++ ++ ++echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 ++echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 ++echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 ++echo "configure:2733: checking whether to protect include/require statements" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect PHP Format String functions" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 ++ ++ ++cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH 1 ++EOF ++ ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 0 ++EOF ++ ++fi + + + +@@ -16017,6 +16180,62 @@ + fi + + ++ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 ++echo "configure:14928: checking whether realpath is broken" >&5 ++if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then ++ echo $ac_n "(cached) $ac_c" 1>&6 ++else ++ ++ if test "$cross_compiling" = yes; then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -fr conftest* ++ ++ ac_cv_broken_realpath=yes ++ ++fi ++rm -fr conftest* ++fi ++ ++ ++fi ++ ++echo "$ac_t""$ac_cv_broken_realpath" 1>&6 ++ if test "$ac_cv_broken_realpath" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 1 ++EOF ++ ++ else ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 0 ++EOF ++ ++ fi ++ ++ + echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 + echo "configure:16022: checking for declared timezone" >&5 + if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then +@@ -86718,7 +86937,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + cat >> confdefs.h <&6 ++echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 ++# Check whether --enable-varfilter or --disable-varfilter was given. ++if test "${enable_varfilter+set}" = set; then ++ enableval="$enable_varfilter" ++ PHP_VARFILTER=$enableval ++else ++ ++ PHP_VARFILTER=yes ++ ++ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then ++ PHP_VARFILTER=$PHP_ENABLE_ALL ++ fi ++ ++fi ++ ++ ++ ++ext_output="yes, shared" ++ext_shared=yes ++case $PHP_VARFILTER in ++shared,*) ++ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` ++ ;; ++shared) ++ PHP_VARFILTER=yes ++ ;; ++no) ++ ext_output=no ++ ext_shared=no ++ ;; ++*) ++ ext_output=yes ++ ext_shared=no ++ ;; ++esac ++ ++ ++ ++echo "$ac_t""$ext_output" 1>&6 ++ ++ ++ ++ ++if test "$PHP_VARFILTER" != "no"; then ++ cat >> confdefs.h <<\EOF ++#define HAVE_VARFILTER 1 ++EOF ++ ++ ++ ext_builddir=ext/varfilter ++ ext_srcdir=$abs_srcdir/ext/varfilter ++ ++ ac_extra= ++ ++ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then ++ ++ ++ ++ case ext/varfilter in ++ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; ++ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; ++ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; ++ esac ++ ++ ++ ++ b_c_pre=$php_c_pre ++ b_cxx_pre=$php_cxx_pre ++ b_c_meta=$php_c_meta ++ b_cxx_meta=$php_cxx_meta ++ b_c_post=$php_c_post ++ b_cxx_post=$php_cxx_post ++ b_lo=$php_lo ++ ++ ++ old_IFS=$IFS ++ for ac_src in varfilter.c; do ++ ++ IFS=. ++ set $ac_src ++ ac_obj=$1 ++ IFS=$old_IFS ++ ++ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" ++ ++ case $ac_src in ++ *.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" ;; ++ *.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" ;; ++ esac ++ ++ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 +@@ -104088,7 +104566,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + streams.c network.c php_open_temporary_file.c php_logos.c \ +- output.c memory_streams.c user_streams.c; do ++ output.c memory_streams.c user_streams.c hardening_patch.c; do + + IFS=. + set $ac_src +@@ -104273,7 +104751,7 @@ + zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ +- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do ++ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do + + IFS=. + set $ac_src +diff -Nura php-4.4.4/configure.in hardening-patch-4.4.4-0.4.15/configure.in +--- php-4.4.4/configure.in 2006-08-15 14:22:14.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/configure.in 2006-09-05 20:30:51.000000000 +0200 +@@ -247,7 +247,7 @@ + sinclude(Zend/acinclude.m4) + sinclude(Zend/Zend.m4) + sinclude(TSRM/tsrm.m4) +- ++sinclude(main/hardening_patch.m4) + + + divert(2) +@@ -621,6 +621,7 @@ + AC_FUNC_ALLOCA + dnl PHP_AC_BROKEN_SPRINTF + dnl PHP_AC_BROKEN_SNPRINTF ++dnl PHP_AC_BROKEN_REALPATH + PHP_DECLARED_TIMEZONE + PHP_TIME_R_TYPE + PHP_READDIR_R_TYPE +@@ -1260,7 +1261,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + streams.c network.c php_open_temporary_file.c php_logos.c \ +- output.c memory_streams.c user_streams.c) ++ output.c memory_streams.c user_streams.c hardening_patch.c) + PHP_ADD_SOURCES(/main, internal_functions.c,, sapi) + case $host_alias in + *netware*) +@@ -1281,7 +1282,7 @@ + zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ +- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c) ++ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c ) + + if test -r "$abs_srcdir/Zend/zend_objects.c"; then + PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c) +diff -Nura php-4.4.4/ext/fbsql/php_fbsql.c hardening-patch-4.4.4-0.4.15/ext/fbsql/php_fbsql.c +--- php-4.4.4/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1797,8 +1797,24 @@ + } + else if (fbcmdErrorsFound(md)) + { ++#if HARDENING_PATCH ++ char* query_copy; ++ int i; ++#endif + FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); + char* emg = fbcemdAllErrorMessages(emd); ++#if HARDENING_PATCH ++ query_copy=estrdup(query_copy); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ free(emg); ++ fbcemdRelease(emd); ++ result = 0; ++ zend_bailout(); ++ } ++#endif + if (FB_SQL_G(generateWarnings)) + { + if (emg) +diff -Nura php-4.4.4/ext/imap/php_imap.c hardening-patch-4.4.4-0.4.15/ext/imap/php_imap.c +--- php-4.4.4/ext/imap/php_imap.c 2006-08-11 17:07:00.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/ext/imap/php_imap.c 2006-09-05 20:30:51.000000000 +0200 +@@ -738,6 +738,13 @@ + RETURN_FALSE; + } + ++ /* local filename, need to perform open_basedir and safe_mode checks */ ++ if (Z_STRVAL_PP(mailbox)[0] != '{' && ++ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || ++ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { ++ RETURN_FALSE; ++ } ++ + IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); + IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); + +diff -Nura php-4.4.4/ext/mbstring/mbstring.c hardening-patch-4.4.4-0.4.15/ext/mbstring/mbstring.c +--- php-4.4.4/ext/mbstring/mbstring.c 2006-04-03 15:04:13.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/ext/mbstring/mbstring.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1500,6 +1500,7 @@ + char *strtok_buf = NULL, **val_list; + zval *array_ptr = (zval *) arg; + int n, num, val_len, *len_list; ++ unsigned int new_val_len; + enum mbfl_no_encoding from_encoding; + mbfl_string string, resvar, resval; + mbfl_encoding_detector *identd = NULL; +@@ -1622,8 +1623,14 @@ + val_len = len_list[n]; + } + n++; +- /* add variable to symbol table */ +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ /* we need val to be emalloc()ed */ ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ /* add variable to symbol table */ ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); ++ + if (convd != NULL){ + mbfl_string_clear(&resvar); + mbfl_string_clear(&resval); +diff -Nura php-4.4.4/ext/mysql/php_mysql.c hardening-patch-4.4.4-0.4.15/ext/mysql/php_mysql.c +--- php-4.4.4/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1218,6 +1218,8 @@ + { + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; ++ char *copy_query; ++ int i; + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); + +@@ -1268,6 +1270,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #else +@@ -1275,12 +1284,20 @@ + /* check possible error */ + if (MySG(trace_mode)){ + if (mysql_errno(&mysql->conn)){ +- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn)); ++ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #endif ++ + if(use_store == MYSQL_USE_RESULT) { + mysql_result=mysql_use_result(&mysql->conn); + } else { +diff -Nura php-4.4.4/ext/pgsql/pgsql.c hardening-patch-4.4.4-0.4.15/ext/pgsql/pgsql.c +--- php-4.4.4/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1001,10 +1001,28 @@ + case PGRES_EMPTY_QUERY: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: +- case PGRES_FATAL_ERROR: +- PHP_PQ_ERROR("Query failed: %s", pgsql); +- PQclear(pgsql_result); +- RETURN_FALSE; ++ case PGRES_FATAL_ERROR: ++ { ++#if HARDENING_PATCH ++ int i; ++ char *query_copy; ++#endif ++ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); ++ PQclear(pgsql_result); ++#if HARDENING_PATCH ++ query_copy = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ efree(msgbuf); ++ zend_bailout(); ++ } ++#endif ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); ++ efree(msgbuf); ++ RETURN_FALSE; ++ } + break; + case PGRES_COMMAND_OK: /* successful command that did not return rows */ + default: +diff -Nura php-4.4.4/ext/session/mod_files.c hardening-patch-4.4.4-0.4.15/ext/session/mod_files.c +--- php-4.4.4/ext/session/mod_files.c 2006-08-11 17:04:28.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/ext/session/mod_files.c 2006-09-05 20:30:51.000000000 +0200 +@@ -397,6 +397,34 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(files) ++{ ++ char buf[MAXPATHLEN]; ++ int fd; ++ PS_FILES_DATA; ++ ++ if (!ps_files_valid_key(key)) { ++ return FAILURE; ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { ++ return FAILURE; ++ } ++ ++ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600); ++ ++ if (fd != -1) { ++ close(fd); ++ return SUCCESS; ++ } ++ ++ return FAILURE; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-4.4.4/ext/session/mod_mm.c hardening-patch-4.4.4-0.4.15/ext/session/mod_mm.c +--- php-4.4.4/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/mod_mm.c 2006-09-05 20:30:51.000000000 +0200 +@@ -425,6 +425,42 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(mm) ++{ ++ PS_MM_DATA; ++ ps_sd *sd; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ } ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ mm_lock(data->mm, MM_LOCK_RD); ++ ++ sd = ps_sd_lookup(data, key, 0); ++ if (sd) { ++ mm_unlock(data->mm); ++ return SUCCESS; ++ } ++ ++ mm_unlock(data->mm); ++ ++ return FAILURE; ++} ++ + #endif + + /* +diff -Nura php-4.4.4/ext/session/mod_user.c hardening-patch-4.4.4-0.4.15/ext/session/mod_user.c +--- php-4.4.4/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/mod_user.c 2006-09-05 20:30:51.000000000 +0200 +@@ -23,7 +23,7 @@ + #include "mod_user.h" + + ps_module ps_mod_user = { +- PS_MOD(user) ++ PS_MOD_SID(user) + }; + + #define SESS_ZVAL_LONG(val, a) \ +@@ -174,6 +174,83 @@ + FINISH; + } + ++PS_CREATE_SID_FUNC(user) ++{ ++ int i; ++ char *val = NULL; ++ zval *retval; ++ ps_user *mdata = PS_GET_MOD_DATA(); ++ ++ if (!mdata) ++ return estrndup("", 0); ++ ++ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { ++ return php_session_create_id(mod_data, newlen TSRMLS_CC); ++ } ++ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); ++ ++ if (retval) { ++ if (Z_TYPE_P(retval) == IS_STRING) { ++ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); ++ } else { ++ val = estrndup("", 0); ++ } ++ zval_ptr_dtor(&retval); ++ } else { ++ val = estrndup("", 0); ++ } ++ ++ return val; ++} ++ ++static int ps_user_valid_key(const char *key TSRMLS_DC) ++{ ++ size_t len; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ ret = FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ ret = FAILURE; ++ ++ return ret; ++} ++ ++PS_VALIDATE_SID_FUNC(user) ++{ ++ zval *args[1]; ++ STDVARS; ++ ++ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { ++ return ps_user_valid_key(key TSRMLS_CC); ++ } ++ SESS_ZVAL_STRING(key, args[0]); ++ ++ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); ++ ++ if (retval) { ++ convert_to_long(retval); ++ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; ++ zval_ptr_dtor(&retval); ++ } ++ ++ return ret; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-4.4.4/ext/session/mod_user.h hardening-patch-4.4.4-0.4.15/ext/session/mod_user.h +--- php-4.4.4/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/mod_user.h 2006-09-05 20:30:51.000000000 +0200 +@@ -22,7 +22,7 @@ + #define MOD_USER_H + + typedef union { +- zval *names[6]; ++ zval *names[8]; + struct { + zval *ps_open; + zval *ps_close; +@@ -30,6 +30,8 @@ + zval *ps_write; + zval *ps_destroy; + zval *ps_gc; ++ zval *ps_create; ++ zval *ps_validate; + } name; + } ps_user; + +diff -Nura php-4.4.4/ext/session/php_session.h hardening-patch-4.4.4-0.4.15/ext/session/php_session.h +--- php-4.4.4/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/php_session.h 2006-09-05 20:30:51.000000000 +0200 +@@ -23,7 +23,7 @@ + + #include "ext/standard/php_var.h" + +-#define PHP_SESSION_API 20020330 ++#define PHP_SESSION_API 20051121 + + #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC + #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC +@@ -32,6 +32,7 @@ + #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC + #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC + #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC ++#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC + + /* default create id function */ + char *php_session_create_id(PS_CREATE_SID_ARGS); +@@ -45,6 +46,7 @@ + int (*s_destroy)(PS_DESTROY_ARGS); + int (*s_gc)(PS_GC_ARGS); + char *(*s_create_sid)(PS_CREATE_SID_ARGS); ++ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); + } ps_module; + + #define PS_GET_MOD_DATA() *mod_data +@@ -57,6 +59,7 @@ + #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) + #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) + #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) ++#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) + + #define PS_FUNCS(x) \ + PS_OPEN_FUNC(x); \ +@@ -65,11 +68,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID_FUNC(x) + + #define PS_MOD(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, php_session_create_id ++ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x + + /* SID enabled module handler definitions */ + #define PS_FUNCS_SID(x) \ +@@ -79,11 +83,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID(x) + + #define PS_MOD_SID(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, ps_create_sid_##x ++ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x + + typedef enum { + php_session_disabled, +@@ -120,6 +125,7 @@ + zend_bool use_only_cookies; + zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ ++ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + int send_cookie; + int define_sid; + } php_ps_globals; +diff -Nura php-4.4.4/ext/session/session.c hardening-patch-4.4.4-0.4.15/ext/session/session.c +--- php-4.4.4/ext/session/session.c 2006-08-01 10:33:13.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/ext/session/session.c 2006-09-05 20:30:51.000000000 +0200 +@@ -155,6 +155,7 @@ + STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) ++ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals) +@@ -643,6 +644,15 @@ + return; + } + ++ /* If there is an ID, use session module to verify it */ ++ if (PS(id)) { ++ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ efree(PS(id)); ++ PS(id) = NULL; ++ PS(send_cookie) = 1; ++ } ++ } ++ + /* If there is no ID, use session module to create one */ + if (!PS(id)) + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); +@@ -1266,18 +1276,25 @@ + Sets user-level functions */ + PHP_FUNCTION(session_set_save_handler) + { +- zval **args[6]; +- int i; ++ zval **args[8]; ++ int i, numargs; + ps_user *mdata; + char *name; + +- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) ++ numargs = ZEND_NUM_ARGS(); ++ args[6] = NULL; ++ args[7] = NULL; ++ ++ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) + WRONG_PARAM_COUNT; + + if (PS(session_status) != php_session_none) + RETURN_FALSE; + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ continue; ++ } + if (!zend_is_callable(*args[i], 0, &name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); + efree(name); +@@ -1290,7 +1307,11 @@ + + mdata = emalloc(sizeof(*mdata)); + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ mdata->names[i] = NULL; ++ continue; ++ } + ZVAL_ADDREF(*args[i]); + mdata->names[i] = *args[i]; + } +@@ -1351,12 +1372,24 @@ + Update the current session id with a newly generated one. */ + PHP_FUNCTION(session_regenerate_id) + { ++ zend_bool del_ses = 0; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) { ++ WRONG_PARAM_COUNT; ++ } ++ + if (SG(headers_sent)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); + RETURN_FALSE; + } + if (PS(session_status) == php_session_active) { +- if (PS(id)) efree(PS(id)); ++ if (PS(id)) { ++ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed"); ++ RETURN_FALSE; ++ } ++ efree(PS(id)); ++ } + + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); + +diff -Nura php-4.4.4/ext/session/tests/014.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/014.phpt +--- php-4.4.4/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:30:51.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.bug_compat_42=1 +diff -Nura php-4.4.4/ext/session/tests/015.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/015.phpt +--- php-4.4.4/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:30:51.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + arg_separator.output=& + session.name=PHPSESSID +diff -Nura php-4.4.4/ext/session/tests/018.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/018.phpt +--- php-4.4.4/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:30:51.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + session.name=PHPSESSID +diff -Nura php-4.4.4/ext/session/tests/020.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/020.phpt +--- php-4.4.4/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:30:51.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + arg_separator.output=& +diff -Nura php-4.4.4/ext/session/tests/021.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/021.phpt +--- php-4.4.4/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:30:51.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" +diff -Nura php-4.4.4/ext/standard/array.c hardening-patch-4.4.4-0.4.15/ext/standard/array.c +--- php-4.4.4/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/array.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1162,6 +1162,32 @@ + } + } + } ++ ++ if (var_name[0] == 'H') { ++ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_FILES")==0)|| ++ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { ++ return 0; ++ } ++ } else if (var_name[0] == '_') { ++ if ((strcmp(var_name, "_COOKIE")==0)|| ++ (strcmp(var_name, "_ENV")==0)|| ++ (strcmp(var_name, "_FILES")==0)|| ++ (strcmp(var_name, "_GET")==0)|| ++ (strcmp(var_name, "_POST")==0)|| ++ (strcmp(var_name, "_REQUEST")==0)|| ++ (strcmp(var_name, "_SESSION")==0)|| ++ (strcmp(var_name, "_SERVER")==0)) { ++ return 0; ++ } ++ } else if (strcmp(var_name, "GLOBALS")==0) { ++ return 0; ++ } + + return 1; + } +diff -Nura php-4.4.4/ext/standard/basic_functions.c hardening-patch-4.4.4-0.4.15/ext/standard/basic_functions.c +--- php-4.4.4/ext/standard/basic_functions.c 2006-06-29 00:09:09.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:34:48.000000000 +0200 +@@ -107,12 +107,14 @@ + typedef struct _php_shutdown_function_entry { + zval **arguments; + int arg_count; ++ zend_bool created_by_eval; + } php_shutdown_function_entry; + + typedef struct _user_tick_function_entry { + zval **arguments; + int arg_count; + int calling; ++ zend_bool created_by_eval; + } user_tick_function_entry; + + /* some prototypes for local functions */ +@@ -295,6 +297,8 @@ + PHP_FE(get_html_translation_table, NULL) + PHP_FE(sha1, NULL) + PHP_FE(sha1_file, NULL) ++ PHP_FE(sha256, NULL) ++ PHP_FE(sha256_file, NULL) + PHP_NAMED_FE(md5,php_if_md5, NULL) + PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) + PHP_NAMED_FE(crc32,php_if_crc32, NULL) +@@ -676,7 +680,7 @@ + PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) + + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +- PHP_FE(realpath, NULL) ++ PHP_STATIC_FE("realpath", zif_real_path, NULL) + #endif + + #ifdef HAVE_FNMATCH +@@ -2101,6 +2105,13 @@ + { + zval retval; + char *function_name = NULL; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (shutdown_function_entry->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { + php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); +@@ -2116,6 +2127,9 @@ + if (function_name) { + efree(function_name); + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + return 0; + } + +@@ -2123,6 +2137,13 @@ + { + zval retval; + zval *function = tick_fe->arguments[0]; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (tick_fe->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + /* Prevent reentrant calls to the same user ticks function */ + if (! tick_fe->calling) { +@@ -2154,6 +2175,9 @@ + + tick_fe->calling = 0; + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + } + + static void run_user_tick_functions(int tick_count) +@@ -2222,6 +2246,13 @@ + efree(shutdown_function_entry.arguments); + RETURN_FALSE; + } ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ shutdown_function_entry.created_by_eval = 1; ++ } else { ++ shutdown_function_entry.created_by_eval = 0; ++ } ++#endif + + /* Prevent entering of anything but valid callback (syntax check only!) */ + if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { +@@ -2503,6 +2534,15 @@ + + convert_to_string_ex(varname); + ++ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ ++ if (PG(safe_mode)) { ++ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || ++ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || ++ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { ++ RETURN_FALSE; ++ } ++ } ++ + zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); + } + /* }}} */ +@@ -2759,6 +2799,13 @@ + } + + tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ tick_fe.created_by_eval = 1; ++ } else { ++ tick_fe.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { + efree(tick_fe.arguments); +@@ -3057,6 +3104,35 @@ + new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); + } + ++ if (new_key[0] == 'H') { ++ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_FILES")==0)|| ++ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (new_key[0] == '_') { ++ if ((strcmp(new_key, "_COOKIE")==0)|| ++ (strcmp(new_key, "_ENV")==0)|| ++ (strcmp(new_key, "_FILES")==0)|| ++ (strcmp(new_key, "_GET")==0)|| ++ (strcmp(new_key, "_POST")==0)|| ++ (strcmp(new_key, "_REQUEST")==0)|| ++ (strcmp(new_key, "_SESSION")==0)|| ++ (strcmp(new_key, "_SERVER")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (strcmp(new_key, "GLOBALS")==0) { ++ efree(new_key); ++ return 0; ++ } ++ + zend_hash_del(&EG(symbol_table), new_key, new_key_len); + ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); + +diff -Nura php-4.4.4/ext/standard/config.m4 hardening-patch-4.4.4-0.4.15/ext/standard/config.m4 +--- php-4.4.4/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/config.m4 2006-09-05 20:30:51.000000000 +0200 +@@ -203,7 +203,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) + ]) +@@ -419,6 +419,6 @@ + url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ + http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ +- var_unserializer.c ftok.c aggregation.c sha1.c ) ++ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ) + + PHP_ADD_MAKEFILE_FRAGMENT +diff -Nura php-4.4.4/ext/standard/crypt_blowfish.c hardening-patch-4.4.4-0.4.15/ext/standard/crypt_blowfish.c +--- php-4.4.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,748 @@ ++/* ++ * This code comes from John the Ripper password cracker, with reentrant ++ * and crypt(3) interfaces added, but optimizations specific to password ++ * cracking removed. ++ * ++ * Written by Solar Designer in 1998-2002 and ++ * placed in the public domain. ++ * ++ * There's absolutely no warranty. ++ * ++ * It is my intent that you should be able to use this on your system, ++ * as a part of a software package, or anywhere else to improve security, ++ * ensure compatibility, or for any other purpose. I would appreciate ++ * it if you give credit where it is due and keep your modifications in ++ * the public domain as well, but I don't require that in order to let ++ * you place this code and any modifications you make under a license ++ * of your choice. ++ * ++ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) ++ * by Niels Provos , and uses some of his ++ * ideas. The password hashing algorithm was designed by David Mazieres ++ * . ++ * ++ * There's a paper on the algorithm that explains its design decisions: ++ * ++ * http://www.usenix.org/events/usenix99/provos.html ++ * ++ * Some of the tricks in BF_ROUND might be inspired by Eric Young's ++ * Blowfish library (I can't be sure if I would think of something if I ++ * hadn't seen his code). ++ */ ++ ++#include ++ ++#include ++#ifndef __set_errno ++#define __set_errno(val) errno = (val) ++#endif ++ ++#undef __CONST ++#ifdef __GNUC__ ++#define __CONST __const ++#else ++#define __CONST ++#endif ++ ++#ifdef __i386__ ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#elif defined(__alpha__) || defined(__hppa__) ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#else ++#define BF_ASM 0 ++#define BF_SCALE 0 ++#endif ++ ++typedef unsigned int BF_word; ++ ++/* Number of Blowfish rounds, this is also hardcoded into a few places */ ++#define BF_N 16 ++ ++typedef BF_word BF_key[BF_N + 2]; ++ ++typedef struct { ++ BF_word S[4][0x100]; ++ BF_key P; ++} BF_ctx; ++ ++/* ++ * Magic IV for 64 Blowfish encryptions that we do at the end. ++ * The string is "OrpheanBeholderScryDoubt" on big-endian. ++ */ ++static BF_word BF_magic_w[6] = { ++ 0x4F727068, 0x65616E42, 0x65686F6C, ++ 0x64657253, 0x63727944, 0x6F756274 ++}; ++ ++/* ++ * P-box and S-box tables initialized with digits of Pi. ++ */ ++static BF_ctx BF_init_state = { ++ { ++ { ++ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, ++ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, ++ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, ++ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, ++ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, ++ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, ++ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, ++ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, ++ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, ++ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, ++ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, ++ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, ++ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, ++ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, ++ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, ++ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, ++ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, ++ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, ++ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, ++ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, ++ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, ++ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, ++ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, ++ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, ++ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, ++ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, ++ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, ++ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, ++ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, ++ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, ++ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, ++ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, ++ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, ++ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, ++ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, ++ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, ++ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, ++ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, ++ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, ++ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, ++ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, ++ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, ++ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, ++ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, ++ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, ++ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, ++ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, ++ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, ++ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, ++ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, ++ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, ++ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, ++ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, ++ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, ++ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, ++ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, ++ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, ++ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, ++ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, ++ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, ++ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, ++ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, ++ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, ++ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a ++ }, { ++ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, ++ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, ++ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, ++ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, ++ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, ++ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, ++ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, ++ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, ++ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, ++ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, ++ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, ++ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, ++ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, ++ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, ++ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, ++ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, ++ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, ++ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, ++ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, ++ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, ++ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, ++ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, ++ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, ++ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, ++ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, ++ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, ++ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, ++ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, ++ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, ++ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, ++ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, ++ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, ++ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, ++ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, ++ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, ++ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, ++ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, ++ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, ++ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, ++ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, ++ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, ++ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, ++ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, ++ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, ++ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, ++ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, ++ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, ++ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, ++ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, ++ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, ++ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, ++ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, ++ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, ++ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, ++ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, ++ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, ++ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, ++ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, ++ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, ++ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, ++ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, ++ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, ++ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, ++ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 ++ }, { ++ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, ++ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, ++ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, ++ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, ++ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, ++ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, ++ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, ++ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, ++ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, ++ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, ++ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, ++ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, ++ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, ++ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, ++ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, ++ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, ++ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, ++ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, ++ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, ++ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, ++ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, ++ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, ++ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, ++ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, ++ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, ++ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, ++ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, ++ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, ++ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, ++ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, ++ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, ++ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, ++ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, ++ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, ++ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, ++ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, ++ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, ++ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, ++ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, ++ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, ++ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, ++ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, ++ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, ++ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, ++ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, ++ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, ++ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, ++ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, ++ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, ++ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, ++ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, ++ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, ++ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, ++ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, ++ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, ++ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, ++ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, ++ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, ++ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, ++ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, ++ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, ++ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, ++ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, ++ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 ++ }, { ++ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, ++ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, ++ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, ++ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, ++ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, ++ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, ++ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, ++ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, ++ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, ++ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, ++ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, ++ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, ++ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, ++ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, ++ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, ++ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, ++ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, ++ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, ++ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, ++ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, ++ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, ++ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, ++ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, ++ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, ++ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, ++ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, ++ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, ++ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, ++ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, ++ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, ++ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, ++ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, ++ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, ++ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, ++ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, ++ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, ++ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, ++ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, ++ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, ++ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, ++ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, ++ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, ++ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, ++ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, ++ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, ++ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, ++ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, ++ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, ++ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, ++ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, ++ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, ++ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, ++ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, ++ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, ++ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, ++ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, ++ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, ++ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, ++ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, ++ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, ++ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, ++ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, ++ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, ++ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 ++ } ++ }, { ++ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, ++ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, ++ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, ++ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, ++ 0x9216d5d9, 0x8979fb1b ++ } ++}; ++ ++static unsigned char BF_itoa64[64 + 1] = ++ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ++ ++static unsigned char BF_atoi64[0x60] = { ++ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, ++ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, ++ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, ++ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, ++ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 ++}; ++ ++/* ++ * This may be optimized out if built with function inlining and no BF_ASM. ++ */ ++static void clean(void *data, int size) ++{ ++#if BF_ASM ++ extern void _BF_clean(void *data); ++#endif ++ memset(data, 0, size); ++#if BF_ASM ++ _BF_clean(data); ++#endif ++} ++ ++#define BF_safe_atoi64(dst, src) \ ++{ \ ++ tmp = (unsigned char)(src); \ ++ if (tmp == '$') break; \ ++ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ ++ tmp = BF_atoi64[tmp]; \ ++ if (tmp > 63) return -1; \ ++ (dst) = tmp; \ ++} ++ ++static int BF_decode(BF_word *dst, __CONST char *src, int size) ++{ ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned char *end = dptr + size; ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned int tmp, c1, c2, c3, c4; ++ ++ do { ++ BF_safe_atoi64(c1, *sptr++); ++ BF_safe_atoi64(c2, *sptr++); ++ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c3, *sptr++); ++ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c4, *sptr++); ++ *dptr++ = ((c3 & 0x03) << 6) | c4; ++ } while (dptr < end); ++ ++ while (dptr < end) ++ *dptr++ = 0; ++ ++ return 0; ++} ++ ++static void BF_encode(char *dst, __CONST BF_word *src, int size) ++{ ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned char *end = sptr + size; ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned int c1, c2; ++ ++ do { ++ c1 = *sptr++; ++ *dptr++ = BF_itoa64[c1 >> 2]; ++ c1 = (c1 & 0x03) << 4; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 4; ++ *dptr++ = BF_itoa64[c1]; ++ c1 = (c2 & 0x0f) << 2; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 6; ++ *dptr++ = BF_itoa64[c1]; ++ *dptr++ = BF_itoa64[c2 & 0x3f]; ++ } while (sptr < end); ++} ++ ++static void BF_swap(BF_word *x, int count) ++{ ++ static int endianness_check = 1; ++ char *is_little_endian = (char *)&endianness_check; ++ BF_word tmp; ++ ++ if (*is_little_endian) ++ do { ++ tmp = *x; ++ tmp = (tmp << 16) | (tmp >> 16); ++ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); ++ } while (--count); ++} ++ ++#if BF_SCALE ++/* Architectures which can shift addresses left by 2 bits with no extra cost */ ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp2 = L >> 8; \ ++ tmp2 &= 0xFF; \ ++ tmp3 = L >> 16; \ ++ tmp3 &= 0xFF; \ ++ tmp4 = L >> 24; \ ++ tmp1 = data.ctx.S[3][tmp1]; \ ++ tmp2 = data.ctx.S[2][tmp2]; \ ++ tmp3 = data.ctx.S[1][tmp3]; \ ++ tmp3 += data.ctx.S[0][tmp4]; \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#else ++/* Architectures with no complicated addressing modes supported */ ++#define BF_INDEX(S, i) \ ++ (*((BF_word *)(((unsigned char *)S) + (i)))) ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp1 <<= 2; \ ++ tmp2 = L >> 6; \ ++ tmp2 &= 0x3FC; \ ++ tmp3 = L >> 14; \ ++ tmp3 &= 0x3FC; \ ++ tmp4 = L >> 22; \ ++ tmp4 &= 0x3FC; \ ++ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ ++ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ ++ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ ++ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#endif ++ ++/* ++ * Encrypt one block, BF_N is hardcoded here. ++ */ ++#define BF_ENCRYPT \ ++ L ^= data.ctx.P[0]; \ ++ BF_ROUND(L, R, 0); \ ++ BF_ROUND(R, L, 1); \ ++ BF_ROUND(L, R, 2); \ ++ BF_ROUND(R, L, 3); \ ++ BF_ROUND(L, R, 4); \ ++ BF_ROUND(R, L, 5); \ ++ BF_ROUND(L, R, 6); \ ++ BF_ROUND(R, L, 7); \ ++ BF_ROUND(L, R, 8); \ ++ BF_ROUND(R, L, 9); \ ++ BF_ROUND(L, R, 10); \ ++ BF_ROUND(R, L, 11); \ ++ BF_ROUND(L, R, 12); \ ++ BF_ROUND(R, L, 13); \ ++ BF_ROUND(L, R, 14); \ ++ BF_ROUND(R, L, 15); \ ++ tmp4 = R; \ ++ R = L; \ ++ L = tmp4 ^ data.ctx.P[BF_N + 1]; ++ ++#if BF_ASM ++#define BF_body() \ ++ _BF_body_r(&data.ctx); ++#else ++#define BF_body() \ ++ L = R = 0; \ ++ ptr = data.ctx.P; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.P[BF_N + 2]); \ ++\ ++ ptr = data.ctx.S[0]; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.S[3][0xFF]); ++#endif ++ ++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) ++{ ++ __CONST char *ptr = key; ++ int i, j; ++ BF_word tmp; ++ ++ for (i = 0; i < BF_N + 2; i++) { ++ tmp = 0; ++ for (j = 0; j < 4; j++) { ++ tmp <<= 8; ++ tmp |= *ptr; ++ ++ if (!*ptr) ptr = key; else ptr++; ++ } ++ ++ expanded[i] = tmp; ++ initial[i] = BF_init_state.P[i] ^ tmp; ++ } ++} ++ ++char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, ++ char *output, int size) ++{ ++#if BF_ASM ++ extern void _BF_body_r(BF_ctx *ctx); ++#endif ++ struct { ++ BF_ctx ctx; ++ BF_key expanded_key; ++ union { ++ BF_word salt[4]; ++ BF_word output[6]; ++ } binary; ++ } data; ++ BF_word L, R; ++ BF_word tmp1, tmp2, tmp3, tmp4; ++ BF_word *ptr; ++ BF_word count; ++ int i; ++ ++ if (size < 7 + 22 + 31 + 1) { ++ __set_errno(ERANGE); ++ return NULL; ++ } ++ ++ if (setting[0] != '$' || ++ setting[1] != '2' || ++ setting[2] != 'a' || ++ setting[3] != '$' || ++ setting[4] < '0' || setting[4] > '3' || ++ setting[5] < '0' || setting[5] > '9' || ++ setting[6] != '$') { ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); ++ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { ++ clean(data.binary.salt, sizeof(data.binary.salt)); ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ BF_swap(data.binary.salt, 4); ++ ++ BF_set_key(key, data.expanded_key, data.ctx.P); ++ ++ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); ++ ++ L = R = 0; ++ for (i = 0; i < BF_N + 2; i += 2) { ++ L ^= data.binary.salt[i & 2]; ++ R ^= data.binary.salt[(i & 2) + 1]; ++ BF_ENCRYPT; ++ data.ctx.P[i] = L; ++ data.ctx.P[i + 1] = R; ++ } ++ ++ ptr = data.ctx.S[0]; ++ do { ++ ptr += 4; ++ L ^= data.binary.salt[(BF_N + 2) & 3]; ++ R ^= data.binary.salt[(BF_N + 3) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 4) = L; ++ *(ptr - 3) = R; ++ ++ L ^= data.binary.salt[(BF_N + 4) & 3]; ++ R ^= data.binary.salt[(BF_N + 5) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 2) = L; ++ *(ptr - 1) = R; ++ } while (ptr < &data.ctx.S[3][0xFF]); ++ ++ do { ++ data.ctx.P[0] ^= data.expanded_key[0]; ++ data.ctx.P[1] ^= data.expanded_key[1]; ++ data.ctx.P[2] ^= data.expanded_key[2]; ++ data.ctx.P[3] ^= data.expanded_key[3]; ++ data.ctx.P[4] ^= data.expanded_key[4]; ++ data.ctx.P[5] ^= data.expanded_key[5]; ++ data.ctx.P[6] ^= data.expanded_key[6]; ++ data.ctx.P[7] ^= data.expanded_key[7]; ++ data.ctx.P[8] ^= data.expanded_key[8]; ++ data.ctx.P[9] ^= data.expanded_key[9]; ++ data.ctx.P[10] ^= data.expanded_key[10]; ++ data.ctx.P[11] ^= data.expanded_key[11]; ++ data.ctx.P[12] ^= data.expanded_key[12]; ++ data.ctx.P[13] ^= data.expanded_key[13]; ++ data.ctx.P[14] ^= data.expanded_key[14]; ++ data.ctx.P[15] ^= data.expanded_key[15]; ++ data.ctx.P[16] ^= data.expanded_key[16]; ++ data.ctx.P[17] ^= data.expanded_key[17]; ++ ++ BF_body(); ++ ++ tmp1 = data.binary.salt[0]; ++ tmp2 = data.binary.salt[1]; ++ tmp3 = data.binary.salt[2]; ++ tmp4 = data.binary.salt[3]; ++ data.ctx.P[0] ^= tmp1; ++ data.ctx.P[1] ^= tmp2; ++ data.ctx.P[2] ^= tmp3; ++ data.ctx.P[3] ^= tmp4; ++ data.ctx.P[4] ^= tmp1; ++ data.ctx.P[5] ^= tmp2; ++ data.ctx.P[6] ^= tmp3; ++ data.ctx.P[7] ^= tmp4; ++ data.ctx.P[8] ^= tmp1; ++ data.ctx.P[9] ^= tmp2; ++ data.ctx.P[10] ^= tmp3; ++ data.ctx.P[11] ^= tmp4; ++ data.ctx.P[12] ^= tmp1; ++ data.ctx.P[13] ^= tmp2; ++ data.ctx.P[14] ^= tmp3; ++ data.ctx.P[15] ^= tmp4; ++ data.ctx.P[16] ^= tmp1; ++ data.ctx.P[17] ^= tmp2; ++ ++ BF_body(); ++ } while (--count); ++ ++ for (i = 0; i < 6; i += 2) { ++ L = BF_magic_w[i]; ++ R = BF_magic_w[i + 1]; ++ ++ count = 64; ++ do { ++ BF_ENCRYPT; ++ } while (--count); ++ ++ data.binary.output[i] = L; ++ data.binary.output[i + 1] = R; ++ } ++ ++ memcpy(output, setting, 7 + 22 - 1); ++ output[7 + 22 - 1] = BF_itoa64[(int) ++ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; ++ ++/* This has to be bug-compatible with the original implementation, so ++ * only encode 23 of the 24 bytes. :-) */ ++ BF_swap(data.binary.output, 6); ++ BF_encode(&output[7 + 22], data.binary.output, 23); ++ output[7 + 22 + 31] = '\0'; ++ ++/* Overwrite the most obvious sensitive data we have on the stack. Note ++ * that this does not guarantee there's no sensitive data left on the ++ * stack and/or in registers; I'm not aware of portable code that does. */ ++ clean(&data, sizeof(data)); ++ ++ return output; ++} ++ ++char *_crypt_gensalt_blowfish_rn(unsigned long count, ++ __CONST char *input, int size, char *output, int output_size) ++{ ++ if (size < 16 || output_size < 7 + 22 + 1 || ++ (count && (count < 4 || count > 31))) { ++ if (output_size > 0) output[0] = '\0'; ++ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); ++ return NULL; ++ } ++ ++ if (!count) count = 5; ++ ++ output[0] = '$'; ++ output[1] = '2'; ++ output[2] = 'a'; ++ output[3] = '$'; ++ output[4] = '0' + count / 10; ++ output[5] = '0' + count % 10; ++ output[6] = '$'; ++ ++ BF_encode(&output[7], (BF_word *)input, 16); ++ output[7 + 22] = '\0'; ++ ++ return output; ++} +diff -Nura php-4.4.4/ext/standard/crypt.c hardening-patch-4.4.4-0.4.15/ext/standard/crypt.c +--- php-4.4.4/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/crypt.c 2006-09-05 20:30:51.000000000 +0200 +@@ -100,6 +100,8 @@ + return SUCCESS; + } + ++char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); ++char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); + + static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +@@ -135,7 +137,14 @@ + + /* The automatic salt generation only covers standard DES and md5-crypt */ + if(!*salt) { +-#if PHP_MD5_CRYPT ++#if PHP_BLOWFISH_CRYPT ++ char randat[16]; ++ int i; ++ ++ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; ++ ++ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); ++#elif PHP_MD5_CRYPT + strcpy(salt, "$1$"); + php_to64(&salt[3], PHP_CRYPT_RAND, 4); + php_to64(&salt[7], PHP_CRYPT_RAND, 4); +@@ -145,8 +154,24 @@ + salt[2] = '\0'; + #endif + } +- +- RETVAL_STRING(crypt(str, salt), 1); ++ ++ if (salt[0] == '$' && ++ salt[1] == '2' && ++ salt[2] == 'a' && ++ salt[3] == '$' && ++ salt[4] >= '0' && salt[4] <= '3' && ++ salt[5] >= '0' && salt[5] <= '9' && ++ salt[6] == '$') { ++ ++ char output[PHP_MAX_SALT_LEN+1]; ++ ++ output[0] = 0; ++ _crypt_blowfish_rn(str, salt, output, sizeof(output)); ++ RETVAL_STRING(output, 1); ++ ++ } else { ++ RETVAL_STRING(crypt(str, salt), 1); ++ } + } + /* }}} */ + #endif +diff -Nura php-4.4.4/ext/standard/dl.c hardening-patch-4.4.4-0.4.15/ext/standard/dl.c +--- php-4.4.4/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/dl.c 2006-09-05 20:30:51.000000000 +0200 +@@ -160,8 +160,35 @@ + RETURN_FALSE; + } + module_entry = get_module(); ++ ++ /* check if Hardening-Patch is installed */ ++ if (module_entry->zend_api < 1000000000) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ ++ /* check if correct Hardening-Patch is installed */ ++ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ + if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) +- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { ++ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { + /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ + struct pre_4_1_0_module_entry { + char *name; +@@ -195,7 +222,7 @@ + zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; + } else { + name = module_entry->name; +- zend_api = module_entry->zend_api; ++ zend_api = module_entry->real_zend_api; + zend_debug = module_entry->zend_debug; + zts = module_entry->zts; + } +diff -Nura php-4.4.4/ext/standard/file.c hardening-patch-4.4.4-0.4.15/ext/standard/file.c +--- php-4.4.4/ext/standard/file.c 2006-04-14 19:46:59.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/file.c 2006-09-05 20:30:51.000000000 +0200 +@@ -2527,7 +2527,7 @@ + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) + /* {{{ proto string realpath(string path) + Return the resolved path */ +-PHP_FUNCTION(realpath) ++PHP_FUNCTION(real_path) + { + zval **path; + char resolved_path_buff[MAXPATHLEN]; +diff -Nura php-4.4.4/ext/standard/file.h hardening-patch-4.4.4-0.4.15/ext/standard/file.h +--- php-4.4.4/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/file.h 2006-09-05 20:30:51.000000000 +0200 +@@ -64,7 +64,7 @@ + PHP_FUNCTION(fd_set); + PHP_FUNCTION(fd_isset); + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +-PHP_FUNCTION(realpath); ++PHP_FUNCTION(real_path); + #endif + #ifdef HAVE_FNMATCH + PHP_FUNCTION(fnmatch); +diff -Nura php-4.4.4/ext/standard/head.c hardening-patch-4.4.4-0.4.15/ext/standard/head.c +--- php-4.4.4/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/head.c 2006-09-05 20:30:51.000000000 +0200 +@@ -44,7 +44,7 @@ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, + &ctr.line_len, &rep, &ctr.response_code) == FAILURE) + return; +- ++ + sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); + } + /* }}} */ +diff -Nura php-4.4.4/ext/standard/mail.c hardening-patch-4.4.4-0.4.15/ext/standard/mail.c +--- php-4.4.4/ext/standard/mail.c 2006-01-01 14:46:57.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/mail.c 2006-09-05 20:30:51.000000000 +0200 +@@ -78,6 +78,25 @@ + } + /* }}} */ + ++/* {{{ hphp_strcasestr */ ++char *hphp_strcasestr(char *haystack, char *needle) ++{ ++ unsigned char *t, *h, *n; ++ ++ h = (unsigned char *) haystack; ++conts: ++ while (*h) { ++ n = (unsigned char *) needle; ++ for (t=h++; *n && *h; t++, n++) { ++ if (toupper(*t) != toupper(*n)) goto conts; ++ } ++ return ((char*)h-1); ++ } ++ ++ return (NULL); ++} ++/* }}} */ ++ + /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) + Send an email message */ + PHP_FUNCTION(mail) +@@ -103,6 +122,44 @@ + return; + } + ++ if (HG(hphp_mailprotect) > 0) { ++ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { ++ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ /* check for spam attempts with buggy webforms */ ++ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (HG(hphp_mailprotect) > 1) { ++ /* search for to, cc or bcc headers */ ++ if (headers_len > 0 && headers != NULL) { ++ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { ++ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { ++ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { ++ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ } ++ } ++ } ++ + if (to_len > 0) { + to_r = estrndup(to, to_len); + for (; to_len; to_len--) { +diff -Nura php-4.4.4/ext/standard/php_standard.h hardening-patch-4.4.4-0.4.15/ext/standard/php_standard.h +--- php-4.4.4/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/php_standard.h 2006-09-05 20:30:51.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "php_mail.h" + #include "md5.h" + #include "sha1.h" ++#include "sha256.h" + #include "html.h" + #include "exec.h" + #include "file.h" +diff -Nura php-4.4.4/ext/standard/sha256.c hardening-patch-4.4.4-0.4.15/ext/standard/sha256.c +--- php-4.4.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/sha256.c 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,398 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ ++ ++#include ++#include "php.h" ++ ++/* This code is heavily based on the PHP md5/sha1 implementations */ ++ ++#include "sha256.h" ++ ++PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ sprintf(sha256str, "%02x", digest[i]); ++ sha256str += 2; ++ } ++ ++ *sha256str = '\0'; ++} ++ ++/* {{{ proto string sha256(string str [, bool raw_output]) ++ Calculate the sha256 hash of a string */ ++PHP_FUNCTION(sha256) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ PHP_SHA256_CTX context; ++ unsigned char digest[32]; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ sha256str[0] = '\0'; ++ PHP_SHA256Init(&context); ++ PHP_SHA256Update(&context, arg, arg_len); ++ PHP_SHA256Final(digest, &context); ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++ ++} ++ ++/* }}} */ ++ ++/* {{{ proto string sha256_file(string filename [, bool raw_output]) ++ Calculate the sha256 hash of given filename */ ++PHP_FUNCTION(sha256_file) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ unsigned char buf[1024]; ++ unsigned char digest[32]; ++ PHP_SHA256_CTX context; ++ int n; ++ FILE *fp; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { ++ RETURN_FALSE; ++ } ++ ++ if (php_check_open_basedir(arg TSRMLS_CC)) { ++ RETURN_FALSE; ++ } ++ ++ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); ++ RETURN_FALSE; ++ } ++ ++ PHP_SHA256Init(&context); ++ ++ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { ++ PHP_SHA256Update(&context, buf, n); ++ } ++ ++ PHP_SHA256Final(digest, &context); ++ ++ if (ferror(fp)) { ++ fclose(fp); ++ RETURN_FALSE; ++ } ++ ++ fclose(fp); ++ ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++} ++/* }}} */ ++ ++ ++static void SHA256Transform(php_uint32[8], const unsigned char[64]); ++static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); ++static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); ++ ++static unsigned char PADDING[64] = ++{ ++ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++/* F, G, H and I are basic SHA256 functions. ++ */ ++#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) ++#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) ++#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) ++#define I(x, y, z) (((x) & (y)) | ((~x) & z)) ++ ++/* ROTATE_RIGHT rotates x right n bits. ++ */ ++#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) ++ ++/* W[i] ++ */ ++#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ ++ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ ++ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) ++ ++/* ROUND function of sha256 ++ */ ++ ++#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ ++ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ ++ (h) = F((a)) + G((a), (b), (c)) + t1; \ ++ (d) += t1; \ ++ } ++ ++ ++/* {{{ PHP_SHA256Init ++ * SHA256 initialization. Begins an SHA256 operation, writing a new context. ++ */ ++PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context) ++{ ++ context->count[0] = context->count[1] = 0; ++ /* Load magic initialization constants. ++ */ ++ context->state[0] = 0x6a09e667; ++ context->state[1] = 0xbb67ae85; ++ context->state[2] = 0x3c6ef372; ++ context->state[3] = 0xa54ff53a; ++ context->state[4] = 0x510e527f; ++ context->state[5] = 0x9b05688c; ++ context->state[6] = 0x1f83d9ab; ++ context->state[7] = 0x5be0cd19; ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Update ++ SHA256 block update operation. Continues an SHA256 message-digest ++ operation, processing another message block, and updating the ++ context. ++ */ ++PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, ++ unsigned int inputLen) ++{ ++ unsigned int i, index, partLen; ++ ++ /* Compute number of bytes mod 64 */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ++ ++ /* Update number of bits */ ++ if ((context->count[0] += ((php_uint32) inputLen << 3)) ++ < ((php_uint32) inputLen << 3)) ++ context->count[1]++; ++ context->count[1] += ((php_uint32) inputLen >> 29); ++ ++ partLen = 64 - index; ++ ++ /* Transform as many times as possible. ++ */ ++ if (inputLen >= partLen) { ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ++ SHA256Transform(context->state, context->buffer); ++ ++ for (i = partLen; i + 63 < inputLen; i += 64) ++ SHA256Transform(context->state, &input[i]); ++ ++ index = 0; ++ } else ++ i = 0; ++ ++ /* Buffer remaining input */ ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], ++ inputLen - i); ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Final ++ SHA256 finalization. Ends an SHA256 message-digest operation, writing the ++ the message digest and zeroizing the context. ++ */ ++PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) ++{ ++ unsigned char bits[8]; ++ unsigned int index, padLen; ++ ++ /* Save number of bits */ ++ bits[7] = context->count[0] & 0xFF; ++ bits[6] = (context->count[0] >> 8) & 0xFF; ++ bits[5] = (context->count[0] >> 16) & 0xFF; ++ bits[4] = (context->count[0] >> 24) & 0xFF; ++ bits[3] = context->count[1] & 0xFF; ++ bits[2] = (context->count[1] >> 8) & 0xFF; ++ bits[1] = (context->count[1] >> 16) & 0xFF; ++ bits[0] = (context->count[1] >> 24) & 0xFF; ++ ++ /* Pad out to 56 mod 64. ++ */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ++ padLen = (index < 56) ? (56 - index) : (120 - index); ++ PHP_SHA256Update(context, PADDING, padLen); ++ ++ /* Append length (before padding) */ ++ PHP_SHA256Update(context, bits, 8); ++ ++ /* Store state in digest */ ++ SHA256Encode(digest, context->state, 32); ++ ++ /* Zeroize sensitive information. ++ */ ++ memset((unsigned char*) context, 0, sizeof(*context)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Transform ++ * SHA256 basic transformation. Transforms state based on block. ++ */ ++static void SHA256Transform(state, block) ++php_uint32 state[8]; ++const unsigned char block[64]; ++{ ++ php_uint32 a = state[0], b = state[1], c = state[2]; ++ php_uint32 d = state[3], e = state[4], f = state[5]; ++ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; ++ ++ SHA256Decode(x, block, 64); ++ ++ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) ++ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) ++ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) ++ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) ++ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) ++ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) ++ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) ++ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) ++ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) ++ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) ++ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) ++ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) ++ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) ++ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) ++ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) ++ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) ++ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) ++ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) ++ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) ++ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) ++ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) ++ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) ++ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) ++ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) ++ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) ++ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) ++ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) ++ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) ++ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) ++ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) ++ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) ++ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) ++ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) ++ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) ++ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) ++ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) ++ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) ++ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) ++ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) ++ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) ++ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) ++ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) ++ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) ++ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) ++ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) ++ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) ++ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) ++ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) ++ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) ++ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) ++ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) ++ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) ++ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) ++ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) ++ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) ++ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) ++ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) ++ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) ++ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) ++ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) ++ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) ++ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) ++ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) ++ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) ++ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ state[5] += f; ++ state[6] += g; ++ state[7] += h; ++ ++ /* Zeroize sensitive information. */ ++ memset((unsigned char*) x, 0, sizeof(x)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Encode ++ Encodes input (php_uint32) into output (unsigned char). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Encode(output, input, len) ++unsigned char *output; ++php_uint32 *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) { ++ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); ++ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); ++ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); ++ output[j + 3] = (unsigned char) (input[i] & 0xff); ++ } ++} ++/* }}} */ ++ ++/* {{{ SHA256Decode ++ Decodes input (unsigned char) into output (php_uint32). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Decode(output, input, len) ++php_uint32 *output; ++const unsigned char *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) ++ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | ++ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.4/ext/standard/sha256.h hardening-patch-4.4.4-0.4.15/ext/standard/sha256.h +--- php-4.4.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/sha256.h 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ ++ ++#ifndef SHA256_H ++#define SHA256_H ++ ++#include "ext/standard/basic_functions.h" ++ ++/* SHA1 context. */ ++typedef struct { ++ php_uint32 state[8]; /* state (ABCD) */ ++ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ++ unsigned char buffer[64]; /* input buffer */ ++} PHP_SHA256_CTX; ++ ++PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *); ++PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); ++PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); ++ ++PHP_FUNCTION(sha256); ++PHP_FUNCTION(sha256_file); ++ ++#endif +diff -Nura php-4.4.4/ext/standard/syslog.c hardening-patch-4.4.4-0.4.15/ext/standard/syslog.c +--- php-4.4.4/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/standard/syslog.c 2006-09-05 20:30:51.000000000 +0200 +@@ -42,6 +42,8 @@ + */ + PHP_MINIT_FUNCTION(syslog) + { ++ ++#if !HARDENING_PATCH + /* error levels */ + REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ + REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ +@@ -97,7 +99,7 @@ + /* AIX doesn't have LOG_PERROR */ + REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ + #endif +- ++#endif + return SUCCESS; + } + /* }}} */ +diff -Nura php-4.4.4/ext/varfilter/config.m4 hardening-patch-4.4.4-0.4.15/ext/varfilter/config.m4 +--- php-4.4.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/varfilter/config.m4 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,11 @@ ++dnl ++dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++dnl ++ ++PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, ++[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) ++ ++if test "$PHP_VARFILTER" != "no"; then ++ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) ++ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) ++fi +diff -Nura php-4.4.4/ext/varfilter/CREDITS hardening-patch-4.4.4-0.4.15/ext/varfilter/CREDITS +--- php-4.4.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,2 @@ ++varfilter ++Stefan Esser +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-4.4.4/ext/varfilter/php_varfilter.h hardening-patch-4.4.4-0.4.15/ext/varfilter/php_varfilter.h +--- php-4.4.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,144 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifndef PHP_VARFILTER_H ++#define PHP_VARFILTER_H ++ ++extern zend_module_entry varfilter_module_entry; ++#define phpext_varfilter_ptr &varfilter_module_entry ++ ++#ifdef PHP_WIN32 ++#define PHP_VARFILTER_API __declspec(dllexport) ++#else ++#define PHP_VARFILTER_API ++#endif ++ ++#ifdef ZTS ++#include "TSRM.h" ++#endif ++ ++#include "SAPI.h" ++ ++#include "php_variables.h" ++ ++#ifdef ZEND_ENGINE_2 ++#define HASH_HTTP_GET_VARS 0x2095733f ++#define HASH_HTTP_POST_VARS 0xbfee1265 ++#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 ++#define HASH_HTTP_ENV_VARS 0x1fe186a8 ++#define HASH_HTTP_SERVER_VARS 0xc987afd6 ++#define HASH_HTTP_SESSION_VARS 0x7aba0d43 ++#define HASH_HTTP_POST_FILES 0x98eb1ddc ++#define HASH_HTTP_RAW_POST_DATA 0xdd633fec ++#else ++#define HASH_HTTP_GET_VARS 0x8d8645bd ++#define HASH_HTTP_POST_VARS 0x7c699bf3 ++#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f ++#define HASH_HTTP_ENV_VARS 0x84da3016 ++#define HASH_HTTP_SERVER_VARS 0x6dbf964e ++#define HASH_HTTP_SESSION_VARS 0x322906f5 ++#define HASH_HTTP_POST_FILES 0xe4e4ce70 ++#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e ++#endif ++ ++PHP_MINIT_FUNCTION(varfilter); ++PHP_MSHUTDOWN_FUNCTION(varfilter); ++PHP_RINIT_FUNCTION(varfilter); ++PHP_RSHUTDOWN_FUNCTION(varfilter); ++PHP_MINFO_FUNCTION(varfilter); ++ ++ ++ZEND_BEGIN_MODULE_GLOBALS(varfilter) ++/* request variables */ ++ long max_request_variables; ++ long cur_request_variables; ++ long max_varname_length; ++ long max_totalname_length; ++ long max_value_length; ++ long max_array_depth; ++ long max_array_index_length; ++ zend_bool disallow_nul; ++/* cookie variables */ ++ long max_cookie_vars; ++ long cur_cookie_vars; ++ long max_cookie_name_length; ++ long max_cookie_totalname_length; ++ long max_cookie_value_length; ++ long max_cookie_array_depth; ++ long max_cookie_array_index_length; ++ zend_bool disallow_cookie_nul; ++/* get variables */ ++ long max_get_vars; ++ long cur_get_vars; ++ long max_get_name_length; ++ long max_get_totalname_length; ++ long max_get_value_length; ++ long max_get_array_depth; ++ long max_get_array_index_length; ++ zend_bool disallow_get_nul; ++/* post variables */ ++ long max_post_vars; ++ long cur_post_vars; ++ long max_post_name_length; ++ long max_post_totalname_length; ++ long max_post_value_length; ++ long max_post_array_depth; ++ long max_post_array_index_length; ++ zend_bool disallow_post_nul; ++/* fileupload */ ++ long max_uploads; ++ long cur_uploads; ++ zend_bool disallow_elf_files; ++ char *verification_script; ++ ++ zend_bool no_more_variables; ++ zend_bool no_more_get_variables; ++ zend_bool no_more_post_variables; ++ zend_bool no_more_cookie_variables; ++ zend_bool no_more_uploads; ++ ++ZEND_END_MODULE_GLOBALS(varfilter) ++ ++ ++#ifdef ZTS ++#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) ++#else ++#define VARFILTER_G(v) (varfilter_globals.v) ++#endif ++ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); ++SAPI_TREAT_DATA_FUNC(varfilter_treat_data); ++ ++ ++ ++#endif /* PHP_VARFILTER_H */ ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: t ++ * End: ++ */ +diff -Nura php-4.4.4/ext/varfilter/varfilter.c hardening-patch-4.4.4-0.4.15/ext/varfilter/varfilter.c +--- php-4.4.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:51:18.000000000 +0200 +@@ -0,0 +1,915 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "php.h" ++#include "php_ini.h" ++#include "ext/standard/info.h" ++#include "php_varfilter.h" ++#include "hardening_patch.h" ++ ++ZEND_DECLARE_MODULE_GLOBALS(varfilter) ++ ++/* True global resources - no need for thread safety here */ ++static int le_varfilter; ++ ++static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; ++static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; ++static zend_bool hooked = 0; ++ ++/* {{{ varfilter_module_entry ++ */ ++zend_module_entry varfilter_module_entry = { ++#if ZEND_MODULE_API_NO >= 20010901 ++ STANDARD_MODULE_HEADER, ++#endif ++ "varfilter", ++ NULL, ++ PHP_MINIT(varfilter), ++ PHP_MSHUTDOWN(varfilter), ++ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ ++ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ ++ PHP_MINFO(varfilter), ++#if ZEND_MODULE_API_NO >= 20010901 ++ "0.4.15", /* Replace with version number for your extension */ ++#endif ++ STANDARD_MODULE_PROPERTIES ++}; ++/* }}} */ ++ ++#ifdef COMPILE_DL_VARFILTER ++ZEND_GET_MODULE(varfilter) ++#endif ++ ++/* {{{ PHP_INI ++ */ ++PHP_INI_BEGIN() ++ /* for backward compatibility */ ++ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) ++ ++ ++PHP_INI_END() ++/* }}} */ ++ ++/* {{{ php_varfilter_init_globals ++ */ ++static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) ++{ ++ varfilter_globals->max_request_variables = 200; ++ varfilter_globals->max_varname_length = 64; ++ varfilter_globals->max_value_length = 10000; ++ varfilter_globals->max_array_depth = 100; ++ varfilter_globals->max_totalname_length = 256; ++ varfilter_globals->max_array_index_length = 64; ++ varfilter_globals->disallow_nul = 1; ++ ++ varfilter_globals->max_cookie_vars = 100; ++ varfilter_globals->max_cookie_name_length = 64; ++ varfilter_globals->max_cookie_totalname_length = 256; ++ varfilter_globals->max_cookie_value_length = 10000; ++ varfilter_globals->max_cookie_array_depth = 100; ++ varfilter_globals->max_cookie_array_index_length = 64; ++ varfilter_globals->disallow_cookie_nul = 1; ++ ++ varfilter_globals->max_get_vars = 100; ++ varfilter_globals->max_get_name_length = 64; ++ varfilter_globals->max_get_totalname_length = 256; ++ varfilter_globals->max_get_value_length = 512; ++ varfilter_globals->max_get_array_depth = 50; ++ varfilter_globals->max_get_array_index_length = 64; ++ varfilter_globals->disallow_get_nul = 1; ++ ++ varfilter_globals->max_post_vars = 200; ++ varfilter_globals->max_post_name_length = 64; ++ varfilter_globals->max_post_totalname_length = 256; ++ varfilter_globals->max_post_value_length = 65000; ++ varfilter_globals->max_post_array_depth = 100; ++ varfilter_globals->max_post_array_index_length = 64; ++ varfilter_globals->disallow_post_nul = 1; ++ ++ varfilter_globals->max_uploads = 25; ++ varfilter_globals->disallow_elf_files = 1; ++ varfilter_globals->verification_script = NULL; ++ ++ varfilter_globals->no_more_variables = 0; ++ varfilter_globals->no_more_get_variables = 0; ++ varfilter_globals->no_more_post_variables = 0; ++ varfilter_globals->no_more_cookie_variables = 0; ++ varfilter_globals->no_more_uploads = 0; ++ ++ varfilter_globals->cur_request_variables = 0; ++ varfilter_globals->cur_get_vars = 0; ++ varfilter_globals->cur_post_vars = 0; ++ varfilter_globals->cur_cookie_vars = 0; ++ ++ varfilter_globals->cur_uploads = 0; ++ ++} ++/* }}} */ ++ ++ ++void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) ++{ ++ HashTable *svars; ++ int retval, failure=0; ++ ++ orig_register_server_variables(track_vars_array TSRMLS_CC); ++ ++ svars = Z_ARRVAL_P(track_vars_array); ++ ++ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ ++ if (failure) { ++ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); ++ } ++} ++ ++int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) ++{ ++ int retval = SAPI_HEADER_ADD, i; ++ char *tmp; ++ ++ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { ++ ++ tmp = sapi_header->header; ++ for (i=0; iheader_len; i++, tmp++) { ++ if (tmp[0] == 0) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); ++ sapi_header->header_len = i; ++ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); ++ sapi_header->header_len = i; ++ tmp[0] = 0; ++ } ++ } ++ } ++ ++ if (orig_header_handler) { ++ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); ++ } ++ ++ return retval; ++} ++ ++/* {{{ PHP_MINIT_FUNCTION ++ */ ++PHP_MINIT_FUNCTION(varfilter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); ++ REGISTER_INI_ENTRIES(); ++ ++ if (!hooked) { ++ void *temp; ++ hooked = 1; ++ ++ temp = (void *)sapi_module.register_server_variables; ++ if (temp != varfilter_register_server_variables) { ++ orig_register_server_variables = temp; ++ } ++ temp = (void *)sapi_module.header_handler; ++ if (temp != varfilter_header_handler) { ++ orig_header_handler = temp; ++ } ++ } ++ ++ sapi_register_input_filter(varfilter_input_filter); ++ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); ++ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); ++ sapi_register_upload_content_filter(varfilter_upload_content_filter); ++ sapi_register_post_upload_filter(varfilter_post_upload_filter); ++ ++ sapi_module.header_handler = varfilter_header_handler; ++ sapi_module.register_server_variables = varfilter_register_server_variables; ++ ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MSHUTDOWN_FUNCTION ++ */ ++PHP_MSHUTDOWN_FUNCTION(varfilter) ++{ ++ UNREGISTER_INI_ENTRIES(); ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request start */ ++/* {{{ PHP_RINIT_FUNCTION ++ */ ++PHP_RINIT_FUNCTION(varfilter) ++{ ++ VARFILTER_G(cur_request_variables) = 0; ++ VARFILTER_G(cur_get_vars) = 0; ++ VARFILTER_G(cur_post_vars) = 0; ++ VARFILTER_G(cur_cookie_vars) = 0; ++ ++ VARFILTER_G(cur_uploads) = 0; ++ ++ VARFILTER_G(no_more_variables) = 0; ++ VARFILTER_G(no_more_get_variables) = 0; ++ VARFILTER_G(no_more_post_variables) = 0; ++ VARFILTER_G(no_more_cookie_variables) = 0; ++ VARFILTER_G(no_more_uploads) = 0; ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request end */ ++/* {{{ PHP_RSHUTDOWN_FUNCTION ++ */ ++PHP_RSHUTDOWN_FUNCTION(varfilter) ++{ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MINFO_FUNCTION ++ */ ++PHP_MINFO_FUNCTION(varfilter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); ++ php_info_print_table_end(); ++ ++ DISPLAY_INI_ENTRIES(); ++} ++/* }}} */ ++ ++/* {{{ normalize_varname ++ */ ++static void normalize_varname(char *varname) ++{ ++ char *s=varname, *index=NULL, *indexend=NULL, *p; ++ ++ /* overjump leading space */ ++ while (*s == ' ') { ++ s++; ++ } ++ ++ /* and remove it */ ++ if (s != varname) { ++ memmove(varname, s, strlen(s)+1); ++ } ++ ++ for (p=varname; *p && *p != '['; p++) { ++ switch(*p) { ++ case ' ': ++ case '.': ++ *p='_'; ++ break; ++ } ++ } ++ ++ /* find index */ ++ index = strchr(varname, '['); ++ if (index) { ++ index++; ++ s=index; ++ } else { ++ return; ++ } ++ ++ /* done? */ ++ while (index) { ++ ++ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { ++ index++; ++ } ++ indexend = strchr(index, ']'); ++ indexend = indexend ? indexend + 1 : index + strlen(index); ++ ++ if (s != index) { ++ memmove(s, index, strlen(index)+1); ++ s += indexend-index; ++ } else { ++ s = indexend; ++ } ++ ++ if (*s == '[') { ++ s++; ++ index = s; ++ } else { ++ index = NULL; ++ } ++ } ++ *s++='\0'; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC ++ */ ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) ++{ ++ char *index, *prev_index = NULL, *var; ++ unsigned int var_len, total_len, depth = 0; ++ ++ var = estrdup(varname); ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); ++ ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; ++ break; ++ } ++ ++ efree(var); ++ return SUCCESS; ++protected_varname2: ++ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); ++return_failure: ++ efree(var); ++ return FAILURE; ++} ++/* }}} */ ++ ++/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC ++ */ ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) ++{ ++ /* Drop if no more variables flag is set */ ++ if (VARFILTER_G(no_more_uploads)) { ++ return FAILURE; ++ } ++ /* Drop this fileupload if the limit is reached */ ++ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { ++ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); ++ VARFILTER_G(no_more_uploads) = 1; ++ return FAILURE; ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC ++ */ ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) ++{ ++ ++ if (VARFILTER_G(disallow_elf_files)) { ++ ++ if (offset == 0 && buffer_len > 10) { ++ ++ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { ++ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); ++ return FAILURE; ++ } ++ } ++ ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC ++ */ ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) ++{ ++ int retval = SUCCESS; ++ ++ if (VARFILTER_G(verification_script)) { ++ char cmd[8192]; ++ FILE *in; ++ int first=1; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); ++ return FAILURE; ++ } ++ ++ retval = FAILURE; ++ ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ if (first) { ++ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; ++ first = 0; ++ } ++ } ++ pclose(in); ++ } ++ ++ if (retval != SUCCESS) { ++ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); ++ return FAILURE; ++ } ++ ++ VARFILTER_G(cur_uploads)++; ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_INPUT_FILTER_FUNC ++ */ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) ++{ ++ char *index, *prev_index = NULL; ++ unsigned int var_len, total_len, depth = 0; ++ ++ /* Drop this variable if the limit was reached */ ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(no_more_get_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(no_more_post_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(no_more_cookie_variables)) { ++ return 0; ++ } ++ break; ++ default: /* we do not want to protect parse_str() and friends */ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ return 1; ++ } ++ if (VARFILTER_G(no_more_variables)) { ++ return 0; ++ } ++ ++ /* Drop this variable if the limit is now reached */ ++ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { ++ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_variables) = 1; ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { ++ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_get_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { ++ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_cookie_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { ++ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_post_variables) = 1; ++ return 0; ++ } ++ break; ++ } ++ ++ ++ /* Drop this variable if it exceeds the value length limit */ ++ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { ++ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { ++ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { ++ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { ++ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { ++ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { ++ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Check if variable value is truncated by a \0 */ ++ ++ if (val && *val && val_len != strlen(*val)) { ++ ++ if (VARFILTER_G(disallow_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(disallow_get_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(disallow_cookie_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(disallow_post_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ } ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname; ++ break; ++ } ++ ++ /* Okay let PHP register this variable */ ++ VARFILTER_G(cur_request_variables)++; ++ switch (arg) { ++ case PARSE_GET: ++ VARFILTER_G(cur_get_vars)++; ++ break; ++ case PARSE_COOKIE: ++ VARFILTER_G(cur_cookie_vars)++; ++ break; ++ case PARSE_POST: ++ VARFILTER_G(cur_post_vars)++; ++ break; ++ } ++ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ ++ return 1; ++protected_varname: ++ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); ++ return 0; ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: noet sw=4 ts=4 fdm=marker ++ * vim<600: noet sw=4 ts=4 ++ */ ++ ++ +diff -Nura php-4.4.4/main/fopen_wrappers.c hardening-patch-4.4.4-0.4.15/main/fopen_wrappers.c +--- php-4.4.4/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:45.000000000 +0200 +@@ -106,7 +106,10 @@ + } + + /* Resolve the real path into resolved_name */ +- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { ++ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { ++ return -2; ++ } ++ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { + /* Handler for basedirs that end with a / */ + resolved_basedir_len = strlen(resolved_basedir); + if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { +@@ -116,14 +119,20 @@ + } + } + ++ resolved_name_len = strlen(resolved_name); + if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { +- resolved_name_len = strlen(resolved_name); + if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { + resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; + resolved_name[++resolved_name_len] = '\0'; + } + } + ++ if (resolved_name_len == resolved_basedir_len - 1) { ++ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { ++ resolved_basedir_len--; ++ } ++ } ++ + /* Check the path */ + #ifdef PHP_WIN32 + if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { +@@ -137,7 +146,7 @@ + } + } else { + /* Unable to resolve the real path, return -1 */ +- return -1; ++ return -3; + } + } + /* }}} */ +@@ -156,22 +165,44 @@ + char *pathbuf; + char *ptr; + char *end; ++ char path_copy[MAXPATHLEN]; ++ int path_len; ++ ++ /* Special case path ends with a trailing slash */ ++ path_len = strlen(path); ++ if (path_len >= MAXPATHLEN) { ++ errno = EPERM; /* we deny permission to open it */ ++ return -1; ++ } ++ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { ++ memcpy(path_copy, path, path_len+1); ++ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; ++ path_copy[path_len] = '\0'; ++ path = (const char *)&path_copy; ++ } + + pathbuf = estrdup(PG(open_basedir)); + + ptr = pathbuf; + + while (ptr && *ptr) { ++ int res; + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end != NULL) { + *end = '\0'; + end++; + } + +- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { ++ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); ++ if (res == 0) { + efree(pathbuf); + return 0; + } ++ if (res == -2) { ++ efree(pathbuf); ++ errno = EPERM; ++ return -1; ++ } + + ptr = end; + } +diff -Nura php-4.4.4/main/hardened_globals.h hardening-patch-4.4.4-0.4.15/main/hardened_globals.h +--- php-4.4.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/hardened_globals.h 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENED_GLOBALS_H ++#define HARDENED_GLOBALS_H ++ ++typedef struct _hardened_globals hardened_globals_struct; ++ ++#ifdef ZTS ++# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) ++extern int hardened_globals_id; ++#else ++# define HG(v) (hardened_globals.v) ++extern struct _hardened_globals hardened_globals; ++#endif ++ ++ ++struct _hardened_globals { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_1; ++ unsigned int canary_2; ++#endif ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_3; ++ unsigned int canary_4; ++ unsigned int ll_canary_inited; ++#endif ++ zend_bool hphp_sql_bailout_on_error; ++ zend_bool hphp_multiheader; ++ unsigned long hphp_mailprotect; ++ long hard_memory_limit; ++ HashTable *eval_whitelist; ++ HashTable *eval_blacklist; ++ HashTable *func_whitelist; ++ HashTable *func_blacklist; ++ HashTable *include_whitelist; ++ HashTable *include_blacklist; ++ unsigned int dummy; ++}; ++ ++ ++#endif /* HARDENED_GLOBALS_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-4.4.4/main/hardening_patch.c hardening-patch-4.4.4-0.4.15/main/hardening_patch.c +--- php-4.4.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.c 2006-09-07 18:47:49.000000000 +0200 +@@ -0,0 +1,430 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ ++ ++#include "php.h" ++ ++#include ++#include ++ ++#if HAVE_UNISTD_H ++#include ++#endif ++#include "SAPI.h" ++#include "php_globals.h" ++ ++#if HARDENING_PATCH ++ ++#ifdef HAVE_SYS_SOCKET_H ++#include ++#endif ++ ++#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) ++#undef AF_UNIX ++#endif ++ ++#if defined(AF_UNIX) ++#include ++#endif ++ ++#define SYSLOG_PATH "/dev/log" ++ ++#include "snprintf.h" ++ ++#include "hardening_patch.h" ++ ++#ifdef ZTS ++#include "hardened_globals.h" ++int hardened_globals_id; ++#else ++struct _hardened_globals hardened_globals; ++#endif ++ ++static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) ++{ ++ memset(hardened_globals, 0, sizeof(*hardened_globals)); ++} ++ ++ ++PHPAPI void hardened_startup() ++{ ++#ifdef ZTS ++ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); ++#else ++ hardened_globals_ctor(&hardened_globals TSRMLS_CC); ++#endif ++} ++ ++PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) ++{ ++ HG(canary_1) = php_canary(); ++ HG(canary_2) = php_canary(); ++} ++ ++char *loglevel2string(int loglevel) ++{ ++ switch (loglevel) { ++ case S_FILES: ++ return "FILES"; ++ case S_INCLUDE: ++ return "INCLUDE"; ++ case S_MEMORY: ++ return "MEMORY"; ++ case S_MISC: ++ return "MISC"; ++ case S_SQL: ++ return "SQL"; ++ case S_EXECUTOR: ++ return "EXECUTOR"; ++ case S_VARS: ++ return "VARS"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++PHPAPI void php_security_log(int loglevel, char *fmt, ...) ++{ ++#if defined(AF_UNIX) ++ int s, r, i=0; ++ struct sockaddr_un saun; ++ char buf[4096+64]; ++ char error[4096+100]; ++ char *ip_address; ++ char *fname; ++ int lineno; ++ va_list ap; ++ TSRMLS_FETCH(); ++ ++ if (EG(hphp_log_use_x_forwarded_for)) { ++ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "X-FORWARDED-FOR not set"; ++ } ++ } else { ++ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "REMOTE_ADDR not set"; ++ } ++ } ++ ++ ++ va_start(ap, fmt); ++ ap_php_vsnprintf(error, sizeof(error), fmt, ap); ++ va_end(ap); ++ while (error[i]) { ++ if (error[i] < 32) error[i] = '.'; ++ i++; ++ } ++ ++ if (zend_is_executing(TSRMLS_C)) { ++ lineno = zend_get_executed_lineno(TSRMLS_C); ++ fname = zend_get_executed_filename(TSRMLS_C); ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); ++ } else { ++ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); ++ if (fname==NULL) { ++ fname = "unknown"; ++ } ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); ++ } ++ ++ /* Syslog-Logging disabled? */ ++ if ((EG(hphp_log_syslog) & loglevel)==0) { ++ goto log_sapi; ++ } ++ ++ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); ++ ++ s = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ s = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ goto log_sapi; ++ } ++ } ++ send(s, error, strlen(error), 0); ++ ++ close(s); ++ ++log_sapi: ++ /* SAPI Logging activated? */ ++ if ((EG(hphp_log_sapi) & loglevel)!=0) { ++ sapi_module.log_message(buf); ++ } ++ ++log_script: ++ /* script logging activaed? */ ++ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { ++ char cmd[8192], *cmdpos, *bufpos; ++ FILE *in; ++ int space; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); ++ space = sizeof(cmd) - strlen(cmd); ++ cmdpos = cmd + strlen(cmd); ++ bufpos = buf; ++ if (space <= 1) return; ++ while (space > 2 && *bufpos) { ++ if (*bufpos == '\'') { ++ if (space<=5) break; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\\'; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\''; ++ bufpos++; ++ space-=4; ++ } else { ++ *cmdpos++ = *bufpos++; ++ space--; ++ } ++ } ++ *cmdpos++ = '\''; ++ *cmdpos = 0; ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); ++ return; ++ } ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ } ++ pclose(in); ++ } ++ ++#endif ++} ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++PHPAPI unsigned int php_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++ ++PHPAPI int php_is_valid_include(zval *z) ++{ ++ char *filename; ++ int len, i; ++ TSRMLS_FETCH(); ++ ++ /* must be of type string */ ++ if (z->type != IS_STRING || z->value.str.val == NULL) { ++ return (0); ++ } ++ ++ /* short cut */ ++ filename = z->value.str.val; ++ len = z->value.str.len; ++ ++ /* 1. must be shorter than MAXPATHLEN */ ++ if (len > MAXPATHLEN) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 2. must not be cutted */ ++ if (len != strlen(filename)) { ++ char *fname = estrndup(filename, len); ++ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ ++ if (strstr(filename, "://")) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ ++ /* no black or whitelist then disallow all */ ++ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* whitelist is stronger than blacklist */ ++ if (HG(include_whitelist)) { ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ zend_bool isOk = 0; ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_whitelist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ isOk = 1; ++ break; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_whitelist)); ++ } while (1); ++ ++ /* not found in whitelist */ ++ if (!isOk) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); ++ efree(fname); ++ return 0; ++ } ++ ++ s = h + 3; ++ } while (1); ++ } else { ++ /* okay then handle the blacklist */ ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_blacklist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); ++ efree(fname); ++ return 0; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_blacklist)); ++ } while (1); ++ ++ s = h + 3; ++ } while (1); ++ } ++ ++ efree(fname); ++ } ++ ++ /* 4. must not be an uploaded file */ ++ if (SG(rfc1867_uploaded_files)) { ++ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { ++ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); ++ return (0); ++ } ++ } ++ ++ /* passed all tests */ ++ return (1); ++} ++ ++#endif ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.4/main/hardening_patch.h hardening-patch-4.4.4-0.4.15/main/hardening_patch.h +--- php-4.4.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.h 2006-09-07 18:51:06.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENING_PATCH_H ++#define HARDENING_PATCH_H ++ ++#include "zend.h" ++ ++#if HARDENING_PATCH ++PHPAPI void php_security_log(int loglevel, char *fmt, ...); ++PHPAPI void hardened_startup(); ++#define HARDENING_PATCH_VERSION "0.4.15" ++ ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++PHPAPI unsigned int php_canary(); ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++PHPAPI int php_is_valid_include(zval *z); ++#endif ++ ++#endif /* HARDENING_PATCH_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-4.4.4/main/hardening_patch.m4 hardening-patch-4.4.4-0.4.15/main/hardening_patch.m4 +--- php-4.4.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.m4 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,95 @@ ++dnl ++dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ ++dnl ++dnl This file contains Hardening Patch for PHP specific autoconf functions. ++dnl ++ ++AC_ARG_ENABLE(hardening-patch-mm-protect, ++[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-ll-protect, ++[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-inc-protect, ++[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-fmt-protect, ++[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-hash-protect, ++[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++]) ++ ++AC_MSG_CHECKING(whether to protect the Zend Memory Manager) ++AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the Zend Linked Lists) ++AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect include/require statements) ++AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect PHP Format String functions) ++AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) ++AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) ++ ++ ++AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) ++fi ++ +diff -Nura php-4.4.4/main/main.c hardening-patch-4.4.4-0.4.15/main/main.c +--- php-4.4.4/main/main.c 2006-05-19 00:36:14.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/main/main.c 2006-09-05 20:30:51.000000000 +0200 +@@ -92,6 +92,10 @@ + PHPAPI int core_globals_id; + #endif + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#endif ++ + #define ERROR_BUF_LEN 1024 + + typedef struct { +@@ -142,17 +146,39 @@ + */ + static PHP_INI_MH(OnChangeMemoryLimit) + { ++#if HARDENING_PATCH ++ long hard_memory_limit = 1<<30; ++ ++ if (stage == ZEND_INI_STAGE_RUNTIME) { ++ if (HG(hard_memory_limit) == 0) { ++ HG(hard_memory_limit) = PG(memory_limit); ++ } ++ hard_memory_limit = HG(hard_memory_limit); ++ } else { ++ HG(hard_memory_limit) = 0; ++ } ++#endif + if (new_value) { + PG(memory_limit) = zend_atoi(new_value, new_value_length); ++#if HARDENING_PATCH ++ if (PG(memory_limit) > hard_memory_limit) { ++ PG(memory_limit) = hard_memory_limit; ++ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); ++ return FAILURE; ++ } ++#endif + } else { ++#if HARDENING_PATCH ++ PG(memory_limit) = hard_memory_limit; ++#else + PG(memory_limit) = 1<<30; /* effectively, no limit */ ++#endif + } + return zend_set_memory_limit(PG(memory_limit)); + } + /* }}} */ + #endif + +- + /* {{{ php_disable_functions + */ + static void php_disable_functions(TSRMLS_D) +@@ -1008,6 +1034,9 @@ + + zend_try { + shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); ++#if HARDENING_PATCH ++ hardened_clear_mm_canaries(TSRMLS_C); ++#endif + } zend_end_try(); + + zend_try { +@@ -1098,6 +1127,10 @@ + tsrm_ls = ts_resource(0); + #endif + ++#if HARDENING_PATCH ++ hardened_startup(); ++#endif ++ + sapi_initialize_empty_request(TSRMLS_C); + sapi_activate(TSRMLS_C); + +@@ -1109,6 +1142,12 @@ + + php_output_startup(); + ++#if HARDENING_PATCH_INC_PROTECT ++ zuf.is_valid_include = php_is_valid_include; ++#endif ++#if HARDENING_PATCH ++ zuf.security_log_function = php_security_log; ++#endif + zuf.error_function = php_error_cb; + zuf.printf_function = php_printf; + zuf.write_function = php_body_write_wrapper; +@@ -1210,6 +1249,10 @@ + REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS); + 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); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); ++#endif + REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); +@@ -1317,7 +1360,7 @@ + */ + static inline void php_register_server_variables(TSRMLS_D) + { +- zval *array_ptr=NULL; ++ zval *array_ptr=NULL, *vptr; + + ALLOC_ZVAL(array_ptr); + array_init(array_ptr); +diff -Nura php-4.4.4/main/php_config.h.in hardening-patch-4.4.4-0.4.15/main/php_config.h.in +--- php-4.4.4/main/php_config.h.in 2006-08-15 14:01:21.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/main/php_config.h.in 2006-09-05 20:30:51.000000000 +0200 +@@ -1,4 +1,4 @@ +-/* main/php_config.h.in. Generated automatically from configure.in by autoheader. */ ++/* main/php_config.h.in. Generated automatically from configure.in by autoheader 2.13. */ + /* Leave this file alone */ + #define ZEND_API + #define ZEND_DLEXPORT +@@ -865,6 +865,39 @@ + /* Enabling BIND8 compatibility for Panther */ + #undef BIND_8_COMPAT + ++/* Hardening-Patch */ ++#undef HARDENING_PATCH ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ + /* Whether you have AOLserver */ + #undef HAVE_AOLSERVER + +@@ -1148,6 +1181,12 @@ + /* Define if you have the getaddrinfo function */ + #undef HAVE_GETADDRINFO + ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ + /* Whether system headers declare timezone */ + #undef HAVE_DECLARED_TIMEZONE + +diff -Nura php-4.4.4/main/php_content_types.c hardening-patch-4.4.4-0.4.15/main/php_content_types.c +--- php-4.4.4/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/php_content_types.c 2006-09-05 20:30:51.000000000 +0200 +@@ -77,6 +77,7 @@ + sapi_register_post_entries(php_post_entries); + sapi_register_default_post_reader(php_default_post_reader); + sapi_register_treat_data(php_default_treat_data); ++ sapi_register_input_filter(php_default_input_filter); + return SUCCESS; + } + /* }}} */ +diff -Nura php-4.4.4/main/php.h hardening-patch-4.4.4-0.4.15/main/php.h +--- php-4.4.4/main/php.h 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/php.h 2006-09-05 20:30:51.000000000 +0200 +@@ -35,11 +35,19 @@ + #include "zend_qsort.h" + #include "php_compat.h" + ++ + #include "zend_API.h" + + #undef sprintf + #define sprintf php_sprintf + ++#if HARDENING_PATCH ++#if HAVE_REALPATH ++#undef realpath ++#define realpath php_realpath ++#endif ++#endif ++ + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ + #undef PHP_DEBUG + #define PHP_DEBUG ZEND_DEBUG +@@ -409,6 +417,10 @@ + #endif + #endif /* !XtOffsetOf */ + ++#if HARDENING_PATCH ++#include "hardening_patch.h" ++#endif ++ + #endif + + /* +diff -Nura php-4.4.4/main/php_variables.c hardening-patch-4.4.4-0.4.15/main/php_variables.c +--- php-4.4.4/main/php_variables.c 2006-02-13 13:19:10.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/php_variables.c 2006-09-05 20:30:51.000000000 +0200 +@@ -238,17 +238,28 @@ + while (var) { + val = strchr(var, '='); + if (val) { /* have a value */ +- int val_len; ++ unsigned int val_len, new_val_len; + + *val++ = '\0'; + php_url_decode(var, strlen(var)); + val_len = php_url_decode(val, strlen(val)); +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } + var = php_strtok_r(NULL, "&", &strtok_buf); + } + } + ++SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) ++{ ++ /* TODO: check .ini setting here and apply user-defined input filter */ ++ *new_val_len = val_len; ++ return 1; ++} ++ + SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) + { + char *res = NULL, *var, *val, *separator=NULL; +@@ -326,15 +337,26 @@ + while (var) { + val = strchr(var, '='); + if (val) { /* have a value */ +- int val_len; ++ unsigned int val_len, new_val_len; + + *val++ = '\0'; + php_url_decode(var, strlen(var)); + val_len = php_url_decode(val, strlen(val)); +- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); ++ val = estrndup(val, val_len); ++ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } else { ++ unsigned int val_len, new_val_len; ++ + php_url_decode(var, strlen(var)); +- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC); ++ val_len = 0; ++ val = estrndup("", 0); ++ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { ++ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); ++ } ++ efree(val); + } + var = php_strtok_r(NULL, separator, &strtok_buf); + } +diff -Nura php-4.4.4/main/rfc1867.c hardening-patch-4.4.4-0.4.15/main/rfc1867.c +--- php-4.4.4/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/rfc1867.c 2006-09-05 20:30:51.000000000 +0200 +@@ -128,6 +128,8 @@ + #define UPLOAD_ERROR_D 4 /* No file uploaded */ + #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ + #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ ++#define UPLOAD_ERROR_X 99 /* Filter forbids upload */ ++ + + void php_rfc1867_register_constants(TSRMLS_D) + { +@@ -138,6 +140,7 @@ + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); + } + + static void normalize_protected_variable(char *varname TSRMLS_DC) +@@ -849,6 +852,7 @@ + char buff[FILLUNIT]; + char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; + int blen=0, wlen=0; ++ unsigned long offset; + + zend_llist_clean(&header); + +@@ -897,21 +901,24 @@ + if (!filename && param) { + + char *value = multipart_buffer_read_body(mbuff TSRMLS_CC); ++ unsigned int new_val_len; /* Dummy variable */ + + if (!value) { + value = estrdup(""); + } + ++ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) { + #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) +- if (php_mb_encoding_translation(TSRMLS_C)) { +- php_mb_gpc_stack_variable(param, value, &val_list, &len_list, +- &num_vars, &num_vars_max TSRMLS_CC); +- } else { +- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); +- } ++ if (php_mb_encoding_translation(TSRMLS_C)) { ++ php_mb_gpc_stack_variable(param, value, &val_list, &len_list, ++ &num_vars, &num_vars_max TSRMLS_CC); ++ } else { ++ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); ++ } + #else +- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); ++ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); + #endif ++ } + if (!strcasecmp(param, "MAX_FILE_SIZE")) { + max_file_size = atol(value); + } +@@ -963,7 +970,11 @@ + tmp++; + } + } +- ++ ++ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { ++ skip_upload = 1; ++ } ++ + total_bytes = cancel_upload = 0; + + if (!skip_upload) { +@@ -987,6 +998,11 @@ + cancel_upload = UPLOAD_ERROR_D; + } + ++ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ ++ offset = 0; + end = 0; + while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) + { +@@ -997,6 +1013,11 @@ + sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); + cancel_upload = UPLOAD_ERROR_B; + } else if (blen > 0) { ++ ++ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + wlen = write(fd, buff, blen); + + if (wlen < blen) { +@@ -1004,6 +1025,7 @@ + cancel_upload = UPLOAD_ERROR_F; + } else { + total_bytes += wlen; ++ offset += wlen; + } + } + } +@@ -1025,6 +1047,10 @@ + } + #endif + ++ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + if (cancel_upload) { + if (temp_filename) { + if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ +diff -Nura php-4.4.4/main/SAPI.c hardening-patch-4.4.4-0.4.15/main/SAPI.c +--- php-4.4.4/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/SAPI.c 2006-09-05 20:30:51.000000000 +0200 +@@ -854,6 +854,37 @@ + return SUCCESS; + } + ++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)) ++{ ++ sapi_module.input_filter = input_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) ++{ ++ sapi_module.upload_varname_filter = upload_varname_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) ++{ ++ sapi_module.pre_upload_filter = pre_upload_filter; ++ return SUCCESS; ++} ++ ++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)) ++{ ++ sapi_module.upload_content_filter = upload_content_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) ++{ ++ sapi_module.post_upload_filter = post_upload_filter; ++ return SUCCESS; ++} ++ ++ + + SAPI_API int sapi_flush(TSRMLS_D) + { +diff -Nura php-4.4.4/main/SAPI.h hardening-patch-4.4.4-0.4.15/main/SAPI.h +--- php-4.4.4/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/SAPI.h 2006-09-05 20:30:51.000000000 +0200 +@@ -101,9 +101,10 @@ + char *current_user; + int current_user_length; + +- /* this is necessary for CLI module */ +- int argc; +- char **argv; ++ /* this is necessary for CLI module */ ++ int argc; ++ char **argv; ++ + } sapi_request_info; + + +@@ -177,6 +178,10 @@ + SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); + SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); + SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); + + SAPI_API int sapi_flush(TSRMLS_D); + SAPI_API struct stat *sapi_get_stat(TSRMLS_D); +@@ -238,8 +243,16 @@ + int (*get_target_uid)(uid_t * TSRMLS_DC); + int (*get_target_gid)(gid_t * TSRMLS_DC); + ++ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); ++ ++ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); ++ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); ++ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); ++ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); ++ + void (*ini_defaults)(HashTable *configuration_hash); + int phpinfo_as_text; ++ + }; + + +@@ -262,16 +275,27 @@ + + #define SAPI_DEFAULT_MIMETYPE "text/html" + #define SAPI_DEFAULT_CHARSET "" ++ ++#if HARDENING_PATCH ++#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" ++#else + #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION ++#endif + + #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) + #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) + + #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) ++#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) ++#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) ++#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) ++#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) ++#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) + + SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); + SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); + SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); ++SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter); + + #define STANDARD_SAPI_MODULE_PROPERTIES + +diff -Nura php-4.4.4/main/snprintf.c hardening-patch-4.4.4-0.4.15/main/snprintf.c +--- php-4.4.4/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/snprintf.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1014,7 +1014,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = cc; ++#endif + break; + + /* +diff -Nura php-4.4.4/main/spprintf.c hardening-patch-4.4.4-0.4.15/main/spprintf.c +--- php-4.4.4/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/main/spprintf.c 2006-09-05 20:30:51.000000000 +0200 +@@ -630,7 +630,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = xbuf->len; ++#endif + break; + + /* +diff -Nura php-4.4.4/php.ini-dist hardening-patch-4.4.4-0.4.15/php.ini-dist +--- php-4.4.4/php.ini-dist 2005-12-30 18:19:43.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/php.ini-dist 2006-09-05 20:30:51.000000000 +0200 +@@ -1114,6 +1114,209 @@ + ;exif.decode_jis_motorola = JIS + ;exif.decode_jis_intel = JIS + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-4.4.4/php.ini-recommended hardening-patch-4.4.4-0.4.15/php.ini-recommended +--- php-4.4.4/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/php.ini-recommended 2006-09-05 20:30:51.000000000 +0200 +@@ -1112,6 +1112,209 @@ + ;exif.decode_jis_motorola = JIS + ;exif.decode_jis_intel = JIS + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-4.4.4/README.input_filter hardening-patch-4.4.4-0.4.15/README.input_filter +--- php-4.4.4/README.input_filter 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/README.input_filter 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,193 @@ ++Input Filter Support ported from PHP 5 ++-------------------------------------- ++ ++XSS (Cross Site Scripting) hacks are becoming more and more prevalent, ++and can be quite difficult to prevent. Whenever you accept user data ++and somehow display this data back to users, you are likely vulnerable ++to XSS hacks. ++ ++The Input Filter support in PHP 5 is aimed at providing the framework ++through which a company-wide or site-wide security policy can be ++enforced. It is implemented as a SAPI hook and is called from the ++treat_data and post handler functions. To implement your own security ++policy you will need to write a standard PHP extension. ++ ++A simple implementation might look like the following. This stores the ++original raw user data and adds a my_get_raw() function while the normal ++$_POST, $_GET and $_COOKIE arrays are only populated with stripped ++data. In this simple example all I am doing is calling strip_tags() on ++the data. If register_globals is turned on, the default globals that ++are created will be stripped ($foo) while a $RAW_foo is created with the ++original user input. ++ ++ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) ++ zval *post_array; ++ zval *get_array; ++ zval *cookie_array; ++ZEND_END_MODULE_GLOBALS(my_input_filter) ++ ++#ifdef ZTS ++#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v) ++#else ++#define IF_G(v) (my_input_filter_globals.v) ++#endif ++ ++ZEND_DECLARE_MODULE_GLOBALS(my_input_filter) ++ ++function_entry my_input_filter_functions[] = { ++ PHP_FE(my_get_raw, NULL) ++ {NULL, NULL, NULL} ++}; ++ ++zend_module_entry my_input_filter_module_entry = { ++ STANDARD_MODULE_HEADER, ++ "my_input_filter", ++ my_input_filter_functions, ++ PHP_MINIT(my_input_filter), ++ PHP_MSHUTDOWN(my_input_filter), ++ NULL, ++ PHP_RSHUTDOWN(my_input_filter), ++ PHP_MINFO(my_input_filter), ++ "0.1", ++ STANDARD_MODULE_PROPERTIES ++}; ++ ++PHP_MINIT_FUNCTION(my_input_filter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL); ++ ++ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); ++ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); ++ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); ++ ++ sapi_register_input_filter(my_sapi_input_filter); ++ return SUCCESS; ++} ++ ++PHP_RSHUTDOWN_FUNCTION(my_input_filter) ++{ ++ if(IF_G(get_array)) { ++ zval_ptr_dtor(&IF_G(get_array)); ++ IF_G(get_array) = NULL; ++ } ++ if(IF_G(post_array)) { ++ zval_ptr_dtor(&IF_G(post_array)); ++ IF_G(post_array) = NULL; ++ } ++ if(IF_G(cookie_array)) { ++ zval_ptr_dtor(&IF_G(cookie_array)); ++ IF_G(cookie_array) = NULL; ++ } ++ return SUCCESS; ++} ++ ++PHP_MINFO_FUNCTION(my_input_filter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); ++ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $"); ++ php_info_print_table_end(); ++} ++ ++/* The filter handler. If you return 1 from it, then PHP also registers the ++ * (modified) variable. Returning 0 prevents PHP from registering the variable; ++ * you can use this if your filter already registers the variable under a ++ * different name, or if you just don't want the variable registered at all. */ ++SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter) ++{ ++ zval new_var; ++ zval *array_ptr = NULL; ++ char *raw_var; ++ int var_len; ++ ++ assert(*val != NULL); ++ ++ switch(arg) { ++ case PARSE_GET: ++ if(!IF_G(get_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(get_array) = array_ptr; ++ break; ++ case PARSE_POST: ++ if(!IF_G(post_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(post_array) = array_ptr; ++ break; ++ case PARSE_COOKIE: ++ if(!IF_G(cookie_array)) { ++ ALLOC_ZVAL(array_ptr); ++ array_init(array_ptr); ++ INIT_PZVAL(array_ptr); ++ } ++ IF_G(cookie_array) = array_ptr; ++ break; ++ } ++ Z_STRLEN(new_var) = val_len; ++ Z_STRVAL(new_var) = estrndup(*val, val_len); ++ Z_TYPE(new_var) = IS_STRING; ++ ++ var_len = strlen(var); ++ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ ++ strcpy(raw_var, "RAW_"); ++ strlcat(raw_var,var,var_len+5); ++ ++ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC); ++ ++ php_strip_tags(*val, val_len, NULL, NULL, 0); ++ ++ *new_val_len = strlen(*val); ++ return 1; ++} ++ ++PHP_FUNCTION(my_get_raw) ++{ ++ long arg; ++ char *var; ++ int var_len; ++ zval **tmp; ++ zval *array_ptr = NULL; ++ HashTable *hash_ptr; ++ char *raw_var; ++ ++ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) { ++ return; ++ } ++ ++ switch(arg) { ++ case PARSE_GET: ++ array_ptr = IF_G(get_array); ++ break; ++ case PARSE_POST: ++ array_ptr = IF_G(post_array); ++ break; ++ case PARSE_COOKIE: ++ array_ptr = IF_G(post_array); ++ break; ++ } ++ ++ if(!array_ptr) RETURN_FALSE; ++ ++ /* ++ * I'm changing the variable name here because when running with register_globals on, ++ * the variable will end up in the global symbol table ++ */ ++ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ ++ strcpy(raw_var, "RAW_"); ++ strlcat(raw_var,var,var_len+5); ++ hash_ptr = HASH_OF(array_ptr); ++ ++ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) { ++ *return_value = **tmp; ++ zval_copy_ctor(return_value); ++ } else { ++ RETVAL_FALSE; ++ } ++ efree(raw_var); ++} ++ +diff -Nura php-4.4.4/run-tests.php hardening-patch-4.4.4-0.4.15/run-tests.php +--- php-4.4.4/run-tests.php 2006-01-18 18:59:41.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/run-tests.php 2006-09-05 20:30:51.000000000 +0200 +@@ -152,6 +152,10 @@ + 'error_reporting=2047', + 'display_errors=1', + 'log_errors=0', ++ 'hphp.executor.include.whitelist=cookietest', ++ 'hphp.log.syslog=0', ++ 'hphp.log.sapi=0', ++ 'hphp.log.script=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=1', +diff -Nura php-4.4.4/sapi/apache/mod_php4.c hardening-patch-4.4.4-0.4.15/sapi/apache/mod_php4.c +--- php-4.4.4/sapi/apache/mod_php4.c 2006-05-13 23:42:14.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/sapi/apache/mod_php4.c 2006-09-05 20:30:51.000000000 +0200 +@@ -451,7 +451,7 @@ + sapi_apache_get_fd, + sapi_apache_force_http_10, + sapi_apache_get_target_uid, +- sapi_apache_get_target_gid ++ sapi_apache_get_target_gid, + }; + /* }}} */ + +@@ -897,7 +897,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component("PHP/" PHP_VERSION); ++#endif + } + } + #endif +diff -Nura php-4.4.4/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.4-0.4.15/sapi/apache2filter/sapi_apache2.c +--- php-4.4.4/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:30:51.000000000 +0200 +@@ -562,7 +562,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-4.4.4/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.4-0.4.15/sapi/apache2handler/sapi_apache2.c +--- php-4.4.4/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:30:51.000000000 +0200 +@@ -340,7 +340,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-4.4.4/sapi/cgi/cgi_main.c hardening-patch-4.4.4-0.4.15/sapi/cgi/cgi_main.c +--- php-4.4.4/sapi/cgi/cgi_main.c 2006-02-22 16:11:53.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1435,11 +1435,19 @@ + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } ++#if HARDENING_PATCH ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif ++#else + #if ZEND_DEBUG + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #else + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #endif ++#endif + php_end_ob_buffers(1 TSRMLS_CC); + exit(0); + break; +diff -Nura php-4.4.4/sapi/cli/php_cli.c hardening-patch-4.4.4-0.4.15/sapi/cli/php_cli.c +--- php-4.4.4/sapi/cli/php_cli.c 2006-05-18 22:33:46.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:30:51.000000000 +0200 +@@ -656,11 +656,19 @@ + if (php_request_startup(TSRMLS_C)==FAILURE) { + goto err; + } ++#if HARDENING_PATCH ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif ++#else + #if ZEND_DEBUG + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #else + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + #endif ++#endif + php_end_ob_buffers(1 TSRMLS_CC); + exit_status=0; + goto out; +diff -Nura php-4.4.4/TSRM/TSRM.h hardening-patch-4.4.4-0.4.15/TSRM/TSRM.h +--- php-4.4.4/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/TSRM/TSRM.h 2006-09-05 20:30:51.000000000 +0200 +@@ -33,6 +33,13 @@ + # define TSRM_API + #endif + ++#if HARDENING_PATCH ++# if HAVE_REALPATH ++# undef realpath ++# define realpath php_realpath ++# endif ++#endif ++ + /* Only compile multi-threading functions if we're in ZTS mode */ + #ifdef ZTS + +@@ -84,6 +91,7 @@ + + #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts + ++ + #ifdef __cplusplus + extern "C" { + #endif +diff -Nura php-4.4.4/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.c +--- php-4.4.4/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:30:51.000000000 +0200 +@@ -179,6 +179,178 @@ + return p; + } + ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved) ++{ ++ struct stat sb; ++ char *p, *q, *s; ++ size_t left_len, resolved_len; ++ unsigned symlinks; ++ int serrno, slen; ++ int is_dir = 1; ++ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; ++ ++ serrno = errno; ++ symlinks = 0; ++ if (path[0] == '/') { ++ resolved[0] = '/'; ++ resolved[1] = '\0'; ++ if (path[1] == '\0') ++ return (resolved); ++ resolved_len = 1; ++ left_len = strlcpy(left, path + 1, sizeof(left)); ++ } else { ++ if (getcwd(resolved, PATH_MAX) == NULL) { ++ strlcpy(resolved, ".", PATH_MAX); ++ return (NULL); ++ } ++ resolved_len = strlen(resolved); ++ left_len = strlcpy(left, path, sizeof(left)); ++ } ++ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ ++ /* ++ * Iterate over path components in `left'. ++ */ ++ while (left_len != 0) { ++ /* ++ * Extract the next path component and adjust `left' ++ * and its length. ++ */ ++ p = strchr(left, '/'); ++ s = p ? p : left + left_len; ++ if (s - left >= sizeof(next_token)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ memcpy(next_token, left, s - left); ++ next_token[s - left] = '\0'; ++ left_len -= s - left; ++ if (p != NULL) ++ memmove(left, s + 1, left_len + 1); ++ if (resolved[resolved_len - 1] != '/') { ++ if (resolved_len + 1 >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ resolved[resolved_len++] = '/'; ++ resolved[resolved_len] = '\0'; ++ } ++ if (next_token[0] == '\0') ++ continue; ++ else if (strcmp(next_token, ".") == 0) ++ continue; ++ else if (strcmp(next_token, "..") == 0) { ++ /* ++ * Strip the last path component except when we have ++ * single "/" ++ */ ++ if (!is_dir) { ++ errno = ENOENT; ++ return (NULL); ++ } ++ if (resolved_len > 1) { ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ continue; ++ } ++ ++ /* ++ * Append the next path component and lstat() it. If ++ * lstat() fails we still can return successfully if ++ * there are no more path components left. ++ */ ++ resolved_len = strlcat(resolved, next_token, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ if (lstat(resolved, &sb) != 0) { ++ if (errno == ENOENT) { ++ if (p == NULL) { ++ errno = serrno; ++ return (resolved); ++ } else ++ /* dirty hack to support a vanilla PHP feature */ ++ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { ++ resolved_len = strlcat(resolved, "/", PATH_MAX); ++ resolved_len = strlcat(resolved, left, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ errno = serrno; ++ return (resolved); ++ } ++ } ++ return (NULL); ++ } ++ if (S_ISLNK(sb.st_mode)) { ++ if (symlinks++ > MAXSYMLINKS) { ++ errno = ELOOP; ++ return (NULL); ++ } ++ slen = readlink(resolved, symlink, sizeof(symlink) - 1); ++ if (slen < 0) ++ return (NULL); ++ symlink[slen] = '\0'; ++ if (symlink[0] == '/') { ++ resolved[1] = 0; ++ resolved_len = 1; ++ } else if (resolved_len > 1) { ++ /* Strip the last path component. */ ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ ++ /* ++ * If there are any path components left, then ++ * append them to symlink. The result is placed ++ * in `left'. ++ */ ++ if (p != NULL) { ++ if (symlink[slen - 1] != '/') { ++ if (slen + 1 >= sizeof(symlink)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ symlink[slen] = '/'; ++ symlink[slen + 1] = 0; ++ } ++ left_len = strlcat(symlink, left, sizeof(left)); ++ if (left_len >= sizeof(left)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ } ++ left_len = strlcpy(left, symlink, sizeof(left)); ++ } else { ++ if (S_ISDIR(sb.st_mode)) { ++ is_dir = 1; ++ } else { ++ is_dir = 0; ++ } ++ } ++ } ++ ++ /* ++ * Remove trailing slash except when the resolved pathname ++ * is a single "/". ++ */ ++ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') ++ resolved[resolved_len - 1] = '\0'; ++ return (resolved); ++} ++#endif ++ + CWD_API void virtual_cwd_startup(void) + { + char cwd[MAXPATHLEN]; +@@ -300,8 +472,11 @@ + + if (path_length == 0) + return (0); +- if (path_length >= MAXPATHLEN) ++ if (path_length >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return (1); ++ } + + #if !defined(TSRM_WIN32) && !defined(NETWARE) + /* cwd_length can be 0 when getcwd() fails. +@@ -313,8 +488,9 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + } else { /* Concat current directory with relative path and then run realpath() on it */ +@@ -323,6 +499,8 @@ + + ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); + if (!tmp) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(ptr, state->cwd, state->cwd_length); +@@ -332,6 +510,8 @@ + ptr += path_length; + *ptr = '\0'; + if (strlen(tmp) >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + free(tmp); + return 1; + } +@@ -340,9 +520,10 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + free(tmp); +- return 1; */ ++ return 1; + } + } + free(tmp); +diff -Nura php-4.4.4/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.h +--- php-4.4.4/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:30:51.000000000 +0200 +@@ -128,6 +128,22 @@ + + typedef int (*verify_path_func)(const cwd_state *); + ++#ifndef HAVE_STRLCPY ++CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); ++#undef strlcpy ++#define strlcpy php_strlcpy ++#endif ++ ++#ifndef HAVE_STRLCAT ++CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); ++#undef strlcat ++#define strlcat php_strlcat ++#endif ++ ++ ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved); ++#endif + CWD_API void virtual_cwd_startup(void); + CWD_API void virtual_cwd_shutdown(void); + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); +diff -Nura php-4.4.4/Zend/zend_alloc.c hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.c +--- php-4.4.4/Zend/zend_alloc.c 2006-08-10 19:27:12.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.c 2006-09-05 20:30:51.000000000 +0200 +@@ -56,6 +56,11 @@ + # define END_MAGIC_SIZE 0 + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++# define CANARY_SIZE sizeof(unsigned int) ++#else ++# define CANARY_SIZE 0 ++#endif + + # if MEMORY_LIMIT + # if ZEND_DEBUG +@@ -104,9 +109,17 @@ + if (p==AG(head)) { \ + AG(head) = p->pNext; \ + } else { \ ++ if (p != p->pLast->pNext) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pLast->pNext = p->pNext; \ + } \ + if (p->pNext) { \ ++ if (p != p->pNext->pLast) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pNext->pLast = p->pLast; \ + } + +@@ -138,6 +151,12 @@ + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { ++ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); ++ exit(1); ++ } ++#endif + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + + if (size > INT_MAX || SIZE < size) { +@@ -159,6 +178,10 @@ + AG(cache_stats)[CACHE_INDEX][1]++; + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->cached = 0; + p->size = size; + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); +@@ -174,7 +197,7 @@ + AG(allocated_memory_peak) = AG(allocated_memory); + } + #endif +- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); + } + + emalloc_error: +@@ -206,7 +229,10 @@ + # endif + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif +- ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } +@@ -233,17 +259,36 @@ + return emalloc_rel(lval + offset); + } + } +- ++ ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); ++#endif + zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset); + return 0; + } + + ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++efree_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); ++ exit(1); ++ } ++ /* to catch double efree()s */ ++ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); ++ p->canary = 0; ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring", +@@ -288,6 +333,9 @@ + size_t _size = nmemb * size; + + if (nmemb && (_size/nmemb!=size)) { ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); ++#endif + fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); + #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID + kill(getpid(), SIGSEGV); +@@ -307,6 +355,9 @@ + + ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p; + zend_mem_header *orig; + DECLARE_CACHE_VARS(); +@@ -318,6 +369,16 @@ + + p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++erealloc_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); ++ exit(1); ++ } ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + void *new_p; +@@ -348,7 +409,7 @@ + } + #endif + REMOVE_POINTER_FROM_LIST(p); +- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); + erealloc_error: + if (!p) { + if (!allow_failure) { +@@ -371,6 +432,9 @@ + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + + HANDLE_UNBLOCK_INTERRUPTIONS(); +@@ -445,6 +509,10 @@ + { + AG(head) = NULL; + ++#if HARDENING_PATCH_MM_PROTECT ++ HG(canary_1) = zend_canary(); ++ HG(canary_2) = zend_canary(); ++#endif + #if MEMORY_LIMIT + AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ + AG(allocated_memory) = 0; +diff -Nura php-4.4.4/Zend/zend_alloc.h hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.h +--- php-4.4.4/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.h 2006-09-05 20:30:51.000000000 +0200 +@@ -32,6 +32,9 @@ + #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL + + typedef struct _zend_mem_header { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary; ++#endif + #if ZEND_DEBUG + long magic; + char *filename; +diff -Nura php-4.4.4/Zend/zend_builtin_functions.c hardening-patch-4.4.4-0.4.15/Zend/zend_builtin_functions.c +--- php-4.4.4/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:30:51.000000000 +0200 +@@ -49,6 +49,9 @@ + static ZEND_FUNCTION(crash); + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++static ZEND_FUNCTION(heap_overflow); ++#endif + static ZEND_FUNCTION(get_included_files); + static ZEND_FUNCTION(is_subclass_of); + static ZEND_FUNCTION(is_a); +@@ -101,6 +104,9 @@ + ZEND_FE(crash, NULL) + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ ZEND_FE(heap_overflow, NULL) ++#endif + ZEND_FE(get_included_files, NULL) + ZEND_FALIAS(get_required_files, get_included_files, NULL) + ZEND_FE(is_subclass_of, NULL) +@@ -805,6 +811,19 @@ + + #endif /* ZEND_DEBUG */ + ++ ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ZEND_FUNCTION(heap_overflow) ++{ ++ char *nowhere = emalloc(10); ++ ++ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); ++ ++ efree(nowhere); ++} ++#endif ++ ++ + /* {{{ proto array get_included_files(void) + Returns an array with the file names that were include_once()'d */ + ZEND_FUNCTION(get_included_files) +diff -Nura php-4.4.4/Zend/zend.c hardening-patch-4.4.4-0.4.15/Zend/zend.c +--- php-4.4.4/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend.c 2006-09-05 20:30:51.000000000 +0200 +@@ -53,6 +53,12 @@ + ZEND_API void (*zend_unblock_interruptions)(void); + ZEND_API void (*zend_ticks_function)(int ticks); + ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); ++#if HARDENING_PATCH ++ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + + void (*zend_on_timeout)(int seconds TSRMLS_DC); + +@@ -70,9 +76,391 @@ + return SUCCESS; + } + ++#if HARDENING_PATCH ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; ++ } else { ++ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_facility) = LOG_USER; ++ } else { ++ EG(hphp_log_syslog_facility) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_priority) = LOG_ALERT; ++ } else { ++ EG(hphp_log_syslog_priority) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_sapi) ++{ ++ if (!new_value) { ++ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; ++ } else { ++ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_script) ++{ ++ if (!new_value) { ++ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL); ++ } else { ++ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) ++{ ++ if (EG(hphp_log_scriptname)) { ++ pefree(EG(hphp_log_scriptname),1); ++ } ++ EG(hphp_log_scriptname) = NULL; ++ if (new_value) { ++ EG(hphp_log_scriptname) = pestrdup(new_value,1); ++ } ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_whitelist_destroy: ++ if (HG(include_whitelist)) { ++ zend_hash_destroy(HG(include_whitelist)); ++ pefree(HG(include_whitelist),1); ++ } ++ HG(include_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_whitelist_destroy; ++ } ++ ++ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_blacklist_destroy: ++ if (HG(include_blacklist)) { ++ zend_hash_destroy(HG(include_blacklist)); ++ pefree(HG(include_blacklist),1); ++ } ++ HG(include_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_blacklist_destroy; ++ } ++ ++ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_whitelist_destroy: ++ if (HG(eval_whitelist)) { ++ zend_hash_destroy(HG(eval_whitelist)); ++ pefree(HG(eval_whitelist),1); ++ } ++ HG(eval_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_whitelist_destroy; ++ } ++ ++ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_blacklist_destroy: ++ if (HG(eval_blacklist)) { ++ zend_hash_destroy(HG(eval_blacklist)); ++ pefree(HG(eval_blacklist), 1); ++ } ++ HG(eval_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_blacklist_destroy; ++ } ++ ++ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_whitelist_destroy: ++ if (HG(func_whitelist)) { ++ zend_hash_destroy(HG(func_whitelist)); ++ pefree(HG(func_whitelist),1); ++ } ++ HG(func_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_whitelist_destroy; ++ } ++ ++ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_blacklist_destroy: ++ if (HG(func_blacklist)) { ++ zend_hash_destroy(HG(func_blacklist)); ++ pefree(HG(func_blacklist),1); ++ } ++ HG(func_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_blacklist_destroy; ++ } ++ ++ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++#endif + + ZEND_INI_BEGIN() + ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) ++#if HARDENING_PATCH ++ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) ++ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) ++ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) ++ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) ++ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) ++ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) ++ 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) ++ ++ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) ++ ++ 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) ++ 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) ++ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) ++ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) ++#endif + ZEND_INI_END() + + +@@ -354,8 +742,12 @@ + zend_init_rsrc_plist(TSRMLS_C); + EG(lambda_count)=0; + EG(user_error_handler) = NULL; ++ EG(in_code_type) = 0; + EG(in_execution) = 0; + EG(current_execute_data) = NULL; ++#if HARDENING_PATCH ++ EG(hphp_log_scriptname) = NULL; ++#endif + } + + +@@ -420,6 +812,14 @@ + extern zend_scanner_globals language_scanner_globals; + #endif + ++ /* Set up Hardening-Patch utility functions first */ ++#if HARDENING_PATCH ++ zend_security_log = utility_functions->security_log_function; ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ zend_is_valid_include = utility_functions->is_valid_include; ++#endif ++ + #ifdef ZTS + ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + #else +@@ -619,6 +1019,7 @@ + } + CG(unclean_shutdown) = 1; + CG(in_compilation) = EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(current_execute_data) = NULL; + longjmp(EG(bailout), FAILURE); + } +diff -Nura php-4.4.4/Zend/zend_canary.c hardening-patch-4.4.4-0.4.15/Zend/zend_canary.c +--- php-4.4.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_canary.c 2006-09-05 20:30:51.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ ++ ++#include "zend.h" ++ ++#include ++#include ++ ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++ZEND_API unsigned int zend_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-4.4.4/Zend/zend_compile.c hardening-patch-4.4.4-0.4.15/Zend/zend_compile.c +--- php-4.4.4/Zend/zend_compile.c 2006-02-23 19:07:16.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_compile.c 2006-09-05 20:30:51.000000000 +0200 +@@ -768,6 +768,13 @@ + op_array.function_name = name; + op_array.arg_types = NULL; + op_array.return_reference = return_reference; ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array.created_by_eval = 1; ++ } else { ++ op_array.created_by_eval = 0; ++ } ++#endif + + if (is_method) { + if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { +diff -Nura php-4.4.4/Zend/zend_compile.h hardening-patch-4.4.4-0.4.15/Zend/zend_compile.h +--- php-4.4.4/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_compile.h 2006-09-05 20:30:51.000000000 +0200 +@@ -106,6 +106,9 @@ + char *filename; + + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; ++#if HARDENING_PATCH ++ zend_bool created_by_eval; ++#endif + }; + + +@@ -549,6 +552,7 @@ + #define ZEND_USER_FUNCTION 2 + #define ZEND_OVERLOADED_FUNCTION 3 + #define ZEND_EVAL_CODE 4 ++#define ZEND_SANDBOX_CODE 6 + + #define ZEND_INTERNAL_CLASS 1 + #define ZEND_USER_CLASS 2 +diff -Nura php-4.4.4/Zend/zend_constants.c hardening-patch-4.4.4-0.4.15/Zend/zend_constants.c +--- php-4.4.4/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_constants.c 2006-09-05 20:30:51.000000000 +0200 +@@ -111,6 +111,74 @@ + REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); + + REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); ++ ++ /* error levels */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); ++ /* facility: type of program logging the message */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NEWS ++ /* No LOG_NEWS on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ ++#endif ++#ifdef LOG_UUCP ++ /* No LOG_UUCP on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_CRON ++ /* apparently some systems don't have this one */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_AUTHPRIV ++ /* AIX doesn't have LOG_AUTHPRIV */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); ++#endif ++#if !defined(PHP_WIN32) && !defined(NETWARE) ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); ++#endif ++ /* options */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NOWAIT ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_PERROR ++ /* AIX doesn't have LOG_PERROR */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ ++#endif ++#endif + + /* true/false constants */ + { +diff -Nura php-4.4.4/Zend/zend_errors.h hardening-patch-4.4.4-0.4.15/Zend/zend_errors.h +--- php-4.4.4/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_errors.h 2006-09-05 20:30:51.000000000 +0200 +@@ -36,5 +36,18 @@ + #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) + #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) + ++#if HARDENING_PATCH ++#define S_MEMORY (1<<0L) ++#define S_VARS (1<<1L) ++#define S_FILES (1<<2L) ++#define S_INCLUDE (1<<3L) ++#define S_SQL (1<<4L) ++#define S_EXECUTOR (1<<5L) ++#define S_MAIL (1<<6L) ++#define S_MISC (1<<30L) ++#define S_INTERNAL (1<<29L) ++#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) ++#endif ++ + #endif /* ZEND_ERRORS_H */ + +diff -Nura php-4.4.4/Zend/zend_execute_API.c hardening-patch-4.4.4-0.4.15/Zend/zend_execute_API.c +--- php-4.4.4/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:30:51.000000000 +0200 +@@ -142,6 +142,7 @@ + EG(class_table) = CG(class_table); + + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + + zend_ptr_stack_init(&EG(argument_stack)); + +@@ -431,12 +432,14 @@ + zend_execute_data execute_data; + + /* Initialize execute_data */ ++ memset(&execute_data, 0, sizeof(execute_data)); + EX(fbc) = NULL; + EX(object).ptr = NULL; + EX(ce) = NULL; + EX(Ts) = NULL; + EX(op_array) = NULL; + EX(opline) = NULL; ++ EX(execute_depth) = 0; + + *retval_ptr_ptr = NULL; + +@@ -494,6 +497,39 @@ + zval_dtor(&function_name_copy); + return FAILURE; + } ++#if HARDENING_PATCH ++ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val); ++ zval_dtor(&function_name_copy); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + zval_dtor(&function_name_copy); + + for (i=0; itype = type; + EG(return_value_ptr_ptr) = &local_retval_ptr; + EG(active_op_array) = new_op_array; + EG(no_extensions)=1; +@@ -673,6 +709,10 @@ + return retval; + } + ++ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++{ ++ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); ++} + + void execute_new_code(TSRMLS_D) + { +diff -Nura php-4.4.4/Zend/zend_execute.c hardening-patch-4.4.4-0.4.15/Zend/zend_execute.c +--- php-4.4.4/Zend/zend_execute.c 2006-08-11 15:04:14.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1042,6 +1042,7 @@ + zend_execute_data execute_data; + + /* Initialize execute_data */ ++ memset(&execute_data, 0, sizeof(execute_data)); + EX(fbc) = NULL; + EX(ce) = NULL; + EX(object).ptr = NULL; +@@ -1053,9 +1054,21 @@ + } + EX(prev_execute_data) = EG(current_execute_data); + EX(original_in_execution)=EG(in_execution); ++ EX(original_in_code_type)=EG(in_code_type); + + EG(current_execute_data) = &execute_data; + ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif ++ + EG(in_execution) = 1; + if (op_array->start_op) { + EX(opline) = op_array->start_op; +@@ -1087,6 +1100,19 @@ + } + } + ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif ++ + while (1) { + #ifdef ZEND_WIN32 + if (EG(timed_out)) { +@@ -1634,6 +1660,36 @@ + if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) { + zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val); + } ++#if HARDENING_PATCH ++ if (active_function_table == EG(function_table)) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++#endif ++ + zval_dtor(&tmp); + EX(fbc) = function; + overloaded_function_call_cont: +@@ -1649,6 +1705,35 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); + zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce)); + EX(object).ptr = NULL; +@@ -1821,6 +1906,7 @@ + efree(EX(Ts)); + } + EG(in_execution) = EX(original_in_execution); ++ EG(in_code_type) = EX(original_in_code_type); + EG(current_execute_data) = EX(prev_execute_data); + return; + } +@@ -2210,7 +2296,12 @@ + int dummy = 1; + zend_file_handle file_handle = {0}; + ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS ++#else + if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS ++#endif + && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { + + file_handle.filename = inc_filename->value.str.val; +@@ -2239,6 +2330,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +diff -Nura php-4.4.4/Zend/zend_execute_globals.h hardening-patch-4.4.4-0.4.15/Zend/zend_execute_globals.h +--- php-4.4.4/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute_globals.h 2006-09-05 20:30:51.000000000 +0200 +@@ -60,6 +60,8 @@ + object_info object; + temp_variable *Ts; + zend_bool original_in_execution; ++ zend_uint original_in_code_type; ++ zend_uint execute_depth; + zend_op_array *op_array; + struct _zend_execute_data *prev_execute_data; + } zend_execute_data; +diff -Nura php-4.4.4/Zend/zend_extensions.c hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.c +--- php-4.4.4/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.c 2006-09-05 20:30:51.000000000 +0200 +@@ -54,23 +54,44 @@ + return FAILURE; + } + ++ /* check if module is compiled against Hardening-Patch */ ++ if (extension_version_info->zend_extension_api_no < 1000000000) { ++ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } ++ ++ ++ /* check if module is compiled against correct Hardening-Patch version */ ++ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { ++ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ extension_version_info->zend_extension_api_no, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } + + /* allow extension to proclaim compatibility with any Zend version */ +- 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)) { +- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { ++ 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)) { ++ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is outdated.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO); + DL_UNLOAD(handle); + return FAILURE; +- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { ++ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is newer.\n" + "Contact %s at %s for a later version of %s.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO, + new_extension->author, + new_extension->URL, +diff -Nura php-4.4.4/Zend/zend_extensions.h hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.h +--- php-4.4.4/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.h 2006-09-05 20:30:51.000000000 +0200 +@@ -23,6 +23,9 @@ + + #include "zend_compile.h" + ++/* Create own API version number for Hardening-Patch */ ++ ++#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805 + #define ZEND_EXTENSION_API_NO 20050606 + + typedef struct _zend_extension_version_info { +@@ -30,6 +33,7 @@ + char *required_zend_version; + unsigned char thread_safe; + unsigned char debug; ++ int real_zend_extension_api_no; + } zend_extension_version_info; + + +@@ -96,7 +100,7 @@ + + + #define ZEND_EXTENSION() \ +- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } ++ 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 } + + #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 + #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 +diff -Nura php-4.4.4/Zend/zend_globals.h hardening-patch-4.4.4-0.4.15/Zend/zend_globals.h +--- php-4.4.4/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_globals.h 2006-09-05 20:30:51.000000000 +0200 +@@ -163,6 +163,16 @@ + + int error_reporting; + int orig_error_reporting; ++#if HARDENING_PATCH ++ int hphp_log_syslog; ++ int hphp_log_syslog_facility; ++ int hphp_log_syslog_priority; ++ int hphp_log_sapi; ++ int hphp_log_script; ++ char *hphp_log_scriptname; ++ zend_bool hphp_log_use_x_forwarded_for; ++ long hphp_executor_max_depth; ++#endif + int exit_status; + + zend_op_array *active_op_array; +@@ -176,6 +186,7 @@ + int ticks_count; + + zend_bool in_execution; ++ zend_uint in_code_type; + zend_bool bailout_set; + zend_bool full_tables_cleanup; + +diff -Nura php-4.4.4/Zend/zend.h hardening-patch-4.4.4-0.4.15/Zend/zend.h +--- php-4.4.4/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend.h 2006-09-05 20:30:51.000000000 +0200 +@@ -274,9 +274,10 @@ + struct _zval_struct { + /* Variable information */ + zvalue_value value; /* value */ ++ zend_uint refcount; ++ zend_ushort flags; + zend_uchar type; /* active type */ + zend_uchar is_ref; +- zend_ushort refcount; + }; + + +@@ -337,6 +338,12 @@ + void (*ticks_function)(int ticks); + void (*on_timeout)(int seconds TSRMLS_DC); + zend_bool (*open_function)(const char *filename, struct _zend_file_handle *); ++#if HARDENING_PATCH ++ void (*security_log_function)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ int (*is_valid_include)(zval *z); ++#endif + } zend_utility_functions; + + +@@ -468,7 +475,16 @@ + extern ZEND_API void (*zend_ticks_function)(int ticks); + extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); + extern void (*zend_on_timeout)(int seconds TSRMLS_DC); ++#if HARDENING_PATCH ++extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++extern ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ZEND_API unsigned int zend_canary(void); ++#endif + + ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3); + +@@ -575,6 +591,11 @@ + + #define ZEND_MAX_RESERVED_RESOURCES 4 + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#include "php_syslog.h" ++#endif ++ + #endif /* ZEND_H */ + + /* +diff -Nura php-4.4.4/Zend/zend_hash.c hardening-patch-4.4.4-0.4.15/Zend/zend_hash.c +--- php-4.4.4/Zend/zend_hash.c 2006-02-01 10:11:55.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_hash.c 2006-09-05 20:30:51.000000000 +0200 +@@ -26,6 +26,17 @@ + # include + #endif + ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int zend_hash_canary = 0x1234567; ++ zend_bool zend_hash_canary_inited = 0; ++#endif ++ ++#define CHECK_HASH_CANARY(hash) \ ++ if (zend_hash_canary != (hash)->canary) { \ ++ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ ++ exit(1); \ ++ } ++ + #define HANDLE_NUMERIC(key, length, func) { \ + register char *tmp=key; \ + \ +@@ -175,6 +186,9 @@ + { + uint i = 3; + Bucket **tmp; ++#if HARDENING_PATCH_HASH_PROTECT ++ TSRMLS_FETCH(); ++#endif + + SET_INCONSISTENT(HT_OK); + +@@ -184,6 +198,13 @@ + + ht->nTableSize = 1 << i; + ht->nTableMask = ht->nTableSize - 1; ++#if HARDENING_PATCH_HASH_PROTECT ++ if (zend_hash_canary_inited==0) { ++ zend_hash_canary = zend_canary(); ++ zend_hash_canary_inited = 1; ++ } ++ ht->canary = zend_hash_canary; ++#endif + ht->pDestructor = pDestructor; + ht->pListHead = NULL; + ht->pListTail = NULL; +@@ -259,6 +280,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -327,6 +351,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -402,6 +429,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -450,7 +480,7 @@ + IS_CONSISTENT(ht); + + if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ +- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); ++ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); + if (t) { + HANDLE_BLOCK_INTERRUPTIONS(); + ht->arBuckets = t; +@@ -460,6 +490,7 @@ + HANDLE_UNBLOCK_INTERRUPTIONS(); + return SUCCESS; + } ++ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); + return FAILURE; + } + return SUCCESS; +@@ -526,6 +557,9 @@ + ht->pInternalPointer = p->pListNext; + } + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (!p->pDataPtr) { +@@ -555,6 +589,9 @@ + q = p; + p = p->pListNext; + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(q->pData); + } + if (!q->pDataPtr && q->pData) { +@@ -581,6 +618,9 @@ + q = p; + p = p->pListNext; + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(q->pData); + } + if (!q->pDataPtr && q->pData) { +@@ -610,6 +650,9 @@ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (!p->pDataPtr) { +diff -Nura php-4.4.4/Zend/zend_hash.h hardening-patch-4.4.4-0.4.15/Zend/zend_hash.h +--- php-4.4.4/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_hash.h 2006-09-05 20:30:51.000000000 +0200 +@@ -54,6 +54,9 @@ + } Bucket; + + typedef struct _hashtable { ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int canary; ++#endif + uint nTableSize; + uint nTableMask; + uint nNumOfElements; +diff -Nura php-4.4.4/Zend/zend_ini.c hardening-patch-4.4.4-0.4.15/Zend/zend_ini.c +--- php-4.4.4/Zend/zend_ini.c 2005-09-02 23:09:03.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:37.000000000 +0200 +@@ -256,7 +256,8 @@ + zend_ini_entry *ini_entry; + TSRMLS_FETCH(); + +- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { ++ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || ++ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifyable & ZEND_INI_USER) == 0)) { + return FAILURE; + } + +diff -Nura php-4.4.4/Zend/zend_ini.h hardening-patch-4.4.4-0.4.15/Zend/zend_ini.h +--- php-4.4.4/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_ini.h 2006-09-05 20:30:51.000000000 +0200 +@@ -174,6 +174,7 @@ + /* Standard message handlers */ + BEGIN_EXTERN_C() + ZEND_API ZEND_INI_MH(OnUpdateBool); ++#define OnUpdateLong OnUpdateInt + ZEND_API ZEND_INI_MH(OnUpdateInt); + ZEND_API ZEND_INI_MH(OnUpdateReal); + ZEND_API ZEND_INI_MH(OnUpdateString); +diff -Nura php-4.4.4/Zend/zend_language_scanner.l hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.l +--- php-4.4.4/Zend/zend_language_scanner.l 2006-04-13 15:52:24.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:30:51.000000000 +0200 +@@ -393,6 +393,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-4.4.4/Zend/zend_language_scanner.c hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.c +--- php-4.4.4/Zend/zend_language_scanner.c 2006-08-15 14:01:21.000000000 +0200 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:30:51.000000000 +0200 +@@ -3036,6 +3036,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-4.4.4/Zend/zend_llist.c hardening-patch-4.4.4-0.4.15/Zend/zend_llist.c +--- php-4.4.4/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_llist.c 2006-09-05 20:30:51.000000000 +0200 +@@ -21,9 +21,49 @@ + #include "zend.h" + #include "zend_llist.h" + #include "zend_qsort.h" ++#include "zend_globals.h" ++ ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int zend_llist_canary_1 = 0x1234567; ++ unsigned int zend_llist_canary_2 = 0x1553425; ++ zend_bool zend_llist_canary_inited = 0; ++#endif ++ ++#define CHECK_LIST_CANARY(list) \ ++ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ ++ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ ++ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++#define CHECK_LISTELEMENT_CANARY(elem, list) \ ++ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ ++ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ ++ exit(1); \ ++ } ++ + + ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ ++ if (persistent) { ++ if (!zend_llist_canary_inited) { ++ /* do not change order to ensure thread safety */ ++ zend_llist_canary_1 = zend_canary(); ++ zend_llist_canary_2 = zend_canary(); ++ zend_llist_canary_inited = 1; ++ } ++ } else ++ if (!HG(ll_canary_inited)) { ++ HG(canary_3) = zend_canary(); ++ HG(canary_4) = zend_canary(); ++ HG(ll_canary_inited) = 1; ++ } ++ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); ++ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); ++#endif + l->head = NULL; + l->tail = NULL; + l->count = 0; +@@ -37,6 +77,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->prev = l->tail; + tmp->next = NULL; + if (l->tail) { +@@ -55,6 +100,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->next = l->head; + tmp->prev = NULL; + if (l->head) { +@@ -91,10 +141,20 @@ + zend_llist_element *current=l->head; + zend_llist_element *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (compare(current->data, element)) { + DEL_LLIST_ELEMENT(current, l); ++#if HARDENING_PATCH_LL_PROTECT ++ current->canary = 0; ++#endif + break; + } + current = next; +@@ -106,7 +166,14 @@ + { + zend_llist_element *current=l->head, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (l->dtor) { + l->dtor(current->data); +@@ -131,7 +198,14 @@ + zend_llist_element *old_tail; + void *data; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if ((old_tail = l->tail)) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(old_tail, l) ++#endif + if (l->tail->prev) { + l->tail->prev->next = NULL; + } +@@ -157,9 +231,16 @@ + { + zend_llist_element *ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(src) ++#endif + zend_llist_init(dst, src->size, src->dtor, src->persistent); + ptr = src->head; + while (ptr) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(ptr, src) ++#endif + zend_llist_add_element(dst, ptr->data); + ptr = ptr->next; + } +@@ -170,11 +251,21 @@ + { + zend_llist_element *element, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + element=l->head; + while (element) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + next = element->next; + if (func(element->data)) { + DEL_LLIST_ELEMENT(element, l); ++#if HARDENING_PATCH_LL_PROTECT ++ element->canary = 0; ++#endif + } + element = next; + } +@@ -185,7 +276,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data TSRMLS_CC); + } + } +@@ -197,6 +294,9 @@ + zend_llist_element **elements; + zend_llist_element *element, **ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + if (l->count <= 0) { + return; + } +@@ -206,6 +306,9 @@ + ptr = &elements[0]; + + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + *ptr++ = element; + } + +@@ -228,7 +331,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, arg TSRMLS_CC); + } + } +@@ -239,8 +348,14 @@ + zend_llist_element *element; + va_list args; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + va_start(args, num_args); + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, num_args, args TSRMLS_CC); + } + va_end(args); +@@ -249,6 +364,10 @@ + + ZEND_API int zend_llist_count(zend_llist *l) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + return l->count; + } + +@@ -256,8 +375,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->head; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -269,8 +395,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->tail; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -282,9 +415,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->next; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +@@ -296,9 +439,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->prev; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +diff -Nura php-4.4.4/Zend/zend_llist.h hardening-patch-4.4.4-0.4.15/Zend/zend_llist.h +--- php-4.4.4/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_llist.h 2006-09-05 20:30:51.000000000 +0200 +@@ -24,6 +24,9 @@ + #include + + typedef struct _zend_llist_element { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary, padding; ++#endif + struct _zend_llist_element *next; + struct _zend_llist_element *prev; + char data[1]; /* Needs to always be last in the struct */ +@@ -36,6 +39,9 @@ + typedef void (*llist_apply_func_t)(void * TSRMLS_DC); + + typedef struct _zend_llist { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_h; /* head */ ++#endif + zend_llist_element *head; + zend_llist_element *tail; + size_t size; +@@ -43,6 +49,9 @@ + llist_dtor_func_t dtor; + unsigned char persistent; + zend_llist_element *traverse_ptr; ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_t; /* tail */ ++#endif + } zend_llist; + + typedef zend_llist_element* zend_llist_position; +diff -Nura php-4.4.4/Zend/zend_modules.h hardening-patch-4.4.4-0.4.15/Zend/zend_modules.h +--- php-4.4.4/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_modules.h 2006-09-05 20:30:51.000000000 +0200 +@@ -34,6 +34,7 @@ + ZEND_API extern unsigned char second_arg_force_ref[]; + ZEND_API extern unsigned char third_arg_force_ref[]; + ++#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112 + #define ZEND_MODULE_API_NO 20020429 + #ifdef ZTS + #define USING_ZTS 1 +@@ -41,9 +42,9 @@ + #define USING_ZTS 0 + #endif + +-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS ++#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS + +-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 ++#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO + + #define STANDARD_MODULE_PROPERTIES \ + NULL, NULL, STANDARD_MODULE_PROPERTIES_EX +@@ -75,6 +76,7 @@ + unsigned char type; + void *handle; + int module_number; ++ unsigned int real_zend_api; + }; + + +diff -Nura php-4.4.4/Zend/zend_opcode.c hardening-patch-4.4.4-0.4.15/Zend/zend_opcode.c +--- php-4.4.4/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_opcode.c 2006-09-05 20:30:51.000000000 +0200 +@@ -88,6 +88,9 @@ + op_array->done_pass_two = 0; + + op_array->start_op = NULL; ++#if HARDENING_PATCH ++ op_array->created_by_eval = 0; ++#endif + + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); + } +diff -Nura php-4.4.4/Zend/zend_operators.c hardening-patch-4.4.4-0.4.15/Zend/zend_operators.c +--- php-4.4.4/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_operators.c 2006-09-05 20:30:51.000000000 +0200 +@@ -1604,6 +1604,20 @@ + return (op->value.lval ? 1 : 0); + } + ++ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) ++{ ++ register unsigned char *str = (unsigned char*)source; ++ register unsigned char *result = (unsigned char*)dest; ++ register unsigned char *end = str + length; ++ ++ while (str < end) { ++ *result++ = tolower((int)*str++); ++ } ++ *result = *end; ++ ++ return dest; ++} ++ + ZEND_API void zend_str_tolower(char *str, unsigned int length) + { + register char *p=str, *end=p+length; +diff -Nura php-4.4.4/Zend/zend_operators.h hardening-patch-4.4.4-0.4.15/Zend/zend_operators.h +--- php-4.4.4/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100 ++++ hardening-patch-4.4.4-0.4.15/Zend/zend_operators.h 2006-09-05 20:30:51.000000000 +0200 +@@ -174,6 +174,14 @@ + #endif + + ZEND_API void zend_str_tolower(char *str, unsigned int length); ++ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length); ++ ++static inline char * ++zend_str_tolower_dup(const char *source, unsigned int length) ++{ ++ return zend_str_tolower_copy((char *)emalloc(length+1), source, length); ++} ++ + ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2); + ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3); + ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2); diff --git a/0.4.15/hardening-patch-5.1.4-0.4.15.patch b/0.4.15/hardening-patch-5.1.4-0.4.15.patch new file mode 100644 index 0000000..6b2eba0 --- /dev/null +++ b/0.4.15/hardening-patch-5.1.4-0.4.15.patch @@ -0,0 +1,9802 @@ +diff -Nura php-5.1.4/Changelog.hphp hardening-patch-5.1.4-0.4.15/Changelog.hphp +--- php-5.1.4/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Changelog.hphp 2006-09-07 19:32:29.000000000 +0200 +@@ -0,0 +1,61 @@ ++Changelog of the Hardening-Patch ++-------------------------------- ++ ++0.4.15 - 07. September 2006 ++ ++ PHP4: ++ [+] Fix for potential DOS in handling of include blacklists ++ ++ PHP4+5: ++ [+] Backported a fix for open_basedir problems with insanse PHP scripts ++ [+] Added a fix for ini_restore() PHP security vulnerability ++ ++0.4.14 - 11. August 2006 ++ ++ PHP4: ++ [+] Remove unecessary call to AC_BROKEN_REALPATH ++ ++ PHP5: ++ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant ++ ++ PHP4+5: ++ [+] Added a few PHP security fixes / see changelog.secfix for details ++ [+] Fixed the memory_limit protection for systems with different perdir memory_limits ++ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments ++ ++0.4.13 - 07. August 2006 ++ ++ PHP4+5: ++ [+] Added a fix for a compile problem on solaris due to missing strcasestr() ++ ++0.4.12 - 19. July 2006 ++ ++ PHP4: ++ [+] Added fixes from sf4 security patch / see changelog.secfix for details ++ ++ PHP5: ++ [+] Added fixes from sf5 security patch / see changelog.secfix for details ++ ++ PHP4+5: ++ [+] Added anti mail spam feature ++ [+] Speedup of zend_hash canary (clear/destroy) ++ [+] Added a fix for a DOS in the handling of URL blacklists ++ ++0.4.11 - 13. May 2006 ++ ++ PHP5: ++ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache ++ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 ++ ++ PHP4+5: ++ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories ++ ++ ++0.4.10 - 11. May 2006 ++ ++ PHP4: ++ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed ++ ++ PHP4+5: ++ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir ++ +diff -Nura php-5.1.4/Changelog.secfix hardening-patch-5.1.4-0.4.15/Changelog.secfix +--- php-5.1.4/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Changelog.secfix 2006-09-05 20:31:02.000000000 +0200 +@@ -0,0 +1,40 @@ ++Changelog of PHP 5.1.4 Security Fixes ++ ++Release 6 - 11. August 2006 ++ ++ [+] Added IMAP open_basedir/safe_mode check ++ [+] Added a fix for previous ext/session fixes ++ [+] Added upstream fix to ext/socket ++ [+] Added sscanf() security fix ++ [+] Added fixes for handling of corrupt .gif files to gdlib ++ ++Release 5 - 13. July 2006 ++ ++ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode ++ ++Release 4 - 13. July 2006 ++ ++ [+] Added a recursive array printing fix to the phpinfo() XSS fix ++ [+] Added a fix for stat() on non existing files in safe_mode ++ ++Release 3 - 07. July 2006 ++ ++ [+] Added a fix for an integer overflow in str_repeat() ++ [+] Added a *working* wordwrap() fix ++ [+] Added code to make memory_limit work on 64bit systems ++ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability ++ [+] Added a fix for overlong tempfilename ++ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl ++ [+] Added a high characters fix to ext/wddx ++ ++Release 2 - 16. May 2006 ++ ++ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP ++ tarball got updated ++ ++Release 1 - 13. May 2006 ++ ++ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball ++ and is downloaded when make install is called (usually as root -> security risk) ++ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache ++ +diff -Nura php-5.1.4/configure hardening-patch-5.1.4-0.4.15/configure +--- php-5.1.4/configure 2006-05-12 16:41:10.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/configure 2006-09-05 20:31:02.000000000 +0200 +@@ -942,6 +942,16 @@ + ac_help="$ac_help + --with-libdir=NAME Look for libraries in .../NAME rather than .../lib" + ac_help="$ac_help ++ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." ++ac_help="$ac_help ++ --disable-hardening-patch-ll-protect Disable the Linked List protection." ++ac_help="$ac_help ++ --disable-hardening-patch-inc-protect Disable include/require protection." ++ac_help="$ac_help ++ --disable-hardening-patch-fmt-protect Disable format string protection." ++ac_help="$ac_help ++ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." ++ac_help="$ac_help + + SAPI modules: + " +@@ -1410,6 +1420,8 @@ + ac_help="$ac_help + --enable-wddx Enable WDDX support" + ac_help="$ac_help ++ --disable-varfilter Disable Hardening-Patch's variable filter" ++ac_help="$ac_help + --disable-xml Disable XML support" + ac_help="$ac_help + --with-libxml-dir=DIR XML: libxml2 install prefix" +@@ -3618,6 +3630,157 @@ + + + ++# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. ++if test "${enable_hardening_patch_mm_protect+set}" = set; then ++ enableval="$enable_hardening_patch_mm_protect" ++ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. ++if test "${enable_hardening_patch_ll_protect+set}" = set; then ++ enableval="$enable_hardening_patch_ll_protect" ++ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. ++if test "${enable_hardening_patch_inc_protect+set}" = set; then ++ enableval="$enable_hardening_patch_inc_protect" ++ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. ++if test "${enable_hardening_patch_fmt_protect+set}" = set; then ++ enableval="$enable_hardening_patch_fmt_protect" ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. ++if test "${enable_hardening_patch_hash_protect+set}" = set; then ++ enableval="$enable_hardening_patch_hash_protect" ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++ ++fi ++ ++ ++echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 ++echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 ++echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 ++echo "configure:2733: checking whether to protect include/require statements" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect PHP Format String functions" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 ++ ++ ++cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH 1 ++EOF ++ ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 0 ++EOF ++ ++fi + + + +@@ -18607,6 +18770,62 @@ + fi + + ++ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 ++echo "configure:14928: checking whether realpath is broken" >&5 ++if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then ++ echo $ac_n "(cached) $ac_c" 1>&6 ++else ++ ++ if test "$cross_compiling" = yes; then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -fr conftest* ++ ++ ac_cv_broken_realpath=yes ++ ++fi ++rm -fr conftest* ++fi ++ ++ ++fi ++ ++echo "$ac_t""$ac_cv_broken_realpath" 1>&6 ++ if test "$ac_cv_broken_realpath" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 1 ++EOF ++ ++ else ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 0 ++EOF ++ ++ fi ++ ++ + echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 + echo "configure:18612: checking for declared timezone" >&5 + if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then +@@ -89422,7 +89641,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + cat >> confdefs.h <&6 ++echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 ++# Check whether --enable-varfilter or --disable-varfilter was given. ++if test "${enable_varfilter+set}" = set; then ++ enableval="$enable_varfilter" ++ PHP_VARFILTER=$enableval ++else ++ ++ PHP_VARFILTER=yes ++ ++ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then ++ PHP_VARFILTER=$PHP_ENABLE_ALL ++ fi ++ ++fi ++ ++ ++ ++ext_output="yes, shared" ++ext_shared=yes ++case $PHP_VARFILTER in ++shared,*) ++ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` ++ ;; ++shared) ++ PHP_VARFILTER=yes ++ ;; ++no) ++ ext_output=no ++ ext_shared=no ++ ;; ++*) ++ ext_output=yes ++ ext_shared=no ++ ;; ++esac ++ ++ ++ ++echo "$ac_t""$ext_output" 1>&6 ++ ++ ++ ++ ++if test "$PHP_VARFILTER" != "no"; then ++ cat >> confdefs.h <<\EOF ++#define HAVE_VARFILTER 1 ++EOF ++ ++ ++ ext_builddir=ext/varfilter ++ ext_srcdir=$abs_srcdir/ext/varfilter ++ ++ ac_extra= ++ ++ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then ++ ++ ++ ++ case ext/varfilter in ++ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; ++ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; ++ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; ++ esac ++ ++ ++ ++ b_c_pre=$php_c_pre ++ b_cxx_pre=$php_cxx_pre ++ b_c_meta=$php_c_meta ++ b_cxx_meta=$php_cxx_meta ++ b_c_post=$php_c_post ++ b_cxx_post=$php_cxx_post ++ b_lo=$php_lo ++ ++ ++ old_IFS=$IFS ++ for ac_src in varfilter.c; do ++ ++ IFS=. ++ set $ac_src ++ ac_obj=$1 ++ IFS=$old_IFS ++ ++ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" ++ ++ case $ac_src in ++ *.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" ;; ++ *.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" ;; ++ esac ++ ++ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 +@@ -112351,7 +112829,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + network.c php_open_temporary_file.c php_logos.c \ +- output.c ; do ++ output.c hardening_patch.c ; do + + IFS=. + set $ac_src +@@ -112596,7 +113074,7 @@ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ + zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ +- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do ++ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do + + IFS=. + set $ac_src +diff -Nura php-5.1.4/configure.in hardening-patch-5.1.4-0.4.15/configure.in +--- php-5.1.4/configure.in 2006-05-04 01:30:02.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/configure.in 2006-09-05 20:31:02.000000000 +0200 +@@ -209,7 +209,7 @@ + + sinclude(Zend/Zend.m4) + sinclude(TSRM/tsrm.m4) +- ++sinclude(main/hardening_patch.m4) + + divert(2) + +@@ -1275,7 +1275,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + network.c php_open_temporary_file.c php_logos.c \ +- output.c ) ++ output.c hardening_patch.c ) + + PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ + plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c) +@@ -1302,7 +1302,7 @@ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ + zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ +- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c) ++ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c ) + + if test -r "$abs_srcdir/Zend/zend_objects.c"; then + PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \ +diff -Nura php-5.1.4/ext/curl/interface.c hardening-patch-5.1.4-0.4.15/ext/curl/interface.c +--- php-5.1.4/ext/curl/interface.c 2006-04-13 13:26:10.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/curl/interface.c 2006-09-05 20:31:02.000000000 +0200 +@@ -167,6 +167,11 @@ + RETURN_FALSE; \ + } \ + \ ++ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ ++ RETURN_FALSE; \ ++ } \ ++ \ + if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ + (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ + ) { \ +@@ -1065,7 +1070,6 @@ + case CURLOPT_FTPLISTONLY: + case CURLOPT_FTPAPPEND: + case CURLOPT_NETRC: +- case CURLOPT_FOLLOWLOCATION: + case CURLOPT_PUT: + #if CURLOPT_MUTE != 0 + case CURLOPT_MUTE: +@@ -1116,6 +1120,16 @@ + convert_to_long_ex(zvalue); + error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); + break; ++ case CURLOPT_FOLLOWLOCATION: ++ convert_to_long_ex(zvalue); ++ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ++ if (Z_LVAL_PP(zvalue) != 0) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set"); ++ RETURN_FALSE; ++ } ++ } ++ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); ++ break; + case CURLOPT_URL: + case CURLOPT_PROXY: + case CURLOPT_USERPWD: +diff -Nura php-5.1.4/ext/curl/streams.c hardening-patch-5.1.4-0.4.15/ext/curl/streams.c +--- php-5.1.4/ext/curl/streams.c 2006-01-01 13:50:01.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/curl/streams.c 2006-09-05 20:31:02.000000000 +0200 +@@ -289,7 +289,11 @@ + curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream); + + /* currently buggy (bug is in curl) */ +- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); ++ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { ++ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); ++ } else { ++ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); ++ } + + curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr); + curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0); +diff -Nura php-5.1.4/ext/fbsql/php_fbsql.c hardening-patch-5.1.4-0.4.15/ext/fbsql/php_fbsql.c +--- php-5.1.4/ext/fbsql/php_fbsql.c 2006-01-01 13:50:06.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:31:02.000000000 +0200 +@@ -1925,8 +1925,24 @@ + } + else if (fbcmdErrorsFound(md)) + { ++#if HARDENING_PATCH ++ char* query_copy; ++ int i; ++#endif + FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); + char* emg = fbcemdAllErrorMessages(emd); ++#if HARDENING_PATCH ++ query_copy=estrdup(query_copy); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ free(emg); ++ fbcemdRelease(emd); ++ result = 0; ++ zend_bailout(); ++ } ++#endif + if (FB_SQL_G(generateWarnings)) + { + if (emg) +diff -Nura php-5.1.4/ext/gd/libgd/gd.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd.c +--- php-5.1.4/ext/gd/libgd/gd.c 2005-09-30 22:48:05.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd.c 2006-09-05 20:31:02.000000000 +0200 +@@ -2161,7 +2161,7 @@ + for (x = 0; (x < w); x++) { + int c = gdImageGetPixel (src, srcX + x, srcY + y); + if (c != src->transparent) { +- gdImageSetPixel (dst, dstX + x, dstY + y, gdTrueColor(src->red[c], src->green[c], src->blue[c])); ++ gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c])); + } + } + } +diff -Nura php-5.1.4/ext/gd/libgd/gd_gd2.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gd2.c +--- php-5.1.4/ext/gd/libgd/gd_gd2.c 2005-08-18 14:54:43.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gd2.c 2006-09-05 20:31:02.000000000 +0200 +@@ -430,6 +430,10 @@ + + gdImagePtr im; + ++ if (w<1 || h <1) { ++ return 0; ++ } ++ + /* The next few lines are basically copied from gd2CreateFromFile + * we change the file size, so don't want to use the code directly. + * but we do need to know the file size. +diff -Nura php-5.1.4/ext/gd/libgd/gd_gif_in.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_in.c +--- php-5.1.4/ext/gd/libgd/gd_gif_in.c 2005-09-24 16:39:16.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_in.c 2006-09-05 20:31:02.000000000 +0200 +@@ -44,7 +44,7 @@ + #define LOCALCOLORMAP 0x80 + #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) + +-#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0) ++#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0) + + #define LM_to_uint(a,b) (((b)<<8)|(a)) + +@@ -147,6 +147,9 @@ + Background = buf[5]; + AspectRatio = buf[6]; + ++ imw = LM_to_uint(buf[0],buf[1]); ++ imh = LM_to_uint(buf[2],buf[3]); ++ + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + if (ReadColorMap(fd, BitPixel, ColorMap)) { + return 0; +@@ -182,14 +185,13 @@ + + bitPixel = 1<<((buf[8]&0x07)+1); + +- imw = LM_to_uint(buf[4],buf[5]); +- imh = LM_to_uint(buf[6],buf[7]); +- if (!(im = gdImageCreate(imw, imh))) { +- return 0; +- } ++ if (!(im = gdImageCreate(imw, imh))) { ++ return 0; ++ } ++ + im->interlace = BitSet(buf[8], INTERLACE); + if (! useGlobalColormap) { +- if (ReadColorMap(fd, bitPixel, localColorMap)) { ++ if (ReadColorMap(fd, bitPixel, localColorMap)) { + return 0; + } + ReadImage(im, fd, imw, imh, localColorMap, +@@ -212,6 +214,10 @@ + if (!im) { + return 0; + } ++ if (!im->colorsTotal) { ++ gdImageDestroy(im); ++ return 0; ++ } + /* Check for open colors at the end, so + we can reduce colorsTotal and ultimately + BitsPerPixel */ +@@ -502,6 +508,18 @@ + int v; + int xpos = 0, ypos = 0, pass = 0; + int i; ++ ++ /* ++ ** Initialize the Compression routines ++ */ ++ if (! ReadOK(fd,&c,1)) { ++ return; ++ } ++ ++ if (c > MAX_LWZ_BITS) { ++ return; ++ } ++ + /* Stash the color map into the image */ + for (i=0; (ired[i] = cmap[CM_RED][i]; +@@ -511,12 +529,7 @@ + } + /* Many (perhaps most) of these colors will remain marked open. */ + im->colorsTotal = gdMaxColors; +- /* +- ** Initialize the Compression routines +- */ +- if (! ReadOK(fd,&c,1)) { +- return; +- } ++ + if (LWZReadByte(fd, TRUE, c) < 0) { + return; + } +diff -Nura php-5.1.4/ext/gd/libgd/gd_gif_out.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_out.c +--- php-5.1.4/ext/gd/libgd/gd_gif_out.c 2006-03-13 22:56:38.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_out.c 2006-09-05 20:31:02.000000000 +0200 +@@ -265,9 +265,11 @@ + int InitCodeSize; + int i; + GifCtx ctx; ++ ++ memset(&ctx, 0, sizeof(ctx)); + ctx.Interlace = GInterlace; + ctx.in_count = 1; +- memset(&ctx, 0, sizeof(ctx)); ++ + ColorMapSize = 1 << BitsPerPixel; + + RWidth = ctx.Width = GWidth; +diff -Nura php-5.1.4/ext/gd/tests/bug37346.gif hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.gif +--- php-5.1.4/ext/gd/tests/bug37346.gif 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.gif 2006-09-05 20:31:02.000000000 +0200 +@@ -0,0 +1,4 @@ ++GIF89a ++< ++ ++, Ҷ˵˲ +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-5.1.4/ext/gd/tests/bug37346.phpt hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.phpt +--- php-5.1.4/ext/gd/tests/bug37346.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.phpt 2006-09-05 20:31:02.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++Bug #37346 (gdimagecreatefromgif, bad colormap) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECTF-- ++Warning: imagecreatefromgif(): '%sbug37346.gif' is not a valid GIF file in %sbug37346.php on line %d +diff -Nura php-5.1.4/ext/gd/tests/bug37360.gif hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.gif +--- php-5.1.4/ext/gd/tests/bug37360.gif 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.gif 2006-09-05 20:31:02.000000000 +0200 +@@ -0,0 +1,469 @@ ++GIF89aK+wױ⾱c BsȼԾǼ䒐j2ȴħ¹ȭOIsŦ*ƶï;k-fݺ޲ڛવ󘞳0սӲXixQվtڷ0Æʼõ˽ֵƳĝ˳$Qx,\ƹ4-42󶹾$m✆~%}ѹa9˰ȷϯش2ƹ|Ƹ25Є=1=HCןz]߬Έ54/ᒧ?6ջ! NETSCAPE2.1! , H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ ++JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ nÈN̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ2j("x00(xLc:Ԓ`}>@C& ;e X4,]*:N$)$ H ,2 Kh a1i<Hr14"07wưR# iަZsŀ֢3\do!kJ?H#fqnĬ<4re0m5 ++]:޲'(O"#``ahؑii oSD1G|2^$f` fP )$+P>0"eHHe2瑀&$@ p~B5!U@ ++0A W_3l TQ$ ``.P~`Q Ƞ(!4id){`!3?0 ++!t!6(؀@`&E1S(z0Q)dЉg, A >,lE%D @cV8R& 6q A0XCB,lPB0y|kPRC8`Nx?`H PAaJPY'iԹR#PB:␋fP >c0 -Be ,8W E+d0lE(;$ ++Hl?Xc'BE0HY(X5@3pO H ++H.ـFH]^0DiH 2JUjUA.ѱ1Kg@* ++ڊ? @Tb~xM7 I8A &Qa CA0HG@gZ0@qT L)p&mpZ6ax 2&bY6@8.DUzY(ߨ0aA N PЁa-ʔJ a&@8`p y\LHP ++#t鐀17B@9%yS 4]!&bAx)@DBm*; gۀ5=I*g ! r ++@Xf X# Bq$4 h3`f-ٶ5հ 7h1vP p ++8f n3N@:`.R LC;P5O`N&G:% 3F8֙6Lr'`AbL_dzU$׾6[f{HCwfo mg@G9Q ++k d8$nr8k- kfHx -D@k)" ++3ii Ѐj؉=P P f~2( Y"0-p TВ `qȖډIu- ) !zy@S ++i @oЃް~IJ uT ++V- p@0Zv|pT0p' Tؑ` |eXS{ 4w@i2܀0n\װ k Ay1 QUD T` 1Q T>Xei.iGxtAop Qw S~Ot*z` ++逕EpP`o0s8 ++R`} I߰x`q։ Z gm{wP  UP ++YhPI. {r @ ++)Ug6* YqV4UjfK0R J @P Er0 a#.h؟#AV .py@@ LZp >I}H a ++ @@@NwwJ(G,Pn~Nj0 ++Q m ++LX@D@ 5`}z XM  ˖G 0,4qZ@Qf>h)@L `@g{ ++ W&@ˈ0 7 \xB .@<H mJf0`ooSC Mpf;uʤp,y ++ О|~xhƌp=i ++̌O q@t֢ L:-Pg ZpHQ cA6J 7B B^|m0pJs+iPDpu  J0?dlcq-骵LP ++0u6mP݀Po H 少Q Tpfu`̠P<`rПTͅg4 LypX]n>0 ql)0AgKЅ9vp~No ++Pi=O mM!U`lh}P+/<〒@qk ~zoGP ++ԪꃞpsQEl`Z:ȝ}KfV[{·=0P i`YW h-k)s* .ٓkȸ.@.p b dJ L"]UXr3 zmr7[L@Yk|m^x@ :g0y0*]0>_p-C?F FGv.6L MKLpm~VPX pY\A9CoE?'Pے`x }~{\M` - ++`%` ՛  7btπ\ymUkMJM߲Nhg`-} n-ʝ $< virKxRA &IIQLW_ ++4cBE!EvIR8cٲ%AFΤYM9uOA~LR48C7g6d{B+9"Ba۴0b7BFHQ_y,+]IK_&\pE2FqBen4,-a7 ++hװ:@,DMԄdVc1UfXusa'N,T堲 ,Ki܁`$Mݻ$+Et'좢F8%7")R0){ocp@ 4"#xg98a(Xʅ5l;rX ++X 8[H}HO(b=".ܜ!-¹@$Trɜ $RA*0^Ă"VYG!$q`ʒpMD6(DD -8*NIFut8"n(gـ, yA) ++RDV 1z 1" Gab뭀:Zl`qX&2]Ԩ6঑ $Tp:Zm @br+$wC!qf# y4j`b ?m+G łcggTrƅ tA\` ++˰*x5y]Tc;` 1xa $KBYRA  k5qiLaz* 7h-W@y W3|V)qFG۞q޸`) ++$l;GL r=H fθۆ !#y&6j"%x ++J馱<~xaA:(\FʯNsxWm p"fVC mr廁< #`P(QXJ7.6g48N<-xԧ: PC H5` @`i$ A@}ÜBY l $,4U3A- EMq4`d xǐr=B):NР%Hpk"1&h$<4\P(V PrT h><3 - pk(-ե̚DHx\fc@'$-P<`l~+{P9`zcn" \Naײӻ`nԃmTgИ SZF0ӗ`ǕB:q xaCNo؂ޕK)>7X3;jԦ@l[`H̟!ْ&@6gj#v=]NC+)qtFnrc=}2_ZäjpQ{cSyH"N-*@'HvG QN@%`|ы`/y/) 5,>[,q$b77^ GKpo4F+p<5;k tI\WZ ++?* [ָi/l0()_\:7 ++ł@H?l?zwB?yY؁p:-83NH"? .p@KPK$WaXh70 @;z#`. "[ P&V.gP -7hB 4g؁ ++K.q N@I ):X-yl ++X & =h#39;Ba ++#(GÂ&ɣ(XDF @ {l*x3D(Eqp< Z{iC +h:ul( '`ҝ+˧ ( HR. !ig58qr* (. ++,{g0 ++t-U &h9MRfHsМ $i(PDITNP0`9 >Vr+| HT$F1{X PCl ˄U$E2?B.0|-Խ#8"hJbP(Ι)X3U3(PVn4 4 "rHQɷwTW]h<[- 0`ʩ#x*VMOis(+epЉENTG#w@H ڀ֓eL+L9 *6Y(NҝUО518IL6 o0xըo85_6P0+, @X) F/l#=3`]hR("|mFR9\x91 ++x̛AY \F,(]]PV!6hɦ)S*30؝"B65peL!@٢$o \^g;eyFȝ `_l8P]2]?8T'*`k&MJ^m]]Z ~`w^ l|饊j@Tf<;E ]Xpۨn=d&=>a%^Z(#51w)1h=Rɡ"\“hq-;ĨXJ`ec,"i% d5؞(c\`-/Xk1-M ++XQ I>S5µ^|taeQ/;Va^0P#F; [,(Z6:t;]!T7"i>"vuWBbR"#PJ_]hY$E> Hj8aa8ţpȃA؀jh..Sx㷸 8`eW^s5Tk+8; ++f@1T1kÄ^L+_o-%sc6.:S*P pU"konnղ> hm*0`l*쌃ˍ;/;(#`j/L &!d<#~z=S@䞞C` vqfVx#*en#  ++ă["Wn'P Xݖ7)mf ҽRP+l!Ѐ nB Z6,>!6ws5l 9os:aЖ@= $/th;tD?g۽pG=t50%tntN{uWG} WTf7V?WW8ėZf`\]g`^cd0ČJo]0vj8hlmgxɼpd7X<`s?w6/pwlRzHc,Eplx/x?xOx_xox ! , H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ ++JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ>K̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(=3(x:ࡃ+KL3RP8p(Ň޵ܰ;3&d&RlP򢆏>PI$A7*=sCK,dڈ 0N>PS<<#?<(P& 'fs&N-!s`D\OJ^d ++Ϣ6}#>QGKc,,ejL@*MBA03$#& (vDrJ Ϙ#3 mZd  <r3$L7L !QȢ$SP͔K`)tj@Mm^t!'IBkt B$u-KD ++XL kDq 4 В Y77@:%8@#7nj/pm/B\J ++31` ݼmӏZIDV+ P2BHL1Vq$? ++;ÌU TNr`е@sS@  ++FPy$J&_Bd9F TBް@R.8X# -#riW @ '0XHFFQQˠTԨJĴ8<[D$эRh!f0m@vh &^xFe=!*Hc2P3b#A5 vUWР'ZNrTURrqC9]̕s4Ak jUS`wZ !X0 4[ˈI4zH@> 6EX>"` ++>TM. ++\,OQJX=V 1039N 7Åhi uN`m`BiFwSaP%0m;=X'(߅> 9dzbrƾAFc\pִp7@nР)N' 5%@ {G%Psw&pp0|0qW/7Iw 5yp97%}p?62PF2?@ok0Syn#ZSjBU p62 [ /pv`v  zpEբ>5 q  ,2 ="h# Z *opjk_ΰC?Q~u7PTWX@0-Yg{C=@ `& |"303=^1-u9@u(RTPkmD,QF6C9@\oLy? ++vN0 ? ++Y v { H Y &P Iq*pQ@ݤ(nJ oDcxVnUCDwW ++GB19JP-N+ ++3f`_0* Y(h0w"P% t("P^`jX=jp)D)@߰V9e4'@NJhty4<DP)@Dp T0 #P*h@ 0wl Pe8s(I(qRmd=cyx(ntKp !߰uB8p<%eN4 'H\tT}> \`@ hvl1ղ& @@($00KdL)ZӛްOsmnqsV&Rney.4`W 0 `G)0"`_pk2 hpdp6(p@2vxTpR ++Q@@߀D(B@zj4d'Rk~Eޔh)Z ++d  ,phoARZ ++( 8y7W)@y=&O(}ť/1DP EB0@Ry9ɣR G7.ped @( I* p" ]0 :38xcU,*HpgNHМVV7tgdWV ?.Z[1c*s@NJf.`LyN0v`i ++ceGM L^+{giPuHuHBL@"hf"i!tRKsڴRcRpV'LN?C P9Y;vGvG`g[ScP-Ёs.]*OJTt7Z9^6V`/ ؛Gg5G ++p㨰c@C@x I`{*Pp0{֐P|O( ++ֆup4E 3z{xݠc%3K N8eFx3Czd#R~L ++T^^p8w`k * Pl8,@VnʤB@hɫzxԩ {j#RZN.G &s3o ++kyz }yF;R s*15 P,p7f3gzrVRA` z4tx sjL!|9Qؤ.CsRpz-oyЭx4Јjtΐ ++  .js0j `0?{3P MuC01th8~ 3zlDkn؁9R,e58J.~kx?p)XB'PVpv@@lʯְ@A ++} BR u9PwTd/ QcoIhVÜч ea n[/yَo Gw`j?vJ` ϐUp^@l \ -u2Hƻ,CXp}wkLз2$!Q,nGd@8CXq[TnXDnLp*) vHJcČ4[zxݐn ϰ6һӧ@j_M5;[baiv 0% P` iDZ`Jcu8J*nk=vR.7fsJlSܹsj`Jy04`2 ++FD6npOWFUmp} 'ТQLc `@L3A8cvm/Lolg vqIst@1Tiny ߀4P| ++P]úPt6@@G⺽,pXl~*ZV&'ԋ6gUQV"#@qP ++PϰqUPh3pN} fukpGڥ$(@xn5PוIZg4 I<͍hקNs,u40C $3dmC E`@00f.R&4vu5"U6nȨ_WE5{y8?pˁ1o@p*/~VJ[Z4@CTRy~}=ۦ!p\SvhIZ~hG'm4LP :Gdg.F  ].p #[4~YTлi-RH ++?RUV,kBSvD10Pi=Z@P!VU_;T"nFn&tI'n pv¥(D(@?:4G VLh#@]H-hfh ++hp.j٢A醊@p(G`(C=x ++B(Rg8uW^{o!nh$6p" s &(s y @PPE\ |Bn01!,`x ++ Ҹ8ܜdɨA!N./op *SM7H= gwj-1 ++hb۳Wc yƊ$+@W=kimk I\a꩟, * % (x f*7 ++ |UڨH4րggF$ Z1˝¡eS9l{fC}C`ALF+\-nr1*@d2D[$%!UU 48<+ Tyg`P ++ %ot* z& 8Ƀm`X!*Z0p]e$ ++0 ++B3pnt@qc`a"'D6VA9`BQ8Gʴ;m#0iBH1t@ 4!"&t HA74pm@P@  ++ ++e5o*ߨCܬ⏲s8P\`EQH ndMYBRs`(h9K``A !&oa ++(`Ӗ$# * (0]ꀁA ++0j=hq8\Bd*XB˻G !(#4'H@p&wZgGXfH-ᐈ3iNkC*g B4 Ѓ ++Հ? ` ++ 0eD|f-H8hIO\@݃v)QHܰYnݤiM4B rJ|h@K ++3@ ++D\L ++=.<XgyЂ* 0lƩj rq3%5XM|ÚK h,&P&(뮪DHRba'fD9 poT*3r@֪8 aB}3"u3x#2lqijgHpcTeID& ]b٧j ++(QNYiU^$E#CT!9t", @A ('ݕ)0!d@񆗸V]h_X.@l"g D) ++<ވBX;bJ"yZh7NA*A7*|-HMxUTS39&$g*0JAr{%p"  4W lLPUƣ!ܼ'"n36p g܁=ZN ++j3:D4/k s")?A Tyh$+xWy7R >=u*Tb&9=܄}ŌoH@@"PkULQS ALm^/ @co<8[a>} 03P @n?ۍR}(3"pƣX= G Auz  'Vao:!>$`i). ++Zu>%AS&b@E\1`! {O1 ++Q&%$utכ&`H` ++|Ɛ?C`pQ< ++HYl0mǾϐ3BJqtc 3H:4n~>B*{AwYD ++|D5{ﵗHTC XA+Db O "`ƚSx[!XT=mCH+[ %H?S9 ++Kz/;0 ϪK<ʀPJ"H ++f(CoCx6؀ ++Bx ++* Hqr'. ++cu$I8g8;P;BX> )C p595ZQ.ȁe=87KY*`pb(hrŀCQ8!* X P5{5 ꛙ ,GdXϲx0%)8DTIړ ++ii9DYB ++^7P]LF|3&Pac\  03'a ++(GHg(50R`HG + &3  1Rm1Y#0ȃn#HXP$KFTzW*Hz1Đ<MmIm iSM'9FuCӂsXͳP!h3ΐIQaH[ ++!( ў2D\UDSR*ȃC3ܥZfh(X:1@G`t-'`0PP(.,ޙA53.L:[(M+Ї,m HS( Yl_o2m.^ ,AǪ4pT2gpt \gʐ8i. MH(R"-ġa;=f ++3pN2v".HU8õFC"(%(#bm@fڅNpS74UoեD[hK߆oVc]PpFbdW@('@& Ʋ-[gV+5eaHnqm0>N;IP~7xr!Icpæbx&p;u&+q&-r1Vg4kƠbѦ_胰sm<^_ц]HʡրRE*(p .c027i7xn!NC=pH쉞`b PuVoU&-*Cg辠Su` vƞ_fG*sy_ 8j_˖-hlO?P(nzxiE~Jw9􇆎oW.ZohȝeKŽgXv˅VA JCx($~wWtog[OV&˸c .daBSz abX!2M(d;>&:zV(80l"I=߻Oo8xw~FANP4 :^gȁȊ{c8H?(Ũoo{_o8thȉ.>P>] y/Pq ++N?9O)6CyI9ȷ}|(j1NdG?/m`vG?t~ e&Wh7؀':Lgab}KF8o ++ ++2l!Ĉ'Rhg89Ɛ"G,i$ʔ*Ia,@ 8&Μ⬛:-j(RP9LIRC7g).<+ذHAh*1IJ5zHK7,Lzk.ޅb HI0+<.IJ#,n-8U@G L7Gtä[fG.P( Na6Eܺ)"^~m3g\3o^EgEȱ0#y^=&. yr;H'~b]()~ ++Ч@4ۀSݓm;48ax1@haSA#4!}Sh]GH8cs"fXl2Av_ ++f y7ǒQf_`.h"eJ-AW\Y2 Q IR/50&lPr,VEԠ k,`sGZTy brp)DB*Fei!G`:+G++uxt|*,͊t ++J,JdJ5&( Lڪ" Ey&@{(Ԁq@{0];P0&0Ŵ ++ LX `I!j ++JP"`¨"l)J/\g:uF;2%XڰQygeg"',,5-Rԙ"[w}9SWR/h>*Ep07dmv߅_ %fEnψ!Dzk-M m>zlGrX*MG6:a݉  &%;9|^h2?}[}|kV2qEۋ)? e)RǙ ++0fD*H9{-1NȟG.M ++8p$ψC/x CZ{R*rC<:%2N|"()RV"-r^"(1f<#Ө5n|#(9ұv#=~# )A<$"! , H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ ++JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKguew߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ ~!(_f] >B/` f (FCaUd(]$·A`,Hd7U|!G#8# B ژ0xhA3D,԰e ++N ]B0@Dr5A`1  ++4@3$;DU$D)8HpE8)01HANG@d$=#~҂}@ 9l bAEtM ++ `˄QE#fI_t@] D4&X ++DB8^ ~,aC "xDIHܵ3)tD ++\P-G||p=cD .!$,]H0D80"-:ރE ++X0 WYtLt͕TSJk@ ++bT]XH 1)B;gD8)4$tEAvC`0[8'9=W0 q{耇{ A7|CG0 Bw7BoPyopP2AҒnH0727g # 8Pߗ!~ c:T0îH),3i V .`.,U ++:@@@0@.q %, 'U`OG5cϋX#nET`RƍFLlu`mJXX ++se Z`©(H8xl[؂!F@ԪaĊoW(* ̀( 2TB3xȴalZ@oZfĺmZBWS" H9t ~jj`(@ ++Џ. @/,\庑 ++,@ E@@j Қa%4qQ#  >J  IHRX}.tT8жP4"T_ fܥ{`pV`M_D-k7y ‹dh5*`$n=A@G5 8vA*#B)zrr:#-uQB q ga98IP3DV[)6"Iఈ `#^M`6@Ÿ u-(DAРWX4 ++ZK%'HB2YG4,P2#P ++tOL(BIڄU csmgpu7޻XRJsFrl{ W$^ ܃& H]֔o pWIi~:qXj4sy1͉d>+   R8qpEN!caQ͡FfAQ{aB3BނԈ>W,oν:'敂W ++$|S:sa5A:8O |:&ڗņFqrP ֙ skZ:Kg[b`1a.5xrA"+7F6yDm-ac"O}@ ++\P/Yчy ݀lK paJaH,s"H#,uycͲ)@,V ++0u}$P}3PG3Q"5p c~ ZF:0p DppA +BkzlBTR=Zk@Vt%p/TzXx U\*B:U 0-Y7 ~.GLUX~@_q7pv74 RV1YFT/4kmZ nZ &  R}P6}i1Q6z-XߦʷGt3wSaUAQ,ݰ& Zv35{Cv^_ ++ ++ P$epBe k4 e( nS0m &QH'a`< nqyP_#4wZUU&bsVp 0G|eK?* HPZoYLQtȉF]4p!% T6t\Uo Y4%gqlP# Om$ ++`2pl03ie050 0R0PO=li(Q"qU0sG80Z@vև.ɔ+Dp'jpwa$ w E++_|sR/ ++ # ]0 >eM > `c ++P3P :C&7I5pV PKGF7̠w)v'K;/Soji&1Es@R.L04 ? `@  ++`0# _" l`  S=@#!:DPzr/J4@ ]~E3MzekT4Dp6iCB"-XTa@AŔrexJYH!) ~b9 k EȺExR*5Ы0`p ++ Pś%W`0+ +r%Lw;t)@~@.PS ++Q@ SxcW ++\`{0Dj']1X?X0Gp.Lua4RWdT2 [ '`v P,ؐf c l ߷O$ T85@KPx""vJX? יđb`bBQKxQZUX`A9UT0zR ++p=dT- @ngπ @ _`30T $*h{r Upbߦ8Q@Ɲܾ F V^'+B^3WQ:Ps2Qb] Z ++s =0PfͰ0=@ =E![ 쀆{u d6m1ȳX8ZZ ,˸(Qpgw0{9 _Ϡԅ\1 ;`6g kP"/N%Е0 F{P-=0x{r 5jF;㨃?pyuPy`4G8T@)[.UK* `  #0S``ϰUp?)Le$>,@sv!WL@};{e ++G" dG[ZN n^Z> 0dL󽰕Pl @"t tS  ;`!K._|A\%?.b(D޳b bPAG5vT1 =@+  ++ 8@ ++I Č=L"ŋh%` g)Ud'NPT[ 4̛dR*ox3JpI)=,)jYiծe[q IF:@ɭoTпNR =s7s1>A*4h;6l @p&k$TqbQ S35 QBj֞4K1B!I+m\3ܔ˲haŠtH.S,Saf`KgkF.㺔`Bc ++h-Ha"L{q"atQA0!^ǚ0y@*i~gN( loBg8dHpAÞC8zL5[ @K6Ϥ"3S"žFGD@tg@y80lFo A1g2c@9 ++(lBqV 懈ͣ%(@ - ++jIbt ++HA,)  x  "@H@B rʁ:y87B^|"Q(`\Aq‚zK7$N:j @$qbTX]ck(8"`hnb{r!&i놑08oC?k) @$:HyF(\ l$ ++VJ! ++,(E:_=䃬ib$14M NV0QA )g ++TH:xq&B)Њ+[n(6i@9$%lU`w=hn9!pC E$" a80ȯg(9QA)38\pC8o \@x$37doTYNx@@Ē&؀aW aJ0 8 vCLT H4a8AK90d4lbul< \ ++(I̼7܃ÜLJ@ I ++{A((љp"2U̥ Q +~) 45?Ѐ) C@kق:&M`QDxЂ oK@\1 4"sm ɬ(~A97H̫QN&<-i0!SޠZ [ 1aT9!RPky﵃&8ԻYAFh9#1 (F\ 5&(#`@  Ϲ pF:ukB uyF9]F ++UXnjQ[3'DPi@YF̡0\#I3dprph!XYnχ|<l 9w ++H+ B@ޕ-0DPaYQldnR+vh8$5c88P&haJA6??- ^@C"/P ++[|`sFsÎ^x'!-rh Ǯξr =X 8.{E hLaun@ ρA{(SP|.)޻<0C'l ys&:@o  ++KolfYD ?C*@޺E؀ɪE>J!79ѓ$aFD7 ʡ>@ӣ?]K>^{1P  ]x=;t:Ѐ@6;!AB[*:9kp)<7X5:(`/s,X@@%@4 @N{*XCdR~ ++yĕKh 7rۄ+tn(.5S5s5Cj]|("J OŲѷJ*{  mQƕ3Km `A,S5= ++<< ),+%P@(7F q/(#C%~5291  x%Nl[u$3 XGy)Plh0AU {0!Jy(wਔ:> ( d\Qq؆'5"脏CӂC^|Gh8P10!IP M䕔(K:<7@PSp Y̵E`M(<xl0ɬlSH6>rp[9g}Z N@C885T<l3+Ѐ`hD'@E%_S9-ė@H͕1!.l70ȪL*ġH&LCZP{.pDÄ"ЀbY@<9$oX!뼇L,(PZӂ( @(x0Pz}τ?+p&PE?Є8-R:(ʴ| YֱTD`z@8?*Ӱ_@sD]T`KXNPUI$ʌ8ФpX%(SyDQP@Hń;\C(yO9+::Ђwb:д΋T|y؂nDfSyܼ:IE?N-bUAyXZBҔH?F ++`x 4edo2`[7/]J8,]D'GسPp_ м{Xp(A(h ͍ ZXVC@٥u_XAO'h=Օ 7 ڐQ/8gm^I`7s V] "`&^<T0 M!X^ GNc!Y`f17'5=j_1#+??@yDD D(}`[@%SXI"p܀5h|M@+L,H,|"~a}H55\TX9c8]D=} E-rՍc$ ++x 6XuVIǭ 0gh8Uc>N ZСpw8ݠI[C`4I%h5T3GF] OV8'J$(Y"Rf+؀mE 7Shd-]^N{p ++g.P5I`εWuL%qe4fZ0d`(Uv%@YET@1{^ E~ ddMh~hՁ&RA&X$9Tx 4 K^ jTJJ鞼68]d68t}!Eir @{ hoViH .^0P`3F: =qLkH-j+ЇMe\sp UI,,$^~)Ul Jb@0C'` x|f*#l),6bGDrX} ++Xf` 틨 8R7a5'f .xD`؇NCF-o[n*Vȥj'苘GXaΈ"Cݿ[#m\%x_ ~v2mA11 EX ӽ W256`H8g-UT˲1OhK{Pc po~I f-ސPN]K lqy(f.FT+LoԮqB 5(^r%r ++r,/O4Æ S䮃M>>X570&mR>bTvo8 7gF85o@U+s-".rq+t,IRktp3> S_1.WY(pRp`F"'c/ ++F&'{(c/N;4gtZރ8owQӄyP w_p}+X~fO+RB]PH ++(tuUA8``qÌХxz ,u))@vSq~p;u݋wCPƊt'%UYG| σ(X)(M1Pw8FzR805oR\.(`()0Ѵ0098 7 K(0s؀0 63f_@y;:5W8e&|PX)aI%@05+d 0D➄P[E"8f5!={Gwe WM.Li(BPķ ++2l!Ĉ'Rh"ƅ*0,#Ȑ"G,idF(h"lyր˜ )'> `',l7U4j*֬Z+H3Q̙B, 9"ࠠB ++80ּzKpd0BlKwUXEE +++SWLТ>x4Ԫ)b !'<@,AOT&L`Zm8ʭ~vRPj+[tDK[JCǓ/o4_Fw2L_]0N ++uk9` YC BeuF"7!Z8QD 1eQp)"y|hc\"=(?'h1h("Ww*'֏QJ9U}xSb ـ6HeyE ++}dP[""@E`&h'sQ E !*:!RŢZZ)d@ `ɥzfW* v1&9*bK肘Yy1ڟ?jA 4D,A:le1Z{q}Rd6b;.Uݮ)EpP.j IpIϜВ& 0u~,L0C Ūv(|%"̑-1c< ؠd=@1IN,eIVčJ[)$KAR^=6zء.1$ " ++d=jiB|o97ߡF`-6k7 +%>y@x)0eŞn <3̒e0. ܺ bKK[3D*?@^8ȔD%' @BLp8"߰z`bX~E|D|!*(r!XWK F,C؅ D0+fok,"4Qa@uG(2-'{A0> UH!sE ++`I%$b2ID`Q&2E> m,  Gl0*e&Q3؀2WLY o1IVERQ.A/UmcK,PX"q Y%>'iD` P~2T˅ ++O5R4_ ZDp9hs–J(E%bdL}S@5IfY5wQj7T 2.!ԩvJfCBqq1X3uqҲܐVYЀc\$5:CY+ӯ{FI>o`j9k>]H ++.a|VJLHfR ++`!vz <` md2}.t+Rֽ.vr.x+񒷼=/zӫ}/|+ҷ/~/lހ! ,K H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ ++JѣH* (KJJuf*$!Yկ` ++ٳoq1M۷pa>cϬoh߿!TKZ+^p…C̸e-Ck١ˠCmafhVFكpڬ B>#-hN< ++uk?P?BTkтGk8ʟ_ڨ1G@m=2 (=7v =H3U<83]$hBP$QE~F dwhiE7Th R"70~ Y|MwSJo^l ݀-zrY C QV;wp#_} K50rf`M"lQC_V ++ڀgaD3g<,pF)'@|ֵnP}9΅0A&`$ ++0A2hD0BX؀C` sF H@   h((5H1(X(0"~v9-`~ppAEp&#֠FЂ+D.Aby? ++70#$X M1Q6) uE*IG XɃ Q#6p]Fk SE4myE #@ 0 &~F@7+>D6҂AZ\X1Yc P,yX ++`h8ChX(o &`4VԢĂOc`waƻPt'PI%E87 ++^,T4Y>c@TRSo#&@Qf_pA@~EWY9s٥ ++ݠxȹ  Vb ++npb Q *kZT`ٖBW6hB7`lୁ@`-lzxYSIT04HMI;+` AįT0P Zs f3BX[#+3܃8.{[ " ++uR"m8̲@6&V{`lIhoW{#D JkOd_ f Rڲf%B^P` iXR)hPef݁%) m.вr u@op\o0"c"6!T;QCc[Aí7fBeB@3R`!8ՋAqx*\i2X8@,V 4^vO=a QC(\a!DM]Qq1,h^Qmgr⽺ЀWBA$(@jW$7 8Py{['5Рg89&uyuk4#`z}ЬZp?ΈRPa4XCM(rh\0ޣx@EF x]5^Z  h3ր/v#smbRDA CKܝ8L ++=)&A֝0ba (,2'm--'F3(1 ha0HA7b9K_kD 1D@e! {w'Qu]gJ'} +WB5q * ++U`Ey LpwZw4J(<GmfSʥn``kQS10.@-H#?4qpU@Mpw ++(XP+蹠 K݀#߷yiv )asXV:ٜ5JGq@V >2Pv{1(ĥtQXq Yl˕ B@3OxDK\*֗z baZ9 T ~1Lc Zp>+bq@YfTeFfPp^/{ dʫŠP6WŤ ՘YPi+d$'ڭAzWFC1TO4%Kߠj%)@;y溣pa Rh ~T}0p- 5+?k)x 0# @;p 0 #0 P ++YQّEivL1+@gP\xX@0kj P#0 ++F GRc X Zp6  ]"D$ $  ++28ap]Z('W#w%8aA2.@/0K8Ϋ [=[ 9K@GTTU ++&KrCɄ£oRgdfm }a c{eP  ohQ;p ++X-wtRƮukdPF> c ˛{ @ =`,!F.I0̪" [i2)]CUL$[zsq95@:4X)qXvZS ++ #v,| e${TqJwoP |Q.rR"v ++ :˗ ++І1Qy`F,w@mu.jeH:@ -S=7XfLP?-:wh|rz  ;/ XS>$ м =% @@y] ++(pJGp5q} wƷ1)˟04!BfrP9 ٙ =0L ]@䭀)No}7m ++@MҋF<` xu8fXS &ԃ0Cސj ++P  ߆ ++!d#u&Nj  oB# e  R[ ++``([p;~\D - NNP*=nR0 e[p `|_Xfn;痐  pГ^ p *a*1Q}x`ՇNor?p r| ?0R際 es p@&G8-:uZ|tT!ֱ.A`d88N> }w> hkKI` >`054/tQL,Kq2S# KN3ՠ ++~ ? R ِPkYj@Q} ++DVGSH@/N 0$K2@Ae; #[0.UIeKw{7#,#XKH(oO57qV  ++#@ @ 2p p˶eP c ԋ0XZMX< _XP\. 33   G ++_P n;~ Y0_= AjoqbwG9 Ҡ ++ ++ f  ++IFoʮ1@L.3J0&==G %̤I"qK1eΌ #&TH} OA%ZQI.eڴh ++dค]_ k4,@@iو +"K K ++A@&=D_2mbF*otcȑ%O>4@kT񪀀1dˮfl oy0[`g& hxCѥO^:g\ ++Ǽ:Ҩ +4eǰ8%6W)R="# 3耓Fs & ++(RD Ĩ :CC̟$T1NkJ0Jb8ࢸz0ÜH?+"8)H4`)@C- ++K!o ED24L3 )\ #Cf1OTi(BvQM>0*䐡ᡤԀ! l28,2ISM9% o8Ѣ64SUuUVzs Z!B(Bzh0/!/6 .%8Z[pERh  CT("`FVtQ\jAN(ZkIu ++h#q+`F4&^j@H,6.A4QC ^x I)ῸAEcvz7 ++%q;9!Һje|FLb_ zj!MRc(`ۅR;F8(2(hiw(r9x T4 ;dՈ⎞¿(g R0F,sv 7Xc -(o ++|x ƙF0-DJV YfU2D ++e12 }`Kmrヘo6S,xPd N0#Jp<"8 0@ ++8`% '(phc4P$ #@"W{UPtP=чc ad \@0@ )P7C0qUR8R O^@`(dG: 3 (Y_8 _c#Io\A ,`4Xd z 7sAD8T ++{d/}!' #0X@!;W"X3P(`R)ES+6 dg;2< \r,3"kDF6&R.&( *DT7SP ++*htxt(p& "h ?h .d)\:S:P6Xa \Tk4 (M l 0 jWjN,8j9(Z P;\M@,{P:qt (Y`HYLSS( ++)-Tp&G xE WԢV.D6yJ`@8SAd8*a` 4$9:02ӝ.&v ז b0'n}0GX6"MoS{N;` ++kVfz_y[ϙ ViqAExpg8mǮ\? pll@qf1j! *fl?ӨT]$ ++i[|!N34߸k(6% ++ v"4"Y?e$Zbp]j`LĶ {sRsZoHukhh7R ϛ7*6 zm$ "C(X(F9}~C 7̀@ bx0PD?']#u%hׅuIp70B!ؠ ++Pk] V7 B<[#0^Z'al+ @W0I '9-Q ++l ++d+hA 8P킫% 5q ++'p#q+JƇQ('BWDϭ>CTz"^6`&7ڠ% 3 WQ >Hfg@آ ++#\ }~G 2`u<ƾ TL4b؂Fx?!@ +Xo\0ahhN9` 4):!; g~Ӻ=eu FtLTG~'xЂ ++V6@Kw_2&5ȸ8脏x;?\S?R`mԸ@h@4*Є.X:4}>C(AOs,a@f 4x|H01x@BЃ$*X `_8@8={g>Ȁ1B8*8>Zp.8DpAj_xl:L@CH„*7.1`ALK'1XH\ƀ>x$`[5xL0"}.*x9Xg7dEe\ ++L8 ' ?87 *@F02'6?IXFt<.0pBQs2d=G(4HG ++S!(++XH`:Sx(ȟ ++KH&ڀAҀP|ɏsn[bD< J2pw0A${o1$+Є3AL:.ʗl=rAp KL$smsADLT(?Sˌ4tX`[l?DpA>1g`L&ۮ6d;#Sh1L+J D-()td;7K;"H\FO4E%"(m _'ǎ1rD(e ++hLnSNL&Db'pKgA\EXl2;ɤ$dώ0H5Bٹ{O#tD}OC<#6`D,8D5 |%6N 8;+0> gjȔ݌Py1K_ CX7L%*y C@IDLAΑ ELY L=PPS<8{]!`nX[35­>5^i:PCgX(/35 CBϑTAhF%40QH8Ҏ3s( XPMȘ[SܐtRNa%A=hv*J|THE(8 ++P/@(d5dV`Tf .x<`5DW/AE ++nUSFHJ"A->UKEDQ8`+й(+Μ33؅hN#hC)9YYm>L({=X( 2L?d WUMZCG3` 0Y1( X1`%[ˑSvs h#@><R=S [( ~dc ^=J1hՐW7^ypys)݅ 7\:0 ڼ'eӰ `QqZH~)@;/S ++^Nݮ=<4ah{87S8؅*K0  ++X8Q ~&Q$s\R7(4Ңx5yۅ, ++T ++%Vch ++80bx4W=:Mx߼ 𧕁KEo䩂 ~YI"ͣ0oY. g__T@U,La8e8~hEPL*Zdd=z ++ff f+XffN1o*G^4E(=bP۠k^a(*gZ{1h^=K3v,EZi`1(8w`4H]hh^2 3c'ϵjw2H[8k]w ++`s_vwGwo+ds zm G~o*.P8b,J5 ++w^"{N9wg\oy:Fywe~wyvJfywZ<z_ZtMR6_DH4Be_gvDF/8F. KH{{{{{{{{||/|?|O|_|o||ȏ|ɟ|ʯ|˿||ͯ! ,K H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ ++JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿S}L #^̸ǐ#KL˘3k̹ϠCMӨS^ͺuC®cT,۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟O}PAeB @? ЂF$3a ?AA2""aϸ!."<⌂=s-#I#=CJ?U!}jHbePq]z 7͘AL D p -܂w Ig_ l7XHR 'Z ræ7)o' Itm(w.Kj @FP'55d4'h7=s%jd ̤=T-D(N-$) RD9:0< x"'_4S[@ĤR&a ++1 SԜBԢ}9[p hyp^¥~ruHZ7>t0,})]X$%L'K!l|$xWc4\ ++$&. ?C @x$"EIf5*Ra92Ry3q PqKc Ѽ=;ZmcȰW--/$Tk *iH Lj`X[3w XC!EDTFb<)x0f({  t!@j_.5FL p@b7@,.lp!xx~i8^ r#aǬf!- ++D{;עo[;H3@ ++@!8l21RXH5PDP̰1JC["reG9HCt(}cl!"yPgTaQ͟M{ = ++ yx8 Pm|@D'"L/PB !e[Qln E0~( `5 ++3vBda3RJ@ ⫹9Dy´3 Skt6N)?W2A`l# Y0i(@ ++;= GL9 3rۗq "#bmS"UPoVPf@q 0FvPht ilP;-4KPїu #01YZŌ ++("81PtfptpE@ ++ U`X8P3 ++YV^<+D®l p*`v ]A@82}+"ppW8mb{U qn a wˍd* B@IV!P$+l +m` '>KxceE`G9K]04ūNj +l g gk0鎕$#6\ЁB0wߋ j㋵P}P6IPZtDk}e)¦;js!P \$ `m+(((pr ++uJ0@ :&4L` k=8{mplO<P @@xӲH+!w& Z3 ;jj } 0 l*r+ mJkl% B ߐ1Lj?< ++r!0 -[8#ZI*+z4@,|倱019,0A'%0 c T#`"/' /D N`́IHHmtڂ0q9L@(HjB%T]ìjF E2}%$X8qńN@€0@L!K TO -` ++* CP 4p!}B Lz&O6 &A2$$%M$Ld@< 59(] =-(B]`JpϠ v F p9x<`HJә#P&'+ 9IPsIq@1ԁ ++c=VS`đ(p ++-k`&fN&K)] VF"6(Lʲ L.oLW f&-59;ۗ~ q ++P@4 ++rK ++s#@LcAx% B(l;S2p`p9|0na ݂l ++%g@ζ`+";P dpe0 ahQpئ ٌ(%xW % k"3x $Cd*yΈQ(P;~0àʢ&P<'֪&⪔zR$S$ n @n`O=ӻ ++`Ȍ-Po.xWkw0 4]Is7 ǁT|@p͡<ʦ`Xlh | -I[`&"gaqF 1 a ++PխrUR22}L@K$Qa`PV}OPG`0c(F PoKﭽ`N"1 K`@DP.LML`d ++NC @DN_4x/P[X%!Ȳb ϼp ++q m@@ ~P !Hl qgЂnO ++k\ ]a82\ .An;`#6R/̸| $XA .dC%NTTZKʕ悃!E)wA@9L< 1yրCVA^ ++K %ZQx/QAcLCOnzP!U0!$H 8³qΥ[.. ++@YH$΁P <a`gLTZj[\>whO7s;dݷ8C0R{Cy_ "E臠.#G:ge㢖\{%CLhLbޑvgJ 0Qv.$;Pv1:2n8(t{CXwƧ~ &z#I"# ',k1 v ++57 ּ]w*nuZ9 ++*uCڜƨלmʹ@b%`C#by`` $g %'tw _%*Hq_I`%:pj`mA σfxHBe ` ++ x@:X` шnt t-`PRL8X@<<@Z`Nۂ!AŰC N+l Jx/\7uJ҂HaEQ P!K@&x@& G@B$ a 468VU/B<o  7y@Ocl ~NEV(+u 10o0#ҢC,z=#U0}r8 tF&l Q@h^ЂZ4Tt.C;&{`a\Gf.Z@6B_d-L&'8 X=y0K2΀AQ(`؍PYg&Nj*4L fE# "IZ A ++A b ++'` 1o$ ++=Sn4b77$]Y,T#@tC"}" ЩLJ Xa K&@pԁD) +jBA̠ ++CT }elB@r>{B,C1D4?q0&"AF#&P D *aB-B/]3asH!C^V`*g|Q cE7h H ++ZC(P]7~9 "Ap9e2V Z9[498Q'I.1@Pq*,pjܓMlq:"ԀE0% `}Yqq$/iXE +f &$v=G"AgIK AJ pB(v &ev3jݶ;PzaCB Ox`Z ϲGօ4 F*pY:$0ဃB%JPeg["q8P:ux1Oh':k.[Pкn'|WB @  g9%Ѻ͢e ++@*\#7Q[S``e?b vq`0}XWZ6ha&I3;Ep[:E  EP8 PYp 1{B&(H6̺P Р~^#V'z޵wg޳]N/9Ƀ@*p]ts\5! a|m0 ";514@n {Pݴm X;G>6' H\?w?S6鼴^>(d c *v ++'a}K?h?i!8;CzUS?t;;t @]34H߻?  |Ae ?TAC80 0X,LBI K;NK8 ++TB03q<!BA_ C9I1!c0PK9 A;HCCıg>l3(/࿃@Z􎖲9PEg&A@Q"@+V<'|FoojlDSlFxPāt46ԭwG~3~DLM|K ++4NLŚddlN4*fH[Dw„ O) ++x켇c ODaL*dI`Ot[D.ONt{C4fP΋tP1 8do`?D@m>H \,Qd0HQHeQ=QDSH)D1N0t]!EM=HJI^\Ĺ<F)LR,EЅ#1P/L<+3=L'-u|, (xS24Q?uJ<3`,=Ԭ|2_8;](TGE݅F+Aԏ`N`^`n`~`` ` ++` ` ` ```aa.a>aFۀ!,K H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ ++JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pf|Lݻ5˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(O=#+7 x E`H8 RHQeѡ8t8^w^^;PԨ) Tp |X+`658E ,Bkk}ݕgv{Yz džy0Ȋ@9c 숕y[ ׄvW'd u @T<[n@gq0ndz%}fHfj LИF x 'Y@u"pSHPu%ZE gpHvGffmVp`*xy Y459 @CpetpShEp&y<VP ++k)Pyٝ'dXXמW ,ڢG b"ti0TUEoz+0 t {;A}X$ ++GR}Ét! `p.J pU" gD ++pn0aA؅d`}Zb)(!}whjmЭ!%@Scp ++gjH@H ++< lvipްUP@oע+G؎O ! mߤAjА[s@LP Pp)~ 0  ]Z@؊BhiJ J0 hpUuY^Ho w+Q@n t&ӈ 0N۠nPܺu(pZHW*F[V798p5h#p pU- ++.YiU ` x!mgPXh^Kzݐ^ffj op ++N@DKz`_M( @zZtSpa{P ++0Y0X@F^Hг. ++ګi X) +@5 K Se L̠*T`)Jf^0L0 APu\ PT - ++xJJPu5'ƅ 0k@T GՐ\P ++7!1Ģj 0$SP p Lp@a.)9 9QpV M+(pYhpym ppm}p(K S,5@]Z\xy T0YAe5, \JPZUSjKʿj* ʃ*\Uy\r^v4) a ++Bs +ŰV j ++a a [,uiiQPZp8v |O  nК ѯ~Y HIV@DMOд(`U` `Qgp,!;Ωt J ++ ++P-@Э- 5pP(=<` |HPPr&() n` dA |0i`KXɥEh<L y PZP?' (OQXuOjAXIP:iʎܝoŀޏE߄{dPipL4U@跦 ʀJ 4HpO sKgђ`ݭM~P ++L;,:mΥ0ׅj ݐJ,M@ ++mLmw,O@ u ++pQhy7)M' ++C@n)B^=y0 Eu&b cJIjP&nͫ* ++p ++j; P 'KiyQP혋J^쒰S, FـrpQgDP ++IF@Ig Z0O+Ucn؅#P ++MZ d.Zp~2OzpSPaj>I ++Ncʼnώ-- ++`]`>]9=0M0ͱ rc! ++L x +PGQ!nV` #}KVpمyu`, ۭNǢG %U, ++"!ع/~ ̿Z(2K?+ L`ߠKK|H*W6~=yk]ƒ$O!ϰI)UMg1eΜCHqZF") u{,.eSQNZU(݀"s5HO0^|IB6sTV=fB$1 A9Ѣ)@[e̙5ooEYH:t,UKS*B*3*MdTǎ@y6[oO^u 0rڻW*e;$0 B&*:wf@ PQFy ; 4@ɁI4+""0ɒB"@kB 4tEcj" ++uT0#FLD*! CD&g IF,RFJ"-QdzXmB01fS`&vhq&, ++ ha- 5Pa"Je$6~9s'\;BK3!aPjF\s 7!Q\sՕ)]UЂth<Բ>+f`>Z ++I" XI6rgĀvu]] E~-Hi;Q'1*]Ι ^hڙ&pܡLw ܹ^Cv@J{gѢBيAM"TDDBa@p$˜=]`Xdm"W((@ҳ9S',\M7@P hZ >N2>tQo3~ar4G1Y@R%S8\0galoZ $c]ƅ5hcs׽_a7() ++%~[ @cm +D2Pw@Rp\*Ђ3f,Hb !C%&g*ϣΊ)Ny 6T@7z ++ؕ(i^s& ++=}bH}`ʳij /M97v"L GI=I.: ++/Av 0v5St)Zgpc}/#FpB swś ++$ }hcQͨT7<PO0A50Xlq ~nJ?7*EWpZBa9J2H@sԉ~ߴ BE6r8܊r Hasނk /to[<3>$tk ;,W{ş7 ihΠ@rd?eAJF0;|#5 :+ yJ'8BJA|.Y@G%./Mg-+~X`@L6kKSh @ ++XF:@bJh:#s4Nx)* 7b$B&IMk  ++ (1b;Hb1:ɌBw HP7ĉ 8-C$# $/Qb?+:pF/ڍC$L8:(+ʨ,$n(Eo-̌(`ţHCˢp!lMHߢMDECAJLj&$L:F,|\N/A{5 5PĂ(pjF_ ONKZiMOC FD' ˟b "@8P 0KlPНĂ `M ++1Ȁ:ODK;R1ؿvnU|]M؅ oXIMuSHy&} O\l\1;(.j<9e $4.%O*5ŕNk@EP6LSC+ö;4F;B5<;DTL0d!|8ȁ̯+a&b+hb-I_1_0A)&c ++4v-Iܥ""J8c=>; @n4HFaD.]1E怨I>.d @1Ѕ=%&eW~eXeYeZe[e\e]e^e_e`fafb.fc>fdNfe^ffnfg~fhfifjfkflfmfnfofpgqgr.gs>gtNgu^gvngw~gt; +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-5.1.4/ext/gd/tests/bug37360.phpt hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.phpt +--- php-5.1.4/ext/gd/tests/bug37360.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.phpt 2006-09-05 20:31:02.000000000 +0200 +@@ -0,0 +1,14 @@ ++--TEST-- ++Bug #37360 (gdimagecreatefromgif, bad image sizes) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECTF-- ++resource(%d) of type (gd) +diff -Nura php-5.1.4/ext/imap/php_imap.c hardening-patch-5.1.4-0.4.15/ext/imap/php_imap.c +--- php-5.1.4/ext/imap/php_imap.c 2006-01-28 09:07:20.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/imap/php_imap.c 2006-09-05 20:31:02.000000000 +0200 +@@ -26,7 +26,7 @@ + | PHP 4.0 updates: Zeev Suraski | + +----------------------------------------------------------------------+ + */ +-/* $Id: php_imap.c,v 1.208.2.7 2006/01/28 08:07:20 mike Exp $ */ ++/* $Id: php_imap.c,v 1.208.2.8 2006/08/04 20:31:41 iliaa Exp $ */ + + #define IMAP41 + +@@ -761,6 +761,13 @@ + efree(IMAPG(imap_password)); + } + ++ /* local filename, need to perform open_basedir and safe_mode checks */ ++ if (Z_STRVAL_PP(mailbox)[0] != '{' && ++ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || ++ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { ++ RETURN_FALSE; ++ } ++ + IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); + IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); + +diff -Nura php-5.1.4/ext/mysql/php_mysql.c hardening-patch-5.1.4-0.4.15/ext/mysql/php_mysql.c +--- php-5.1.4/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:31:02.000000000 +0200 +@@ -1231,6 +1231,8 @@ + { + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; ++ char *copy_query; ++ int i; + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); + +@@ -1281,6 +1283,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #else +@@ -1291,6 +1300,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #endif +diff -Nura php-5.1.4/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.4-0.4.15/ext/mysqli/mysqli_nonapi.c +--- php-5.1.4/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/mysqli/mysqli_nonapi.c 2006-09-05 20:31:02.000000000 +0200 +@@ -184,6 +184,17 @@ + if (mysql_real_query(mysql->mysql, query, query_len)) { + char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; + unsigned int s_errno; ++#if HARDENING_PATCH ++ char *query_copy = estrdup(query); ++ int i; ++ ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } ++#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + + /* we have to save error information, cause +@@ -234,6 +245,17 @@ + MYSQLI_DISABLE_MQ; + + if (mysql_real_query(mysql->mysql, query, query_len)) { ++#if HARDENING_PATCH ++ char *query_copy = estrdup(query); ++ int i; ++ ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } ++#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } +diff -Nura php-5.1.4/ext/pgsql/pgsql.c hardening-patch-5.1.4-0.4.15/ext/pgsql/pgsql.c +--- php-5.1.4/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:31:04.000000000 +0200 +@@ -1152,10 +1152,28 @@ + case PGRES_EMPTY_QUERY: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: +- case PGRES_FATAL_ERROR: +- PHP_PQ_ERROR("Query failed: %s", pgsql); +- PQclear(pgsql_result); +- RETURN_FALSE; ++ case PGRES_FATAL_ERROR: ++ { ++#if HARDENING_PATCH ++ int i; ++ char *query_copy; ++#endif ++ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); ++ PQclear(pgsql_result); ++#if HARDENING_PATCH ++ query_copy = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ efree(msgbuf); ++ zend_bailout(); ++ } ++#endif ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); ++ efree(msgbuf); ++ RETURN_FALSE; ++ } + break; + case PGRES_COMMAND_OK: /* successful command that did not return rows */ + default: +diff -Nura php-5.1.4/ext/session/mod_files.c hardening-patch-5.1.4-0.4.15/ext/session/mod_files.c +--- php-5.1.4/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/session/mod_files.c 2006-09-05 20:31:04.000000000 +0200 +@@ -152,6 +152,7 @@ + + if (!ps_files_valid_key(key)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); ++ PS(invalid_session_id) = 1; + return; + } + if (!ps_files_path_create(buf, sizeof(buf), data, key)) +@@ -401,7 +402,12 @@ + ps_files_close(data); + + if (VCWD_UNLINK(buf) == -1) { +- return FAILURE; ++ /* This is a little safety check for instances when we are dealing with a regenerated session ++ * that was not yet written to disk ++ */ ++ if (!VCWD_ACCESS(buf, F_OK)) { ++ return FAILURE; ++ } + } + } + +@@ -422,6 +428,35 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(files) ++{ ++ char buf[MAXPATHLEN]; ++ int fd; ++ PS_FILES_DATA; ++ ++ if (!ps_files_valid_key(key)) { ++ return FAILURE; ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { ++ return FAILURE; ++ } ++ ++ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, ++ data->filemode); ++ ++ if (fd != -1) { ++ close(fd); ++ return SUCCESS; ++ } ++ ++ return FAILURE; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-5.1.4/ext/session/mod_mm.c hardening-patch-5.1.4-0.4.15/ext/session/mod_mm.c +--- php-5.1.4/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/session/mod_mm.c 2006-09-05 20:31:04.000000000 +0200 +@@ -425,6 +425,42 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(mm) ++{ ++ PS_MM_DATA; ++ ps_sd *sd; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ } ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ mm_lock(data->mm, MM_LOCK_RD); ++ ++ sd = ps_sd_lookup(data, key, 0); ++ if (sd) { ++ mm_unlock(data->mm); ++ return SUCCESS; ++ } ++ ++ mm_unlock(data->mm); ++ ++ return FAILURE; ++} ++ + #endif + + /* +diff -Nura php-5.1.4/ext/session/mod_user.c hardening-patch-5.1.4-0.4.15/ext/session/mod_user.c +--- php-5.1.4/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/session/mod_user.c 2006-09-05 20:31:04.000000000 +0200 +@@ -23,7 +23,7 @@ + #include "mod_user.h" + + ps_module ps_mod_user = { +- PS_MOD(user) ++ PS_MOD_SID(user) + }; + + #define SESS_ZVAL_LONG(val, a) \ +@@ -174,6 +174,83 @@ + FINISH; + } + ++PS_CREATE_SID_FUNC(user) ++{ ++ int i; ++ char *val = NULL; ++ zval *retval; ++ ps_user *mdata = PS_GET_MOD_DATA(); ++ ++ if (!mdata) ++ return estrndup("", 0); ++ ++ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { ++ return php_session_create_id(mod_data, newlen TSRMLS_CC); ++ } ++ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); ++ ++ if (retval) { ++ if (Z_TYPE_P(retval) == IS_STRING) { ++ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); ++ } else { ++ val = estrndup("", 0); ++ } ++ zval_ptr_dtor(&retval); ++ } else { ++ val = estrndup("", 0); ++ } ++ ++ return val; ++} ++ ++static int ps_user_valid_key(const char *key TSRMLS_DC) ++{ ++ size_t len; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ ret = FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ ret = FAILURE; ++ ++ return ret; ++} ++ ++PS_VALIDATE_SID_FUNC(user) ++{ ++ zval *args[1]; ++ STDVARS; ++ ++ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { ++ return ps_user_valid_key(key TSRMLS_CC); ++ } ++ SESS_ZVAL_STRING(key, args[0]); ++ ++ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); ++ ++ if (retval) { ++ convert_to_long(retval); ++ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; ++ zval_ptr_dtor(&retval); ++ } ++ ++ return ret; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-5.1.4/ext/session/mod_user.h hardening-patch-5.1.4-0.4.15/ext/session/mod_user.h +--- php-5.1.4/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/session/mod_user.h 2006-09-05 20:31:04.000000000 +0200 +@@ -22,7 +22,7 @@ + #define MOD_USER_H + + typedef union { +- zval *names[6]; ++ zval *names[8]; + struct { + zval *ps_open; + zval *ps_close; +@@ -30,6 +30,8 @@ + zval *ps_write; + zval *ps_destroy; + zval *ps_gc; ++ zval *ps_create; ++ zval *ps_validate; + } name; + } ps_user; + +diff -Nura php-5.1.4/ext/session/php_session.h hardening-patch-5.1.4-0.4.15/ext/session/php_session.h +--- php-5.1.4/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/session/php_session.h 2006-09-05 20:31:04.000000000 +0200 +@@ -23,7 +23,7 @@ + + #include "ext/standard/php_var.h" + +-#define PHP_SESSION_API 20020330 ++#define PHP_SESSION_API 20051121 + + #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC + #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC +@@ -32,6 +32,7 @@ + #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC + #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC + #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC ++#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC + + /* default create id function */ + PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); +@@ -45,6 +46,7 @@ + int (*s_destroy)(PS_DESTROY_ARGS); + int (*s_gc)(PS_GC_ARGS); + char *(*s_create_sid)(PS_CREATE_SID_ARGS); ++ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); + } ps_module; + + #define PS_GET_MOD_DATA() *mod_data +@@ -57,6 +59,7 @@ + #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) + #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) + #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) ++#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) + + #define PS_FUNCS(x) \ + PS_OPEN_FUNC(x); \ +@@ -65,11 +68,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID_FUNC(x) + + #define PS_MOD(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, php_session_create_id ++ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x + + /* SID enabled module handler definitions */ + #define PS_FUNCS_SID(x) \ +@@ -79,11 +83,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID(x) + + #define PS_MOD_SID(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, ps_create_sid_##x ++ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x + + typedef enum { + php_session_disabled, +@@ -120,11 +125,13 @@ + zend_bool use_only_cookies; + zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ ++ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + + long hash_func; + long hash_bits_per_character; + int send_cookie; + int define_sid; ++ zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ + } php_ps_globals; + + typedef php_ps_globals zend_ps_globals; +diff -Nura php-5.1.4/ext/session/session.c hardening-patch-5.1.4-0.4.15/ext/session/session.c +--- php-5.1.4/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/session/session.c 2006-09-05 20:31:04.000000000 +0200 +@@ -166,6 +166,7 @@ + STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) ++ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals) +@@ -280,9 +281,13 @@ + PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) + { + zval **sym_track = NULL; +- +- zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, +- (void *) &sym_track); ++ ++ IF_SESSION_VARS() { ++ zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, ++ (void *) &sym_track); ++ } else { ++ return; ++ } + + /* + * Set up a proper reference between $_SESSION["x"] and $x. +@@ -758,9 +763,23 @@ + return; + } + ++ /* If there is an ID, use session module to verify it */ ++ if (PS(id)) { ++ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ efree(PS(id)); ++ PS(id) = NULL; ++ PS(send_cookie) = 1; ++ } ++ } ++ + /* If there is no ID, use session module to create one */ +- if (!PS(id)) ++ if (!PS(id)) { ++new_session: + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); ++ if (PS(use_cookies)) { ++ PS(send_cookie) = 1; ++ } ++ } + + /* Read data */ + /* Question: if you create a SID here, should you also try to read data? +@@ -769,9 +788,14 @@ + * session information + */ + php_session_track_init(TSRMLS_C); ++ PS(invalid_session_id) = 0; + if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) { + php_session_decode(val, vallen TSRMLS_CC); + efree(val); ++ } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */ ++ PS(invalid_session_id) = 0; ++ efree(PS(id)); ++ goto new_session; + } + } + +@@ -1377,22 +1401,29 @@ + } + /* }}} */ + +-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) ++/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) + Sets user-level functions */ + PHP_FUNCTION(session_set_save_handler) + { +- zval **args[6]; +- int i; ++ zval **args[8]; ++ int i, numargs; + ps_user *mdata; + char *name; + +- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) ++ numargs = ZEND_NUM_ARGS(); ++ args[6] = NULL; ++ args[7] = NULL; ++ ++ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) + WRONG_PARAM_COUNT; + + if (PS(session_status) != php_session_none) + RETURN_FALSE; + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ continue; ++ } + if (!zend_is_callable(*args[i], 0, &name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); + efree(name); +@@ -1405,7 +1436,11 @@ + + mdata = emalloc(sizeof(*mdata)); + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ mdata->names[i] = NULL; ++ continue; ++ } + ZVAL_ADDREF(*args[i]); + mdata->names[i] = *args[i]; + } +@@ -1475,6 +1510,11 @@ + WRONG_PARAM_COUNT; + } + ++ if (SG(headers_sent)) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); ++ RETURN_FALSE; ++ } ++ + if (PS(session_status) == php_session_active) { + if (PS(id)) { + if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { +@@ -1531,8 +1571,8 @@ + WRONG_PARAM_COUNT; + + if (ac == 1) { +- convert_to_long_ex(p_cache_expire); +- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); ++ convert_to_string_ex(p_cache_expire); ++ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + } + + RETVAL_LONG(old); +diff -Nura php-5.1.4/ext/session/tests/014.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/014.phpt +--- php-5.1.4/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:31:04.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.bug_compat_42=1 +diff -Nura php-5.1.4/ext/session/tests/015.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/015.phpt +--- php-5.1.4/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:31:04.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + arg_separator.output=& + session.name=PHPSESSID +diff -Nura php-5.1.4/ext/session/tests/018.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/018.phpt +--- php-5.1.4/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:31:04.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + session.name=PHPSESSID +diff -Nura php-5.1.4/ext/session/tests/019.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/019.phpt +--- php-5.1.4/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/session/tests/019.phpt 2006-09-05 20:31:04.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.serialize_handler=php +diff -Nura php-5.1.4/ext/session/tests/020.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/020.phpt +--- php-5.1.4/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:31:04.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + arg_separator.output=& +diff -Nura php-5.1.4/ext/session/tests/021.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/021.phpt +--- php-5.1.4/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:31:04.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" +diff -Nura php-5.1.4/ext/session/tests/bug38377.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/bug38377.phpt +--- php-5.1.4/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:31:04.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++bug #38377 (session_destroy() gives warning after session_regenerate_id()) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECT-- ++Done +diff -Nura php-5.1.4/ext/sockets/sockets.c hardening-patch-5.1.4-0.4.15/ext/sockets/sockets.c +--- php-5.1.4/ext/sockets/sockets.c 2006-04-07 16:04:36.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/sockets/sockets.c 2006-09-05 20:31:04.000000000 +0200 +@@ -533,6 +533,7 @@ + { + zval **element; + php_socket *php_sock; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -547,9 +548,10 @@ + if (php_sock->bsd_socket > *max_fd) { + *max_fd = php_sock->bsd_socket; + } ++ num++; + } + +- return 1; ++ return num ? 1 : 0; + } + + static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) +@@ -558,6 +560,7 @@ + zval **dest_element; + php_socket *php_sock; + HashTable *new_hash; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -575,6 +578,7 @@ + zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); + if (dest_element) zval_add_ref(dest_element); + } ++ num++; + } + + /* Destroy old array, add new one */ +@@ -584,7 +588,7 @@ + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(sock_array) = new_hash; + +- return 1; ++ return num ? 1 : 0; + } + + /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds, int tv_sec[, int tv_usec]) +diff -Nura php-5.1.4/ext/sqlite/sess_sqlite.c hardening-patch-5.1.4-0.4.15/ext/sqlite/sess_sqlite.c +--- php-5.1.4/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/sqlite/sess_sqlite.c 2006-09-05 20:31:04.000000000 +0200 +@@ -185,6 +185,76 @@ + return SQLITE_RETVAL(rv); + } + ++PS_VALIDATE_SID_FUNC(sqlite) ++{ ++ PS_SQLITE_DATA; ++ char *query; ++ const char *tail; ++ sqlite_vm *vm; ++ int colcount, result; ++ const char **rowdata, **colnames; ++ char *error; ++ size_t len; ++ const char *p; ++ char c; ++ int ret = FAILURE; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ return FAILURE; ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key); ++ if (query == NULL) { ++ /* no memory */ ++ return FAILURE; ++ } ++ ++ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error); ++ sqlite_freemem(error); ++ sqlite_freemem(query); ++ return FAILURE; ++ } ++ ++ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) { ++ case SQLITE_ROW: ++ if (rowdata[0] != NULL) { ++ ret = SUCCESS; ++ } ++ break; ++ default: ++ sqlite_freemem(error); ++ error = NULL; ++ } ++ ++ if (SQLITE_OK != sqlite_finalize(vm, &error)) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error); ++ sqlite_freemem(error); ++ error = NULL; ++ } ++ ++ sqlite_freemem(query); ++ ++ return ret; ++} ++ + #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */ + + /* +diff -Nura php-5.1.4/ext/sqlite/sqlite.c hardening-patch-5.1.4-0.4.15/ext/sqlite/sqlite.c +--- php-5.1.4/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/sqlite/sqlite.c 2006-09-05 20:31:04.000000000 +0200 +@@ -1530,6 +1530,19 @@ + db->last_err_code = ret; + + if (ret != SQLITE_OK) { ++#if HARDENING_PATCH ++ char *query_copy; ++ int i; ++ ++ query_copy = estrdup(sql); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ sqlite_freemem(errtext); ++ zend_bailout(); ++ } ++#endif + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext); + if (errmsg) { + ZVAL_STRING(errmsg, errtext, 1); +diff -Nura php-5.1.4/ext/standard/array.c hardening-patch-5.1.4-0.4.15/ext/standard/array.c +--- php-5.1.4/ext/standard/array.c 2006-04-12 21:30:52.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/array.c 2006-09-05 20:31:04.000000000 +0200 +@@ -92,6 +92,8 @@ + + #define DOUBLE_DRIFT_FIX 0.000000000000001 + ++ZEND_DECLARE_MODULE_GLOBALS(array) ++ + /* {{{ php_array_init_globals + */ + static void php_array_init_globals(zend_array_globals *array_globals) +@@ -1295,6 +1297,32 @@ + } + } + } ++ ++ if (var_name[0] == 'H') { ++ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_FILES")==0)|| ++ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { ++ return 0; ++ } ++ } else if (var_name[0] == '_') { ++ if ((strcmp(var_name, "_COOKIE")==0)|| ++ (strcmp(var_name, "_ENV")==0)|| ++ (strcmp(var_name, "_FILES")==0)|| ++ (strcmp(var_name, "_GET")==0)|| ++ (strcmp(var_name, "_POST")==0)|| ++ (strcmp(var_name, "_REQUEST")==0)|| ++ (strcmp(var_name, "_SESSION")==0)|| ++ (strcmp(var_name, "_SERVER")==0)) { ++ return 0; ++ } ++ } else if (strcmp(var_name, "GLOBALS")==0) { ++ return 0; ++ } + + return 1; + } +diff -Nura php-5.1.4/ext/standard/basic_functions.c hardening-patch-5.1.4-0.4.15/ext/standard/basic_functions.c +--- php-5.1.4/ext/standard/basic_functions.c 2006-04-03 15:46:11.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:34:44.000000000 +0200 +@@ -151,12 +151,14 @@ + typedef struct _php_shutdown_function_entry { + zval **arguments; + int arg_count; ++ zend_bool created_by_eval; + } php_shutdown_function_entry; + + typedef struct _user_tick_function_entry { + zval **arguments; + int arg_count; + int calling; ++ zend_bool created_by_eval; + } user_tick_function_entry; + + /* some prototypes for local functions */ +@@ -188,6 +190,8 @@ + PHP_FE(get_html_translation_table, NULL) + PHP_FE(sha1, NULL) + PHP_FE(sha1_file, NULL) ++ PHP_FE(sha256, NULL) ++ PHP_FE(sha256_file, NULL) + PHP_NAMED_FE(md5,php_if_md5, NULL) + PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) + PHP_NAMED_FE(crc32,php_if_crc32, NULL) +@@ -632,7 +636,7 @@ + PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) + + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +- PHP_FE(realpath, NULL) ++ PHP_STATIC_FE("realpath", zif_real_path, NULL) + #endif + + #ifdef HAVE_FNMATCH +@@ -2034,7 +2038,7 @@ + break; + + case 3: /*save to a file */ +- stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); ++ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); + if (!stream) + return FAILURE; + php_stream_write(stream, message, strlen(message)); +@@ -2279,6 +2283,13 @@ + { + zval retval; + char *function_name = NULL; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (shutdown_function_entry->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { + php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); +@@ -2294,6 +2305,9 @@ + if (function_name) { + efree(function_name); + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + return 0; + } + +@@ -2301,6 +2315,13 @@ + { + zval retval; + zval *function = tick_fe->arguments[0]; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (tick_fe->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + /* Prevent reentrant calls to the same user ticks function */ + if (! tick_fe->calling) { +@@ -2332,6 +2353,9 @@ + + tick_fe->calling = 0; + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + } + + static void run_user_tick_functions(int tick_count) +@@ -2395,6 +2419,13 @@ + } + + shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ shutdown_function_entry.created_by_eval = 1; ++ } else { ++ shutdown_function_entry.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { + efree(shutdown_function_entry.arguments); +@@ -2722,6 +2753,15 @@ + + convert_to_string_ex(varname); + ++ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ ++ if (PG(safe_mode)) { ++ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || ++ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || ++ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { ++ RETURN_FALSE; ++ } ++ } ++ + zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); + } + /* }}} */ +@@ -2979,6 +3019,13 @@ + } + + tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ tick_fe.created_by_eval = 1; ++ } else { ++ tick_fe.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { + efree(tick_fe.arguments); +@@ -3282,6 +3329,35 @@ + new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); + } + ++ if (new_key[0] == 'H') { ++ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_FILES")==0)|| ++ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (new_key[0] == '_') { ++ if ((strcmp(new_key, "_COOKIE")==0)|| ++ (strcmp(new_key, "_ENV")==0)|| ++ (strcmp(new_key, "_FILES")==0)|| ++ (strcmp(new_key, "_GET")==0)|| ++ (strcmp(new_key, "_POST")==0)|| ++ (strcmp(new_key, "_REQUEST")==0)|| ++ (strcmp(new_key, "_SESSION")==0)|| ++ (strcmp(new_key, "_SERVER")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (strcmp(new_key, "GLOBALS")==0) { ++ efree(new_key); ++ return 0; ++ } ++ + zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); + ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); + +diff -Nura php-5.1.4/ext/standard/config.m4 hardening-patch-5.1.4-0.4.15/ext/standard/config.m4 +--- php-5.1.4/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/config.m4 2006-09-05 20:31:04.000000000 +0200 +@@ -203,7 +203,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) + ]) +@@ -489,7 +489,7 @@ + incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ + http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ + var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ +- filters.c proc_open.c streamsfuncs.c http.c) ++ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ) + + PHP_ADD_MAKEFILE_FRAGMENT + +diff -Nura php-5.1.4/ext/standard/config.w32 hardening-patch-5.1.4-0.4.15/ext/standard/config.w32 +--- php-5.1.4/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/config.w32 2006-09-05 20:31:04.000000000 +0200 +@@ -16,5 +16,5 @@ + url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ + php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ + user_filters.c uuencode.c filters.c proc_open.c \ +- streamsfuncs.c http.c", false /* never shared */); ++ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */); + +diff -Nura php-5.1.4/ext/standard/crypt_blowfish.c hardening-patch-5.1.4-0.4.15/ext/standard/crypt_blowfish.c +--- php-5.1.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:31:04.000000000 +0200 +@@ -0,0 +1,748 @@ ++/* ++ * This code comes from John the Ripper password cracker, with reentrant ++ * and crypt(3) interfaces added, but optimizations specific to password ++ * cracking removed. ++ * ++ * Written by Solar Designer in 1998-2002 and ++ * placed in the public domain. ++ * ++ * There's absolutely no warranty. ++ * ++ * It is my intent that you should be able to use this on your system, ++ * as a part of a software package, or anywhere else to improve security, ++ * ensure compatibility, or for any other purpose. I would appreciate ++ * it if you give credit where it is due and keep your modifications in ++ * the public domain as well, but I don't require that in order to let ++ * you place this code and any modifications you make under a license ++ * of your choice. ++ * ++ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) ++ * by Niels Provos , and uses some of his ++ * ideas. The password hashing algorithm was designed by David Mazieres ++ * . ++ * ++ * There's a paper on the algorithm that explains its design decisions: ++ * ++ * http://www.usenix.org/events/usenix99/provos.html ++ * ++ * Some of the tricks in BF_ROUND might be inspired by Eric Young's ++ * Blowfish library (I can't be sure if I would think of something if I ++ * hadn't seen his code). ++ */ ++ ++#include ++ ++#include ++#ifndef __set_errno ++#define __set_errno(val) errno = (val) ++#endif ++ ++#undef __CONST ++#ifdef __GNUC__ ++#define __CONST __const ++#else ++#define __CONST ++#endif ++ ++#ifdef __i386__ ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#elif defined(__alpha__) || defined(__hppa__) ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#else ++#define BF_ASM 0 ++#define BF_SCALE 0 ++#endif ++ ++typedef unsigned int BF_word; ++ ++/* Number of Blowfish rounds, this is also hardcoded into a few places */ ++#define BF_N 16 ++ ++typedef BF_word BF_key[BF_N + 2]; ++ ++typedef struct { ++ BF_word S[4][0x100]; ++ BF_key P; ++} BF_ctx; ++ ++/* ++ * Magic IV for 64 Blowfish encryptions that we do at the end. ++ * The string is "OrpheanBeholderScryDoubt" on big-endian. ++ */ ++static BF_word BF_magic_w[6] = { ++ 0x4F727068, 0x65616E42, 0x65686F6C, ++ 0x64657253, 0x63727944, 0x6F756274 ++}; ++ ++/* ++ * P-box and S-box tables initialized with digits of Pi. ++ */ ++static BF_ctx BF_init_state = { ++ { ++ { ++ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, ++ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, ++ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, ++ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, ++ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, ++ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, ++ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, ++ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, ++ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, ++ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, ++ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, ++ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, ++ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, ++ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, ++ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, ++ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, ++ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, ++ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, ++ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, ++ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, ++ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, ++ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, ++ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, ++ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, ++ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, ++ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, ++ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, ++ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, ++ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, ++ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, ++ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, ++ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, ++ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, ++ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, ++ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, ++ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, ++ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, ++ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, ++ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, ++ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, ++ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, ++ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, ++ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, ++ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, ++ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, ++ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, ++ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, ++ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, ++ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, ++ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, ++ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, ++ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, ++ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, ++ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, ++ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, ++ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, ++ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, ++ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, ++ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, ++ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, ++ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, ++ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, ++ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, ++ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a ++ }, { ++ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, ++ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, ++ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, ++ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, ++ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, ++ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, ++ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, ++ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, ++ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, ++ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, ++ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, ++ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, ++ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, ++ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, ++ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, ++ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, ++ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, ++ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, ++ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, ++ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, ++ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, ++ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, ++ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, ++ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, ++ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, ++ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, ++ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, ++ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, ++ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, ++ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, ++ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, ++ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, ++ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, ++ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, ++ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, ++ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, ++ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, ++ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, ++ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, ++ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, ++ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, ++ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, ++ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, ++ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, ++ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, ++ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, ++ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, ++ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, ++ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, ++ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, ++ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, ++ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, ++ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, ++ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, ++ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, ++ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, ++ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, ++ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, ++ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, ++ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, ++ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, ++ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, ++ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, ++ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 ++ }, { ++ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, ++ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, ++ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, ++ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, ++ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, ++ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, ++ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, ++ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, ++ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, ++ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, ++ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, ++ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, ++ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, ++ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, ++ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, ++ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, ++ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, ++ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, ++ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, ++ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, ++ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, ++ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, ++ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, ++ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, ++ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, ++ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, ++ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, ++ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, ++ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, ++ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, ++ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, ++ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, ++ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, ++ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, ++ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, ++ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, ++ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, ++ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, ++ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, ++ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, ++ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, ++ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, ++ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, ++ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, ++ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, ++ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, ++ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, ++ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, ++ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, ++ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, ++ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, ++ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, ++ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, ++ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, ++ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, ++ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, ++ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, ++ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, ++ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, ++ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, ++ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, ++ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, ++ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, ++ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 ++ }, { ++ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, ++ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, ++ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, ++ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, ++ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, ++ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, ++ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, ++ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, ++ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, ++ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, ++ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, ++ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, ++ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, ++ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, ++ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, ++ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, ++ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, ++ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, ++ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, ++ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, ++ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, ++ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, ++ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, ++ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, ++ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, ++ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, ++ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, ++ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, ++ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, ++ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, ++ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, ++ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, ++ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, ++ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, ++ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, ++ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, ++ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, ++ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, ++ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, ++ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, ++ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, ++ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, ++ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, ++ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, ++ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, ++ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, ++ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, ++ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, ++ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, ++ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, ++ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, ++ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, ++ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, ++ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, ++ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, ++ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, ++ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, ++ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, ++ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, ++ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, ++ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, ++ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, ++ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, ++ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 ++ } ++ }, { ++ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, ++ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, ++ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, ++ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, ++ 0x9216d5d9, 0x8979fb1b ++ } ++}; ++ ++static unsigned char BF_itoa64[64 + 1] = ++ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ++ ++static unsigned char BF_atoi64[0x60] = { ++ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, ++ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, ++ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, ++ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, ++ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 ++}; ++ ++/* ++ * This may be optimized out if built with function inlining and no BF_ASM. ++ */ ++static void clean(void *data, int size) ++{ ++#if BF_ASM ++ extern void _BF_clean(void *data); ++#endif ++ memset(data, 0, size); ++#if BF_ASM ++ _BF_clean(data); ++#endif ++} ++ ++#define BF_safe_atoi64(dst, src) \ ++{ \ ++ tmp = (unsigned char)(src); \ ++ if (tmp == '$') break; \ ++ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ ++ tmp = BF_atoi64[tmp]; \ ++ if (tmp > 63) return -1; \ ++ (dst) = tmp; \ ++} ++ ++static int BF_decode(BF_word *dst, __CONST char *src, int size) ++{ ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned char *end = dptr + size; ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned int tmp, c1, c2, c3, c4; ++ ++ do { ++ BF_safe_atoi64(c1, *sptr++); ++ BF_safe_atoi64(c2, *sptr++); ++ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c3, *sptr++); ++ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c4, *sptr++); ++ *dptr++ = ((c3 & 0x03) << 6) | c4; ++ } while (dptr < end); ++ ++ while (dptr < end) ++ *dptr++ = 0; ++ ++ return 0; ++} ++ ++static void BF_encode(char *dst, __CONST BF_word *src, int size) ++{ ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned char *end = sptr + size; ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned int c1, c2; ++ ++ do { ++ c1 = *sptr++; ++ *dptr++ = BF_itoa64[c1 >> 2]; ++ c1 = (c1 & 0x03) << 4; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 4; ++ *dptr++ = BF_itoa64[c1]; ++ c1 = (c2 & 0x0f) << 2; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 6; ++ *dptr++ = BF_itoa64[c1]; ++ *dptr++ = BF_itoa64[c2 & 0x3f]; ++ } while (sptr < end); ++} ++ ++static void BF_swap(BF_word *x, int count) ++{ ++ static int endianness_check = 1; ++ char *is_little_endian = (char *)&endianness_check; ++ BF_word tmp; ++ ++ if (*is_little_endian) ++ do { ++ tmp = *x; ++ tmp = (tmp << 16) | (tmp >> 16); ++ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); ++ } while (--count); ++} ++ ++#if BF_SCALE ++/* Architectures which can shift addresses left by 2 bits with no extra cost */ ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp2 = L >> 8; \ ++ tmp2 &= 0xFF; \ ++ tmp3 = L >> 16; \ ++ tmp3 &= 0xFF; \ ++ tmp4 = L >> 24; \ ++ tmp1 = data.ctx.S[3][tmp1]; \ ++ tmp2 = data.ctx.S[2][tmp2]; \ ++ tmp3 = data.ctx.S[1][tmp3]; \ ++ tmp3 += data.ctx.S[0][tmp4]; \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#else ++/* Architectures with no complicated addressing modes supported */ ++#define BF_INDEX(S, i) \ ++ (*((BF_word *)(((unsigned char *)S) + (i)))) ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp1 <<= 2; \ ++ tmp2 = L >> 6; \ ++ tmp2 &= 0x3FC; \ ++ tmp3 = L >> 14; \ ++ tmp3 &= 0x3FC; \ ++ tmp4 = L >> 22; \ ++ tmp4 &= 0x3FC; \ ++ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ ++ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ ++ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ ++ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#endif ++ ++/* ++ * Encrypt one block, BF_N is hardcoded here. ++ */ ++#define BF_ENCRYPT \ ++ L ^= data.ctx.P[0]; \ ++ BF_ROUND(L, R, 0); \ ++ BF_ROUND(R, L, 1); \ ++ BF_ROUND(L, R, 2); \ ++ BF_ROUND(R, L, 3); \ ++ BF_ROUND(L, R, 4); \ ++ BF_ROUND(R, L, 5); \ ++ BF_ROUND(L, R, 6); \ ++ BF_ROUND(R, L, 7); \ ++ BF_ROUND(L, R, 8); \ ++ BF_ROUND(R, L, 9); \ ++ BF_ROUND(L, R, 10); \ ++ BF_ROUND(R, L, 11); \ ++ BF_ROUND(L, R, 12); \ ++ BF_ROUND(R, L, 13); \ ++ BF_ROUND(L, R, 14); \ ++ BF_ROUND(R, L, 15); \ ++ tmp4 = R; \ ++ R = L; \ ++ L = tmp4 ^ data.ctx.P[BF_N + 1]; ++ ++#if BF_ASM ++#define BF_body() \ ++ _BF_body_r(&data.ctx); ++#else ++#define BF_body() \ ++ L = R = 0; \ ++ ptr = data.ctx.P; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.P[BF_N + 2]); \ ++\ ++ ptr = data.ctx.S[0]; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.S[3][0xFF]); ++#endif ++ ++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) ++{ ++ __CONST char *ptr = key; ++ int i, j; ++ BF_word tmp; ++ ++ for (i = 0; i < BF_N + 2; i++) { ++ tmp = 0; ++ for (j = 0; j < 4; j++) { ++ tmp <<= 8; ++ tmp |= *ptr; ++ ++ if (!*ptr) ptr = key; else ptr++; ++ } ++ ++ expanded[i] = tmp; ++ initial[i] = BF_init_state.P[i] ^ tmp; ++ } ++} ++ ++char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, ++ char *output, int size) ++{ ++#if BF_ASM ++ extern void _BF_body_r(BF_ctx *ctx); ++#endif ++ struct { ++ BF_ctx ctx; ++ BF_key expanded_key; ++ union { ++ BF_word salt[4]; ++ BF_word output[6]; ++ } binary; ++ } data; ++ BF_word L, R; ++ BF_word tmp1, tmp2, tmp3, tmp4; ++ BF_word *ptr; ++ BF_word count; ++ int i; ++ ++ if (size < 7 + 22 + 31 + 1) { ++ __set_errno(ERANGE); ++ return NULL; ++ } ++ ++ if (setting[0] != '$' || ++ setting[1] != '2' || ++ setting[2] != 'a' || ++ setting[3] != '$' || ++ setting[4] < '0' || setting[4] > '3' || ++ setting[5] < '0' || setting[5] > '9' || ++ setting[6] != '$') { ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); ++ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { ++ clean(data.binary.salt, sizeof(data.binary.salt)); ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ BF_swap(data.binary.salt, 4); ++ ++ BF_set_key(key, data.expanded_key, data.ctx.P); ++ ++ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); ++ ++ L = R = 0; ++ for (i = 0; i < BF_N + 2; i += 2) { ++ L ^= data.binary.salt[i & 2]; ++ R ^= data.binary.salt[(i & 2) + 1]; ++ BF_ENCRYPT; ++ data.ctx.P[i] = L; ++ data.ctx.P[i + 1] = R; ++ } ++ ++ ptr = data.ctx.S[0]; ++ do { ++ ptr += 4; ++ L ^= data.binary.salt[(BF_N + 2) & 3]; ++ R ^= data.binary.salt[(BF_N + 3) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 4) = L; ++ *(ptr - 3) = R; ++ ++ L ^= data.binary.salt[(BF_N + 4) & 3]; ++ R ^= data.binary.salt[(BF_N + 5) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 2) = L; ++ *(ptr - 1) = R; ++ } while (ptr < &data.ctx.S[3][0xFF]); ++ ++ do { ++ data.ctx.P[0] ^= data.expanded_key[0]; ++ data.ctx.P[1] ^= data.expanded_key[1]; ++ data.ctx.P[2] ^= data.expanded_key[2]; ++ data.ctx.P[3] ^= data.expanded_key[3]; ++ data.ctx.P[4] ^= data.expanded_key[4]; ++ data.ctx.P[5] ^= data.expanded_key[5]; ++ data.ctx.P[6] ^= data.expanded_key[6]; ++ data.ctx.P[7] ^= data.expanded_key[7]; ++ data.ctx.P[8] ^= data.expanded_key[8]; ++ data.ctx.P[9] ^= data.expanded_key[9]; ++ data.ctx.P[10] ^= data.expanded_key[10]; ++ data.ctx.P[11] ^= data.expanded_key[11]; ++ data.ctx.P[12] ^= data.expanded_key[12]; ++ data.ctx.P[13] ^= data.expanded_key[13]; ++ data.ctx.P[14] ^= data.expanded_key[14]; ++ data.ctx.P[15] ^= data.expanded_key[15]; ++ data.ctx.P[16] ^= data.expanded_key[16]; ++ data.ctx.P[17] ^= data.expanded_key[17]; ++ ++ BF_body(); ++ ++ tmp1 = data.binary.salt[0]; ++ tmp2 = data.binary.salt[1]; ++ tmp3 = data.binary.salt[2]; ++ tmp4 = data.binary.salt[3]; ++ data.ctx.P[0] ^= tmp1; ++ data.ctx.P[1] ^= tmp2; ++ data.ctx.P[2] ^= tmp3; ++ data.ctx.P[3] ^= tmp4; ++ data.ctx.P[4] ^= tmp1; ++ data.ctx.P[5] ^= tmp2; ++ data.ctx.P[6] ^= tmp3; ++ data.ctx.P[7] ^= tmp4; ++ data.ctx.P[8] ^= tmp1; ++ data.ctx.P[9] ^= tmp2; ++ data.ctx.P[10] ^= tmp3; ++ data.ctx.P[11] ^= tmp4; ++ data.ctx.P[12] ^= tmp1; ++ data.ctx.P[13] ^= tmp2; ++ data.ctx.P[14] ^= tmp3; ++ data.ctx.P[15] ^= tmp4; ++ data.ctx.P[16] ^= tmp1; ++ data.ctx.P[17] ^= tmp2; ++ ++ BF_body(); ++ } while (--count); ++ ++ for (i = 0; i < 6; i += 2) { ++ L = BF_magic_w[i]; ++ R = BF_magic_w[i + 1]; ++ ++ count = 64; ++ do { ++ BF_ENCRYPT; ++ } while (--count); ++ ++ data.binary.output[i] = L; ++ data.binary.output[i + 1] = R; ++ } ++ ++ memcpy(output, setting, 7 + 22 - 1); ++ output[7 + 22 - 1] = BF_itoa64[(int) ++ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; ++ ++/* This has to be bug-compatible with the original implementation, so ++ * only encode 23 of the 24 bytes. :-) */ ++ BF_swap(data.binary.output, 6); ++ BF_encode(&output[7 + 22], data.binary.output, 23); ++ output[7 + 22 + 31] = '\0'; ++ ++/* Overwrite the most obvious sensitive data we have on the stack. Note ++ * that this does not guarantee there's no sensitive data left on the ++ * stack and/or in registers; I'm not aware of portable code that does. */ ++ clean(&data, sizeof(data)); ++ ++ return output; ++} ++ ++char *_crypt_gensalt_blowfish_rn(unsigned long count, ++ __CONST char *input, int size, char *output, int output_size) ++{ ++ if (size < 16 || output_size < 7 + 22 + 1 || ++ (count && (count < 4 || count > 31))) { ++ if (output_size > 0) output[0] = '\0'; ++ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); ++ return NULL; ++ } ++ ++ if (!count) count = 5; ++ ++ output[0] = '$'; ++ output[1] = '2'; ++ output[2] = 'a'; ++ output[3] = '$'; ++ output[4] = '0' + count / 10; ++ output[5] = '0' + count % 10; ++ output[6] = '$'; ++ ++ BF_encode(&output[7], (BF_word *)input, 16); ++ output[7 + 22] = '\0'; ++ ++ return output; ++} +diff -Nura php-5.1.4/ext/standard/crypt.c hardening-patch-5.1.4-0.4.15/ext/standard/crypt.c +--- php-5.1.4/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/crypt.c 2006-09-05 20:31:04.000000000 +0200 +@@ -100,6 +100,8 @@ + return SUCCESS; + } + ++char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); ++char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); + + static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +@@ -135,7 +137,14 @@ + + /* The automatic salt generation only covers standard DES and md5-crypt */ + if(!*salt) { +-#if PHP_MD5_CRYPT ++#if PHP_BLOWFISH_CRYPT ++ char randat[16]; ++ int i; ++ ++ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; ++ ++ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); ++#elif PHP_MD5_CRYPT + strcpy(salt, "$1$"); + php_to64(&salt[3], PHP_CRYPT_RAND, 4); + php_to64(&salt[7], PHP_CRYPT_RAND, 4); +@@ -145,8 +154,24 @@ + salt[2] = '\0'; + #endif + } +- +- RETVAL_STRING(crypt(str, salt), 1); ++ ++ if (salt[0] == '$' && ++ salt[1] == '2' && ++ salt[2] == 'a' && ++ salt[3] == '$' && ++ salt[4] >= '0' && salt[4] <= '3' && ++ salt[5] >= '0' && salt[5] <= '9' && ++ salt[6] == '$') { ++ ++ char output[PHP_MAX_SALT_LEN+1]; ++ ++ output[0] = 0; ++ _crypt_blowfish_rn(str, salt, output, sizeof(output)); ++ RETVAL_STRING(output, 1); ++ ++ } else { ++ RETVAL_STRING(crypt(str, salt), 1); ++ } + } + /* }}} */ + #endif +diff -Nura php-5.1.4/ext/standard/dl.c hardening-patch-5.1.4-0.4.15/ext/standard/dl.c +--- php-5.1.4/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/dl.c 2006-09-05 20:31:04.000000000 +0200 +@@ -164,8 +164,35 @@ + RETURN_FALSE; + } + module_entry = get_module(); ++ ++ /* check if Hardening-Patch is installed */ ++ if (module_entry->zend_api < 1000000000) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ ++ /* check if correct Hardening-Patch is installed */ ++ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ + if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) +- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { ++ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { + /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ + struct pre_4_1_0_module_entry { + char *name; +@@ -199,7 +226,7 @@ + zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; + } else { + name = module_entry->name; +- zend_api = module_entry->zend_api; ++ zend_api = module_entry->real_zend_api; + zend_debug = module_entry->zend_debug; + zts = module_entry->zts; + } +diff -Nura php-5.1.4/ext/standard/file.c hardening-patch-5.1.4-0.4.15/ext/standard/file.c +--- php-5.1.4/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/file.c 2006-09-05 20:31:04.000000000 +0200 +@@ -2302,7 +2302,7 @@ + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) + /* {{{ proto string realpath(string path) + Return the resolved path */ +-PHP_FUNCTION(realpath) ++PHP_FUNCTION(real_path) + { + zval **path; + char resolved_path_buff[MAXPATHLEN]; +diff -Nura php-5.1.4/ext/standard/file.h hardening-patch-5.1.4-0.4.15/ext/standard/file.h +--- php-5.1.4/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/file.h 2006-09-05 20:31:04.000000000 +0200 +@@ -61,7 +61,7 @@ + PHP_FUNCTION(fd_set); + PHP_FUNCTION(fd_isset); + #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) +-PHP_FUNCTION(realpath); ++PHP_FUNCTION(real_path); + PHP_FUNCTION(fnmatch); + #endif + PHP_NAMED_FUNCTION(php_if_ftruncate); +diff -Nura php-5.1.4/ext/standard/filestat.c hardening-patch-5.1.4-0.4.15/ext/standard/filestat.c +--- php-5.1.4/ext/standard/filestat.c 2006-04-25 10:41:02.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/filestat.c 2006-09-05 20:31:04.000000000 +0200 +@@ -16,7 +16,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: filestat.c,v 1.136.2.8 2006/04/25 08:41:02 tony2001 Exp $ */ ++/* $Id: filestat.c,v 1.136.2.9 2006/08/10 21:30:23 iliaa Exp $ */ + + #include "php.h" + #include "safe_mode.h" +@@ -634,7 +634,7 @@ + } + + if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) { +- if (php_check_open_basedir(local TSRMLS_CC)) { ++ if (php_check_open_basedir(local TSRMLS_CC) || (PG(safe_mode) && !php_checkuid_ex(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS, CHECKUID_NO_ERRORS))) { + RETURN_FALSE; + } + } +diff -Nura php-5.1.4/ext/standard/head.c hardening-patch-5.1.4-0.4.15/ext/standard/head.c +--- php-5.1.4/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/head.c 2006-09-05 20:31:04.000000000 +0200 +@@ -45,7 +45,7 @@ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, + &ctr.line_len, &rep, &ctr.response_code) == FAILURE) + return; +- ++ + sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); + } + /* }}} */ +diff -Nura php-5.1.4/ext/standard/info.c hardening-patch-5.1.4-0.4.15/ext/standard/info.c +--- php-5.1.4/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/info.c 2006-09-05 20:31:04.000000000 +0200 +@@ -154,7 +154,7 @@ + if (Z_TYPE_PP(tmp) == IS_ARRAY) { + if (!sapi_module.phpinfo_as_text) { + PUTS("
");
+-					zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
++					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
+ 					PUTS("
"); + } else { + zend_print_zval_r(*tmp, 0 TSRMLS_CC); +@@ -411,7 +411,7 @@ + + if (flag & PHP_INFO_GENERAL) { + char *zend_version = get_zend_version(); +- char temp_api[10]; ++ char temp_api[11]; + char *logo_guid; + + php_uname = php_get_uname('a'); +@@ -434,11 +434,22 @@ + PUTS("\" alt=\"PHP Logo\" />"); + } + ++#if HARDENING_PATCH ++ if (!sapi_module.phpinfo_as_text) { ++ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); ++ } else { ++ char temp_ver[40]; ++ ++ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); ++ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); ++ } ++#else + if (!sapi_module.phpinfo_as_text) { + php_printf("

PHP Version %s

\n", PHP_VERSION); + } else { + php_info_print_table_row(2, "PHP Version", PHP_VERSION); +- } ++ } ++#endif + php_info_print_box_end(); + php_info_print_table_start(); + php_info_print_table_row(2, "System", php_uname ); +diff -Nura php-5.1.4/ext/standard/mail.c hardening-patch-5.1.4-0.4.15/ext/standard/mail.c +--- php-5.1.4/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/mail.c 2006-09-05 20:31:04.000000000 +0200 +@@ -78,6 +78,25 @@ + } + /* }}} */ + ++/* {{{ hphp_strcasestr */ ++char *hphp_strcasestr(char *haystack, char *needle) ++{ ++ unsigned char *t, *h, *n; ++ ++ h = (unsigned char *) haystack; ++conts: ++ while (*h) { ++ n = (unsigned char *) needle; ++ for (t=h++; *n && *h; t++, n++) { ++ if (toupper(*t) != toupper(*n)) goto conts; ++ } ++ return ((char*)h-1); ++ } ++ ++ return (NULL); ++} ++/* }}} */ ++ + /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) + Send an email message */ + PHP_FUNCTION(mail) +@@ -104,6 +123,44 @@ + return; + } + ++ if (HG(hphp_mailprotect) > 0) { ++ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { ++ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ /* check for spam attempts with buggy webforms */ ++ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (HG(hphp_mailprotect) > 1) { ++ /* search for to, cc or bcc headers */ ++ if (headers_len > 0 && headers != NULL) { ++ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { ++ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { ++ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { ++ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ } ++ } ++ } ++ + if (to_len > 0) { + to_r = estrndup(to, to_len); + for (; to_len; to_len--) { +diff -Nura php-5.1.4/ext/standard/php_array.h hardening-patch-5.1.4-0.4.15/ext/standard/php_array.h +--- php-5.1.4/ext/standard/php_array.h 2006-02-07 18:54:24.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/php_array.h 2006-09-05 20:31:04.000000000 +0200 +@@ -19,7 +19,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: php_array.h,v 1.50.2.2 2006/02/07 17:54:24 andrei Exp $ */ ++/* $Id: php_array.h,v 1.50.2.3 2006/06/03 18:59:55 andrei Exp $ */ + + #ifndef PHP_ARRAY_H + #define PHP_ARRAY_H +@@ -108,8 +108,6 @@ + int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC); + ZEND_END_MODULE_GLOBALS(array) + +-ZEND_DECLARE_MODULE_GLOBALS(array) +- + #ifdef ZTS + #define ARRAYG(v) TSRMG(array_globals_id, zend_array_globals *, v) + #else +diff -Nura php-5.1.4/ext/standard/php_standard.h hardening-patch-5.1.4-0.4.15/ext/standard/php_standard.h +--- php-5.1.4/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/php_standard.h 2006-09-05 20:31:04.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "php_mail.h" + #include "md5.h" + #include "sha1.h" ++#include "sha256.h" + #include "html.h" + #include "exec.h" + #include "file.h" +diff -Nura php-5.1.4/ext/standard/scanf.c hardening-patch-5.1.4-0.4.15/ext/standard/scanf.c +--- php-5.1.4/ext/standard/scanf.c 2006-01-01 13:50:15.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/scanf.c 2006-09-05 20:31:04.000000000 +0200 +@@ -16,7 +16,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: scanf.c,v 1.31.2.2 2006/01/01 12:50:15 sniper Exp $ */ ++/* $Id: scanf.c,v 1.31.2.3 2006/08/04 20:34:31 tony2001 Exp $ */ + + /* + scanf.c -- +@@ -732,7 +732,7 @@ + if (*end == '$') { + format = end+1; + ch = format++; +- objIndex = varStart + value; ++ objIndex = varStart + value - 1; + } + } + +@@ -762,7 +762,9 @@ + switch (*ch) { + case 'n': + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + zend_uint refcount; + + current = args[objIndex++]; +@@ -888,7 +890,9 @@ + } + } + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + zend_uint refcount; + + current = args[objIndex++]; +@@ -932,7 +936,9 @@ + goto done; + } + if (!(flags & SCAN_SUPPRESS)) { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + zval_dtor( *current ); + ZVAL_STRINGL( *current, string, end-string, 1); +@@ -1089,7 +1095,9 @@ + value = (int) (*fn)(buf, NULL, base); + if ((flags & SCAN_UNSIGNED) && (value < 0)) { + sprintf(buf, "%u", value); /* INTL: ISO digit */ +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + /* change passed value type to string */ + current = args[objIndex++]; + convert_to_string( *current ); +@@ -1098,7 +1106,9 @@ + add_index_string(*return_value, objIndex++, buf, 1); + } + } else { +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + convert_to_long( *current ); + Z_LVAL(**current) = value; +@@ -1206,7 +1216,9 @@ + double dvalue; + *end = '\0'; + dvalue = zend_strtod(buf, NULL); +- if (numVars) { ++ if (numVars && objIndex >= argCount) { ++ break; ++ } else if (numVars) { + current = args[objIndex++]; + convert_to_double( *current ); + Z_DVAL_PP( current ) = dvalue; +diff -Nura php-5.1.4/ext/standard/sha256.c hardening-patch-5.1.4-0.4.15/ext/standard/sha256.c +--- php-5.1.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/sha256.c 2006-09-05 20:31:04.000000000 +0200 +@@ -0,0 +1,388 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ ++ ++#include "php.h" ++ ++/* This code is heavily based on the PHP md5/sha1 implementations */ ++ ++#include "sha256.h" ++ ++PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ sprintf(sha256str, "%02x", digest[i]); ++ sha256str += 2; ++ } ++ ++ *sha256str = '\0'; ++} ++ ++/* {{{ proto string sha256(string str [, bool raw_output]) ++ Calculate the sha256 hash of a string */ ++PHP_FUNCTION(sha256) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ PHP_SHA256_CTX context; ++ unsigned char digest[32]; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ sha256str[0] = '\0'; ++ PHP_SHA256Init(&context); ++ PHP_SHA256Update(&context, arg, arg_len); ++ PHP_SHA256Final(digest, &context); ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++ ++} ++ ++/* }}} */ ++ ++/* {{{ proto string sha256_file(string filename [, bool raw_output]) ++ Calculate the sha256 hash of given filename */ ++PHP_FUNCTION(sha256_file) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ unsigned char buf[1024]; ++ unsigned char digest[32]; ++ PHP_SHA256_CTX context; ++ int n; ++ php_stream *stream; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); ++ if (!stream) { ++ RETURN_FALSE; ++ } ++ ++ PHP_SHA256Init(&context); ++ ++ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ++ PHP_SHA256Update(&context, buf, n); ++ } ++ ++ PHP_SHA256Final(digest, &context); ++ ++ php_stream_close(stream); ++ ++ if (n<0) { ++ RETURN_FALSE; ++ } ++ ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++} ++/* }}} */ ++ ++ ++static void SHA256Transform(php_uint32[8], const unsigned char[64]); ++static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); ++static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); ++ ++static unsigned char PADDING[64] = ++{ ++ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++/* F, G, H and I are basic SHA256 functions. ++ */ ++#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) ++#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) ++#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) ++#define I(x, y, z) (((x) & (y)) | ((~x) & z)) ++ ++/* ROTATE_RIGHT rotates x right n bits. ++ */ ++#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) ++ ++/* W[i] ++ */ ++#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ ++ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ ++ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) ++ ++/* ROUND function of sha256 ++ */ ++ ++#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ ++ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ ++ (h) = F((a)) + G((a), (b), (c)) + t1; \ ++ (d) += t1; \ ++ } ++ ++ ++/* {{{ PHP_SHA256Init ++ * SHA256 initialization. Begins an SHA256 operation, writing a new context. ++ */ ++static void PHP_SHA256Init(PHP_SHA256_CTX * context) ++{ ++ context->count[0] = context->count[1] = 0; ++ /* Load magic initialization constants. ++ */ ++ context->state[0] = 0x6a09e667; ++ context->state[1] = 0xbb67ae85; ++ context->state[2] = 0x3c6ef372; ++ context->state[3] = 0xa54ff53a; ++ context->state[4] = 0x510e527f; ++ context->state[5] = 0x9b05688c; ++ context->state[6] = 0x1f83d9ab; ++ context->state[7] = 0x5be0cd19; ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Update ++ SHA256 block update operation. Continues an SHA256 message-digest ++ operation, processing another message block, and updating the ++ context. ++ */ ++static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, ++ unsigned int inputLen) ++{ ++ unsigned int i, index, partLen; ++ ++ /* Compute number of bytes mod 64 */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ++ ++ /* Update number of bits */ ++ if ((context->count[0] += ((php_uint32) inputLen << 3)) ++ < ((php_uint32) inputLen << 3)) ++ context->count[1]++; ++ context->count[1] += ((php_uint32) inputLen >> 29); ++ ++ partLen = 64 - index; ++ ++ /* Transform as many times as possible. ++ */ ++ if (inputLen >= partLen) { ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ++ SHA256Transform(context->state, context->buffer); ++ ++ for (i = partLen; i + 63 < inputLen; i += 64) ++ SHA256Transform(context->state, &input[i]); ++ ++ index = 0; ++ } else ++ i = 0; ++ ++ /* Buffer remaining input */ ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], ++ inputLen - i); ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Final ++ SHA256 finalization. Ends an SHA256 message-digest operation, writing the ++ the message digest and zeroizing the context. ++ */ ++static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) ++{ ++ unsigned char bits[8]; ++ unsigned int index, padLen; ++ ++ /* Save number of bits */ ++ bits[7] = context->count[0] & 0xFF; ++ bits[6] = (context->count[0] >> 8) & 0xFF; ++ bits[5] = (context->count[0] >> 16) & 0xFF; ++ bits[4] = (context->count[0] >> 24) & 0xFF; ++ bits[3] = context->count[1] & 0xFF; ++ bits[2] = (context->count[1] >> 8) & 0xFF; ++ bits[1] = (context->count[1] >> 16) & 0xFF; ++ bits[0] = (context->count[1] >> 24) & 0xFF; ++ ++ /* Pad out to 56 mod 64. ++ */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ++ padLen = (index < 56) ? (56 - index) : (120 - index); ++ PHP_SHA256Update(context, PADDING, padLen); ++ ++ /* Append length (before padding) */ ++ PHP_SHA256Update(context, bits, 8); ++ ++ /* Store state in digest */ ++ SHA256Encode(digest, context->state, 32); ++ ++ /* Zeroize sensitive information. ++ */ ++ memset((unsigned char*) context, 0, sizeof(*context)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Transform ++ * SHA256 basic transformation. Transforms state based on block. ++ */ ++static void SHA256Transform(state, block) ++php_uint32 state[8]; ++const unsigned char block[64]; ++{ ++ php_uint32 a = state[0], b = state[1], c = state[2]; ++ php_uint32 d = state[3], e = state[4], f = state[5]; ++ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; ++ ++ SHA256Decode(x, block, 64); ++ ++ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) ++ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) ++ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) ++ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) ++ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) ++ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) ++ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) ++ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) ++ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) ++ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) ++ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) ++ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) ++ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) ++ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) ++ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) ++ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) ++ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) ++ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) ++ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) ++ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) ++ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) ++ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) ++ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) ++ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) ++ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) ++ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) ++ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) ++ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) ++ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) ++ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) ++ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) ++ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) ++ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) ++ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) ++ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) ++ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) ++ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) ++ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) ++ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) ++ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) ++ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) ++ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) ++ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) ++ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) ++ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) ++ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) ++ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) ++ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) ++ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) ++ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) ++ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) ++ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) ++ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) ++ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) ++ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) ++ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) ++ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) ++ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) ++ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) ++ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) ++ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) ++ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) ++ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) ++ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) ++ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ state[5] += f; ++ state[6] += g; ++ state[7] += h; ++ ++ /* Zeroize sensitive information. */ ++ memset((unsigned char*) x, 0, sizeof(x)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Encode ++ Encodes input (php_uint32) into output (unsigned char). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Encode(output, input, len) ++unsigned char *output; ++php_uint32 *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) { ++ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); ++ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); ++ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); ++ output[j + 3] = (unsigned char) (input[i] & 0xff); ++ } ++} ++/* }}} */ ++ ++/* {{{ SHA256Decode ++ Decodes input (unsigned char) into output (php_uint32). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Decode(output, input, len) ++php_uint32 *output; ++const unsigned char *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) ++ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | ++ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.4/ext/standard/sha256.h hardening-patch-5.1.4-0.4.15/ext/standard/sha256.h +--- php-5.1.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/sha256.h 2006-09-05 20:31:04.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ ++ ++#ifndef SHA256_H ++#define SHA256_H ++ ++#include "ext/standard/basic_functions.h" ++ ++/* SHA1 context. */ ++typedef struct { ++ php_uint32 state[8]; /* state (ABCD) */ ++ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ++ unsigned char buffer[64]; /* input buffer */ ++} PHP_SHA256_CTX; ++ ++static void PHP_SHA256Init(PHP_SHA256_CTX *); ++static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); ++static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); ++ ++PHP_FUNCTION(sha256); ++PHP_FUNCTION(sha256_file); ++ ++#endif +diff -Nura php-5.1.4/ext/standard/string.c hardening-patch-5.1.4-0.4.15/ext/standard/string.c +--- php-5.1.4/ext/standard/string.c 2006-04-25 14:48:41.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/string.c 2006-09-05 20:31:04.000000000 +0200 +@@ -18,7 +18,7 @@ + +----------------------------------------------------------------------+ + */ + +-/* $Id: string.c,v 1.445.2.14 2006/04/25 12:48:41 tony2001 Exp $ */ ++/* $Id: string.c,v 1.445.2.16 2006/08/10 17:46:43 iliaa Exp $ */ + + /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ + +@@ -632,7 +632,8 @@ + { + const char *text, *breakchar = "\n"; + char *newtext; +- int textlen, breakcharlen = 1, newtextlen, alloced, chk; ++ int textlen, breakcharlen = 1, newtextlen, chk; ++ size_t alloced; + long current = 0, laststart = 0, lastspace = 0; + long linelength = 75; + zend_bool docut = 0; +@@ -1612,10 +1613,18 @@ + RETURN_FALSE; + } + ++ if (haystack_len == 0) { ++ RETURN_FALSE; ++ } ++ + haystack_dup = estrndup(haystack, haystack_len); + php_strtolower(haystack_dup, haystack_len); + + if (Z_TYPE_P(needle) == IS_STRING) { ++ if (Z_STRLEN_P(needle) == 0 || Z_STRLEN_P(needle) > haystack_len) { ++ efree(haystack_dup); ++ RETURN_FALSE; ++ } + needle_dup = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle)); + php_strtolower(needle_dup, Z_STRLEN_P(needle)); + found = php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len); +@@ -4194,7 +4203,7 @@ + zval **input_str; /* Input string */ + zval **mult; /* Multiplier */ + char *result; /* Resulting string */ +- int result_len; /* Length of the resulting string */ ++ size_t result_len; /* Length of the resulting string */ + + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { + WRONG_PARAM_COUNT; +@@ -4219,11 +4228,7 @@ + + /* Initialize the result string */ + result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); +- if (result_len < 1 || result_len > 2147483647) { +- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes"); +- RETURN_FALSE; +- } +- result = (char *)emalloc(result_len + 1); ++ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1); + + /* Heavy optimization for situations where input string is 1 byte long */ + if (Z_STRLEN_PP(input_str) == 1) { +@@ -4894,7 +4899,7 @@ + offset = (offset < 0) ? 0 : offset; + } + +- if ((offset + len) >= s1_len) { ++ if ((offset + len) > s1_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position cannot exceed initial string length"); + RETURN_FALSE; + } +diff -Nura php-5.1.4/ext/standard/syslog.c hardening-patch-5.1.4-0.4.15/ext/standard/syslog.c +--- php-5.1.4/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/standard/syslog.c 2006-09-05 20:31:04.000000000 +0200 +@@ -42,6 +42,7 @@ + */ + PHP_MINIT_FUNCTION(syslog) + { ++#if !HARDENING_PATCH + /* error levels */ + REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ + REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ +@@ -97,6 +98,7 @@ + /* AIX doesn't have LOG_PERROR */ + REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ + #endif ++#endif + BG(syslog_device)=NULL; + + return SUCCESS; +diff -Nura php-5.1.4/ext/varfilter/config.m4 hardening-patch-5.1.4-0.4.15/ext/varfilter/config.m4 +--- php-5.1.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/varfilter/config.m4 2006-09-05 20:31:04.000000000 +0200 +@@ -0,0 +1,11 @@ ++dnl ++dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++dnl ++ ++PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, ++[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) ++ ++if test "$PHP_VARFILTER" != "no"; then ++ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) ++ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) ++fi +diff -Nura php-5.1.4/ext/varfilter/CREDITS hardening-patch-5.1.4-0.4.15/ext/varfilter/CREDITS +--- php-5.1.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:31:04.000000000 +0200 +@@ -0,0 +1,2 @@ ++varfilter ++Stefan Esser +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-5.1.4/ext/varfilter/php_varfilter.h hardening-patch-5.1.4-0.4.15/ext/varfilter/php_varfilter.h +--- php-5.1.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:31:04.000000000 +0200 +@@ -0,0 +1,144 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifndef PHP_VARFILTER_H ++#define PHP_VARFILTER_H ++ ++extern zend_module_entry varfilter_module_entry; ++#define phpext_varfilter_ptr &varfilter_module_entry ++ ++#ifdef PHP_WIN32 ++#define PHP_VARFILTER_API __declspec(dllexport) ++#else ++#define PHP_VARFILTER_API ++#endif ++ ++#ifdef ZTS ++#include "TSRM.h" ++#endif ++ ++#include "SAPI.h" ++ ++#include "php_variables.h" ++ ++#ifdef ZEND_ENGINE_2 ++#define HASH_HTTP_GET_VARS 0x2095733f ++#define HASH_HTTP_POST_VARS 0xbfee1265 ++#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 ++#define HASH_HTTP_ENV_VARS 0x1fe186a8 ++#define HASH_HTTP_SERVER_VARS 0xc987afd6 ++#define HASH_HTTP_SESSION_VARS 0x7aba0d43 ++#define HASH_HTTP_POST_FILES 0x98eb1ddc ++#define HASH_HTTP_RAW_POST_DATA 0xdd633fec ++#else ++#define HASH_HTTP_GET_VARS 0x8d8645bd ++#define HASH_HTTP_POST_VARS 0x7c699bf3 ++#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f ++#define HASH_HTTP_ENV_VARS 0x84da3016 ++#define HASH_HTTP_SERVER_VARS 0x6dbf964e ++#define HASH_HTTP_SESSION_VARS 0x322906f5 ++#define HASH_HTTP_POST_FILES 0xe4e4ce70 ++#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e ++#endif ++ ++PHP_MINIT_FUNCTION(varfilter); ++PHP_MSHUTDOWN_FUNCTION(varfilter); ++PHP_RINIT_FUNCTION(varfilter); ++PHP_RSHUTDOWN_FUNCTION(varfilter); ++PHP_MINFO_FUNCTION(varfilter); ++ ++ ++ZEND_BEGIN_MODULE_GLOBALS(varfilter) ++/* request variables */ ++ long max_request_variables; ++ long cur_request_variables; ++ long max_varname_length; ++ long max_totalname_length; ++ long max_value_length; ++ long max_array_depth; ++ long max_array_index_length; ++ zend_bool disallow_nul; ++/* cookie variables */ ++ long max_cookie_vars; ++ long cur_cookie_vars; ++ long max_cookie_name_length; ++ long max_cookie_totalname_length; ++ long max_cookie_value_length; ++ long max_cookie_array_depth; ++ long max_cookie_array_index_length; ++ zend_bool disallow_cookie_nul; ++/* get variables */ ++ long max_get_vars; ++ long cur_get_vars; ++ long max_get_name_length; ++ long max_get_totalname_length; ++ long max_get_value_length; ++ long max_get_array_depth; ++ long max_get_array_index_length; ++ zend_bool disallow_get_nul; ++/* post variables */ ++ long max_post_vars; ++ long cur_post_vars; ++ long max_post_name_length; ++ long max_post_totalname_length; ++ long max_post_value_length; ++ long max_post_array_depth; ++ long max_post_array_index_length; ++ zend_bool disallow_post_nul; ++/* fileupload */ ++ long max_uploads; ++ long cur_uploads; ++ zend_bool disallow_elf_files; ++ char *verification_script; ++ ++ zend_bool no_more_variables; ++ zend_bool no_more_get_variables; ++ zend_bool no_more_post_variables; ++ zend_bool no_more_cookie_variables; ++ zend_bool no_more_uploads; ++ ++ZEND_END_MODULE_GLOBALS(varfilter) ++ ++ ++#ifdef ZTS ++#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) ++#else ++#define VARFILTER_G(v) (varfilter_globals.v) ++#endif ++ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); ++SAPI_TREAT_DATA_FUNC(varfilter_treat_data); ++ ++ ++ ++#endif /* PHP_VARFILTER_H */ ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: t ++ * End: ++ */ +diff -Nura php-5.1.4/ext/varfilter/varfilter.c hardening-patch-5.1.4-0.4.15/ext/varfilter/varfilter.c +--- php-5.1.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:51:41.000000000 +0200 +@@ -0,0 +1,915 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "php.h" ++#include "php_ini.h" ++#include "ext/standard/info.h" ++#include "php_varfilter.h" ++#include "hardening_patch.h" ++ ++ZEND_DECLARE_MODULE_GLOBALS(varfilter) ++ ++/* True global resources - no need for thread safety here */ ++static int le_varfilter; ++ ++static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; ++static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; ++static zend_bool hooked = 0; ++ ++/* {{{ varfilter_module_entry ++ */ ++zend_module_entry varfilter_module_entry = { ++#if ZEND_MODULE_API_NO >= 20010901 ++ STANDARD_MODULE_HEADER, ++#endif ++ "varfilter", ++ NULL, ++ PHP_MINIT(varfilter), ++ PHP_MSHUTDOWN(varfilter), ++ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ ++ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ ++ PHP_MINFO(varfilter), ++#if ZEND_MODULE_API_NO >= 20010901 ++ "0.4.15", /* Replace with version number for your extension */ ++#endif ++ STANDARD_MODULE_PROPERTIES ++}; ++/* }}} */ ++ ++#ifdef COMPILE_DL_VARFILTER ++ZEND_GET_MODULE(varfilter) ++#endif ++ ++/* {{{ PHP_INI ++ */ ++PHP_INI_BEGIN() ++ /* for backward compatibility */ ++ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) ++ ++ ++PHP_INI_END() ++/* }}} */ ++ ++/* {{{ php_varfilter_init_globals ++ */ ++static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) ++{ ++ varfilter_globals->max_request_variables = 200; ++ varfilter_globals->max_varname_length = 64; ++ varfilter_globals->max_value_length = 10000; ++ varfilter_globals->max_array_depth = 100; ++ varfilter_globals->max_totalname_length = 256; ++ varfilter_globals->max_array_index_length = 64; ++ varfilter_globals->disallow_nul = 1; ++ ++ varfilter_globals->max_cookie_vars = 100; ++ varfilter_globals->max_cookie_name_length = 64; ++ varfilter_globals->max_cookie_totalname_length = 256; ++ varfilter_globals->max_cookie_value_length = 10000; ++ varfilter_globals->max_cookie_array_depth = 100; ++ varfilter_globals->max_cookie_array_index_length = 64; ++ varfilter_globals->disallow_cookie_nul = 1; ++ ++ varfilter_globals->max_get_vars = 100; ++ varfilter_globals->max_get_name_length = 64; ++ varfilter_globals->max_get_totalname_length = 256; ++ varfilter_globals->max_get_value_length = 512; ++ varfilter_globals->max_get_array_depth = 50; ++ varfilter_globals->max_get_array_index_length = 64; ++ varfilter_globals->disallow_get_nul = 1; ++ ++ varfilter_globals->max_post_vars = 200; ++ varfilter_globals->max_post_name_length = 64; ++ varfilter_globals->max_post_totalname_length = 256; ++ varfilter_globals->max_post_value_length = 65000; ++ varfilter_globals->max_post_array_depth = 100; ++ varfilter_globals->max_post_array_index_length = 64; ++ varfilter_globals->disallow_post_nul = 1; ++ ++ varfilter_globals->max_uploads = 25; ++ varfilter_globals->disallow_elf_files = 1; ++ varfilter_globals->verification_script = NULL; ++ ++ varfilter_globals->no_more_variables = 0; ++ varfilter_globals->no_more_get_variables = 0; ++ varfilter_globals->no_more_post_variables = 0; ++ varfilter_globals->no_more_cookie_variables = 0; ++ varfilter_globals->no_more_uploads = 0; ++ ++ varfilter_globals->cur_request_variables = 0; ++ varfilter_globals->cur_get_vars = 0; ++ varfilter_globals->cur_post_vars = 0; ++ varfilter_globals->cur_cookie_vars = 0; ++ ++ varfilter_globals->cur_uploads = 0; ++ ++} ++/* }}} */ ++ ++ ++void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) ++{ ++ HashTable *svars; ++ int retval, failure=0; ++ ++ orig_register_server_variables(track_vars_array TSRMLS_CC); ++ ++ svars = Z_ARRVAL_P(track_vars_array); ++ ++ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ ++ if (failure) { ++ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); ++ } ++} ++ ++int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) ++{ ++ int retval = SAPI_HEADER_ADD, i; ++ char *tmp; ++ ++ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { ++ ++ tmp = sapi_header->header; ++ for (i=0; iheader_len; i++, tmp++) { ++ if (tmp[0] == 0) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); ++ sapi_header->header_len = i; ++ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); ++ sapi_header->header_len = i; ++ tmp[0] = 0; ++ } ++ } ++ } ++ ++ if (orig_header_handler) { ++ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); ++ } ++ ++ return retval; ++} ++ ++/* {{{ PHP_MINIT_FUNCTION ++ */ ++PHP_MINIT_FUNCTION(varfilter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); ++ REGISTER_INI_ENTRIES(); ++ ++ if (!hooked) { ++ void *temp; ++ hooked = 1; ++ ++ temp = (void *)sapi_module.register_server_variables; ++ if (temp != varfilter_register_server_variables) { ++ orig_register_server_variables = temp; ++ } ++ temp = (void *)sapi_module.header_handler; ++ if (temp != varfilter_header_handler) { ++ orig_header_handler = temp; ++ } ++ } ++ ++ sapi_register_input_filter(varfilter_input_filter); ++ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); ++ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); ++ sapi_register_upload_content_filter(varfilter_upload_content_filter); ++ sapi_register_post_upload_filter(varfilter_post_upload_filter); ++ ++ sapi_module.header_handler = varfilter_header_handler; ++ sapi_module.register_server_variables = varfilter_register_server_variables; ++ ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MSHUTDOWN_FUNCTION ++ */ ++PHP_MSHUTDOWN_FUNCTION(varfilter) ++{ ++ UNREGISTER_INI_ENTRIES(); ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request start */ ++/* {{{ PHP_RINIT_FUNCTION ++ */ ++PHP_RINIT_FUNCTION(varfilter) ++{ ++ VARFILTER_G(cur_request_variables) = 0; ++ VARFILTER_G(cur_get_vars) = 0; ++ VARFILTER_G(cur_post_vars) = 0; ++ VARFILTER_G(cur_cookie_vars) = 0; ++ ++ VARFILTER_G(cur_uploads) = 0; ++ ++ VARFILTER_G(no_more_variables) = 0; ++ VARFILTER_G(no_more_get_variables) = 0; ++ VARFILTER_G(no_more_post_variables) = 0; ++ VARFILTER_G(no_more_cookie_variables) = 0; ++ VARFILTER_G(no_more_uploads) = 0; ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request end */ ++/* {{{ PHP_RSHUTDOWN_FUNCTION ++ */ ++PHP_RSHUTDOWN_FUNCTION(varfilter) ++{ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MINFO_FUNCTION ++ */ ++PHP_MINFO_FUNCTION(varfilter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); ++ php_info_print_table_end(); ++ ++ DISPLAY_INI_ENTRIES(); ++} ++/* }}} */ ++ ++/* {{{ normalize_varname ++ */ ++static void normalize_varname(char *varname) ++{ ++ char *s=varname, *index=NULL, *indexend=NULL, *p; ++ ++ /* overjump leading space */ ++ while (*s == ' ') { ++ s++; ++ } ++ ++ /* and remove it */ ++ if (s != varname) { ++ memmove(varname, s, strlen(s)+1); ++ } ++ ++ for (p=varname; *p && *p != '['; p++) { ++ switch(*p) { ++ case ' ': ++ case '.': ++ *p='_'; ++ break; ++ } ++ } ++ ++ /* find index */ ++ index = strchr(varname, '['); ++ if (index) { ++ index++; ++ s=index; ++ } else { ++ return; ++ } ++ ++ /* done? */ ++ while (index) { ++ ++ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { ++ index++; ++ } ++ indexend = strchr(index, ']'); ++ indexend = indexend ? indexend + 1 : index + strlen(index); ++ ++ if (s != index) { ++ memmove(s, index, strlen(index)+1); ++ s += indexend-index; ++ } else { ++ s = indexend; ++ } ++ ++ if (*s == '[') { ++ s++; ++ index = s; ++ } else { ++ index = NULL; ++ } ++ } ++ *s++='\0'; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC ++ */ ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) ++{ ++ char *index, *prev_index = NULL, *var; ++ unsigned int var_len, total_len, depth = 0; ++ ++ var = estrdup(varname); ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); ++ ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; ++ break; ++ } ++ ++ efree(var); ++ return SUCCESS; ++protected_varname2: ++ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); ++return_failure: ++ efree(var); ++ return FAILURE; ++} ++/* }}} */ ++ ++/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC ++ */ ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) ++{ ++ /* Drop if no more variables flag is set */ ++ if (VARFILTER_G(no_more_uploads)) { ++ return FAILURE; ++ } ++ /* Drop this fileupload if the limit is reached */ ++ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { ++ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); ++ VARFILTER_G(no_more_uploads) = 1; ++ return FAILURE; ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC ++ */ ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) ++{ ++ ++ if (VARFILTER_G(disallow_elf_files)) { ++ ++ if (offset == 0 && buffer_len > 10) { ++ ++ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { ++ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); ++ return FAILURE; ++ } ++ } ++ ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC ++ */ ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) ++{ ++ int retval = SUCCESS; ++ ++ if (VARFILTER_G(verification_script)) { ++ char cmd[8192]; ++ FILE *in; ++ int first=1; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); ++ return FAILURE; ++ } ++ ++ retval = FAILURE; ++ ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ if (first) { ++ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; ++ first = 0; ++ } ++ } ++ pclose(in); ++ } ++ ++ if (retval != SUCCESS) { ++ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); ++ return FAILURE; ++ } ++ ++ VARFILTER_G(cur_uploads)++; ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_INPUT_FILTER_FUNC ++ */ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) ++{ ++ char *index, *prev_index = NULL; ++ unsigned int var_len, total_len, depth = 0; ++ ++ /* Drop this variable if the limit was reached */ ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(no_more_get_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(no_more_post_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(no_more_cookie_variables)) { ++ return 0; ++ } ++ break; ++ default: /* we do not want to protect parse_str() and friends */ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ return 1; ++ } ++ if (VARFILTER_G(no_more_variables)) { ++ return 0; ++ } ++ ++ /* Drop this variable if the limit is now reached */ ++ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { ++ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_variables) = 1; ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { ++ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_get_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { ++ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_cookie_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { ++ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_post_variables) = 1; ++ return 0; ++ } ++ break; ++ } ++ ++ ++ /* Drop this variable if it exceeds the value length limit */ ++ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { ++ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { ++ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { ++ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { ++ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { ++ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { ++ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Check if variable value is truncated by a \0 */ ++ ++ if (val && *val && val_len != strlen(*val)) { ++ ++ if (VARFILTER_G(disallow_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(disallow_get_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(disallow_cookie_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(disallow_post_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ } ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname; ++ break; ++ } ++ ++ /* Okay let PHP register this variable */ ++ VARFILTER_G(cur_request_variables)++; ++ switch (arg) { ++ case PARSE_GET: ++ VARFILTER_G(cur_get_vars)++; ++ break; ++ case PARSE_COOKIE: ++ VARFILTER_G(cur_cookie_vars)++; ++ break; ++ case PARSE_POST: ++ VARFILTER_G(cur_post_vars)++; ++ break; ++ } ++ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ ++ return 1; ++protected_varname: ++ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); ++ return 0; ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: noet sw=4 ts=4 fdm=marker ++ * vim<600: noet sw=4 ts=4 ++ */ ++ ++ +diff -Nura php-5.1.4/ext/wddx/wddx.c hardening-patch-5.1.4-0.4.15/ext/wddx/wddx.c +--- php-5.1.4/ext/wddx/wddx.c 2006-04-23 18:02:05.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/ext/wddx/wddx.c 2006-09-05 20:31:04.000000000 +0200 +@@ -399,9 +399,9 @@ + break; + + default: +- if (iscntrl((int)*(unsigned char *)p)) { ++ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) { + FLUSH_BUF(); +- sprintf(control_buf, WDDX_CHAR, *p); ++ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); + php_wddx_add_chunk(packet, control_buf); + } else + buf[l++] = *p; +@@ -751,7 +751,7 @@ + } else if (!strcmp(name, EL_CHAR)) { + int i; + +- for (i = 0; atts[i]; i++) { ++ if (atts) for (i = 0; atts[i]; i++) { + if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) { + char tmp_buf[2]; + +@@ -771,7 +771,7 @@ + } else if (!strcmp(name, EL_BOOLEAN)) { + int i; + +- for (i = 0; atts[i]; i++) { ++ if (atts) for (i = 0; atts[i]; i++) { + if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) { + ent.type = ST_BOOLEAN; + SET_STACK_VARNAME; +@@ -812,7 +812,7 @@ + } else if (!strcmp(name, EL_VAR)) { + int i; + +- for (i = 0; atts[i]; i++) { ++ if (atts) for (i = 0; atts[i]; i++) { + if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) { + char *decoded; + int decoded_len; +@@ -829,7 +829,7 @@ + MAKE_STD_ZVAL(ent.data); + array_init(ent.data); + +- for (i = 0; atts[i]; i++) { ++ if (atts) for (i = 0; atts[i]; i++) { + if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) { + zval *tmp; + char *key; +@@ -869,7 +869,7 @@ + ent.varname = NULL; + ent.data = NULL; + +- for (i = 0; atts[i]; i++) { ++ if (atts) for (i = 0; atts[i]; i++) { + if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) { + char *decoded; + int decoded_len; +diff -Nura php-5.1.4/main/fopen_wrappers.c hardening-patch-5.1.4-0.4.15/main/fopen_wrappers.c +--- php-5.1.4/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:55.000000000 +0200 +@@ -104,7 +104,10 @@ + } + + /* Resolve the real path into resolved_name */ +- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { ++ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { ++ return -2; ++ } ++ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { + /* Handler for basedirs that end with a / */ + resolved_basedir_len = strlen(resolved_basedir); + if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { +@@ -114,14 +117,20 @@ + } + } + ++ resolved_name_len = strlen(resolved_name); + if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { +- resolved_name_len = strlen(resolved_name); + if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { + resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; + resolved_name[++resolved_name_len] = '\0'; + } + } + ++ if (resolved_name_len == resolved_basedir_len - 1) { ++ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { ++ resolved_basedir_len--; ++ } ++ } ++ + /* Check the path */ + #if defined(PHP_WIN32) || defined(NETWARE) + if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { +@@ -135,7 +144,7 @@ + } + } else { + /* Unable to resolve the real path, return -1 */ +- return -1; ++ return -3; + } + } + /* }}} */ +@@ -154,22 +163,44 @@ + char *pathbuf; + char *ptr; + char *end; ++ char path_copy[MAXPATHLEN]; ++ int path_len; ++ ++ /* Special case path ends with a trailing slash */ ++ path_len = strlen(path); ++ if (path_len >= MAXPATHLEN) { ++ errno = EPERM; /* we deny permission to open it */ ++ return -1; ++ } ++ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { ++ memcpy(path_copy, path, path_len+1); ++ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; ++ path_copy[path_len] = '\0'; ++ path = (const char *)&path_copy; ++ } + + pathbuf = estrdup(PG(open_basedir)); + + ptr = pathbuf; + + while (ptr && *ptr) { ++ int res; + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end != NULL) { + *end = '\0'; + end++; + } + +- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { ++ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); ++ if (res == 0) { + efree(pathbuf); + return 0; + } ++ if (res == -2) { ++ efree(pathbuf); ++ errno = EPERM; ++ return -1; ++ } + + ptr = end; + } +diff -Nura php-5.1.4/main/hardened_globals.h hardening-patch-5.1.4-0.4.15/main/hardened_globals.h +--- php-5.1.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/hardened_globals.h 2006-09-05 20:31:05.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENED_GLOBALS_H ++#define HARDENED_GLOBALS_H ++ ++typedef struct _hardened_globals hardened_globals_struct; ++ ++#ifdef ZTS ++# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) ++extern int hardened_globals_id; ++#else ++# define HG(v) (hardened_globals.v) ++extern struct _hardened_globals hardened_globals; ++#endif ++ ++ ++struct _hardened_globals { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_1; ++ unsigned int canary_2; ++#endif ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_3; ++ unsigned int canary_4; ++ unsigned int ll_canary_inited; ++#endif ++ zend_bool hphp_sql_bailout_on_error; ++ zend_bool hphp_multiheader; ++ unsigned long hphp_mailprotect; ++ long hard_memory_limit; ++ HashTable *eval_whitelist; ++ HashTable *eval_blacklist; ++ HashTable *func_whitelist; ++ HashTable *func_blacklist; ++ HashTable *include_whitelist; ++ HashTable *include_blacklist; ++ unsigned int dummy; ++}; ++ ++ ++#endif /* HARDENED_GLOBALS_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-5.1.4/main/hardening_patch.c hardening-patch-5.1.4-0.4.15/main/hardening_patch.c +--- php-5.1.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.c 2006-09-05 20:31:05.000000000 +0200 +@@ -0,0 +1,430 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ ++ ++#include "php.h" ++ ++#include ++#include ++ ++#if HAVE_UNISTD_H ++#include ++#endif ++#include "SAPI.h" ++#include "php_globals.h" ++ ++#if HARDENING_PATCH ++ ++#ifdef HAVE_SYS_SOCKET_H ++#include ++#endif ++ ++#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) ++#undef AF_UNIX ++#endif ++ ++#if defined(AF_UNIX) ++#include ++#endif ++ ++#define SYSLOG_PATH "/dev/log" ++ ++#include "snprintf.h" ++ ++#include "hardening_patch.h" ++ ++#ifdef ZTS ++#include "hardened_globals.h" ++int hardened_globals_id; ++#else ++struct _hardened_globals hardened_globals; ++#endif ++ ++static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) ++{ ++ memset(hardened_globals, 0, sizeof(*hardened_globals)); ++} ++ ++ ++PHPAPI void hardened_startup() ++{ ++#ifdef ZTS ++ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); ++#else ++ hardened_globals_ctor(&hardened_globals TSRMLS_CC); ++#endif ++} ++ ++PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) ++{ ++ HG(canary_1) = php_canary(); ++ HG(canary_2) = php_canary(); ++} ++ ++char *loglevel2string(int loglevel) ++{ ++ switch (loglevel) { ++ case S_FILES: ++ return "FILES"; ++ case S_INCLUDE: ++ return "INCLUDE"; ++ case S_MEMORY: ++ return "MEMORY"; ++ case S_MISC: ++ return "MISC"; ++ case S_SQL: ++ return "SQL"; ++ case S_EXECUTOR: ++ return "EXECUTOR"; ++ case S_VARS: ++ return "VARS"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++PHPAPI void php_security_log(int loglevel, char *fmt, ...) ++{ ++#if defined(AF_UNIX) ++ int s, r, i=0; ++ struct sockaddr_un saun; ++ char buf[4096+64]; ++ char error[4096+100]; ++ char *ip_address; ++ char *fname; ++ int lineno; ++ va_list ap; ++ TSRMLS_FETCH(); ++ ++ if (EG(hphp_log_use_x_forwarded_for)) { ++ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "X-FORWARDED-FOR not set"; ++ } ++ } else { ++ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "REMOTE_ADDR not set"; ++ } ++ } ++ ++ ++ va_start(ap, fmt); ++ ap_php_vsnprintf(error, sizeof(error), fmt, ap); ++ va_end(ap); ++ while (error[i]) { ++ if (error[i] < 32) error[i] = '.'; ++ i++; ++ } ++ ++ if (zend_is_executing(TSRMLS_C)) { ++ lineno = zend_get_executed_lineno(TSRMLS_C); ++ fname = zend_get_executed_filename(TSRMLS_C); ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); ++ } else { ++ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); ++ if (fname==NULL) { ++ fname = "unknown"; ++ } ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); ++ } ++ ++ /* Syslog-Logging disabled? */ ++ if ((EG(hphp_log_syslog) & loglevel)==0) { ++ goto log_sapi; ++ } ++ ++ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); ++ ++ s = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ s = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ goto log_sapi; ++ } ++ } ++ send(s, error, strlen(error), 0); ++ ++ close(s); ++ ++log_sapi: ++ /* SAPI Logging activated? */ ++ if ((EG(hphp_log_sapi) & loglevel)!=0) { ++ sapi_module.log_message(buf); ++ } ++ ++log_script: ++ /* script logging activaed? */ ++ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { ++ char cmd[8192], *cmdpos, *bufpos; ++ FILE *in; ++ int space; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); ++ space = sizeof(cmd) - strlen(cmd); ++ cmdpos = cmd + strlen(cmd); ++ bufpos = buf; ++ if (space <= 1) return; ++ while (space > 2 && *bufpos) { ++ if (*bufpos == '\'') { ++ if (space<=5) break; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\\'; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\''; ++ bufpos++; ++ space-=4; ++ } else { ++ *cmdpos++ = *bufpos++; ++ space--; ++ } ++ } ++ *cmdpos++ = '\''; ++ *cmdpos = 0; ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); ++ return; ++ } ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ } ++ pclose(in); ++ } ++ ++#endif ++} ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++PHPAPI unsigned int php_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++ ++PHPAPI int php_is_valid_include(zval *z) ++{ ++ char *filename; ++ int len, i; ++ TSRMLS_FETCH(); ++ ++ /* must be of type string */ ++ if (z->type != IS_STRING || z->value.str.val == NULL) { ++ return (0); ++ } ++ ++ /* short cut */ ++ filename = z->value.str.val; ++ len = z->value.str.len; ++ ++ /* 1. must be shorter than MAXPATHLEN */ ++ if (len > MAXPATHLEN) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 2. must not be cutted */ ++ if (len != strlen(filename)) { ++ char *fname = estrndup(filename, len); ++ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ ++ if (strstr(filename, "://")) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ ++ /* no black or whitelist then disallow all */ ++ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* whitelist is stronger than blacklist */ ++ if (HG(include_whitelist)) { ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ zend_bool isOk = 0; ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_whitelist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ isOk = 1; ++ break; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_whitelist)); ++ } while (1); ++ ++ /* not found in whitelist */ ++ if (!isOk) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); ++ efree(fname); ++ return 0; ++ } ++ ++ s = h + 3; ++ } while (1); ++ } else { ++ /* okay then handle the blacklist */ ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_blacklist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); ++ efree(fname); ++ return 0; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_blacklist)); ++ } while (1); ++ ++ s = h + 3; ++ } while (1); ++ } ++ ++ efree(fname); ++ } ++ ++ /* 4. must not be an uploaded file */ ++ if (SG(rfc1867_uploaded_files)) { ++ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { ++ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); ++ return (0); ++ } ++ } ++ ++ /* passed all tests */ ++ return (1); ++} ++ ++#endif ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.4/main/hardening_patch.h hardening-patch-5.1.4-0.4.15/main/hardening_patch.h +--- php-5.1.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.h 2006-09-07 18:51:30.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENING_PATCH_H ++#define HARDENING_PATCH_H ++ ++#include "zend.h" ++ ++#if HARDENING_PATCH ++PHPAPI void php_security_log(int loglevel, char *fmt, ...); ++PHPAPI void hardened_startup(); ++#define HARDENING_PATCH_VERSION "0.4.15" ++ ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++PHPAPI unsigned int php_canary(); ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++PHPAPI int php_is_valid_include(zval *z); ++#endif ++ ++#endif /* HARDENING_PATCH_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-5.1.4/main/hardening_patch.m4 hardening-patch-5.1.4-0.4.15/main/hardening_patch.m4 +--- php-5.1.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.m4 2006-09-05 20:31:05.000000000 +0200 +@@ -0,0 +1,95 @@ ++dnl ++dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ ++dnl ++dnl This file contains Hardening Patch for PHP specific autoconf functions. ++dnl ++ ++AC_ARG_ENABLE(hardening-patch-mm-protect, ++[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-ll-protect, ++[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-inc-protect, ++[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-fmt-protect, ++[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-hash-protect, ++[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++]) ++ ++AC_MSG_CHECKING(whether to protect the Zend Memory Manager) ++AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the Zend Linked Lists) ++AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect include/require statements) ++AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect PHP Format String functions) ++AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) ++AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) ++ ++ ++AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) ++fi ++ +diff -Nura php-5.1.4/main/main.c hardening-patch-5.1.4-0.4.15/main/main.c +--- php-5.1.4/main/main.c 2006-04-12 14:49:39.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/main/main.c 2006-09-05 20:31:05.000000000 +0200 +@@ -85,6 +85,10 @@ + + #include "SAPI.h" + #include "rfc1867.h" ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#endif ++ + /* }}} */ + + #ifndef ZTS +@@ -109,17 +113,39 @@ + */ + static PHP_INI_MH(OnChangeMemoryLimit) + { ++#if HARDENING_PATCH ++ long hard_memory_limit = 1<<30; ++ ++ if (stage == ZEND_INI_STAGE_RUNTIME) { ++ if (HG(hard_memory_limit) == 0) { ++ HG(hard_memory_limit) = PG(memory_limit); ++ } ++ hard_memory_limit = HG(hard_memory_limit); ++ } else { ++ HG(hard_memory_limit) = 0; ++ } ++#endif + if (new_value) { + PG(memory_limit) = zend_atoi(new_value, new_value_length); ++#if HARDENING_PATCH ++ if (PG(memory_limit) > hard_memory_limit) { ++ PG(memory_limit) = hard_memory_limit; ++ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); ++ return FAILURE; ++ } ++#endif + } else { ++#if HARDENING_PATCH ++ PG(memory_limit) = hard_memory_limit; ++#else + PG(memory_limit) = 1<<30; /* effectively, no limit */ ++#endif + } + return zend_set_memory_limit(PG(memory_limit)); + } + /* }}} */ + #endif + +- + /* {{{ php_disable_functions + */ + static void php_disable_functions(TSRMLS_D) +@@ -1095,6 +1121,13 @@ + sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1); + } + ++ /* Disable realpath cache if safe_mode or open_basedir are set */ ++ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ++ CWDG(realpath_cache_disable) = 1; ++ } else { ++ CWDG(realpath_cache_disable) = 0; ++ } ++ + if (PG(output_handler) && PG(output_handler)[0]) { + php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); + } else if (PG(output_buffering)) { +@@ -1222,6 +1255,9 @@ + + zend_try { + shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); ++#if HARDENING_PATCH ++ hardened_clear_mm_canaries(TSRMLS_C); ++#endif + } zend_end_try(); + + zend_try { +@@ -1393,6 +1429,10 @@ + tsrm_ls = ts_resource(0); + #endif + ++#if HARDENING_PATCH ++ hardened_startup(); ++#endif ++ + module_shutdown = 0; + module_startup = 1; + sapi_initialize_empty_request(TSRMLS_C); +@@ -1406,6 +1446,12 @@ + + php_output_startup(); + ++#if HARDENING_PATCH_INC_PROTECT ++ zuf.is_valid_include = php_is_valid_include; ++#endif ++#if HARDENING_PATCH ++ zuf.security_log_function = php_security_log; ++#endif + zuf.error_function = php_error_cb; + zuf.printf_function = php_printf; + zuf.write_function = php_body_write_wrapper; +@@ -1476,7 +1522,9 @@ + + /* Disable realpath cache if safe_mode or open_basedir are set */ + if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { +- CWDG(realpath_cache_size_limit) = 0; ++ CWDG(realpath_cache_disable) = 1; ++ } else { ++ CWDG(realpath_cache_disable) = 0; + } + + /* initialize stream wrappers registry +@@ -1517,6 +1565,10 @@ + REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS); + 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); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); ++#endif + REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); +diff -Nura php-5.1.4/main/php_config.h.in hardening-patch-5.1.4-0.4.15/main/php_config.h.in +--- php-5.1.4/main/php_config.h.in 2006-05-12 16:41:13.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/main/php_config.h.in 2006-09-05 20:31:05.000000000 +0200 +@@ -788,6 +788,39 @@ + /* Enabling BIND8 compatibility for Panther */ + #undef BIND_8_COMPAT + ++/* Hardening-Patch for PHP */ ++#undef HARDENING_PATCH ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ + /* Whether you have AOLserver */ + #undef HAVE_AOLSERVER + +@@ -1131,6 +1164,12 @@ + /* Define if you have the getaddrinfo function */ + #undef HAVE_GETADDRINFO + ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ + /* Whether system headers declare timezone */ + #undef HAVE_DECLARED_TIMEZONE + +diff -Nura php-5.1.4/main/php.h hardening-patch-5.1.4-0.4.15/main/php.h +--- php-5.1.4/main/php.h 2006-03-07 23:37:53.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/php.h 2006-09-05 20:31:05.000000000 +0200 +@@ -35,11 +35,19 @@ + #include "zend_qsort.h" + #include "php_compat.h" + ++ + #include "zend_API.h" + + #undef sprintf + #define sprintf php_sprintf + ++#if HARDENING_PATCH ++#if HAVE_REALPATH ++#undef realpath ++#define realpath php_realpath ++#endif ++#endif ++ + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ + #undef PHP_DEBUG + #define PHP_DEBUG ZEND_DEBUG +@@ -338,6 +346,7 @@ + #define PHP_FUNCTION ZEND_FUNCTION + #define PHP_METHOD ZEND_METHOD + ++#define PHP_STATIC_FE ZEND_STATIC_FE + #define PHP_NAMED_FE ZEND_NAMED_FE + #define PHP_FE ZEND_FE + #define PHP_DEP_FE ZEND_DEP_FE +@@ -447,6 +456,10 @@ + #endif + #endif /* !XtOffsetOf */ + ++#if HARDENING_PATCH ++#include "hardening_patch.h" ++#endif ++ + #endif + + /* +diff -Nura php-5.1.4/main/php_open_temporary_file.c hardening-patch-5.1.4-0.4.15/main/php_open_temporary_file.c +--- php-5.1.4/main/php_open_temporary_file.c 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/php_open_temporary_file.c 2006-09-05 20:31:05.000000000 +0200 +@@ -114,17 +114,16 @@ + + path_len = strlen(path); + +- if (!(opened_path = emalloc(MAXPATHLEN))) { +- return -1; +- } +- + if (!path_len || IS_SLASH(path[path_len - 1])) { + trailing_slash = ""; + } else { + trailing_slash = "/"; + } + +- (void)snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", path, trailing_slash, pfx); ++ if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", path, trailing_slash, pfx) >= MAXPATHLEN) { ++ efree(opened_path); ++ return -1; ++ } + + #ifdef PHP_WIN32 + if (GetTempFileName(path, pfx, 0, opened_path)) { +diff -Nura php-5.1.4/main/php_variables.c hardening-patch-5.1.4-0.4.15/main/php_variables.c +--- php-5.1.4/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/main/php_variables.c 2006-09-05 20:31:05.000000000 +0200 +@@ -73,6 +73,10 @@ + symtable1 = Z_ARRVAL_P(track_vars_array); + } else if (PG(register_globals)) { + symtable1 = EG(active_symbol_table); ++ /* GLOBALS hijack attempt, reject parameter */ ++ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) { ++ symtable1 = NULL; ++ } + } + if (!symtable1) { + /* Nothing to do */ +@@ -513,7 +517,7 @@ + */ + static inline void php_register_server_variables(TSRMLS_D) + { +- zval *array_ptr = NULL; ++ zval *array_ptr = NULL, *vptr; + /* turn off magic_quotes while importing server variables */ + int magic_quotes_gpc = PG(magic_quotes_gpc); + +diff -Nura php-5.1.4/main/rfc1867.c hardening-patch-5.1.4-0.4.15/main/rfc1867.c +--- php-5.1.4/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/rfc1867.c 2006-09-05 20:31:05.000000000 +0200 +@@ -132,6 +132,7 @@ + #define UPLOAD_ERROR_D 4 /* No file uploaded */ + #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ + #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ ++#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */ + + void php_rfc1867_register_constants(TSRMLS_D) + { +@@ -142,6 +143,7 @@ + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); + } + + static void normalize_protected_variable(char *varname TSRMLS_DC) +@@ -854,6 +856,7 @@ + char buff[FILLUNIT]; + char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; + int blen=0, wlen=0; ++ unsigned long offset; + + zend_llist_clean(&header); + +@@ -970,7 +973,11 @@ + tmp++; + } + } +- ++ ++ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { ++ skip_upload = 1; ++ } ++ + total_bytes = cancel_upload = 0; + + if (!skip_upload) { +@@ -994,6 +1001,11 @@ + cancel_upload = UPLOAD_ERROR_D; + } + ++ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ ++ offset = 0; + end = 0; + while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) + { +@@ -1008,6 +1020,10 @@ + #endif + cancel_upload = UPLOAD_ERROR_B; + } else if (blen > 0) { ++ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + wlen = write(fd, buff, blen); + + if (wlen < blen) { +@@ -1036,6 +1052,10 @@ + } + #endif + ++ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + if (cancel_upload) { + if (temp_filename) { + if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ +diff -Nura php-5.1.4/main/SAPI.c hardening-patch-5.1.4-0.4.15/main/SAPI.c +--- php-5.1.4/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/SAPI.c 2006-09-05 20:31:05.000000000 +0200 +@@ -870,6 +870,36 @@ + post_entry->content_type_len+1); + } + ++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)) ++{ ++ sapi_module.input_filter = input_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) ++{ ++ sapi_module.upload_varname_filter = upload_varname_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) ++{ ++ sapi_module.pre_upload_filter = pre_upload_filter; ++ return SUCCESS; ++} ++ ++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)) ++{ ++ sapi_module.upload_content_filter = upload_content_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) ++{ ++ sapi_module.post_upload_filter = post_upload_filter; ++ return SUCCESS; ++} ++ + + SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)) + { +@@ -884,11 +914,6 @@ + return SUCCESS; + } + +-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)) +-{ +- sapi_module.input_filter = input_filter; +- return SUCCESS; +-} + + SAPI_API int sapi_flush(TSRMLS_D) + { +diff -Nura php-5.1.4/main/SAPI.h hardening-patch-5.1.4-0.4.15/main/SAPI.h +--- php-5.1.4/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/SAPI.h 2006-09-05 20:31:05.000000000 +0200 +@@ -190,6 +190,10 @@ + SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); + 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)); + ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); ++ + SAPI_API int sapi_flush(TSRMLS_D); + SAPI_API struct stat *sapi_get_stat(TSRMLS_D); + SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC); +@@ -254,6 +258,11 @@ + int (*get_target_gid)(gid_t * TSRMLS_DC); + + unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); ++ ++ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); ++ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); ++ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); ++ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); + + void (*ini_defaults)(HashTable *configuration_hash); + int phpinfo_as_text; +@@ -279,7 +288,11 @@ + + #define SAPI_DEFAULT_MIMETYPE "text/html" + #define SAPI_DEFAULT_CHARSET "" ++#if HARDENING_PATCH ++#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" ++#else + #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION ++#endif + + #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) + #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) +@@ -287,6 +300,11 @@ + #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) + #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) + ++#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) ++#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) ++#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) ++#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) ++ + BEGIN_EXTERN_C() + SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); + SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); +diff -Nura php-5.1.4/main/snprintf.c hardening-patch-5.1.4-0.4.15/main/snprintf.c +--- php-5.1.4/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/snprintf.c 2006-09-05 20:31:05.000000000 +0200 +@@ -1014,7 +1014,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = cc; ++#endif + goto skip_output; + + /* +diff -Nura php-5.1.4/main/spprintf.c hardening-patch-5.1.4-0.4.15/main/spprintf.c +--- php-5.1.4/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/main/spprintf.c 2006-09-05 20:31:05.000000000 +0200 +@@ -630,7 +630,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = xbuf->len; ++#endif + goto skip_output; + + /* +diff -Nura php-5.1.4/pear/Makefile.frag hardening-patch-5.1.4-0.4.15/pear/Makefile.frag +--- php-5.1.4/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/pear/Makefile.frag 2006-09-05 20:31:05.000000000 +0200 +@@ -3,7 +3,7 @@ + peardir=$(PEAR_INSTALLDIR) + + # Skip all php.ini files altogether +-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 ++PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar + + install-pear-installer: $(SAPI_CLI_PATH) + @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" +diff -Nura php-5.1.4/php.ini-dist hardening-patch-5.1.4-0.4.15/php.ini-dist +--- php-5.1.4/php.ini-dist 2006-02-09 00:43:48.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/php.ini-dist 2006-09-05 20:31:05.000000000 +0200 +@@ -1197,6 +1197,209 @@ + ; instead of original one. + soap.wsdl_cache_ttl=86400 + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-5.1.4/php.ini-recommended hardening-patch-5.1.4-0.4.15/php.ini-recommended +--- php-5.1.4/php.ini-recommended 2006-02-09 00:43:48.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/php.ini-recommended 2006-09-05 20:31:06.000000000 +0200 +@@ -1255,6 +1255,209 @@ + ; instead of original one. + soap.wsdl_cache_ttl=86400 + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-5.1.4/run-tests.php hardening-patch-5.1.4-0.4.15/run-tests.php +--- php-5.1.4/run-tests.php 2006-05-03 23:37:16.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/run-tests.php 2006-09-05 20:31:06.000000000 +0200 +@@ -161,6 +161,10 @@ + 'error_reporting=4095', + 'display_errors=1', + 'log_errors=0', ++ 'hphp.executor.include.whitelist=cookietest', ++ 'hphp.log.syslog=0', ++ 'hphp.log.sapi=0', ++ 'hphp.log.script=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=1', +diff -Nura php-5.1.4/sapi/apache/mod_php5.c hardening-patch-5.1.4-0.4.15/sapi/apache/mod_php5.c +--- php-5.1.4/sapi/apache/mod_php5.c 2006-04-02 19:58:17.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/sapi/apache/mod_php5.c 2006-09-05 20:31:06.000000000 +0200 +@@ -482,7 +482,7 @@ + sapi_apache_get_fd, + sapi_apache_force_http_10, + sapi_apache_get_target_uid, +- sapi_apache_get_target_gid ++ sapi_apache_get_target_gid, + }; + /* }}} */ + +@@ -936,7 +936,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component("PHP/" PHP_VERSION); ++#endif + } + } + #endif +diff -Nura php-5.1.4/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.4-0.4.15/sapi/apache2filter/sapi_apache2.c +--- php-5.1.4/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:31:06.000000000 +0200 +@@ -573,7 +573,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-5.1.4/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.4-0.4.15/sapi/apache2handler/sapi_apache2.c +--- php-5.1.4/sapi/apache2handler/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:31:06.000000000 +0200 +@@ -341,7 +341,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-5.1.4/sapi/cgi/cgi_main.c hardening-patch-5.1.4-0.4.15/sapi/cgi/cgi_main.c +--- php-5.1.4/sapi/cgi/cgi_main.c 2006-05-03 21:40:58.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:31:06.000000000 +0200 +@@ -1444,10 +1444,18 @@ + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } ++#if HARDENING_PATCH + #if ZEND_DEBUG +- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); ++ 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()); + #else +- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); ++ 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()); ++#endif ++#else ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif + #endif + php_end_ob_buffers(1 TSRMLS_CC); + exit(0); +diff -Nura php-5.1.4/sapi/cli/php_cli.c hardening-patch-5.1.4-0.4.15/sapi/cli/php_cli.c +--- php-5.1.4/sapi/cli/php_cli.c 2006-02-21 22:15:13.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:31:06.000000000 +0200 +@@ -753,8 +753,14 @@ + goto err; + } + ++#if HARDENING_PATCH ++ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", ++ PHP_VERSION, HARDENING_PATCH_VERSION, ++#else + php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", +- PHP_VERSION, sapi_module.name, __DATE__, __TIME__, ++ PHP_VERSION, ++#endif ++ sapi_module.name, __DATE__, __TIME__, + #if ZEND_DEBUG && defined(HAVE_GCOV) + "(DEBUG GCOV)", + #elif ZEND_DEBUG +diff -Nura php-5.1.4/TSRM/TSRM.h hardening-patch-5.1.4-0.4.15/TSRM/TSRM.h +--- php-5.1.4/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/TSRM/TSRM.h 2006-09-05 20:31:06.000000000 +0200 +@@ -33,6 +33,13 @@ + # define TSRM_API + #endif + ++#if HARDENING_PATCH ++# if HAVE_REALPATH ++# undef realpath ++# define realpath php_realpath ++# endif ++#endif ++ + /* Only compile multi-threading functions if we're in ZTS mode */ + #ifdef ZTS + +@@ -88,6 +95,7 @@ + + #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts + ++ + #ifdef __cplusplus + extern "C" { + #endif +diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.c +--- php-5.1.4/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:31:06.000000000 +0200 +@@ -163,6 +163,7 @@ + static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) + { + CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state); ++ cwd_globals->realpath_cache_disable = 0; + cwd_globals->realpath_cache_size = 0; + cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE; + cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL; +@@ -201,6 +202,176 @@ + return p; + } + ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved) ++{ ++ struct stat sb; ++ char *p, *q, *s; ++ size_t left_len, resolved_len; ++ unsigned symlinks; ++ int serrno, slen; ++ int is_dir = 1; ++ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; ++ ++ serrno = errno; ++ symlinks = 0; ++ if (path[0] == '/') { ++ resolved[0] = '/'; ++ resolved[1] = '\0'; ++ if (path[1] == '\0') ++ return (resolved); ++ resolved_len = 1; ++ left_len = strlcpy(left, path + 1, sizeof(left)); ++ } else { ++ if (getcwd(resolved, PATH_MAX) == NULL) { ++ strlcpy(resolved, ".", PATH_MAX); ++ return (NULL); ++ } ++ resolved_len = strlen(resolved); ++ left_len = strlcpy(left, path, sizeof(left)); ++ } ++ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ ++ /* ++ * Iterate over path components in `left'. ++ */ ++ while (left_len != 0) { ++ /* ++ * Extract the next path component and adjust `left' ++ * and its length. ++ */ ++ p = strchr(left, '/'); ++ s = p ? p : left + left_len; ++ if (s - left >= sizeof(next_token)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ memcpy(next_token, left, s - left); ++ next_token[s - left] = '\0'; ++ left_len -= s - left; ++ if (p != NULL) ++ memmove(left, s + 1, left_len + 1); ++ if (resolved[resolved_len - 1] != '/') { ++ if (resolved_len + 1 >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ resolved[resolved_len++] = '/'; ++ resolved[resolved_len] = '\0'; ++ } ++ if (next_token[0] == '\0') ++ continue; ++ else if (strcmp(next_token, ".") == 0) ++ continue; ++ else if (strcmp(next_token, "..") == 0) { ++ /* ++ * Strip the last path component except when we have ++ * single "/" ++ */ ++ if (!is_dir) { ++ errno = ENOENT; ++ return (NULL); ++ } ++ if (resolved_len > 1) { ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ continue; ++ } ++ ++ /* ++ * Append the next path component and lstat() it. If ++ * lstat() fails we still can return successfully if ++ * there are no more path components left. ++ */ ++ resolved_len = strlcat(resolved, next_token, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ if (lstat(resolved, &sb) != 0) { ++ if (errno == ENOENT) { ++ if (p == NULL) { ++ errno = serrno; ++ return (resolved); ++ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { ++ resolved_len = strlcat(resolved, "/", PATH_MAX); ++ resolved_len = strlcat(resolved, left, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ errno = serrno; ++ return (resolved); ++ } ++ } ++ return (NULL); ++ } ++ if (S_ISLNK(sb.st_mode)) { ++ if (symlinks++ > MAXSYMLINKS) { ++ errno = ELOOP; ++ return (NULL); ++ } ++ slen = readlink(resolved, symlink, sizeof(symlink) - 1); ++ if (slen < 0) ++ return (NULL); ++ symlink[slen] = '\0'; ++ if (symlink[0] == '/') { ++ resolved[1] = 0; ++ resolved_len = 1; ++ } else if (resolved_len > 1) { ++ /* Strip the last path component. */ ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ ++ /* ++ * If there are any path components left, then ++ * append them to symlink. The result is placed ++ * in `left'. ++ */ ++ if (p != NULL) { ++ if (symlink[slen - 1] != '/') { ++ if (slen + 1 >= sizeof(symlink)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ symlink[slen] = '/'; ++ symlink[slen + 1] = 0; ++ } ++ left_len = strlcat(symlink, left, sizeof(left)); ++ if (left_len >= sizeof(left)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ } ++ left_len = strlcpy(left, symlink, sizeof(left)); ++ } else { ++ if (S_ISDIR(sb.st_mode)) { ++ is_dir = 1; ++ } else { ++ is_dir = 0; ++ } ++ } ++ } ++ ++ /* ++ * Remove trailing slash except when the resolved pathname ++ * is a single "/". ++ */ ++ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') ++ resolved[resolved_len - 1] = '\0'; ++ return (resolved); ++} ++#endif ++ + CWD_API void virtual_cwd_startup(void) + { + char cwd[MAXPATHLEN]; +@@ -381,22 +552,33 @@ + #endif + char orig_path[MAXPATHLEN]; + int orig_path_len = 0; ++ int use_realpath_cache = 1; + realpath_cache_bucket *bucket; + time_t t = 0; + TSRMLS_FETCH(); + + if (path_length == 0) + return (0); +- if (path_length >= MAXPATHLEN) ++ if (path_length >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return (1); ++ } ++ ++ /* Disable realpath cache if safe_mode or open_basedir are set */ ++ if (CWDG(realpath_cache_disable)) { ++ use_realpath_cache = 0; ++ } + +- if (use_realpath && CWDG(realpath_cache_size_limit)) { ++ if (use_realpath && use_realpath_cache) { + if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { + memcpy(orig_path, path, path_length+1); + orig_path_len = path_length; + } else { + orig_path_len = path_length + state->cwd_length + 1; + if (orig_path_len >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(orig_path, state->cwd, state->cwd_length); +@@ -414,6 +596,8 @@ + if (verify_path && verify_path(state)) { + CWD_STATE_FREE(state); + *state = old_state; ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } else { + CWD_STATE_FREE(&old_state); +@@ -431,8 +615,9 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + } else { /* Concat current directory with relative path and then run realpath() on it */ +@@ -441,6 +626,8 @@ + + ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); + if (!tmp) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(ptr, state->cwd, state->cwd_length); +@@ -451,6 +638,8 @@ + *ptr = '\0'; + if (strlen(tmp) >= MAXPATHLEN) { + free(tmp); ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + if (use_realpath) { +@@ -458,9 +647,10 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now + free(tmp); +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + free(tmp); +@@ -599,7 +789,7 @@ + #endif + free(free_path); + +- if (use_realpath && CWDG(realpath_cache_size_limit)) { ++ if (use_realpath && use_realpath_cache) { + realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); + } + +diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.h +--- php-5.1.4/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:31:06.000000000 +0200 +@@ -127,6 +127,22 @@ + + typedef int (*verify_path_func)(const cwd_state *); + ++#ifndef HAVE_STRLCPY ++CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); ++#undef strlcpy ++#define strlcpy php_strlcpy ++#endif ++ ++#ifndef HAVE_STRLCAT ++CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); ++#undef strlcat ++#define strlcat php_strlcat ++#endif ++ ++ ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved); ++#endif + CWD_API void virtual_cwd_startup(void); + CWD_API void virtual_cwd_shutdown(void); + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); +@@ -199,6 +215,7 @@ + long realpath_cache_size_limit; + long realpath_cache_ttl; + realpath_cache_bucket *realpath_cache[1024]; ++ int realpath_cache_disable; + } virtual_cwd_globals; + + #ifdef ZTS +diff -Nura php-5.1.4/Zend/zend_alloc.c hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.c +--- php-5.1.4/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.c 2006-09-05 20:31:06.000000000 +0200 +@@ -64,6 +64,11 @@ + # define END_MAGIC_SIZE 0 + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++# define CANARY_SIZE sizeof(unsigned int) ++#else ++# define CANARY_SIZE 0 ++#endif + + # if MEMORY_LIMIT + # if ZEND_DEBUG +@@ -72,7 +77,15 @@ + #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) + # endif + +-#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ ++#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ ++ if (file) { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ ++ } else { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ ++ } \ ++ exit(1); \ ++ } \ ++ AG(allocated_memory) += rs;\ + if (AG(memory_limit)pNext; \ + } else { \ ++ if (p != p->pLast->pNext) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pLast->pNext = p->pNext; \ + } \ + if (p->pNext) { \ ++ if (p != p->pNext->pLast) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pNext->pLast = p->pLast; \ + } + #else +@@ -127,7 +148,7 @@ + #endif + + #define DECLARE_CACHE_VARS() \ +- unsigned int real_size; \ ++ size_t real_size; \ + unsigned int cache_index + + #define REAL_SIZE(size) ((size+7) & ~0x7) +@@ -142,12 +163,22 @@ + + ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { +- zend_mem_header *p; ++ zend_mem_header *p = NULL; + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { ++ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); ++ exit(1); ++ } ++#endif + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + ++ if (size > INT_MAX || SIZE < size) { ++ goto emalloc_error; ++ } ++ + #if !ZEND_DISABLE_MEMORY_CACHE + if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { + p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; +@@ -164,6 +195,10 @@ + AG(cache_stats)[CACHE_INDEX][1]++; + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } else { +@@ -179,11 +214,13 @@ + AG(allocated_memory_peak) = AG(allocated_memory); + } + #endif +- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); + #if !ZEND_DISABLE_MEMORY_CACHE + } + #endif + ++emalloc_error: ++ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (!p) { +@@ -210,7 +247,10 @@ + # endif + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif +- ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } +@@ -238,6 +278,10 @@ + } + } + ++ ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); ++#endif + zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset); + return 0; + } +@@ -270,9 +314,25 @@ + + ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); ++ ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++efree_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); ++ exit(1); ++ } ++ /* to catch double efree()s */ ++ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); ++ p->canary = 0; ++#endif + + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { +@@ -313,23 +373,35 @@ + + ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { +- void *p; +- int final_size = size*nmemb; ++ char *p; ++ size_t _size = nmemb * size; ++ ++ if (nmemb && (_size/nmemb!=size)) { ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); ++#endif ++ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); ++#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID ++ kill(getpid(), SIGSEGV); ++#else ++ exit(1); ++#endif ++ } + +- HANDLE_BLOCK_INTERRUPTIONS(); +- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); +- if (!p) { +- HANDLE_UNBLOCK_INTERRUPTIONS(); +- return (void *) p; ++ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); ++ if (p) { ++ memset(p, 0, _size); + } +- memset(p, 0, final_size); +- HANDLE_UNBLOCK_INTERRUPTIONS(); +- return p; ++ ++ return ((void *)p); + } + + + ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p; + zend_mem_header *orig; + DECLARE_CACHE_VARS(); +@@ -341,6 +413,16 @@ + + p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++erealloc_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); ++ exit(1); ++ } ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + void *new_p; +@@ -357,6 +439,13 @@ + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + + HANDLE_BLOCK_INTERRUPTIONS(); ++ ++ if (size > INT_MAX || SIZE < size) { ++ REMOVE_POINTER_FROM_LIST(p); ++ p = NULL; ++ goto erealloc_error; ++ } ++ + #if MEMORY_LIMIT + CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); + if (AG(allocated_memory) > AG(allocated_memory_peak)) { +@@ -364,7 +453,8 @@ + } + #endif + REMOVE_POINTER_FROM_LIST(p); +- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); ++erealloc_error: + if (!p) { + if (!allow_failure) { + fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); +@@ -386,6 +476,9 @@ + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + + HANDLE_UNBLOCK_INTERRUPTIONS(); +@@ -460,6 +553,10 @@ + { + AG(head) = NULL; + ++#if HARDENING_PATCH_MM_PROTECT ++ HG(canary_1) = zend_canary(); ++ HG(canary_2) = zend_canary(); ++#endif + #if MEMORY_LIMIT + AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ + AG(allocated_memory) = 0; +diff -Nura php-5.1.4/Zend/zend_alloc.h hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.h +--- php-5.1.4/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.h 2006-09-05 20:31:06.000000000 +0200 +@@ -35,6 +35,9 @@ + #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL + + typedef struct _zend_mem_header { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary; ++#endif + #if ZEND_DEBUG + long magic; + char *filename; +diff -Nura php-5.1.4/Zend/zend_API.h hardening-patch-5.1.4-0.4.15/Zend/zend_API.h +--- php-5.1.4/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_API.h 2006-09-05 20:31:06.000000000 +0200 +@@ -47,6 +47,7 @@ + #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) + + #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 }, ++#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 }, + + #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0) + #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0) +diff -Nura php-5.1.4/Zend/zend_builtin_functions.c hardening-patch-5.1.4-0.4.15/Zend/zend_builtin_functions.c +--- php-5.1.4/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:31:06.000000000 +0200 +@@ -53,6 +53,9 @@ + static ZEND_FUNCTION(crash); + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++static ZEND_FUNCTION(heap_overflow); ++#endif + static ZEND_FUNCTION(get_included_files); + static ZEND_FUNCTION(is_subclass_of); + static ZEND_FUNCTION(is_a); +@@ -113,6 +116,9 @@ + ZEND_FE(crash, NULL) + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ ZEND_FE(heap_overflow, NULL) ++#endif + ZEND_FE(get_included_files, NULL) + ZEND_FALIAS(get_required_files, get_included_files, NULL) + ZEND_FE(is_subclass_of, NULL) +@@ -1103,6 +1109,19 @@ + + #endif /* ZEND_DEBUG */ + ++ ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ZEND_FUNCTION(heap_overflow) ++{ ++ char *nowhere = emalloc(10); ++ ++ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); ++ ++ efree(nowhere); ++} ++#endif ++ ++ + /* {{{ proto array get_included_files(void) + Returns an array with the file names that were include_once()'d */ + ZEND_FUNCTION(get_included_files) +diff -Nura php-5.1.4/Zend/zend.c hardening-patch-5.1.4-0.4.15/Zend/zend.c +--- php-5.1.4/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend.c 2006-09-05 20:31:06.000000000 +0200 +@@ -55,6 +55,12 @@ + ZEND_API void (*zend_unblock_interruptions)(void); + ZEND_API void (*zend_ticks_function)(int ticks); + ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); ++#if HARDENING_PATCH ++ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); + ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); + +@@ -74,9 +80,391 @@ + return SUCCESS; + } + ++#if HARDENING_PATCH ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; ++ } else { ++ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_facility) = LOG_USER; ++ } else { ++ EG(hphp_log_syslog_facility) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_priority) = LOG_ALERT; ++ } else { ++ EG(hphp_log_syslog_priority) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_sapi) ++{ ++ if (!new_value) { ++ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; ++ } else { ++ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_script) ++{ ++ if (!new_value) { ++ EG(hphp_log_script) = S_ALL & ~S_MEMORY; ++ } else { ++ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) ++{ ++ if (EG(hphp_log_scriptname)) { ++ pefree(EG(hphp_log_scriptname),1); ++ } ++ EG(hphp_log_scriptname) = NULL; ++ if (new_value) { ++ EG(hphp_log_scriptname) = pestrdup(new_value,1); ++ } ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_whitelist_destroy: ++ if (HG(include_whitelist)) { ++ zend_hash_destroy(HG(include_whitelist)); ++ pefree(HG(include_whitelist),1); ++ } ++ HG(include_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_whitelist_destroy; ++ } ++ ++ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_blacklist_destroy: ++ if (HG(include_blacklist)) { ++ zend_hash_destroy(HG(include_blacklist)); ++ pefree(HG(include_blacklist),1); ++ } ++ HG(include_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_blacklist_destroy; ++ } ++ ++ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_whitelist_destroy: ++ if (HG(eval_whitelist)) { ++ zend_hash_destroy(HG(eval_whitelist)); ++ pefree(HG(eval_whitelist),1); ++ } ++ HG(eval_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_whitelist_destroy; ++ } ++ ++ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_blacklist_destroy: ++ if (HG(eval_blacklist)) { ++ zend_hash_destroy(HG(eval_blacklist)); ++ pefree(HG(eval_blacklist), 1); ++ } ++ HG(eval_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_blacklist_destroy; ++ } ++ ++ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_whitelist_destroy: ++ if (HG(func_whitelist)) { ++ zend_hash_destroy(HG(func_whitelist)); ++ pefree(HG(func_whitelist),1); ++ } ++ HG(func_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_whitelist_destroy; ++ } ++ ++ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_blacklist_destroy: ++ if (HG(func_blacklist)) { ++ zend_hash_destroy(HG(func_blacklist)); ++ pefree(HG(func_blacklist),1); ++ } ++ HG(func_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_blacklist_destroy; ++ } ++ ++ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++#endif + + ZEND_INI_BEGIN() + ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) ++#if HARDENING_PATCH ++ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) ++ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) ++ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) ++ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) ++ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) ++ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) ++ 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) ++ ++ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) ++ ++ 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) ++ 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) ++ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) ++ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) ++#endif + STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals) + #ifdef ZEND_MULTIBYTE + STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) +@@ -501,9 +889,13 @@ + EG(user_error_handler) = NULL; + EG(user_exception_handler) = NULL; + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(in_autoload) = NULL; + EG(current_execute_data) = NULL; + EG(current_module) = NULL; ++#if HARDENING_PATCH ++ EG(hphp_log_scriptname) = NULL; ++#endif + } + + +@@ -574,6 +966,14 @@ + extern zend_scanner_globals language_scanner_globals; + #endif + ++ /* Set up Hardening-Patch utility functions first */ ++#if HARDENING_PATCH ++ zend_security_log = utility_functions->security_log_function; ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ zend_is_valid_include = utility_functions->is_valid_include; ++#endif ++ + #ifdef ZTS + ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + #else +@@ -777,6 +1177,7 @@ + } + CG(unclean_shutdown) = 1; + CG(in_compilation) = EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(current_execute_data) = NULL; + longjmp(EG(bailout), FAILURE); + } +diff -Nura php-5.1.4/Zend/zend_canary.c hardening-patch-5.1.4-0.4.15/Zend/zend_canary.c +--- php-5.1.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_canary.c 2006-09-05 20:31:06.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ ++ ++#include "zend.h" ++ ++#include ++#include ++ ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++ZEND_API unsigned int zend_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.4/Zend/zend_compile.c hardening-patch-5.1.4-0.4.15/Zend/zend_compile.c +--- php-5.1.4/Zend/zend_compile.c 2006-05-02 17:49:26.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_compile.c 2006-09-05 20:31:06.000000000 +0200 +@@ -1093,6 +1093,13 @@ + op_array.prototype = NULL; + + op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array.created_by_eval = 1; ++ } else { ++ op_array.created_by_eval = 0; ++ } ++#endif + + if (is_method) { + char *short_class_name = CG(active_class_entry)->name; +diff -Nura php-5.1.4/Zend/zend_compile.h hardening-patch-5.1.4-0.4.15/Zend/zend_compile.h +--- php-5.1.4/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_compile.h 2006-09-05 20:31:06.000000000 +0200 +@@ -217,6 +217,9 @@ + zend_uint doc_comment_len; + + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; ++#if HARDENING_PATCH ++ zend_bool created_by_eval; ++#endif + }; + + +@@ -295,6 +298,8 @@ + zval ***CVs; + zend_bool original_in_execution; + HashTable *symbol_table; ++ zend_uint original_in_code_type; ++ zend_uint execute_depth; + struct _zend_execute_data *prev_execute_data; + zval *old_error_reporting; + }; +@@ -617,6 +622,7 @@ + #define ZEND_OVERLOADED_FUNCTION 3 + #define ZEND_EVAL_CODE 4 + #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5 ++#define ZEND_SANDBOX_CODE 6 + + #define ZEND_INTERNAL_CLASS 1 + #define ZEND_USER_CLASS 2 +diff -Nura php-5.1.4/Zend/zend_constants.c hardening-patch-5.1.4-0.4.15/Zend/zend_constants.c +--- php-5.1.4/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_constants.c 2006-09-05 20:31:06.000000000 +0200 +@@ -109,6 +109,74 @@ + REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); + + REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); ++ ++ /* error levels */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); ++ /* facility: type of program logging the message */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NEWS ++ /* No LOG_NEWS on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ ++#endif ++#ifdef LOG_UUCP ++ /* No LOG_UUCP on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_CRON ++ /* apparently some systems don't have this one */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_AUTHPRIV ++ /* AIX doesn't have LOG_AUTHPRIV */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); ++#endif ++#if !defined(PHP_WIN32) && !defined(NETWARE) ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); ++#endif ++ /* options */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NOWAIT ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_PERROR ++ /* AIX doesn't have LOG_PERROR */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ ++#endif ++#endif + + /* true/false constants */ + { +diff -Nura php-5.1.4/Zend/zend_errors.h hardening-patch-5.1.4-0.4.15/Zend/zend_errors.h +--- php-5.1.4/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_errors.h 2006-09-05 20:31:06.000000000 +0200 +@@ -38,6 +38,19 @@ + #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) + #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) + ++#if HARDENING_PATCH ++#define S_MEMORY (1<<0L) ++#define S_VARS (1<<1L) ++#define S_FILES (1<<2L) ++#define S_INCLUDE (1<<3L) ++#define S_SQL (1<<4L) ++#define S_EXECUTOR (1<<5L) ++#define S_MAIL (1<<6L) ++#define S_MISC (1<<30L) ++#define S_INTERNAL (1<<29L) ++#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) ++#endif ++ + #endif /* ZEND_ERRORS_H */ + + /* +diff -Nura php-5.1.4/Zend/zend_execute_API.c hardening-patch-5.1.4-0.4.15/Zend/zend_execute_API.c +--- php-5.1.4/Zend/zend_execute_API.c 2006-04-21 00:49:20.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:31:06.000000000 +0200 +@@ -142,6 +142,7 @@ + EG(class_table) = CG(class_table); + + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(in_autoload) = NULL; + EG(autoload_func) = NULL; + +@@ -784,6 +785,39 @@ + if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) { + EX(function_state).function = NULL; + } ++#if HARDENING_PATCH ++ else { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + efree(function_name_lc); + } + +@@ -1076,7 +1110,7 @@ + return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC); + } + +-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC) + { + zval pv; + zend_op_array *new_op_array; +@@ -1109,6 +1143,7 @@ + zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); + zend_op **original_opline_ptr = EG(opline_ptr); + ++ new_op_array->type = type; + EG(return_value_ptr_ptr) = &local_retval_ptr; + EG(active_op_array) = new_op_array; + EG(no_extensions)=1; +@@ -1143,6 +1178,12 @@ + } + + ++ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++{ ++ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); ++} ++ ++ + ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) + { + int result; +diff -Nura php-5.1.4/Zend/zend_execute.c hardening-patch-5.1.4-0.4.15/Zend/zend_execute.c +--- php-5.1.4/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_execute.c 2006-09-05 20:31:06.000000000 +0200 +@@ -1351,6 +1351,37 @@ + /* OBJ-TBI - doesn't support new object model! */ + zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + return 0; + } +@@ -1396,6 +1427,7 @@ + efree(EX(Ts)); \ + } \ + EG(in_execution) = EX(original_in_execution); \ ++ EG(in_code_type) = EX(original_in_code_type); \ + EG(current_execute_data) = EX(prev_execute_data); \ + ZEND_VM_RETURN() + +diff -Nura php-5.1.4/Zend/zend_extensions.c hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.c +--- php-5.1.4/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.c 2006-09-05 20:31:06.000000000 +0200 +@@ -55,23 +55,44 @@ + return FAILURE; + } + ++ /* check if module is compiled against Hardening-Patch */ ++ if (extension_version_info->zend_extension_api_no < 1000000000) { ++ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } ++ ++ ++ /* check if module is compiled against correct Hardening-Patch version */ ++ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { ++ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ extension_version_info->zend_extension_api_no, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } + + /* allow extension to proclaim compatibility with any Zend version */ +- 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)) { +- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { ++ 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)) { ++ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is outdated.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO); + DL_UNLOAD(handle); + return FAILURE; +- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { ++ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is newer.\n" + "Contact %s at %s for a later version of %s.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO, + new_extension->author, + new_extension->URL, +diff -Nura php-5.1.4/Zend/zend_extensions.h hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.h +--- php-5.1.4/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.h 2006-09-05 20:31:06.000000000 +0200 +@@ -24,9 +24,11 @@ + + #include "zend_compile.h" + +-/* The first number is the engine version and the rest is the date. ++/* The first API number is a flag saying that Hardening-Patch is used. ++ * The second number is the engine version and the date. + * This way engine 2 API no. is always greater than engine 1 API no.. + */ ++#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106 + #define ZEND_EXTENSION_API_NO 220051025 + + typedef struct _zend_extension_version_info { +@@ -34,6 +36,7 @@ + char *required_zend_version; + unsigned char thread_safe; + unsigned char debug; ++ int real_zend_extension_api_no; + } zend_extension_version_info; + + +@@ -101,7 +104,7 @@ + + + #define ZEND_EXTENSION() \ +- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } ++ 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 } + + #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 + #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 +diff -Nura php-5.1.4/Zend/zend_globals.h hardening-patch-5.1.4-0.4.15/Zend/zend_globals.h +--- php-5.1.4/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_globals.h 2006-09-05 20:31:06.000000000 +0200 +@@ -180,6 +180,16 @@ + + int error_reporting; + int orig_error_reporting; ++#if HARDENING_PATCH ++ int hphp_log_syslog; ++ int hphp_log_syslog_facility; ++ int hphp_log_syslog_priority; ++ int hphp_log_sapi; ++ int hphp_log_script; ++ char *hphp_log_scriptname; ++ zend_bool hphp_log_use_x_forwarded_for; ++ long hphp_executor_max_depth; ++#endif + int exit_status; + + zend_op_array *active_op_array; +@@ -197,6 +207,7 @@ + int ticks_count; + + zend_bool in_execution; ++ zend_uint in_code_type; + HashTable *in_autoload; + zend_function *autoload_func; + zend_bool bailout_set; +diff -Nura php-5.1.4/Zend/zend.h hardening-patch-5.1.4-0.4.15/Zend/zend.h +--- php-5.1.4/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend.h 2006-09-05 20:31:06.000000000 +0200 +@@ -297,6 +297,7 @@ + /* Variable information */ + zvalue_value value; /* value */ + zend_uint refcount; ++ zend_ushort flags; + zend_uchar type; /* active type */ + zend_uchar is_ref; + }; +@@ -382,6 +383,12 @@ + int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); + int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); + char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); ++#if HARDENING_PATCH ++ void (*security_log_function)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ int (*is_valid_include)(zval *z); ++#endif + } zend_utility_functions; + + +@@ -519,7 +526,16 @@ + extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); + extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); + extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); ++#if HARDENING_PATCH ++extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++extern ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ZEND_API unsigned int zend_canary(void); ++#endif + + ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); + +@@ -644,6 +660,11 @@ + + #include "zend_variables.h" + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#include "php_syslog.h" ++#endif ++ + #endif /* ZEND_H */ + + /* +diff -Nura php-5.1.4/Zend/zend_hash.c hardening-patch-5.1.4-0.4.15/Zend/zend_hash.c +--- php-5.1.4/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_hash.c 2006-09-05 20:31:06.000000000 +0200 +@@ -21,6 +21,18 @@ + + #include "zend.h" + ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int zend_hash_canary = 0x1234567; ++ zend_bool zend_hash_canary_inited = 0; ++#endif ++ ++#define CHECK_HASH_CANARY(hash) \ ++ if (zend_hash_canary != (hash)->canary) { \ ++ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++ + #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ + (element)->pNext = (list_head); \ + (element)->pLast = NULL; \ +@@ -138,6 +150,9 @@ + { + uint i = 3; + Bucket **tmp; ++#if HARDENING_PATCH_HASH_PROTECT ++ TSRMLS_FETCH(); ++#endif + + SET_INCONSISTENT(HT_OK); + +@@ -147,6 +162,13 @@ + + ht->nTableSize = 1 << i; + ht->nTableMask = ht->nTableSize - 1; ++#if HARDENING_PATCH_HASH_PROTECT ++ if (zend_hash_canary_inited==0) { ++ zend_hash_canary = zend_canary(); ++ zend_hash_canary_inited = 1; ++ } ++ ht->canary = zend_hash_canary; ++#endif + ht->pDestructor = pDestructor; + ht->arBuckets = NULL; + ht->pListHead = NULL; +@@ -226,6 +248,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -291,6 +316,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -366,6 +394,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -414,7 +445,7 @@ + IS_CONSISTENT(ht); + + if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ +- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); ++ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); + if (t) { + HANDLE_BLOCK_INTERRUPTIONS(); + ht->arBuckets = t; +@@ -424,6 +455,7 @@ + HANDLE_UNBLOCK_INTERRUPTIONS(); + return SUCCESS; + } ++ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); + return FAILURE; + } + return SUCCESS; +@@ -489,6 +521,9 @@ + ht->pInternalPointer = p->pListNext; + } + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (p->pData != &p->pDataPtr) { +@@ -513,6 +548,11 @@ + + SET_INCONSISTENT(HT_IS_DESTROYING); + ++#if HARDENING_PATCH_HASH_PROTECT ++ if (ht->pDestructor) { ++ CHECK_HASH_CANARY(ht); ++ } ++#endif + p = ht->pListHead; + while (p != NULL) { + q = p; +@@ -539,6 +579,11 @@ + + SET_INCONSISTENT(HT_CLEANING); + ++#if HARDENING_PATCH_HASH_PROTECT ++ if (ht->pDestructor) { ++ CHECK_HASH_CANARY(ht); ++ } ++#endif + p = ht->pListHead; + while (p != NULL) { + q = p; +@@ -573,6 +618,9 @@ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (p->pData != &p->pDataPtr) { +diff -Nura php-5.1.4/Zend/zend_hash.h hardening-patch-5.1.4-0.4.15/Zend/zend_hash.h +--- php-5.1.4/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_hash.h 2006-09-05 20:31:06.000000000 +0200 +@@ -58,6 +58,9 @@ + } Bucket; + + typedef struct _hashtable { ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int canary; ++#endif + uint nTableSize; + uint nTableMask; + uint nNumOfElements; +diff -Nura php-5.1.4/Zend/zend_ini.c hardening-patch-5.1.4-0.4.15/Zend/zend_ini.c +--- php-5.1.4/Zend/zend_ini.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:18.000000000 +0200 +@@ -256,7 +256,8 @@ + zend_ini_entry *ini_entry; + TSRMLS_FETCH(); + +- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { ++ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || ++ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) { + return FAILURE; + } + +diff -Nura php-5.1.4/Zend/zend_language_scanner.l hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.l +--- php-5.1.4/Zend/zend_language_scanner.l 2006-04-13 15:48:28.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:31:06.000000000 +0200 +@@ -389,6 +389,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-5.1.4/Zend/zend_language_scanner.c hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.c +--- php-5.1.4/Zend/zend_language_scanner.c 2006-05-12 16:41:13.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:31:06.000000000 +0200 +@@ -3075,6 +3075,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-5.1.4/Zend/zend_llist.c hardening-patch-5.1.4-0.4.15/Zend/zend_llist.c +--- php-5.1.4/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_llist.c 2006-09-05 20:31:06.000000000 +0200 +@@ -22,9 +22,49 @@ + #include "zend.h" + #include "zend_llist.h" + #include "zend_qsort.h" ++#include "zend_globals.h" ++ ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int zend_llist_canary_1 = 0x1234567; ++ unsigned int zend_llist_canary_2 = 0x1553425; ++ zend_bool zend_llist_canary_inited = 0; ++#endif ++ ++#define CHECK_LIST_CANARY(list) \ ++ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ ++ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ ++ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++#define CHECK_LISTELEMENT_CANARY(elem, list) \ ++ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ ++ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ ++ exit(1); \ ++ } ++ + + ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ ++ if (persistent) { ++ if (!zend_llist_canary_inited) { ++ /* do not change order to ensure thread safety */ ++ zend_llist_canary_1 = zend_canary(); ++ zend_llist_canary_2 = zend_canary(); ++ zend_llist_canary_inited = 1; ++ } ++ } else ++ if (!HG(ll_canary_inited)) { ++ HG(canary_3) = zend_canary(); ++ HG(canary_4) = zend_canary(); ++ HG(ll_canary_inited) = 1; ++ } ++ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); ++ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); ++#endif + l->head = NULL; + l->tail = NULL; + l->count = 0; +@@ -38,6 +78,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->prev = l->tail; + tmp->next = NULL; + if (l->tail) { +@@ -56,6 +101,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->next = l->head; + tmp->prev = NULL; + if (l->head) { +@@ -93,10 +143,20 @@ + zend_llist_element *current=l->head; + zend_llist_element *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (compare(current->data, element)) { + DEL_LLIST_ELEMENT(current, l); ++#if HARDENING_PATCH_LL_PROTECT ++ current->canary = 0; ++#endif + break; + } + current = next; +@@ -108,7 +168,14 @@ + { + zend_llist_element *current=l->head, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (l->dtor) { + l->dtor(current->data); +@@ -133,7 +200,14 @@ + zend_llist_element *old_tail; + void *data; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if ((old_tail = l->tail)) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(old_tail, l) ++#endif + if (l->tail->prev) { + l->tail->prev->next = NULL; + } +@@ -159,9 +233,16 @@ + { + zend_llist_element *ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(src) ++#endif + zend_llist_init(dst, src->size, src->dtor, src->persistent); + ptr = src->head; + while (ptr) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(ptr, src) ++#endif + zend_llist_add_element(dst, ptr->data); + ptr = ptr->next; + } +@@ -172,11 +253,21 @@ + { + zend_llist_element *element, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + element=l->head; + while (element) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + next = element->next; + if (func(element->data)) { + DEL_LLIST_ELEMENT(element, l); ++#if HARDENING_PATCH_LL_PROTECT ++ element->canary = 0; ++#endif + } + element = next; + } +@@ -187,7 +278,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data TSRMLS_CC); + } + } +@@ -199,6 +296,9 @@ + zend_llist_element **elements; + zend_llist_element *element, **ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + if (l->count <= 0) { + return; + } +@@ -208,6 +308,9 @@ + ptr = &elements[0]; + + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + *ptr++ = element; + } + +@@ -230,7 +333,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, arg TSRMLS_CC); + } + } +@@ -241,8 +350,14 @@ + zend_llist_element *element; + va_list args; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + va_start(args, num_args); + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, num_args, args TSRMLS_CC); + } + va_end(args); +@@ -251,6 +366,10 @@ + + ZEND_API int zend_llist_count(zend_llist *l) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + return l->count; + } + +@@ -259,8 +378,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->head; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -272,8 +398,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->tail; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -285,9 +418,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->next; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +@@ -299,9 +442,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->prev; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +diff -Nura php-5.1.4/Zend/zend_llist.h hardening-patch-5.1.4-0.4.15/Zend/zend_llist.h +--- php-5.1.4/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_llist.h 2006-09-05 20:31:06.000000000 +0200 +@@ -23,6 +23,9 @@ + #define ZEND_LLIST_H + + typedef struct _zend_llist_element { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary, padding; ++#endif + struct _zend_llist_element *next; + struct _zend_llist_element *prev; + char data[1]; /* Needs to always be last in the struct */ +@@ -35,6 +38,9 @@ + typedef void (*llist_apply_func_t)(void * TSRMLS_DC); + + typedef struct _zend_llist { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_h; /* head */ ++#endif + zend_llist_element *head; + zend_llist_element *tail; + size_t count; +@@ -42,6 +48,9 @@ + llist_dtor_func_t dtor; + unsigned char persistent; + zend_llist_element *traverse_ptr; ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_t; /* tail */ ++#endif + } zend_llist; + + typedef zend_llist_element* zend_llist_position; +diff -Nura php-5.1.4/Zend/zend_modules.h hardening-patch-5.1.4-0.4.15/Zend/zend_modules.h +--- php-5.1.4/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_modules.h 2006-09-05 20:31:06.000000000 +0200 +@@ -39,6 +39,7 @@ + extern struct _zend_arg_info fifth_arg_force_ref[6]; + extern struct _zend_arg_info all_args_by_ref[1]; + ++#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106 + #define ZEND_MODULE_API_NO 20050922 + #ifdef ZTS + #define USING_ZTS 1 +@@ -46,13 +47,13 @@ + #define USING_ZTS 0 + #endif + +-#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS ++#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS + #define STANDARD_MODULE_HEADER \ + STANDARD_MODULE_HEADER_EX, NULL, NULL + #define ZE2_STANDARD_MODULE_HEADER \ + STANDARD_MODULE_HEADER_EX, ini_entries, NULL + +-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 ++#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO + + #define STANDARD_MODULE_PROPERTIES \ + NULL, STANDARD_MODULE_PROPERTIES_EX +@@ -87,6 +88,7 @@ + unsigned char type; + void *handle; + int module_number; ++ unsigned int real_zend_api; + }; + + #define MODULE_DEP_REQUIRED 1 +diff -Nura php-5.1.4/Zend/zend_opcode.c hardening-patch-5.1.4-0.4.15/Zend/zend_opcode.c +--- php-5.1.4/Zend/zend_opcode.c 2006-04-10 14:26:53.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_opcode.c 2006-09-05 20:31:06.000000000 +0200 +@@ -98,6 +98,9 @@ + op_array->uses_this = 0; + + op_array->start_op = NULL; ++#if HARDENING_PATCH ++ op_array->created_by_eval = 0; ++#endif + + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); + } +diff -Nura php-5.1.4/Zend/zend_vm_def.h hardening-patch-5.1.4-0.4.15/Zend/zend_vm_def.h +--- php-5.1.4/Zend/zend_vm_def.h 2006-04-12 13:37:50.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_def.h 2006-09-05 20:31:06.000000000 +0200 +@@ -1769,6 +1769,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (OP2_TYPE != IS_CONST) { +@@ -1994,6 +2025,34 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++#endif ++ + EX(object) = NULL; + + FREE_OP1(); +@@ -2709,7 +2768,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -2734,6 +2798,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +diff -Nura php-5.1.4/Zend/zend_vm_execute.h hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.h +--- php-5.1.4/Zend/zend_vm_execute.h 2006-04-12 13:37:50.000000000 +0200 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.h 2006-09-05 20:31:07.000000000 +0200 +@@ -56,6 +56,16 @@ + EX(symbol_table) = EG(active_symbol_table); + EX(prev_execute_data) = EG(current_execute_data); + EG(current_execute_data) = &execute_data; ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif + + EG(in_execution) = 1; + if (op_array->start_op) { +@@ -81,6 +91,18 @@ + */ + EX(function_state).function_symbol_table = NULL; + #endif ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif + + while (1) { + #ifdef ZEND_WIN32 +@@ -724,6 +746,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_CONST != IS_CONST) { +@@ -925,6 +978,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_TMP_VAR != IS_CONST) { +@@ -1083,6 +1167,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_VAR != IS_CONST) { +@@ -1330,6 +1445,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_CV != IS_CONST) { +@@ -1635,6 +1781,34 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++#endif ++ + EX(object) = NULL; + + return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +@@ -1914,7 +2088,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -1939,6 +2118,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -4345,7 +4529,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -4370,6 +4559,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -7358,7 +7552,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -7383,6 +7582,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -19470,7 +19674,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -19495,6 +19704,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +diff -Nura php-5.1.4/Zend/zend_vm_execute.skl hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.skl +--- php-5.1.4/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100 ++++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.skl 2006-09-05 20:31:07.000000000 +0200 +@@ -27,6 +27,16 @@ + EX(symbol_table) = EG(active_symbol_table); + EX(prev_execute_data) = EG(current_execute_data); + EG(current_execute_data) = &execute_data; ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif + + EG(in_execution) = 1; + if (op_array->start_op) { +@@ -52,6 +62,18 @@ + */ + EX(function_state).function_symbol_table = NULL; + #endif ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif + + while (1) { + {%ZEND_VM_CONTINUE_LABEL%} diff --git a/0.4.15/hardening-patch-5.1.5-0.4.15.patch b/0.4.15/hardening-patch-5.1.5-0.4.15.patch new file mode 100644 index 0000000..ff15548 --- /dev/null +++ b/0.4.15/hardening-patch-5.1.5-0.4.15.patch @@ -0,0 +1,8817 @@ +diff -Nura php-5.1.5/Changelog.hphp hardening-patch-5.1.5-0.4.15/Changelog.hphp +--- php-5.1.5/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Changelog.hphp 2006-09-07 19:32:16.000000000 +0200 +@@ -0,0 +1,61 @@ ++Changelog of the Hardening-Patch ++-------------------------------- ++ ++0.4.15 - 07. September 2006 ++ ++ PHP4: ++ [+] Fix for potential DOS in handling of include blacklists ++ ++ PHP4+5: ++ [+] Backported a fix for open_basedir problems with insanse PHP scripts ++ [+] Added a fix for ini_restore() PHP security vulnerability ++ ++0.4.14 - 11. August 2006 ++ ++ PHP4: ++ [+] Remove unecessary call to AC_BROKEN_REALPATH ++ ++ PHP5: ++ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant ++ ++ PHP4+5: ++ [+] Added a few PHP security fixes / see changelog.secfix for details ++ [+] Fixed the memory_limit protection for systems with different perdir memory_limits ++ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments ++ ++0.4.13 - 07. August 2006 ++ ++ PHP4+5: ++ [+] Added a fix for a compile problem on solaris due to missing strcasestr() ++ ++0.4.12 - 19. July 2006 ++ ++ PHP4: ++ [+] Added fixes from sf4 security patch / see changelog.secfix for details ++ ++ PHP5: ++ [+] Added fixes from sf5 security patch / see changelog.secfix for details ++ ++ PHP4+5: ++ [+] Added anti mail spam feature ++ [+] Speedup of zend_hash canary (clear/destroy) ++ [+] Added a fix for a DOS in the handling of URL blacklists ++ ++0.4.11 - 13. May 2006 ++ ++ PHP5: ++ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache ++ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 ++ ++ PHP4+5: ++ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories ++ ++ ++0.4.10 - 11. May 2006 ++ ++ PHP4: ++ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed ++ ++ PHP4+5: ++ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir ++ +diff -Nura php-5.1.5/Changelog.secfix hardening-patch-5.1.5-0.4.15/Changelog.secfix +--- php-5.1.5/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Changelog.secfix 2006-09-05 20:31:22.000000000 +0200 +@@ -0,0 +1,40 @@ ++Changelog of PHP 5.1.4 Security Fixes ++ ++Release 6 - 11. August 2006 ++ ++ [+] Added IMAP open_basedir/safe_mode check ++ [+] Added a fix for previous ext/session fixes ++ [+] Added upstream fix to ext/socket ++ [+] Added sscanf() security fix ++ [+] Added fixes for handling of corrupt .gif files to gdlib ++ ++Release 5 - 13. July 2006 ++ ++ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode ++ ++Release 4 - 13. July 2006 ++ ++ [+] Added a recursive array printing fix to the phpinfo() XSS fix ++ [+] Added a fix for stat() on non existing files in safe_mode ++ ++Release 3 - 07. July 2006 ++ ++ [+] Added a fix for an integer overflow in str_repeat() ++ [+] Added a *working* wordwrap() fix ++ [+] Added code to make memory_limit work on 64bit systems ++ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability ++ [+] Added a fix for overlong tempfilename ++ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl ++ [+] Added a high characters fix to ext/wddx ++ ++Release 2 - 16. May 2006 ++ ++ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP ++ tarball got updated ++ ++Release 1 - 13. May 2006 ++ ++ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball ++ and is downloaded when make install is called (usually as root -> security risk) ++ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache ++ +diff -Nura php-5.1.5/configure hardening-patch-5.1.5-0.4.15/configure +--- php-5.1.5/configure 2006-08-15 14:55:40.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/configure 2006-09-05 20:31:22.000000000 +0200 +@@ -942,6 +942,16 @@ + ac_help="$ac_help + --with-libdir=NAME Look for libraries in .../NAME rather than .../lib" + ac_help="$ac_help ++ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." ++ac_help="$ac_help ++ --disable-hardening-patch-ll-protect Disable the Linked List protection." ++ac_help="$ac_help ++ --disable-hardening-patch-inc-protect Disable include/require protection." ++ac_help="$ac_help ++ --disable-hardening-patch-fmt-protect Disable format string protection." ++ac_help="$ac_help ++ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." ++ac_help="$ac_help + + SAPI modules: + " +@@ -1410,6 +1420,8 @@ + ac_help="$ac_help + --enable-wddx Enable WDDX support" + ac_help="$ac_help ++ --disable-varfilter Disable Hardening-Patch's variable filter" ++ac_help="$ac_help + --disable-xml Disable XML support" + ac_help="$ac_help + --with-libxml-dir=DIR XML: libxml2 install prefix" +@@ -3618,6 +3630,157 @@ + + + ++# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. ++if test "${enable_hardening_patch_mm_protect+set}" = set; then ++ enableval="$enable_hardening_patch_mm_protect" ++ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. ++if test "${enable_hardening_patch_ll_protect+set}" = set; then ++ enableval="$enable_hardening_patch_ll_protect" ++ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. ++if test "${enable_hardening_patch_inc_protect+set}" = set; then ++ enableval="$enable_hardening_patch_inc_protect" ++ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. ++if test "${enable_hardening_patch_fmt_protect+set}" = set; then ++ enableval="$enable_hardening_patch_fmt_protect" ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. ++if test "${enable_hardening_patch_hash_protect+set}" = set; then ++ enableval="$enable_hardening_patch_hash_protect" ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++ ++fi ++ ++ ++echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 ++echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 ++echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 ++echo "configure:2733: checking whether to protect include/require statements" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect PHP Format String functions" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 ++ ++ ++cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH 1 ++EOF ++ ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 0 ++EOF ++ ++fi + + + +@@ -18607,6 +18770,62 @@ + fi + + ++ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 ++echo "configure:14928: checking whether realpath is broken" >&5 ++if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then ++ echo $ac_n "(cached) $ac_c" 1>&6 ++else ++ ++ if test "$cross_compiling" = yes; then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -fr conftest* ++ ++ ac_cv_broken_realpath=yes ++ ++fi ++rm -fr conftest* ++fi ++ ++ ++fi ++ ++echo "$ac_t""$ac_cv_broken_realpath" 1>&6 ++ if test "$ac_cv_broken_realpath" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 1 ++EOF ++ ++ else ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 0 ++EOF ++ ++ fi ++ ++ + echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 + echo "configure:18612: checking for declared timezone" >&5 + if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then +@@ -89422,7 +89641,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + cat >> confdefs.h <&6 ++echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 ++# Check whether --enable-varfilter or --disable-varfilter was given. ++if test "${enable_varfilter+set}" = set; then ++ enableval="$enable_varfilter" ++ PHP_VARFILTER=$enableval ++else ++ ++ PHP_VARFILTER=yes ++ ++ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then ++ PHP_VARFILTER=$PHP_ENABLE_ALL ++ fi ++ ++fi ++ ++ ++ ++ext_output="yes, shared" ++ext_shared=yes ++case $PHP_VARFILTER in ++shared,*) ++ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` ++ ;; ++shared) ++ PHP_VARFILTER=yes ++ ;; ++no) ++ ext_output=no ++ ext_shared=no ++ ;; ++*) ++ ext_output=yes ++ ext_shared=no ++ ;; ++esac ++ ++ ++ ++echo "$ac_t""$ext_output" 1>&6 ++ ++ ++ ++ ++if test "$PHP_VARFILTER" != "no"; then ++ cat >> confdefs.h <<\EOF ++#define HAVE_VARFILTER 1 ++EOF ++ ++ ++ ext_builddir=ext/varfilter ++ ext_srcdir=$abs_srcdir/ext/varfilter ++ ++ ac_extra= ++ ++ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then ++ ++ ++ ++ case ext/varfilter in ++ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; ++ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; ++ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; ++ esac ++ ++ ++ ++ b_c_pre=$php_c_pre ++ b_cxx_pre=$php_cxx_pre ++ b_c_meta=$php_c_meta ++ b_cxx_meta=$php_cxx_meta ++ b_c_post=$php_c_post ++ b_cxx_post=$php_cxx_post ++ b_lo=$php_lo ++ ++ ++ old_IFS=$IFS ++ for ac_src in varfilter.c; do ++ ++ IFS=. ++ set $ac_src ++ ac_obj=$1 ++ IFS=$old_IFS ++ ++ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" ++ ++ case $ac_src in ++ *.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" ;; ++ *.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" ;; ++ esac ++ ++ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 +@@ -112351,7 +112829,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + network.c php_open_temporary_file.c php_logos.c \ +- output.c ; do ++ output.c hardening_patch.c ; do + + IFS=. + set $ac_src +@@ -112596,7 +113074,7 @@ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ + zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ +- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do ++ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do + + IFS=. + set $ac_src +diff -Nura php-5.1.5/configure.in hardening-patch-5.1.5-0.4.15/configure.in +--- php-5.1.5/configure.in 2006-08-15 15:14:47.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/configure.in 2006-09-05 20:31:22.000000000 +0200 +@@ -209,7 +209,7 @@ + + sinclude(Zend/Zend.m4) + sinclude(TSRM/tsrm.m4) +- ++sinclude(main/hardening_patch.m4) + + divert(2) + +@@ -1275,7 +1275,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + network.c php_open_temporary_file.c php_logos.c \ +- output.c ) ++ output.c hardening_patch.c ) + + PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ + plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c) +@@ -1302,7 +1302,7 @@ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ + zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ +- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c) ++ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c ) + + if test -r "$abs_srcdir/Zend/zend_objects.c"; then + PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \ +diff -Nura php-5.1.5/ext/curl/interface.c hardening-patch-5.1.5-0.4.15/ext/curl/interface.c +--- php-5.1.5/ext/curl/interface.c 2006-08-10 19:16:35.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/curl/interface.c 2006-09-05 20:31:22.000000000 +0200 +@@ -172,6 +172,11 @@ + RETURN_FALSE; \ + } \ + \ ++ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ ++ RETURN_FALSE; \ ++ } \ ++ \ + if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ + (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ + ) { \ +diff -Nura php-5.1.5/ext/fbsql/php_fbsql.c hardening-patch-5.1.5-0.4.15/ext/fbsql/php_fbsql.c +--- php-5.1.5/ext/fbsql/php_fbsql.c 2006-08-14 20:40:20.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:31:23.000000000 +0200 +@@ -1949,8 +1949,24 @@ + } + else if (fbcmdErrorsFound(md)) + { ++#if HARDENING_PATCH ++ char* query_copy; ++ int i; ++#endif + FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); + char* emg = fbcemdAllErrorMessages(emd); ++#if HARDENING_PATCH ++ query_copy=estrdup(query_copy); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ free(emg); ++ fbcemdRelease(emd); ++ result = 0; ++ zend_bailout(); ++ } ++#endif + if (FB_SQL_G(generateWarnings)) + { + if (emg) +diff -Nura php-5.1.5/ext/imap/php_imap.c hardening-patch-5.1.5-0.4.15/ext/imap/php_imap.c +--- php-5.1.5/ext/imap/php_imap.c 2006-08-11 17:07:13.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/imap/php_imap.c 2006-09-05 20:31:23.000000000 +0200 +@@ -768,6 +768,13 @@ + RETURN_FALSE; + } + ++ /* local filename, need to perform open_basedir and safe_mode checks */ ++ if (Z_STRVAL_PP(mailbox)[0] != '{' && ++ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || ++ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { ++ RETURN_FALSE; ++ } ++ + IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); + IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); + +diff -Nura php-5.1.5/ext/mysql/php_mysql.c hardening-patch-5.1.5-0.4.15/ext/mysql/php_mysql.c +--- php-5.1.5/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:31:23.000000000 +0200 +@@ -1231,6 +1231,8 @@ + { + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; ++ char *copy_query; ++ int i; + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); + +@@ -1281,6 +1283,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #else +@@ -1291,6 +1300,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #endif +diff -Nura php-5.1.5/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.5-0.4.15/ext/mysqli/mysqli_nonapi.c +--- php-5.1.5/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/mysqli/mysqli_nonapi.c 2006-09-05 20:31:23.000000000 +0200 +@@ -184,6 +184,17 @@ + if (mysql_real_query(mysql->mysql, query, query_len)) { + char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; + unsigned int s_errno; ++#if HARDENING_PATCH ++ char *query_copy = estrdup(query); ++ int i; ++ ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } ++#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + + /* we have to save error information, cause +@@ -234,6 +245,17 @@ + MYSQLI_DISABLE_MQ; + + if (mysql_real_query(mysql->mysql, query, query_len)) { ++#if HARDENING_PATCH ++ char *query_copy = estrdup(query); ++ int i; ++ ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } ++#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } +diff -Nura php-5.1.5/ext/pgsql/pgsql.c hardening-patch-5.1.5-0.4.15/ext/pgsql/pgsql.c +--- php-5.1.5/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:31:23.000000000 +0200 +@@ -1152,10 +1152,28 @@ + case PGRES_EMPTY_QUERY: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: +- case PGRES_FATAL_ERROR: +- PHP_PQ_ERROR("Query failed: %s", pgsql); +- PQclear(pgsql_result); +- RETURN_FALSE; ++ case PGRES_FATAL_ERROR: ++ { ++#if HARDENING_PATCH ++ int i; ++ char *query_copy; ++#endif ++ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); ++ PQclear(pgsql_result); ++#if HARDENING_PATCH ++ query_copy = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ efree(msgbuf); ++ zend_bailout(); ++ } ++#endif ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); ++ efree(msgbuf); ++ RETURN_FALSE; ++ } + break; + case PGRES_COMMAND_OK: /* successful command that did not return rows */ + default: +diff -Nura php-5.1.5/ext/session/mod_files.c hardening-patch-5.1.5-0.4.15/ext/session/mod_files.c +--- php-5.1.5/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/session/mod_files.c 2006-09-05 20:31:23.000000000 +0200 +@@ -152,6 +152,7 @@ + + if (!ps_files_valid_key(key)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); ++ PS(invalid_session_id) = 1; + return; + } + if (!ps_files_path_create(buf, sizeof(buf), data, key)) +@@ -401,7 +402,12 @@ + ps_files_close(data); + + if (VCWD_UNLINK(buf) == -1) { +- return FAILURE; ++ /* This is a little safety check for instances when we are dealing with a regenerated session ++ * that was not yet written to disk ++ */ ++ if (!VCWD_ACCESS(buf, F_OK)) { ++ return FAILURE; ++ } + } + } + +@@ -422,6 +428,35 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(files) ++{ ++ char buf[MAXPATHLEN]; ++ int fd; ++ PS_FILES_DATA; ++ ++ if (!ps_files_valid_key(key)) { ++ return FAILURE; ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { ++ return FAILURE; ++ } ++ ++ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, ++ data->filemode); ++ ++ if (fd != -1) { ++ close(fd); ++ return SUCCESS; ++ } ++ ++ return FAILURE; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-5.1.5/ext/session/mod_mm.c hardening-patch-5.1.5-0.4.15/ext/session/mod_mm.c +--- php-5.1.5/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/session/mod_mm.c 2006-09-05 20:31:23.000000000 +0200 +@@ -425,6 +425,42 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(mm) ++{ ++ PS_MM_DATA; ++ ps_sd *sd; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ } ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ mm_lock(data->mm, MM_LOCK_RD); ++ ++ sd = ps_sd_lookup(data, key, 0); ++ if (sd) { ++ mm_unlock(data->mm); ++ return SUCCESS; ++ } ++ ++ mm_unlock(data->mm); ++ ++ return FAILURE; ++} ++ + #endif + + /* +diff -Nura php-5.1.5/ext/session/mod_user.c hardening-patch-5.1.5-0.4.15/ext/session/mod_user.c +--- php-5.1.5/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/session/mod_user.c 2006-09-05 20:31:23.000000000 +0200 +@@ -23,7 +23,7 @@ + #include "mod_user.h" + + ps_module ps_mod_user = { +- PS_MOD(user) ++ PS_MOD_SID(user) + }; + + #define SESS_ZVAL_LONG(val, a) \ +@@ -174,6 +174,83 @@ + FINISH; + } + ++PS_CREATE_SID_FUNC(user) ++{ ++ int i; ++ char *val = NULL; ++ zval *retval; ++ ps_user *mdata = PS_GET_MOD_DATA(); ++ ++ if (!mdata) ++ return estrndup("", 0); ++ ++ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { ++ return php_session_create_id(mod_data, newlen TSRMLS_CC); ++ } ++ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); ++ ++ if (retval) { ++ if (Z_TYPE_P(retval) == IS_STRING) { ++ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); ++ } else { ++ val = estrndup("", 0); ++ } ++ zval_ptr_dtor(&retval); ++ } else { ++ val = estrndup("", 0); ++ } ++ ++ return val; ++} ++ ++static int ps_user_valid_key(const char *key TSRMLS_DC) ++{ ++ size_t len; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ ret = FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ ret = FAILURE; ++ ++ return ret; ++} ++ ++PS_VALIDATE_SID_FUNC(user) ++{ ++ zval *args[1]; ++ STDVARS; ++ ++ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { ++ return ps_user_valid_key(key TSRMLS_CC); ++ } ++ SESS_ZVAL_STRING(key, args[0]); ++ ++ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); ++ ++ if (retval) { ++ convert_to_long(retval); ++ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; ++ zval_ptr_dtor(&retval); ++ } ++ ++ return ret; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-5.1.5/ext/session/mod_user.h hardening-patch-5.1.5-0.4.15/ext/session/mod_user.h +--- php-5.1.5/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/session/mod_user.h 2006-09-05 20:31:23.000000000 +0200 +@@ -22,7 +22,7 @@ + #define MOD_USER_H + + typedef union { +- zval *names[6]; ++ zval *names[8]; + struct { + zval *ps_open; + zval *ps_close; +@@ -30,6 +30,8 @@ + zval *ps_write; + zval *ps_destroy; + zval *ps_gc; ++ zval *ps_create; ++ zval *ps_validate; + } name; + } ps_user; + +diff -Nura php-5.1.5/ext/session/php_session.h hardening-patch-5.1.5-0.4.15/ext/session/php_session.h +--- php-5.1.5/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/session/php_session.h 2006-09-05 20:31:23.000000000 +0200 +@@ -23,7 +23,7 @@ + + #include "ext/standard/php_var.h" + +-#define PHP_SESSION_API 20020330 ++#define PHP_SESSION_API 20051121 + + #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC + #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC +@@ -32,6 +32,7 @@ + #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC + #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC + #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC ++#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC + + /* default create id function */ + PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); +@@ -45,6 +46,7 @@ + int (*s_destroy)(PS_DESTROY_ARGS); + int (*s_gc)(PS_GC_ARGS); + char *(*s_create_sid)(PS_CREATE_SID_ARGS); ++ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); + } ps_module; + + #define PS_GET_MOD_DATA() *mod_data +@@ -57,6 +59,7 @@ + #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) + #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) + #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) ++#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) + + #define PS_FUNCS(x) \ + PS_OPEN_FUNC(x); \ +@@ -65,11 +68,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID_FUNC(x) + + #define PS_MOD(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, php_session_create_id ++ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x + + /* SID enabled module handler definitions */ + #define PS_FUNCS_SID(x) \ +@@ -79,11 +83,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID(x) + + #define PS_MOD_SID(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, ps_create_sid_##x ++ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x + + typedef enum { + php_session_disabled, +@@ -120,11 +125,13 @@ + zend_bool use_only_cookies; + zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ ++ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + + long hash_func; + long hash_bits_per_character; + int send_cookie; + int define_sid; ++ zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ + } php_ps_globals; + + typedef php_ps_globals zend_ps_globals; +diff -Nura php-5.1.5/ext/session/session.c hardening-patch-5.1.5-0.4.15/ext/session/session.c +--- php-5.1.5/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/session/session.c 2006-09-05 20:31:23.000000000 +0200 +@@ -166,6 +166,7 @@ + STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) ++ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals) +@@ -280,9 +281,13 @@ + PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) + { + zval **sym_track = NULL; +- +- zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, +- (void *) &sym_track); ++ ++ IF_SESSION_VARS() { ++ zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, ++ (void *) &sym_track); ++ } else { ++ return; ++ } + + /* + * Set up a proper reference between $_SESSION["x"] and $x. +@@ -758,9 +763,23 @@ + return; + } + ++ /* If there is an ID, use session module to verify it */ ++ if (PS(id)) { ++ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ efree(PS(id)); ++ PS(id) = NULL; ++ PS(send_cookie) = 1; ++ } ++ } ++ + /* If there is no ID, use session module to create one */ +- if (!PS(id)) ++ if (!PS(id)) { ++new_session: + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); ++ if (PS(use_cookies)) { ++ PS(send_cookie) = 1; ++ } ++ } + + /* Read data */ + /* Question: if you create a SID here, should you also try to read data? +@@ -769,9 +788,14 @@ + * session information + */ + php_session_track_init(TSRMLS_C); ++ PS(invalid_session_id) = 0; + if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) { + php_session_decode(val, vallen TSRMLS_CC); + efree(val); ++ } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */ ++ PS(invalid_session_id) = 0; ++ efree(PS(id)); ++ goto new_session; + } + } + +@@ -1377,22 +1401,29 @@ + } + /* }}} */ + +-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) ++/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) + Sets user-level functions */ + PHP_FUNCTION(session_set_save_handler) + { +- zval **args[6]; +- int i; ++ zval **args[8]; ++ int i, numargs; + ps_user *mdata; + char *name; + +- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) ++ numargs = ZEND_NUM_ARGS(); ++ args[6] = NULL; ++ args[7] = NULL; ++ ++ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) + WRONG_PARAM_COUNT; + + if (PS(session_status) != php_session_none) + RETURN_FALSE; + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ continue; ++ } + if (!zend_is_callable(*args[i], 0, &name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); + efree(name); +@@ -1405,7 +1436,11 @@ + + mdata = emalloc(sizeof(*mdata)); + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ mdata->names[i] = NULL; ++ continue; ++ } + ZVAL_ADDREF(*args[i]); + mdata->names[i] = *args[i]; + } +@@ -1475,6 +1510,11 @@ + WRONG_PARAM_COUNT; + } + ++ if (SG(headers_sent)) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); ++ RETURN_FALSE; ++ } ++ + if (PS(session_status) == php_session_active) { + if (PS(id)) { + if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { +@@ -1531,8 +1571,8 @@ + WRONG_PARAM_COUNT; + + if (ac == 1) { +- convert_to_long_ex(p_cache_expire); +- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); ++ convert_to_string_ex(p_cache_expire); ++ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + } + + RETVAL_LONG(old); +diff -Nura php-5.1.5/ext/session/tests/014.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/014.phpt +--- php-5.1.5/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:31:23.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.bug_compat_42=1 +diff -Nura php-5.1.5/ext/session/tests/015.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/015.phpt +--- php-5.1.5/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:31:23.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + arg_separator.output=& + session.name=PHPSESSID +diff -Nura php-5.1.5/ext/session/tests/018.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/018.phpt +--- php-5.1.5/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:31:23.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + session.name=PHPSESSID +diff -Nura php-5.1.5/ext/session/tests/019.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/019.phpt +--- php-5.1.5/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/session/tests/019.phpt 2006-09-05 20:31:23.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.serialize_handler=php +diff -Nura php-5.1.5/ext/session/tests/020.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/020.phpt +--- php-5.1.5/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:31:23.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + arg_separator.output=& +diff -Nura php-5.1.5/ext/session/tests/021.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/021.phpt +--- php-5.1.5/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:31:23.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" +diff -Nura php-5.1.5/ext/session/tests/bug38377.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/bug38377.phpt +--- php-5.1.5/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:31:23.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++bug #38377 (session_destroy() gives warning after session_regenerate_id()) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECT-- ++Done +diff -Nura php-5.1.5/ext/sockets/sockets.c hardening-patch-5.1.5-0.4.15/ext/sockets/sockets.c +--- php-5.1.5/ext/sockets/sockets.c 2006-04-07 16:04:36.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/sockets/sockets.c 2006-09-05 20:31:23.000000000 +0200 +@@ -533,6 +533,7 @@ + { + zval **element; + php_socket *php_sock; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -547,9 +548,10 @@ + if (php_sock->bsd_socket > *max_fd) { + *max_fd = php_sock->bsd_socket; + } ++ num++; + } + +- return 1; ++ return num ? 1 : 0; + } + + static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) +@@ -558,6 +560,7 @@ + zval **dest_element; + php_socket *php_sock; + HashTable *new_hash; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -575,6 +578,7 @@ + zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); + if (dest_element) zval_add_ref(dest_element); + } ++ num++; + } + + /* Destroy old array, add new one */ +@@ -584,7 +588,7 @@ + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(sock_array) = new_hash; + +- return 1; ++ return num ? 1 : 0; + } + + /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds, int tv_sec[, int tv_usec]) +diff -Nura php-5.1.5/ext/sqlite/sess_sqlite.c hardening-patch-5.1.5-0.4.15/ext/sqlite/sess_sqlite.c +--- php-5.1.5/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/sqlite/sess_sqlite.c 2006-09-05 20:31:23.000000000 +0200 +@@ -185,6 +185,76 @@ + return SQLITE_RETVAL(rv); + } + ++PS_VALIDATE_SID_FUNC(sqlite) ++{ ++ PS_SQLITE_DATA; ++ char *query; ++ const char *tail; ++ sqlite_vm *vm; ++ int colcount, result; ++ const char **rowdata, **colnames; ++ char *error; ++ size_t len; ++ const char *p; ++ char c; ++ int ret = FAILURE; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ return FAILURE; ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key); ++ if (query == NULL) { ++ /* no memory */ ++ return FAILURE; ++ } ++ ++ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error); ++ sqlite_freemem(error); ++ sqlite_freemem(query); ++ return FAILURE; ++ } ++ ++ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) { ++ case SQLITE_ROW: ++ if (rowdata[0] != NULL) { ++ ret = SUCCESS; ++ } ++ break; ++ default: ++ sqlite_freemem(error); ++ error = NULL; ++ } ++ ++ if (SQLITE_OK != sqlite_finalize(vm, &error)) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error); ++ sqlite_freemem(error); ++ error = NULL; ++ } ++ ++ sqlite_freemem(query); ++ ++ return ret; ++} ++ + #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */ + + /* +diff -Nura php-5.1.5/ext/sqlite/sqlite.c hardening-patch-5.1.5-0.4.15/ext/sqlite/sqlite.c +--- php-5.1.5/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/sqlite/sqlite.c 2006-09-05 20:31:23.000000000 +0200 +@@ -1530,6 +1530,19 @@ + db->last_err_code = ret; + + if (ret != SQLITE_OK) { ++#if HARDENING_PATCH ++ char *query_copy; ++ int i; ++ ++ query_copy = estrdup(sql); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ sqlite_freemem(errtext); ++ zend_bailout(); ++ } ++#endif + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext); + if (errmsg) { + ZVAL_STRING(errmsg, errtext, 1); +diff -Nura php-5.1.5/ext/standard/array.c hardening-patch-5.1.5-0.4.15/ext/standard/array.c +--- php-5.1.5/ext/standard/array.c 2006-06-03 20:59:55.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/array.c 2006-09-05 20:31:23.000000000 +0200 +@@ -1297,6 +1297,32 @@ + } + } + } ++ ++ if (var_name[0] == 'H') { ++ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_FILES")==0)|| ++ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { ++ return 0; ++ } ++ } else if (var_name[0] == '_') { ++ if ((strcmp(var_name, "_COOKIE")==0)|| ++ (strcmp(var_name, "_ENV")==0)|| ++ (strcmp(var_name, "_FILES")==0)|| ++ (strcmp(var_name, "_GET")==0)|| ++ (strcmp(var_name, "_POST")==0)|| ++ (strcmp(var_name, "_REQUEST")==0)|| ++ (strcmp(var_name, "_SESSION")==0)|| ++ (strcmp(var_name, "_SERVER")==0)) { ++ return 0; ++ } ++ } else if (strcmp(var_name, "GLOBALS")==0) { ++ return 0; ++ } + + return 1; + } +diff -Nura php-5.1.5/ext/standard/basic_functions.c hardening-patch-5.1.5-0.4.15/ext/standard/basic_functions.c +--- php-5.1.5/ext/standard/basic_functions.c 2006-06-29 00:08:59.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:19:27.000000000 +0200 +@@ -151,12 +151,14 @@ + typedef struct _php_shutdown_function_entry { + zval **arguments; + int arg_count; ++ zend_bool created_by_eval; + } php_shutdown_function_entry; + + typedef struct _user_tick_function_entry { + zval **arguments; + int arg_count; + int calling; ++ zend_bool created_by_eval; + } user_tick_function_entry; + + /* some prototypes for local functions */ +@@ -188,6 +190,8 @@ + PHP_FE(get_html_translation_table, NULL) + PHP_FE(sha1, NULL) + PHP_FE(sha1_file, NULL) ++ PHP_FE(sha256, NULL) ++ PHP_FE(sha256_file, NULL) + PHP_NAMED_FE(md5,php_if_md5, NULL) + PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) + PHP_NAMED_FE(crc32,php_if_crc32, NULL) +@@ -632,7 +636,7 @@ + PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) + + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +- PHP_FE(realpath, NULL) ++ PHP_STATIC_FE("realpath", zif_real_path, NULL) + #endif + + #ifdef HAVE_FNMATCH +@@ -2279,6 +2283,13 @@ + { + zval retval; + char *function_name = NULL; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (shutdown_function_entry->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { + php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); +@@ -2294,6 +2305,9 @@ + if (function_name) { + efree(function_name); + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + return 0; + } + +@@ -2301,6 +2315,13 @@ + { + zval retval; + zval *function = tick_fe->arguments[0]; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (tick_fe->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + /* Prevent reentrant calls to the same user ticks function */ + if (! tick_fe->calling) { +@@ -2332,6 +2353,9 @@ + + tick_fe->calling = 0; + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + } + + static void run_user_tick_functions(int tick_count) +@@ -2395,6 +2419,13 @@ + } + + shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ shutdown_function_entry.created_by_eval = 1; ++ } else { ++ shutdown_function_entry.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { + efree(shutdown_function_entry.arguments); +@@ -2722,6 +2753,15 @@ + + convert_to_string_ex(varname); + ++ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ ++ if (PG(safe_mode)) { ++ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || ++ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || ++ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { ++ RETURN_FALSE; ++ } ++ } ++ + zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); + } + /* }}} */ +@@ -2979,6 +3019,13 @@ + } + + tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ tick_fe.created_by_eval = 1; ++ } else { ++ tick_fe.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { + efree(tick_fe.arguments); +@@ -3282,6 +3329,35 @@ + new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); + } + ++ if (new_key[0] == 'H') { ++ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_FILES")==0)|| ++ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (new_key[0] == '_') { ++ if ((strcmp(new_key, "_COOKIE")==0)|| ++ (strcmp(new_key, "_ENV")==0)|| ++ (strcmp(new_key, "_FILES")==0)|| ++ (strcmp(new_key, "_GET")==0)|| ++ (strcmp(new_key, "_POST")==0)|| ++ (strcmp(new_key, "_REQUEST")==0)|| ++ (strcmp(new_key, "_SESSION")==0)|| ++ (strcmp(new_key, "_SERVER")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (strcmp(new_key, "GLOBALS")==0) { ++ efree(new_key); ++ return 0; ++ } ++ + zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); + ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); + +diff -Nura php-5.1.5/ext/standard/config.m4 hardening-patch-5.1.5-0.4.15/ext/standard/config.m4 +--- php-5.1.5/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/config.m4 2006-09-05 20:31:23.000000000 +0200 +@@ -203,7 +203,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) + ]) +@@ -489,7 +489,7 @@ + incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ + http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ + var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ +- filters.c proc_open.c streamsfuncs.c http.c) ++ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ) + + PHP_ADD_MAKEFILE_FRAGMENT + +diff -Nura php-5.1.5/ext/standard/config.w32 hardening-patch-5.1.5-0.4.15/ext/standard/config.w32 +--- php-5.1.5/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/config.w32 2006-09-05 20:31:23.000000000 +0200 +@@ -16,5 +16,5 @@ + url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ + php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ + user_filters.c uuencode.c filters.c proc_open.c \ +- streamsfuncs.c http.c", false /* never shared */); ++ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */); + +diff -Nura php-5.1.5/ext/standard/crypt_blowfish.c hardening-patch-5.1.5-0.4.15/ext/standard/crypt_blowfish.c +--- php-5.1.5/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:31:23.000000000 +0200 +@@ -0,0 +1,748 @@ ++/* ++ * This code comes from John the Ripper password cracker, with reentrant ++ * and crypt(3) interfaces added, but optimizations specific to password ++ * cracking removed. ++ * ++ * Written by Solar Designer in 1998-2002 and ++ * placed in the public domain. ++ * ++ * There's absolutely no warranty. ++ * ++ * It is my intent that you should be able to use this on your system, ++ * as a part of a software package, or anywhere else to improve security, ++ * ensure compatibility, or for any other purpose. I would appreciate ++ * it if you give credit where it is due and keep your modifications in ++ * the public domain as well, but I don't require that in order to let ++ * you place this code and any modifications you make under a license ++ * of your choice. ++ * ++ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) ++ * by Niels Provos , and uses some of his ++ * ideas. The password hashing algorithm was designed by David Mazieres ++ * . ++ * ++ * There's a paper on the algorithm that explains its design decisions: ++ * ++ * http://www.usenix.org/events/usenix99/provos.html ++ * ++ * Some of the tricks in BF_ROUND might be inspired by Eric Young's ++ * Blowfish library (I can't be sure if I would think of something if I ++ * hadn't seen his code). ++ */ ++ ++#include ++ ++#include ++#ifndef __set_errno ++#define __set_errno(val) errno = (val) ++#endif ++ ++#undef __CONST ++#ifdef __GNUC__ ++#define __CONST __const ++#else ++#define __CONST ++#endif ++ ++#ifdef __i386__ ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#elif defined(__alpha__) || defined(__hppa__) ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#else ++#define BF_ASM 0 ++#define BF_SCALE 0 ++#endif ++ ++typedef unsigned int BF_word; ++ ++/* Number of Blowfish rounds, this is also hardcoded into a few places */ ++#define BF_N 16 ++ ++typedef BF_word BF_key[BF_N + 2]; ++ ++typedef struct { ++ BF_word S[4][0x100]; ++ BF_key P; ++} BF_ctx; ++ ++/* ++ * Magic IV for 64 Blowfish encryptions that we do at the end. ++ * The string is "OrpheanBeholderScryDoubt" on big-endian. ++ */ ++static BF_word BF_magic_w[6] = { ++ 0x4F727068, 0x65616E42, 0x65686F6C, ++ 0x64657253, 0x63727944, 0x6F756274 ++}; ++ ++/* ++ * P-box and S-box tables initialized with digits of Pi. ++ */ ++static BF_ctx BF_init_state = { ++ { ++ { ++ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, ++ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, ++ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, ++ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, ++ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, ++ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, ++ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, ++ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, ++ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, ++ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, ++ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, ++ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, ++ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, ++ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, ++ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, ++ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, ++ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, ++ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, ++ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, ++ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, ++ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, ++ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, ++ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, ++ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, ++ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, ++ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, ++ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, ++ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, ++ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, ++ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, ++ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, ++ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, ++ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, ++ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, ++ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, ++ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, ++ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, ++ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, ++ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, ++ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, ++ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, ++ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, ++ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, ++ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, ++ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, ++ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, ++ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, ++ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, ++ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, ++ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, ++ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, ++ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, ++ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, ++ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, ++ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, ++ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, ++ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, ++ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, ++ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, ++ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, ++ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, ++ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, ++ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, ++ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a ++ }, { ++ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, ++ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, ++ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, ++ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, ++ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, ++ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, ++ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, ++ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, ++ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, ++ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, ++ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, ++ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, ++ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, ++ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, ++ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, ++ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, ++ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, ++ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, ++ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, ++ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, ++ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, ++ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, ++ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, ++ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, ++ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, ++ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, ++ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, ++ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, ++ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, ++ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, ++ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, ++ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, ++ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, ++ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, ++ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, ++ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, ++ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, ++ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, ++ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, ++ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, ++ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, ++ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, ++ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, ++ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, ++ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, ++ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, ++ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, ++ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, ++ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, ++ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, ++ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, ++ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, ++ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, ++ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, ++ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, ++ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, ++ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, ++ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, ++ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, ++ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, ++ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, ++ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, ++ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, ++ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 ++ }, { ++ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, ++ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, ++ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, ++ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, ++ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, ++ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, ++ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, ++ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, ++ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, ++ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, ++ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, ++ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, ++ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, ++ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, ++ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, ++ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, ++ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, ++ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, ++ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, ++ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, ++ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, ++ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, ++ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, ++ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, ++ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, ++ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, ++ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, ++ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, ++ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, ++ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, ++ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, ++ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, ++ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, ++ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, ++ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, ++ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, ++ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, ++ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, ++ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, ++ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, ++ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, ++ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, ++ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, ++ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, ++ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, ++ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, ++ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, ++ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, ++ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, ++ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, ++ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, ++ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, ++ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, ++ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, ++ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, ++ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, ++ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, ++ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, ++ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, ++ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, ++ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, ++ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, ++ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, ++ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 ++ }, { ++ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, ++ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, ++ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, ++ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, ++ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, ++ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, ++ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, ++ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, ++ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, ++ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, ++ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, ++ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, ++ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, ++ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, ++ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, ++ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, ++ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, ++ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, ++ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, ++ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, ++ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, ++ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, ++ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, ++ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, ++ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, ++ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, ++ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, ++ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, ++ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, ++ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, ++ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, ++ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, ++ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, ++ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, ++ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, ++ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, ++ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, ++ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, ++ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, ++ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, ++ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, ++ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, ++ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, ++ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, ++ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, ++ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, ++ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, ++ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, ++ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, ++ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, ++ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, ++ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, ++ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, ++ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, ++ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, ++ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, ++ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, ++ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, ++ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, ++ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, ++ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, ++ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, ++ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, ++ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 ++ } ++ }, { ++ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, ++ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, ++ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, ++ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, ++ 0x9216d5d9, 0x8979fb1b ++ } ++}; ++ ++static unsigned char BF_itoa64[64 + 1] = ++ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ++ ++static unsigned char BF_atoi64[0x60] = { ++ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, ++ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, ++ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, ++ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, ++ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 ++}; ++ ++/* ++ * This may be optimized out if built with function inlining and no BF_ASM. ++ */ ++static void clean(void *data, int size) ++{ ++#if BF_ASM ++ extern void _BF_clean(void *data); ++#endif ++ memset(data, 0, size); ++#if BF_ASM ++ _BF_clean(data); ++#endif ++} ++ ++#define BF_safe_atoi64(dst, src) \ ++{ \ ++ tmp = (unsigned char)(src); \ ++ if (tmp == '$') break; \ ++ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ ++ tmp = BF_atoi64[tmp]; \ ++ if (tmp > 63) return -1; \ ++ (dst) = tmp; \ ++} ++ ++static int BF_decode(BF_word *dst, __CONST char *src, int size) ++{ ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned char *end = dptr + size; ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned int tmp, c1, c2, c3, c4; ++ ++ do { ++ BF_safe_atoi64(c1, *sptr++); ++ BF_safe_atoi64(c2, *sptr++); ++ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c3, *sptr++); ++ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c4, *sptr++); ++ *dptr++ = ((c3 & 0x03) << 6) | c4; ++ } while (dptr < end); ++ ++ while (dptr < end) ++ *dptr++ = 0; ++ ++ return 0; ++} ++ ++static void BF_encode(char *dst, __CONST BF_word *src, int size) ++{ ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned char *end = sptr + size; ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned int c1, c2; ++ ++ do { ++ c1 = *sptr++; ++ *dptr++ = BF_itoa64[c1 >> 2]; ++ c1 = (c1 & 0x03) << 4; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 4; ++ *dptr++ = BF_itoa64[c1]; ++ c1 = (c2 & 0x0f) << 2; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 6; ++ *dptr++ = BF_itoa64[c1]; ++ *dptr++ = BF_itoa64[c2 & 0x3f]; ++ } while (sptr < end); ++} ++ ++static void BF_swap(BF_word *x, int count) ++{ ++ static int endianness_check = 1; ++ char *is_little_endian = (char *)&endianness_check; ++ BF_word tmp; ++ ++ if (*is_little_endian) ++ do { ++ tmp = *x; ++ tmp = (tmp << 16) | (tmp >> 16); ++ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); ++ } while (--count); ++} ++ ++#if BF_SCALE ++/* Architectures which can shift addresses left by 2 bits with no extra cost */ ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp2 = L >> 8; \ ++ tmp2 &= 0xFF; \ ++ tmp3 = L >> 16; \ ++ tmp3 &= 0xFF; \ ++ tmp4 = L >> 24; \ ++ tmp1 = data.ctx.S[3][tmp1]; \ ++ tmp2 = data.ctx.S[2][tmp2]; \ ++ tmp3 = data.ctx.S[1][tmp3]; \ ++ tmp3 += data.ctx.S[0][tmp4]; \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#else ++/* Architectures with no complicated addressing modes supported */ ++#define BF_INDEX(S, i) \ ++ (*((BF_word *)(((unsigned char *)S) + (i)))) ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp1 <<= 2; \ ++ tmp2 = L >> 6; \ ++ tmp2 &= 0x3FC; \ ++ tmp3 = L >> 14; \ ++ tmp3 &= 0x3FC; \ ++ tmp4 = L >> 22; \ ++ tmp4 &= 0x3FC; \ ++ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ ++ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ ++ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ ++ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#endif ++ ++/* ++ * Encrypt one block, BF_N is hardcoded here. ++ */ ++#define BF_ENCRYPT \ ++ L ^= data.ctx.P[0]; \ ++ BF_ROUND(L, R, 0); \ ++ BF_ROUND(R, L, 1); \ ++ BF_ROUND(L, R, 2); \ ++ BF_ROUND(R, L, 3); \ ++ BF_ROUND(L, R, 4); \ ++ BF_ROUND(R, L, 5); \ ++ BF_ROUND(L, R, 6); \ ++ BF_ROUND(R, L, 7); \ ++ BF_ROUND(L, R, 8); \ ++ BF_ROUND(R, L, 9); \ ++ BF_ROUND(L, R, 10); \ ++ BF_ROUND(R, L, 11); \ ++ BF_ROUND(L, R, 12); \ ++ BF_ROUND(R, L, 13); \ ++ BF_ROUND(L, R, 14); \ ++ BF_ROUND(R, L, 15); \ ++ tmp4 = R; \ ++ R = L; \ ++ L = tmp4 ^ data.ctx.P[BF_N + 1]; ++ ++#if BF_ASM ++#define BF_body() \ ++ _BF_body_r(&data.ctx); ++#else ++#define BF_body() \ ++ L = R = 0; \ ++ ptr = data.ctx.P; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.P[BF_N + 2]); \ ++\ ++ ptr = data.ctx.S[0]; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.S[3][0xFF]); ++#endif ++ ++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) ++{ ++ __CONST char *ptr = key; ++ int i, j; ++ BF_word tmp; ++ ++ for (i = 0; i < BF_N + 2; i++) { ++ tmp = 0; ++ for (j = 0; j < 4; j++) { ++ tmp <<= 8; ++ tmp |= *ptr; ++ ++ if (!*ptr) ptr = key; else ptr++; ++ } ++ ++ expanded[i] = tmp; ++ initial[i] = BF_init_state.P[i] ^ tmp; ++ } ++} ++ ++char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, ++ char *output, int size) ++{ ++#if BF_ASM ++ extern void _BF_body_r(BF_ctx *ctx); ++#endif ++ struct { ++ BF_ctx ctx; ++ BF_key expanded_key; ++ union { ++ BF_word salt[4]; ++ BF_word output[6]; ++ } binary; ++ } data; ++ BF_word L, R; ++ BF_word tmp1, tmp2, tmp3, tmp4; ++ BF_word *ptr; ++ BF_word count; ++ int i; ++ ++ if (size < 7 + 22 + 31 + 1) { ++ __set_errno(ERANGE); ++ return NULL; ++ } ++ ++ if (setting[0] != '$' || ++ setting[1] != '2' || ++ setting[2] != 'a' || ++ setting[3] != '$' || ++ setting[4] < '0' || setting[4] > '3' || ++ setting[5] < '0' || setting[5] > '9' || ++ setting[6] != '$') { ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); ++ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { ++ clean(data.binary.salt, sizeof(data.binary.salt)); ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ BF_swap(data.binary.salt, 4); ++ ++ BF_set_key(key, data.expanded_key, data.ctx.P); ++ ++ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); ++ ++ L = R = 0; ++ for (i = 0; i < BF_N + 2; i += 2) { ++ L ^= data.binary.salt[i & 2]; ++ R ^= data.binary.salt[(i & 2) + 1]; ++ BF_ENCRYPT; ++ data.ctx.P[i] = L; ++ data.ctx.P[i + 1] = R; ++ } ++ ++ ptr = data.ctx.S[0]; ++ do { ++ ptr += 4; ++ L ^= data.binary.salt[(BF_N + 2) & 3]; ++ R ^= data.binary.salt[(BF_N + 3) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 4) = L; ++ *(ptr - 3) = R; ++ ++ L ^= data.binary.salt[(BF_N + 4) & 3]; ++ R ^= data.binary.salt[(BF_N + 5) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 2) = L; ++ *(ptr - 1) = R; ++ } while (ptr < &data.ctx.S[3][0xFF]); ++ ++ do { ++ data.ctx.P[0] ^= data.expanded_key[0]; ++ data.ctx.P[1] ^= data.expanded_key[1]; ++ data.ctx.P[2] ^= data.expanded_key[2]; ++ data.ctx.P[3] ^= data.expanded_key[3]; ++ data.ctx.P[4] ^= data.expanded_key[4]; ++ data.ctx.P[5] ^= data.expanded_key[5]; ++ data.ctx.P[6] ^= data.expanded_key[6]; ++ data.ctx.P[7] ^= data.expanded_key[7]; ++ data.ctx.P[8] ^= data.expanded_key[8]; ++ data.ctx.P[9] ^= data.expanded_key[9]; ++ data.ctx.P[10] ^= data.expanded_key[10]; ++ data.ctx.P[11] ^= data.expanded_key[11]; ++ data.ctx.P[12] ^= data.expanded_key[12]; ++ data.ctx.P[13] ^= data.expanded_key[13]; ++ data.ctx.P[14] ^= data.expanded_key[14]; ++ data.ctx.P[15] ^= data.expanded_key[15]; ++ data.ctx.P[16] ^= data.expanded_key[16]; ++ data.ctx.P[17] ^= data.expanded_key[17]; ++ ++ BF_body(); ++ ++ tmp1 = data.binary.salt[0]; ++ tmp2 = data.binary.salt[1]; ++ tmp3 = data.binary.salt[2]; ++ tmp4 = data.binary.salt[3]; ++ data.ctx.P[0] ^= tmp1; ++ data.ctx.P[1] ^= tmp2; ++ data.ctx.P[2] ^= tmp3; ++ data.ctx.P[3] ^= tmp4; ++ data.ctx.P[4] ^= tmp1; ++ data.ctx.P[5] ^= tmp2; ++ data.ctx.P[6] ^= tmp3; ++ data.ctx.P[7] ^= tmp4; ++ data.ctx.P[8] ^= tmp1; ++ data.ctx.P[9] ^= tmp2; ++ data.ctx.P[10] ^= tmp3; ++ data.ctx.P[11] ^= tmp4; ++ data.ctx.P[12] ^= tmp1; ++ data.ctx.P[13] ^= tmp2; ++ data.ctx.P[14] ^= tmp3; ++ data.ctx.P[15] ^= tmp4; ++ data.ctx.P[16] ^= tmp1; ++ data.ctx.P[17] ^= tmp2; ++ ++ BF_body(); ++ } while (--count); ++ ++ for (i = 0; i < 6; i += 2) { ++ L = BF_magic_w[i]; ++ R = BF_magic_w[i + 1]; ++ ++ count = 64; ++ do { ++ BF_ENCRYPT; ++ } while (--count); ++ ++ data.binary.output[i] = L; ++ data.binary.output[i + 1] = R; ++ } ++ ++ memcpy(output, setting, 7 + 22 - 1); ++ output[7 + 22 - 1] = BF_itoa64[(int) ++ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; ++ ++/* This has to be bug-compatible with the original implementation, so ++ * only encode 23 of the 24 bytes. :-) */ ++ BF_swap(data.binary.output, 6); ++ BF_encode(&output[7 + 22], data.binary.output, 23); ++ output[7 + 22 + 31] = '\0'; ++ ++/* Overwrite the most obvious sensitive data we have on the stack. Note ++ * that this does not guarantee there's no sensitive data left on the ++ * stack and/or in registers; I'm not aware of portable code that does. */ ++ clean(&data, sizeof(data)); ++ ++ return output; ++} ++ ++char *_crypt_gensalt_blowfish_rn(unsigned long count, ++ __CONST char *input, int size, char *output, int output_size) ++{ ++ if (size < 16 || output_size < 7 + 22 + 1 || ++ (count && (count < 4 || count > 31))) { ++ if (output_size > 0) output[0] = '\0'; ++ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); ++ return NULL; ++ } ++ ++ if (!count) count = 5; ++ ++ output[0] = '$'; ++ output[1] = '2'; ++ output[2] = 'a'; ++ output[3] = '$'; ++ output[4] = '0' + count / 10; ++ output[5] = '0' + count % 10; ++ output[6] = '$'; ++ ++ BF_encode(&output[7], (BF_word *)input, 16); ++ output[7 + 22] = '\0'; ++ ++ return output; ++} +diff -Nura php-5.1.5/ext/standard/crypt.c hardening-patch-5.1.5-0.4.15/ext/standard/crypt.c +--- php-5.1.5/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/crypt.c 2006-09-05 20:31:23.000000000 +0200 +@@ -100,6 +100,8 @@ + return SUCCESS; + } + ++char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); ++char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); + + static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +@@ -135,7 +137,14 @@ + + /* The automatic salt generation only covers standard DES and md5-crypt */ + if(!*salt) { +-#if PHP_MD5_CRYPT ++#if PHP_BLOWFISH_CRYPT ++ char randat[16]; ++ int i; ++ ++ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; ++ ++ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); ++#elif PHP_MD5_CRYPT + strcpy(salt, "$1$"); + php_to64(&salt[3], PHP_CRYPT_RAND, 4); + php_to64(&salt[7], PHP_CRYPT_RAND, 4); +@@ -145,8 +154,24 @@ + salt[2] = '\0'; + #endif + } +- +- RETVAL_STRING(crypt(str, salt), 1); ++ ++ if (salt[0] == '$' && ++ salt[1] == '2' && ++ salt[2] == 'a' && ++ salt[3] == '$' && ++ salt[4] >= '0' && salt[4] <= '3' && ++ salt[5] >= '0' && salt[5] <= '9' && ++ salt[6] == '$') { ++ ++ char output[PHP_MAX_SALT_LEN+1]; ++ ++ output[0] = 0; ++ _crypt_blowfish_rn(str, salt, output, sizeof(output)); ++ RETVAL_STRING(output, 1); ++ ++ } else { ++ RETVAL_STRING(crypt(str, salt), 1); ++ } + } + /* }}} */ + #endif +diff -Nura php-5.1.5/ext/standard/dl.c hardening-patch-5.1.5-0.4.15/ext/standard/dl.c +--- php-5.1.5/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/dl.c 2006-09-05 20:31:23.000000000 +0200 +@@ -164,8 +164,35 @@ + RETURN_FALSE; + } + module_entry = get_module(); ++ ++ /* check if Hardening-Patch is installed */ ++ if (module_entry->zend_api < 1000000000) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ ++ /* check if correct Hardening-Patch is installed */ ++ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ + if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) +- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { ++ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { + /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ + struct pre_4_1_0_module_entry { + char *name; +@@ -199,7 +226,7 @@ + zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; + } else { + name = module_entry->name; +- zend_api = module_entry->zend_api; ++ zend_api = module_entry->real_zend_api; + zend_debug = module_entry->zend_debug; + zts = module_entry->zts; + } +diff -Nura php-5.1.5/ext/standard/file.c hardening-patch-5.1.5-0.4.15/ext/standard/file.c +--- php-5.1.5/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/file.c 2006-09-05 20:31:23.000000000 +0200 +@@ -2302,7 +2302,7 @@ + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) + /* {{{ proto string realpath(string path) + Return the resolved path */ +-PHP_FUNCTION(realpath) ++PHP_FUNCTION(real_path) + { + zval **path; + char resolved_path_buff[MAXPATHLEN]; +diff -Nura php-5.1.5/ext/standard/file.h hardening-patch-5.1.5-0.4.15/ext/standard/file.h +--- php-5.1.5/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/file.h 2006-09-05 20:31:23.000000000 +0200 +@@ -61,7 +61,7 @@ + PHP_FUNCTION(fd_set); + PHP_FUNCTION(fd_isset); + #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) +-PHP_FUNCTION(realpath); ++PHP_FUNCTION(real_path); + PHP_FUNCTION(fnmatch); + #endif + PHP_NAMED_FUNCTION(php_if_ftruncate); +diff -Nura php-5.1.5/ext/standard/head.c hardening-patch-5.1.5-0.4.15/ext/standard/head.c +--- php-5.1.5/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/head.c 2006-09-05 20:31:23.000000000 +0200 +@@ -45,7 +45,7 @@ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, + &ctr.line_len, &rep, &ctr.response_code) == FAILURE) + return; +- ++ + sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); + } + /* }}} */ +diff -Nura php-5.1.5/ext/standard/info.c hardening-patch-5.1.5-0.4.15/ext/standard/info.c +--- php-5.1.5/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/info.c 2006-09-05 20:31:23.000000000 +0200 +@@ -154,7 +154,7 @@ + if (Z_TYPE_PP(tmp) == IS_ARRAY) { + if (!sapi_module.phpinfo_as_text) { + PUTS("
");
+-					zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
++					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
+ 					PUTS("
"); + } else { + zend_print_zval_r(*tmp, 0 TSRMLS_CC); +@@ -411,7 +411,7 @@ + + if (flag & PHP_INFO_GENERAL) { + char *zend_version = get_zend_version(); +- char temp_api[10]; ++ char temp_api[11]; + char *logo_guid; + + php_uname = php_get_uname('a'); +@@ -434,11 +434,22 @@ + PUTS("\" alt=\"PHP Logo\" />"); + } + ++#if HARDENING_PATCH ++ if (!sapi_module.phpinfo_as_text) { ++ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); ++ } else { ++ char temp_ver[40]; ++ ++ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); ++ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); ++ } ++#else + if (!sapi_module.phpinfo_as_text) { + php_printf("

PHP Version %s

\n", PHP_VERSION); + } else { + php_info_print_table_row(2, "PHP Version", PHP_VERSION); +- } ++ } ++#endif + php_info_print_box_end(); + php_info_print_table_start(); + php_info_print_table_row(2, "System", php_uname ); +diff -Nura php-5.1.5/ext/standard/mail.c hardening-patch-5.1.5-0.4.15/ext/standard/mail.c +--- php-5.1.5/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/mail.c 2006-09-05 20:31:23.000000000 +0200 +@@ -78,6 +78,25 @@ + } + /* }}} */ + ++/* {{{ hphp_strcasestr */ ++char *hphp_strcasestr(char *haystack, char *needle) ++{ ++ unsigned char *t, *h, *n; ++ ++ h = (unsigned char *) haystack; ++conts: ++ while (*h) { ++ n = (unsigned char *) needle; ++ for (t=h++; *n && *h; t++, n++) { ++ if (toupper(*t) != toupper(*n)) goto conts; ++ } ++ return ((char*)h-1); ++ } ++ ++ return (NULL); ++} ++/* }}} */ ++ + /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) + Send an email message */ + PHP_FUNCTION(mail) +@@ -104,6 +123,44 @@ + return; + } + ++ if (HG(hphp_mailprotect) > 0) { ++ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { ++ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ /* check for spam attempts with buggy webforms */ ++ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (HG(hphp_mailprotect) > 1) { ++ /* search for to, cc or bcc headers */ ++ if (headers_len > 0 && headers != NULL) { ++ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { ++ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { ++ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { ++ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ } ++ } ++ } ++ + if (to_len > 0) { + to_r = estrndup(to, to_len); + for (; to_len; to_len--) { +diff -Nura php-5.1.5/ext/standard/php_standard.h hardening-patch-5.1.5-0.4.15/ext/standard/php_standard.h +--- php-5.1.5/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/php_standard.h 2006-09-05 20:31:23.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "php_mail.h" + #include "md5.h" + #include "sha1.h" ++#include "sha256.h" + #include "html.h" + #include "exec.h" + #include "file.h" +diff -Nura php-5.1.5/ext/standard/sha256.c hardening-patch-5.1.5-0.4.15/ext/standard/sha256.c +--- php-5.1.5/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/sha256.c 2006-09-05 20:31:23.000000000 +0200 +@@ -0,0 +1,388 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ ++ ++#include "php.h" ++ ++/* This code is heavily based on the PHP md5/sha1 implementations */ ++ ++#include "sha256.h" ++ ++PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ sprintf(sha256str, "%02x", digest[i]); ++ sha256str += 2; ++ } ++ ++ *sha256str = '\0'; ++} ++ ++/* {{{ proto string sha256(string str [, bool raw_output]) ++ Calculate the sha256 hash of a string */ ++PHP_FUNCTION(sha256) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ PHP_SHA256_CTX context; ++ unsigned char digest[32]; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ sha256str[0] = '\0'; ++ PHP_SHA256Init(&context); ++ PHP_SHA256Update(&context, arg, arg_len); ++ PHP_SHA256Final(digest, &context); ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++ ++} ++ ++/* }}} */ ++ ++/* {{{ proto string sha256_file(string filename [, bool raw_output]) ++ Calculate the sha256 hash of given filename */ ++PHP_FUNCTION(sha256_file) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ unsigned char buf[1024]; ++ unsigned char digest[32]; ++ PHP_SHA256_CTX context; ++ int n; ++ php_stream *stream; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); ++ if (!stream) { ++ RETURN_FALSE; ++ } ++ ++ PHP_SHA256Init(&context); ++ ++ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ++ PHP_SHA256Update(&context, buf, n); ++ } ++ ++ PHP_SHA256Final(digest, &context); ++ ++ php_stream_close(stream); ++ ++ if (n<0) { ++ RETURN_FALSE; ++ } ++ ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++} ++/* }}} */ ++ ++ ++static void SHA256Transform(php_uint32[8], const unsigned char[64]); ++static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); ++static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); ++ ++static unsigned char PADDING[64] = ++{ ++ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++/* F, G, H and I are basic SHA256 functions. ++ */ ++#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) ++#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) ++#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) ++#define I(x, y, z) (((x) & (y)) | ((~x) & z)) ++ ++/* ROTATE_RIGHT rotates x right n bits. ++ */ ++#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) ++ ++/* W[i] ++ */ ++#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ ++ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ ++ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) ++ ++/* ROUND function of sha256 ++ */ ++ ++#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ ++ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ ++ (h) = F((a)) + G((a), (b), (c)) + t1; \ ++ (d) += t1; \ ++ } ++ ++ ++/* {{{ PHP_SHA256Init ++ * SHA256 initialization. Begins an SHA256 operation, writing a new context. ++ */ ++static void PHP_SHA256Init(PHP_SHA256_CTX * context) ++{ ++ context->count[0] = context->count[1] = 0; ++ /* Load magic initialization constants. ++ */ ++ context->state[0] = 0x6a09e667; ++ context->state[1] = 0xbb67ae85; ++ context->state[2] = 0x3c6ef372; ++ context->state[3] = 0xa54ff53a; ++ context->state[4] = 0x510e527f; ++ context->state[5] = 0x9b05688c; ++ context->state[6] = 0x1f83d9ab; ++ context->state[7] = 0x5be0cd19; ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Update ++ SHA256 block update operation. Continues an SHA256 message-digest ++ operation, processing another message block, and updating the ++ context. ++ */ ++static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, ++ unsigned int inputLen) ++{ ++ unsigned int i, index, partLen; ++ ++ /* Compute number of bytes mod 64 */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ++ ++ /* Update number of bits */ ++ if ((context->count[0] += ((php_uint32) inputLen << 3)) ++ < ((php_uint32) inputLen << 3)) ++ context->count[1]++; ++ context->count[1] += ((php_uint32) inputLen >> 29); ++ ++ partLen = 64 - index; ++ ++ /* Transform as many times as possible. ++ */ ++ if (inputLen >= partLen) { ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ++ SHA256Transform(context->state, context->buffer); ++ ++ for (i = partLen; i + 63 < inputLen; i += 64) ++ SHA256Transform(context->state, &input[i]); ++ ++ index = 0; ++ } else ++ i = 0; ++ ++ /* Buffer remaining input */ ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], ++ inputLen - i); ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Final ++ SHA256 finalization. Ends an SHA256 message-digest operation, writing the ++ the message digest and zeroizing the context. ++ */ ++static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) ++{ ++ unsigned char bits[8]; ++ unsigned int index, padLen; ++ ++ /* Save number of bits */ ++ bits[7] = context->count[0] & 0xFF; ++ bits[6] = (context->count[0] >> 8) & 0xFF; ++ bits[5] = (context->count[0] >> 16) & 0xFF; ++ bits[4] = (context->count[0] >> 24) & 0xFF; ++ bits[3] = context->count[1] & 0xFF; ++ bits[2] = (context->count[1] >> 8) & 0xFF; ++ bits[1] = (context->count[1] >> 16) & 0xFF; ++ bits[0] = (context->count[1] >> 24) & 0xFF; ++ ++ /* Pad out to 56 mod 64. ++ */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ++ padLen = (index < 56) ? (56 - index) : (120 - index); ++ PHP_SHA256Update(context, PADDING, padLen); ++ ++ /* Append length (before padding) */ ++ PHP_SHA256Update(context, bits, 8); ++ ++ /* Store state in digest */ ++ SHA256Encode(digest, context->state, 32); ++ ++ /* Zeroize sensitive information. ++ */ ++ memset((unsigned char*) context, 0, sizeof(*context)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Transform ++ * SHA256 basic transformation. Transforms state based on block. ++ */ ++static void SHA256Transform(state, block) ++php_uint32 state[8]; ++const unsigned char block[64]; ++{ ++ php_uint32 a = state[0], b = state[1], c = state[2]; ++ php_uint32 d = state[3], e = state[4], f = state[5]; ++ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; ++ ++ SHA256Decode(x, block, 64); ++ ++ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) ++ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) ++ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) ++ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) ++ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) ++ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) ++ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) ++ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) ++ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) ++ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) ++ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) ++ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) ++ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) ++ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) ++ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) ++ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) ++ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) ++ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) ++ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) ++ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) ++ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) ++ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) ++ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) ++ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) ++ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) ++ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) ++ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) ++ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) ++ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) ++ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) ++ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) ++ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) ++ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) ++ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) ++ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) ++ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) ++ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) ++ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) ++ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) ++ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) ++ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) ++ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) ++ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) ++ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) ++ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) ++ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) ++ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) ++ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) ++ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) ++ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) ++ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) ++ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) ++ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) ++ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) ++ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) ++ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) ++ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) ++ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) ++ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) ++ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) ++ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) ++ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) ++ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) ++ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) ++ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ state[5] += f; ++ state[6] += g; ++ state[7] += h; ++ ++ /* Zeroize sensitive information. */ ++ memset((unsigned char*) x, 0, sizeof(x)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Encode ++ Encodes input (php_uint32) into output (unsigned char). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Encode(output, input, len) ++unsigned char *output; ++php_uint32 *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) { ++ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); ++ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); ++ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); ++ output[j + 3] = (unsigned char) (input[i] & 0xff); ++ } ++} ++/* }}} */ ++ ++/* {{{ SHA256Decode ++ Decodes input (unsigned char) into output (php_uint32). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Decode(output, input, len) ++php_uint32 *output; ++const unsigned char *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) ++ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | ++ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.5/ext/standard/sha256.h hardening-patch-5.1.5-0.4.15/ext/standard/sha256.h +--- php-5.1.5/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/sha256.h 2006-09-05 20:31:23.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ ++ ++#ifndef SHA256_H ++#define SHA256_H ++ ++#include "ext/standard/basic_functions.h" ++ ++/* SHA1 context. */ ++typedef struct { ++ php_uint32 state[8]; /* state (ABCD) */ ++ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ++ unsigned char buffer[64]; /* input buffer */ ++} PHP_SHA256_CTX; ++ ++static void PHP_SHA256Init(PHP_SHA256_CTX *); ++static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); ++static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); ++ ++PHP_FUNCTION(sha256); ++PHP_FUNCTION(sha256_file); ++ ++#endif +diff -Nura php-5.1.5/ext/standard/syslog.c hardening-patch-5.1.5-0.4.15/ext/standard/syslog.c +--- php-5.1.5/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/standard/syslog.c 2006-09-05 20:31:23.000000000 +0200 +@@ -42,6 +42,7 @@ + */ + PHP_MINIT_FUNCTION(syslog) + { ++#if !HARDENING_PATCH + /* error levels */ + REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ + REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ +@@ -97,6 +98,7 @@ + /* AIX doesn't have LOG_PERROR */ + REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ + #endif ++#endif + BG(syslog_device)=NULL; + + return SUCCESS; +diff -Nura php-5.1.5/ext/varfilter/config.m4 hardening-patch-5.1.5-0.4.15/ext/varfilter/config.m4 +--- php-5.1.5/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/varfilter/config.m4 2006-09-05 20:31:23.000000000 +0200 +@@ -0,0 +1,11 @@ ++dnl ++dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++dnl ++ ++PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, ++[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) ++ ++if test "$PHP_VARFILTER" != "no"; then ++ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) ++ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) ++fi +diff -Nura php-5.1.5/ext/varfilter/CREDITS hardening-patch-5.1.5-0.4.15/ext/varfilter/CREDITS +--- php-5.1.5/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:31:23.000000000 +0200 +@@ -0,0 +1,2 @@ ++varfilter ++Stefan Esser +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-5.1.5/ext/varfilter/php_varfilter.h hardening-patch-5.1.5-0.4.15/ext/varfilter/php_varfilter.h +--- php-5.1.5/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:31:23.000000000 +0200 +@@ -0,0 +1,144 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifndef PHP_VARFILTER_H ++#define PHP_VARFILTER_H ++ ++extern zend_module_entry varfilter_module_entry; ++#define phpext_varfilter_ptr &varfilter_module_entry ++ ++#ifdef PHP_WIN32 ++#define PHP_VARFILTER_API __declspec(dllexport) ++#else ++#define PHP_VARFILTER_API ++#endif ++ ++#ifdef ZTS ++#include "TSRM.h" ++#endif ++ ++#include "SAPI.h" ++ ++#include "php_variables.h" ++ ++#ifdef ZEND_ENGINE_2 ++#define HASH_HTTP_GET_VARS 0x2095733f ++#define HASH_HTTP_POST_VARS 0xbfee1265 ++#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 ++#define HASH_HTTP_ENV_VARS 0x1fe186a8 ++#define HASH_HTTP_SERVER_VARS 0xc987afd6 ++#define HASH_HTTP_SESSION_VARS 0x7aba0d43 ++#define HASH_HTTP_POST_FILES 0x98eb1ddc ++#define HASH_HTTP_RAW_POST_DATA 0xdd633fec ++#else ++#define HASH_HTTP_GET_VARS 0x8d8645bd ++#define HASH_HTTP_POST_VARS 0x7c699bf3 ++#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f ++#define HASH_HTTP_ENV_VARS 0x84da3016 ++#define HASH_HTTP_SERVER_VARS 0x6dbf964e ++#define HASH_HTTP_SESSION_VARS 0x322906f5 ++#define HASH_HTTP_POST_FILES 0xe4e4ce70 ++#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e ++#endif ++ ++PHP_MINIT_FUNCTION(varfilter); ++PHP_MSHUTDOWN_FUNCTION(varfilter); ++PHP_RINIT_FUNCTION(varfilter); ++PHP_RSHUTDOWN_FUNCTION(varfilter); ++PHP_MINFO_FUNCTION(varfilter); ++ ++ ++ZEND_BEGIN_MODULE_GLOBALS(varfilter) ++/* request variables */ ++ long max_request_variables; ++ long cur_request_variables; ++ long max_varname_length; ++ long max_totalname_length; ++ long max_value_length; ++ long max_array_depth; ++ long max_array_index_length; ++ zend_bool disallow_nul; ++/* cookie variables */ ++ long max_cookie_vars; ++ long cur_cookie_vars; ++ long max_cookie_name_length; ++ long max_cookie_totalname_length; ++ long max_cookie_value_length; ++ long max_cookie_array_depth; ++ long max_cookie_array_index_length; ++ zend_bool disallow_cookie_nul; ++/* get variables */ ++ long max_get_vars; ++ long cur_get_vars; ++ long max_get_name_length; ++ long max_get_totalname_length; ++ long max_get_value_length; ++ long max_get_array_depth; ++ long max_get_array_index_length; ++ zend_bool disallow_get_nul; ++/* post variables */ ++ long max_post_vars; ++ long cur_post_vars; ++ long max_post_name_length; ++ long max_post_totalname_length; ++ long max_post_value_length; ++ long max_post_array_depth; ++ long max_post_array_index_length; ++ zend_bool disallow_post_nul; ++/* fileupload */ ++ long max_uploads; ++ long cur_uploads; ++ zend_bool disallow_elf_files; ++ char *verification_script; ++ ++ zend_bool no_more_variables; ++ zend_bool no_more_get_variables; ++ zend_bool no_more_post_variables; ++ zend_bool no_more_cookie_variables; ++ zend_bool no_more_uploads; ++ ++ZEND_END_MODULE_GLOBALS(varfilter) ++ ++ ++#ifdef ZTS ++#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) ++#else ++#define VARFILTER_G(v) (varfilter_globals.v) ++#endif ++ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); ++SAPI_TREAT_DATA_FUNC(varfilter_treat_data); ++ ++ ++ ++#endif /* PHP_VARFILTER_H */ ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: t ++ * End: ++ */ +diff -Nura php-5.1.5/ext/varfilter/varfilter.c hardening-patch-5.1.5-0.4.15/ext/varfilter/varfilter.c +--- php-5.1.5/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:52:22.000000000 +0200 +@@ -0,0 +1,915 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "php.h" ++#include "php_ini.h" ++#include "ext/standard/info.h" ++#include "php_varfilter.h" ++#include "hardening_patch.h" ++ ++ZEND_DECLARE_MODULE_GLOBALS(varfilter) ++ ++/* True global resources - no need for thread safety here */ ++static int le_varfilter; ++ ++static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; ++static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; ++static zend_bool hooked = 0; ++ ++/* {{{ varfilter_module_entry ++ */ ++zend_module_entry varfilter_module_entry = { ++#if ZEND_MODULE_API_NO >= 20010901 ++ STANDARD_MODULE_HEADER, ++#endif ++ "varfilter", ++ NULL, ++ PHP_MINIT(varfilter), ++ PHP_MSHUTDOWN(varfilter), ++ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ ++ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ ++ PHP_MINFO(varfilter), ++#if ZEND_MODULE_API_NO >= 20010901 ++ "0.4.15", /* Replace with version number for your extension */ ++#endif ++ STANDARD_MODULE_PROPERTIES ++}; ++/* }}} */ ++ ++#ifdef COMPILE_DL_VARFILTER ++ZEND_GET_MODULE(varfilter) ++#endif ++ ++/* {{{ PHP_INI ++ */ ++PHP_INI_BEGIN() ++ /* for backward compatibility */ ++ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) ++ ++ ++PHP_INI_END() ++/* }}} */ ++ ++/* {{{ php_varfilter_init_globals ++ */ ++static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) ++{ ++ varfilter_globals->max_request_variables = 200; ++ varfilter_globals->max_varname_length = 64; ++ varfilter_globals->max_value_length = 10000; ++ varfilter_globals->max_array_depth = 100; ++ varfilter_globals->max_totalname_length = 256; ++ varfilter_globals->max_array_index_length = 64; ++ varfilter_globals->disallow_nul = 1; ++ ++ varfilter_globals->max_cookie_vars = 100; ++ varfilter_globals->max_cookie_name_length = 64; ++ varfilter_globals->max_cookie_totalname_length = 256; ++ varfilter_globals->max_cookie_value_length = 10000; ++ varfilter_globals->max_cookie_array_depth = 100; ++ varfilter_globals->max_cookie_array_index_length = 64; ++ varfilter_globals->disallow_cookie_nul = 1; ++ ++ varfilter_globals->max_get_vars = 100; ++ varfilter_globals->max_get_name_length = 64; ++ varfilter_globals->max_get_totalname_length = 256; ++ varfilter_globals->max_get_value_length = 512; ++ varfilter_globals->max_get_array_depth = 50; ++ varfilter_globals->max_get_array_index_length = 64; ++ varfilter_globals->disallow_get_nul = 1; ++ ++ varfilter_globals->max_post_vars = 200; ++ varfilter_globals->max_post_name_length = 64; ++ varfilter_globals->max_post_totalname_length = 256; ++ varfilter_globals->max_post_value_length = 65000; ++ varfilter_globals->max_post_array_depth = 100; ++ varfilter_globals->max_post_array_index_length = 64; ++ varfilter_globals->disallow_post_nul = 1; ++ ++ varfilter_globals->max_uploads = 25; ++ varfilter_globals->disallow_elf_files = 1; ++ varfilter_globals->verification_script = NULL; ++ ++ varfilter_globals->no_more_variables = 0; ++ varfilter_globals->no_more_get_variables = 0; ++ varfilter_globals->no_more_post_variables = 0; ++ varfilter_globals->no_more_cookie_variables = 0; ++ varfilter_globals->no_more_uploads = 0; ++ ++ varfilter_globals->cur_request_variables = 0; ++ varfilter_globals->cur_get_vars = 0; ++ varfilter_globals->cur_post_vars = 0; ++ varfilter_globals->cur_cookie_vars = 0; ++ ++ varfilter_globals->cur_uploads = 0; ++ ++} ++/* }}} */ ++ ++ ++void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) ++{ ++ HashTable *svars; ++ int retval, failure=0; ++ ++ orig_register_server_variables(track_vars_array TSRMLS_CC); ++ ++ svars = Z_ARRVAL_P(track_vars_array); ++ ++ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ ++ if (failure) { ++ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); ++ } ++} ++ ++int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) ++{ ++ int retval = SAPI_HEADER_ADD, i; ++ char *tmp; ++ ++ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { ++ ++ tmp = sapi_header->header; ++ for (i=0; iheader_len; i++, tmp++) { ++ if (tmp[0] == 0) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); ++ sapi_header->header_len = i; ++ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); ++ sapi_header->header_len = i; ++ tmp[0] = 0; ++ } ++ } ++ } ++ ++ if (orig_header_handler) { ++ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); ++ } ++ ++ return retval; ++} ++ ++/* {{{ PHP_MINIT_FUNCTION ++ */ ++PHP_MINIT_FUNCTION(varfilter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); ++ REGISTER_INI_ENTRIES(); ++ ++ if (!hooked) { ++ void *temp; ++ hooked = 1; ++ ++ temp = (void *)sapi_module.register_server_variables; ++ if (temp != varfilter_register_server_variables) { ++ orig_register_server_variables = temp; ++ } ++ temp = (void *)sapi_module.header_handler; ++ if (temp != varfilter_header_handler) { ++ orig_header_handler = temp; ++ } ++ } ++ ++ sapi_register_input_filter(varfilter_input_filter); ++ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); ++ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); ++ sapi_register_upload_content_filter(varfilter_upload_content_filter); ++ sapi_register_post_upload_filter(varfilter_post_upload_filter); ++ ++ sapi_module.header_handler = varfilter_header_handler; ++ sapi_module.register_server_variables = varfilter_register_server_variables; ++ ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MSHUTDOWN_FUNCTION ++ */ ++PHP_MSHUTDOWN_FUNCTION(varfilter) ++{ ++ UNREGISTER_INI_ENTRIES(); ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request start */ ++/* {{{ PHP_RINIT_FUNCTION ++ */ ++PHP_RINIT_FUNCTION(varfilter) ++{ ++ VARFILTER_G(cur_request_variables) = 0; ++ VARFILTER_G(cur_get_vars) = 0; ++ VARFILTER_G(cur_post_vars) = 0; ++ VARFILTER_G(cur_cookie_vars) = 0; ++ ++ VARFILTER_G(cur_uploads) = 0; ++ ++ VARFILTER_G(no_more_variables) = 0; ++ VARFILTER_G(no_more_get_variables) = 0; ++ VARFILTER_G(no_more_post_variables) = 0; ++ VARFILTER_G(no_more_cookie_variables) = 0; ++ VARFILTER_G(no_more_uploads) = 0; ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request end */ ++/* {{{ PHP_RSHUTDOWN_FUNCTION ++ */ ++PHP_RSHUTDOWN_FUNCTION(varfilter) ++{ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MINFO_FUNCTION ++ */ ++PHP_MINFO_FUNCTION(varfilter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); ++ php_info_print_table_end(); ++ ++ DISPLAY_INI_ENTRIES(); ++} ++/* }}} */ ++ ++/* {{{ normalize_varname ++ */ ++static void normalize_varname(char *varname) ++{ ++ char *s=varname, *index=NULL, *indexend=NULL, *p; ++ ++ /* overjump leading space */ ++ while (*s == ' ') { ++ s++; ++ } ++ ++ /* and remove it */ ++ if (s != varname) { ++ memmove(varname, s, strlen(s)+1); ++ } ++ ++ for (p=varname; *p && *p != '['; p++) { ++ switch(*p) { ++ case ' ': ++ case '.': ++ *p='_'; ++ break; ++ } ++ } ++ ++ /* find index */ ++ index = strchr(varname, '['); ++ if (index) { ++ index++; ++ s=index; ++ } else { ++ return; ++ } ++ ++ /* done? */ ++ while (index) { ++ ++ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { ++ index++; ++ } ++ indexend = strchr(index, ']'); ++ indexend = indexend ? indexend + 1 : index + strlen(index); ++ ++ if (s != index) { ++ memmove(s, index, strlen(index)+1); ++ s += indexend-index; ++ } else { ++ s = indexend; ++ } ++ ++ if (*s == '[') { ++ s++; ++ index = s; ++ } else { ++ index = NULL; ++ } ++ } ++ *s++='\0'; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC ++ */ ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) ++{ ++ char *index, *prev_index = NULL, *var; ++ unsigned int var_len, total_len, depth = 0; ++ ++ var = estrdup(varname); ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); ++ ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; ++ break; ++ } ++ ++ efree(var); ++ return SUCCESS; ++protected_varname2: ++ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); ++return_failure: ++ efree(var); ++ return FAILURE; ++} ++/* }}} */ ++ ++/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC ++ */ ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) ++{ ++ /* Drop if no more variables flag is set */ ++ if (VARFILTER_G(no_more_uploads)) { ++ return FAILURE; ++ } ++ /* Drop this fileupload if the limit is reached */ ++ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { ++ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); ++ VARFILTER_G(no_more_uploads) = 1; ++ return FAILURE; ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC ++ */ ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) ++{ ++ ++ if (VARFILTER_G(disallow_elf_files)) { ++ ++ if (offset == 0 && buffer_len > 10) { ++ ++ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { ++ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); ++ return FAILURE; ++ } ++ } ++ ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC ++ */ ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) ++{ ++ int retval = SUCCESS; ++ ++ if (VARFILTER_G(verification_script)) { ++ char cmd[8192]; ++ FILE *in; ++ int first=1; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); ++ return FAILURE; ++ } ++ ++ retval = FAILURE; ++ ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ if (first) { ++ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; ++ first = 0; ++ } ++ } ++ pclose(in); ++ } ++ ++ if (retval != SUCCESS) { ++ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); ++ return FAILURE; ++ } ++ ++ VARFILTER_G(cur_uploads)++; ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_INPUT_FILTER_FUNC ++ */ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) ++{ ++ char *index, *prev_index = NULL; ++ unsigned int var_len, total_len, depth = 0; ++ ++ /* Drop this variable if the limit was reached */ ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(no_more_get_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(no_more_post_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(no_more_cookie_variables)) { ++ return 0; ++ } ++ break; ++ default: /* we do not want to protect parse_str() and friends */ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ return 1; ++ } ++ if (VARFILTER_G(no_more_variables)) { ++ return 0; ++ } ++ ++ /* Drop this variable if the limit is now reached */ ++ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { ++ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_variables) = 1; ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { ++ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_get_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { ++ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_cookie_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { ++ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_post_variables) = 1; ++ return 0; ++ } ++ break; ++ } ++ ++ ++ /* Drop this variable if it exceeds the value length limit */ ++ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { ++ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { ++ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { ++ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { ++ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { ++ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { ++ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Check if variable value is truncated by a \0 */ ++ ++ if (val && *val && val_len != strlen(*val)) { ++ ++ if (VARFILTER_G(disallow_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(disallow_get_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(disallow_cookie_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(disallow_post_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ } ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname; ++ break; ++ } ++ ++ /* Okay let PHP register this variable */ ++ VARFILTER_G(cur_request_variables)++; ++ switch (arg) { ++ case PARSE_GET: ++ VARFILTER_G(cur_get_vars)++; ++ break; ++ case PARSE_COOKIE: ++ VARFILTER_G(cur_cookie_vars)++; ++ break; ++ case PARSE_POST: ++ VARFILTER_G(cur_post_vars)++; ++ break; ++ } ++ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ ++ return 1; ++protected_varname: ++ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); ++ return 0; ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: noet sw=4 ts=4 fdm=marker ++ * vim<600: noet sw=4 ts=4 ++ */ ++ ++ +diff -Nura php-5.1.5/ext/wddx/wddx.c hardening-patch-5.1.5-0.4.15/ext/wddx/wddx.c +--- php-5.1.5/ext/wddx/wddx.c 2006-05-25 12:01:30.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/ext/wddx/wddx.c 2006-09-05 20:31:23.000000000 +0200 +@@ -399,9 +399,9 @@ + break; + + default: +- if (iscntrl((int)*(unsigned char *)p)) { ++ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) { + FLUSH_BUF(); +- sprintf(control_buf, WDDX_CHAR, *p); ++ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); + php_wddx_add_chunk(packet, control_buf); + } else + buf[l++] = *p; +diff -Nura php-5.1.5/main/fopen_wrappers.c hardening-patch-5.1.5-0.4.15/main/fopen_wrappers.c +--- php-5.1.5/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/fopen_wrappers.c 2006-09-07 18:54:01.000000000 +0200 +@@ -104,7 +104,10 @@ + } + + /* Resolve the real path into resolved_name */ +- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { ++ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { ++ return -2; ++ } ++ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { + /* Handler for basedirs that end with a / */ + resolved_basedir_len = strlen(resolved_basedir); + if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { +@@ -114,14 +117,20 @@ + } + } + ++ resolved_name_len = strlen(resolved_name); + if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { +- resolved_name_len = strlen(resolved_name); + if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { + resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; + resolved_name[++resolved_name_len] = '\0'; + } + } + ++ if (resolved_name_len == resolved_basedir_len - 1) { ++ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { ++ resolved_basedir_len--; ++ } ++ } ++ + /* Check the path */ + #if defined(PHP_WIN32) || defined(NETWARE) + if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { +@@ -135,7 +144,7 @@ + } + } else { + /* Unable to resolve the real path, return -1 */ +- return -1; ++ return -3; + } + } + /* }}} */ +@@ -154,22 +163,44 @@ + char *pathbuf; + char *ptr; + char *end; ++ char path_copy[MAXPATHLEN]; ++ int path_len; ++ ++ /* Special case path ends with a trailing slash */ ++ path_len = strlen(path); ++ if (path_len >= MAXPATHLEN) { ++ errno = EPERM; /* we deny permission to open it */ ++ return -1; ++ } ++ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { ++ memcpy(path_copy, path, path_len+1); ++ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; ++ path_copy[path_len] = '\0'; ++ path = (const char *)&path_copy; ++ } + + pathbuf = estrdup(PG(open_basedir)); + + ptr = pathbuf; + + while (ptr && *ptr) { ++ int res; + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end != NULL) { + *end = '\0'; + end++; + } + +- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { ++ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); ++ if (res == 0) { + efree(pathbuf); + return 0; + } ++ if (res == -2) { ++ efree(pathbuf); ++ errno = EPERM; ++ return -1; ++ } + + ptr = end; + } +diff -Nura php-5.1.5/main/hardened_globals.h hardening-patch-5.1.5-0.4.15/main/hardened_globals.h +--- php-5.1.5/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/hardened_globals.h 2006-09-05 20:31:24.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENED_GLOBALS_H ++#define HARDENED_GLOBALS_H ++ ++typedef struct _hardened_globals hardened_globals_struct; ++ ++#ifdef ZTS ++# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) ++extern int hardened_globals_id; ++#else ++# define HG(v) (hardened_globals.v) ++extern struct _hardened_globals hardened_globals; ++#endif ++ ++ ++struct _hardened_globals { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_1; ++ unsigned int canary_2; ++#endif ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_3; ++ unsigned int canary_4; ++ unsigned int ll_canary_inited; ++#endif ++ zend_bool hphp_sql_bailout_on_error; ++ zend_bool hphp_multiheader; ++ unsigned long hphp_mailprotect; ++ long hard_memory_limit; ++ HashTable *eval_whitelist; ++ HashTable *eval_blacklist; ++ HashTable *func_whitelist; ++ HashTable *func_blacklist; ++ HashTable *include_whitelist; ++ HashTable *include_blacklist; ++ unsigned int dummy; ++}; ++ ++ ++#endif /* HARDENED_GLOBALS_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-5.1.5/main/hardening_patch.c hardening-patch-5.1.5-0.4.15/main/hardening_patch.c +--- php-5.1.5/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/hardening_patch.c 2006-09-05 20:31:24.000000000 +0200 +@@ -0,0 +1,430 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ ++ ++#include "php.h" ++ ++#include ++#include ++ ++#if HAVE_UNISTD_H ++#include ++#endif ++#include "SAPI.h" ++#include "php_globals.h" ++ ++#if HARDENING_PATCH ++ ++#ifdef HAVE_SYS_SOCKET_H ++#include ++#endif ++ ++#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) ++#undef AF_UNIX ++#endif ++ ++#if defined(AF_UNIX) ++#include ++#endif ++ ++#define SYSLOG_PATH "/dev/log" ++ ++#include "snprintf.h" ++ ++#include "hardening_patch.h" ++ ++#ifdef ZTS ++#include "hardened_globals.h" ++int hardened_globals_id; ++#else ++struct _hardened_globals hardened_globals; ++#endif ++ ++static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) ++{ ++ memset(hardened_globals, 0, sizeof(*hardened_globals)); ++} ++ ++ ++PHPAPI void hardened_startup() ++{ ++#ifdef ZTS ++ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); ++#else ++ hardened_globals_ctor(&hardened_globals TSRMLS_CC); ++#endif ++} ++ ++PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) ++{ ++ HG(canary_1) = php_canary(); ++ HG(canary_2) = php_canary(); ++} ++ ++char *loglevel2string(int loglevel) ++{ ++ switch (loglevel) { ++ case S_FILES: ++ return "FILES"; ++ case S_INCLUDE: ++ return "INCLUDE"; ++ case S_MEMORY: ++ return "MEMORY"; ++ case S_MISC: ++ return "MISC"; ++ case S_SQL: ++ return "SQL"; ++ case S_EXECUTOR: ++ return "EXECUTOR"; ++ case S_VARS: ++ return "VARS"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++PHPAPI void php_security_log(int loglevel, char *fmt, ...) ++{ ++#if defined(AF_UNIX) ++ int s, r, i=0; ++ struct sockaddr_un saun; ++ char buf[4096+64]; ++ char error[4096+100]; ++ char *ip_address; ++ char *fname; ++ int lineno; ++ va_list ap; ++ TSRMLS_FETCH(); ++ ++ if (EG(hphp_log_use_x_forwarded_for)) { ++ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "X-FORWARDED-FOR not set"; ++ } ++ } else { ++ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "REMOTE_ADDR not set"; ++ } ++ } ++ ++ ++ va_start(ap, fmt); ++ ap_php_vsnprintf(error, sizeof(error), fmt, ap); ++ va_end(ap); ++ while (error[i]) { ++ if (error[i] < 32) error[i] = '.'; ++ i++; ++ } ++ ++ if (zend_is_executing(TSRMLS_C)) { ++ lineno = zend_get_executed_lineno(TSRMLS_C); ++ fname = zend_get_executed_filename(TSRMLS_C); ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); ++ } else { ++ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); ++ if (fname==NULL) { ++ fname = "unknown"; ++ } ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); ++ } ++ ++ /* Syslog-Logging disabled? */ ++ if ((EG(hphp_log_syslog) & loglevel)==0) { ++ goto log_sapi; ++ } ++ ++ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); ++ ++ s = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ s = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ goto log_sapi; ++ } ++ } ++ send(s, error, strlen(error), 0); ++ ++ close(s); ++ ++log_sapi: ++ /* SAPI Logging activated? */ ++ if ((EG(hphp_log_sapi) & loglevel)!=0) { ++ sapi_module.log_message(buf); ++ } ++ ++log_script: ++ /* script logging activaed? */ ++ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { ++ char cmd[8192], *cmdpos, *bufpos; ++ FILE *in; ++ int space; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); ++ space = sizeof(cmd) - strlen(cmd); ++ cmdpos = cmd + strlen(cmd); ++ bufpos = buf; ++ if (space <= 1) return; ++ while (space > 2 && *bufpos) { ++ if (*bufpos == '\'') { ++ if (space<=5) break; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\\'; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\''; ++ bufpos++; ++ space-=4; ++ } else { ++ *cmdpos++ = *bufpos++; ++ space--; ++ } ++ } ++ *cmdpos++ = '\''; ++ *cmdpos = 0; ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); ++ return; ++ } ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ } ++ pclose(in); ++ } ++ ++#endif ++} ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++PHPAPI unsigned int php_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++ ++PHPAPI int php_is_valid_include(zval *z) ++{ ++ char *filename; ++ int len, i; ++ TSRMLS_FETCH(); ++ ++ /* must be of type string */ ++ if (z->type != IS_STRING || z->value.str.val == NULL) { ++ return (0); ++ } ++ ++ /* short cut */ ++ filename = z->value.str.val; ++ len = z->value.str.len; ++ ++ /* 1. must be shorter than MAXPATHLEN */ ++ if (len > MAXPATHLEN) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 2. must not be cutted */ ++ if (len != strlen(filename)) { ++ char *fname = estrndup(filename, len); ++ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ ++ if (strstr(filename, "://")) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ ++ /* no black or whitelist then disallow all */ ++ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* whitelist is stronger than blacklist */ ++ if (HG(include_whitelist)) { ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ zend_bool isOk = 0; ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_whitelist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ isOk = 1; ++ break; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_whitelist)); ++ } while (1); ++ ++ /* not found in whitelist */ ++ if (!isOk) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); ++ efree(fname); ++ return 0; ++ } ++ ++ s = h + 3; ++ } while (1); ++ } else { ++ /* okay then handle the blacklist */ ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_blacklist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); ++ efree(fname); ++ return 0; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_blacklist)); ++ } while (1); ++ ++ s = h + 3; ++ } while (1); ++ } ++ ++ efree(fname); ++ } ++ ++ /* 4. must not be an uploaded file */ ++ if (SG(rfc1867_uploaded_files)) { ++ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { ++ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); ++ return (0); ++ } ++ } ++ ++ /* passed all tests */ ++ return (1); ++} ++ ++#endif ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.5/main/hardening_patch.h hardening-patch-5.1.5-0.4.15/main/hardening_patch.h +--- php-5.1.5/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/hardening_patch.h 2006-09-07 18:52:11.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENING_PATCH_H ++#define HARDENING_PATCH_H ++ ++#include "zend.h" ++ ++#if HARDENING_PATCH ++PHPAPI void php_security_log(int loglevel, char *fmt, ...); ++PHPAPI void hardened_startup(); ++#define HARDENING_PATCH_VERSION "0.4.15" ++ ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++PHPAPI unsigned int php_canary(); ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++PHPAPI int php_is_valid_include(zval *z); ++#endif ++ ++#endif /* HARDENING_PATCH_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-5.1.5/main/hardening_patch.m4 hardening-patch-5.1.5-0.4.15/main/hardening_patch.m4 +--- php-5.1.5/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/hardening_patch.m4 2006-09-05 20:31:24.000000000 +0200 +@@ -0,0 +1,95 @@ ++dnl ++dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ ++dnl ++dnl This file contains Hardening Patch for PHP specific autoconf functions. ++dnl ++ ++AC_ARG_ENABLE(hardening-patch-mm-protect, ++[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-ll-protect, ++[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-inc-protect, ++[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-fmt-protect, ++[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-hash-protect, ++[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++]) ++ ++AC_MSG_CHECKING(whether to protect the Zend Memory Manager) ++AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the Zend Linked Lists) ++AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect include/require statements) ++AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect PHP Format String functions) ++AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) ++AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) ++ ++ ++AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) ++fi ++ +diff -Nura php-5.1.5/main/main.c hardening-patch-5.1.5-0.4.15/main/main.c +--- php-5.1.5/main/main.c 2006-08-10 23:49:56.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/main/main.c 2006-09-05 20:31:24.000000000 +0200 +@@ -85,6 +85,10 @@ + + #include "SAPI.h" + #include "rfc1867.h" ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#endif ++ + /* }}} */ + + #ifndef ZTS +@@ -109,17 +113,39 @@ + */ + static PHP_INI_MH(OnChangeMemoryLimit) + { ++#if HARDENING_PATCH ++ long hard_memory_limit = 1<<30; ++ ++ if (stage == ZEND_INI_STAGE_RUNTIME) { ++ if (HG(hard_memory_limit) == 0) { ++ HG(hard_memory_limit) = PG(memory_limit); ++ } ++ hard_memory_limit = HG(hard_memory_limit); ++ } else { ++ HG(hard_memory_limit) = 0; ++ } ++#endif + if (new_value) { + PG(memory_limit) = zend_atoi(new_value, new_value_length); ++#if HARDENING_PATCH ++ if (PG(memory_limit) > hard_memory_limit) { ++ PG(memory_limit) = hard_memory_limit; ++ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); ++ return FAILURE; ++ } ++#endif + } else { ++#if HARDENING_PATCH ++ PG(memory_limit) = hard_memory_limit; ++#else + PG(memory_limit) = 1<<30; /* effectively, no limit */ ++#endif + } + return zend_set_memory_limit(PG(memory_limit)); + } + /* }}} */ + #endif + +- + /* {{{ php_disable_functions + */ + static void php_disable_functions(TSRMLS_D) +@@ -1100,6 +1126,13 @@ + sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1); + } + ++ /* Disable realpath cache if safe_mode or open_basedir are set */ ++ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ++ CWDG(realpath_cache_disable) = 1; ++ } else { ++ CWDG(realpath_cache_disable) = 0; ++ } ++ + if (PG(output_handler) && PG(output_handler)[0]) { + php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); + } else if (PG(output_buffering)) { +@@ -1227,6 +1260,9 @@ + + zend_try { + shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); ++#if HARDENING_PATCH ++ hardened_clear_mm_canaries(TSRMLS_C); ++#endif + } zend_end_try(); + + zend_try { +@@ -1398,6 +1434,10 @@ + tsrm_ls = ts_resource(0); + #endif + ++#if HARDENING_PATCH ++ hardened_startup(); ++#endif ++ + module_shutdown = 0; + module_startup = 1; + sapi_initialize_empty_request(TSRMLS_C); +@@ -1411,6 +1451,12 @@ + + php_output_startup(); + ++#if HARDENING_PATCH_INC_PROTECT ++ zuf.is_valid_include = php_is_valid_include; ++#endif ++#if HARDENING_PATCH ++ zuf.security_log_function = php_security_log; ++#endif + zuf.error_function = php_error_cb; + zuf.printf_function = php_printf; + zuf.write_function = php_body_write_wrapper; +@@ -1481,7 +1527,9 @@ + + /* Disable realpath cache if safe_mode or open_basedir are set */ + if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { +- CWDG(realpath_cache_size_limit) = 0; ++ CWDG(realpath_cache_disable) = 1; ++ } else { ++ CWDG(realpath_cache_disable) = 0; + } + + /* initialize stream wrappers registry +@@ -1522,6 +1570,10 @@ + REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS); + 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); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); ++#endif + REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); +diff -Nura php-5.1.5/main/php_config.h.in hardening-patch-5.1.5-0.4.15/main/php_config.h.in +--- php-5.1.5/main/php_config.h.in 2006-08-15 14:55:43.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/main/php_config.h.in 2006-09-05 20:31:24.000000000 +0200 +@@ -788,6 +788,39 @@ + /* Enabling BIND8 compatibility for Panther */ + #undef BIND_8_COMPAT + ++/* Hardening-Patch for PHP */ ++#undef HARDENING_PATCH ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ + /* Whether you have AOLserver */ + #undef HAVE_AOLSERVER + +@@ -1131,6 +1164,12 @@ + /* Define if you have the getaddrinfo function */ + #undef HAVE_GETADDRINFO + ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ + /* Whether system headers declare timezone */ + #undef HAVE_DECLARED_TIMEZONE + +diff -Nura php-5.1.5/main/php.h hardening-patch-5.1.5-0.4.15/main/php.h +--- php-5.1.5/main/php.h 2006-03-07 23:37:53.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/php.h 2006-09-05 20:31:24.000000000 +0200 +@@ -35,11 +35,19 @@ + #include "zend_qsort.h" + #include "php_compat.h" + ++ + #include "zend_API.h" + + #undef sprintf + #define sprintf php_sprintf + ++#if HARDENING_PATCH ++#if HAVE_REALPATH ++#undef realpath ++#define realpath php_realpath ++#endif ++#endif ++ + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ + #undef PHP_DEBUG + #define PHP_DEBUG ZEND_DEBUG +@@ -338,6 +346,7 @@ + #define PHP_FUNCTION ZEND_FUNCTION + #define PHP_METHOD ZEND_METHOD + ++#define PHP_STATIC_FE ZEND_STATIC_FE + #define PHP_NAMED_FE ZEND_NAMED_FE + #define PHP_FE ZEND_FE + #define PHP_DEP_FE ZEND_DEP_FE +@@ -447,6 +456,10 @@ + #endif + #endif /* !XtOffsetOf */ + ++#if HARDENING_PATCH ++#include "hardening_patch.h" ++#endif ++ + #endif + + /* +diff -Nura php-5.1.5/main/php_variables.c hardening-patch-5.1.5-0.4.15/main/php_variables.c +--- php-5.1.5/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/main/php_variables.c 2006-09-05 20:31:24.000000000 +0200 +@@ -73,6 +73,10 @@ + symtable1 = Z_ARRVAL_P(track_vars_array); + } else if (PG(register_globals)) { + symtable1 = EG(active_symbol_table); ++ /* GLOBALS hijack attempt, reject parameter */ ++ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) { ++ symtable1 = NULL; ++ } + } + if (!symtable1) { + /* Nothing to do */ +@@ -513,7 +517,7 @@ + */ + static inline void php_register_server_variables(TSRMLS_D) + { +- zval *array_ptr = NULL; ++ zval *array_ptr = NULL, *vptr; + /* turn off magic_quotes while importing server variables */ + int magic_quotes_gpc = PG(magic_quotes_gpc); + +diff -Nura php-5.1.5/main/rfc1867.c hardening-patch-5.1.5-0.4.15/main/rfc1867.c +--- php-5.1.5/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/rfc1867.c 2006-09-05 20:31:24.000000000 +0200 +@@ -132,6 +132,7 @@ + #define UPLOAD_ERROR_D 4 /* No file uploaded */ + #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ + #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ ++#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */ + + void php_rfc1867_register_constants(TSRMLS_D) + { +@@ -142,6 +143,7 @@ + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); + } + + static void normalize_protected_variable(char *varname TSRMLS_DC) +@@ -854,6 +856,7 @@ + char buff[FILLUNIT]; + char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; + int blen=0, wlen=0; ++ unsigned long offset; + + zend_llist_clean(&header); + +@@ -970,7 +973,11 @@ + tmp++; + } + } +- ++ ++ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { ++ skip_upload = 1; ++ } ++ + total_bytes = cancel_upload = 0; + + if (!skip_upload) { +@@ -994,6 +1001,11 @@ + cancel_upload = UPLOAD_ERROR_D; + } + ++ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ ++ offset = 0; + end = 0; + while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) + { +@@ -1008,6 +1020,10 @@ + #endif + cancel_upload = UPLOAD_ERROR_B; + } else if (blen > 0) { ++ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + wlen = write(fd, buff, blen); + + if (wlen < blen) { +@@ -1036,6 +1052,10 @@ + } + #endif + ++ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + if (cancel_upload) { + if (temp_filename) { + if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ +diff -Nura php-5.1.5/main/SAPI.c hardening-patch-5.1.5-0.4.15/main/SAPI.c +--- php-5.1.5/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/SAPI.c 2006-09-05 20:31:24.000000000 +0200 +@@ -870,6 +870,36 @@ + post_entry->content_type_len+1); + } + ++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)) ++{ ++ sapi_module.input_filter = input_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) ++{ ++ sapi_module.upload_varname_filter = upload_varname_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) ++{ ++ sapi_module.pre_upload_filter = pre_upload_filter; ++ return SUCCESS; ++} ++ ++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)) ++{ ++ sapi_module.upload_content_filter = upload_content_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) ++{ ++ sapi_module.post_upload_filter = post_upload_filter; ++ return SUCCESS; ++} ++ + + SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)) + { +@@ -884,11 +914,6 @@ + return SUCCESS; + } + +-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)) +-{ +- sapi_module.input_filter = input_filter; +- return SUCCESS; +-} + + SAPI_API int sapi_flush(TSRMLS_D) + { +diff -Nura php-5.1.5/main/SAPI.h hardening-patch-5.1.5-0.4.15/main/SAPI.h +--- php-5.1.5/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/SAPI.h 2006-09-05 20:31:24.000000000 +0200 +@@ -190,6 +190,10 @@ + SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); + 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)); + ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); ++ + SAPI_API int sapi_flush(TSRMLS_D); + SAPI_API struct stat *sapi_get_stat(TSRMLS_D); + SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC); +@@ -254,6 +258,11 @@ + int (*get_target_gid)(gid_t * TSRMLS_DC); + + unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); ++ ++ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); ++ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); ++ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); ++ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); + + void (*ini_defaults)(HashTable *configuration_hash); + int phpinfo_as_text; +@@ -279,7 +288,11 @@ + + #define SAPI_DEFAULT_MIMETYPE "text/html" + #define SAPI_DEFAULT_CHARSET "" ++#if HARDENING_PATCH ++#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" ++#else + #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION ++#endif + + #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) + #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) +@@ -287,6 +300,11 @@ + #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) + #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) + ++#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) ++#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) ++#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) ++#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) ++ + BEGIN_EXTERN_C() + SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); + SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); +diff -Nura php-5.1.5/main/snprintf.c hardening-patch-5.1.5-0.4.15/main/snprintf.c +--- php-5.1.5/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/snprintf.c 2006-09-05 20:31:24.000000000 +0200 +@@ -1014,7 +1014,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = cc; ++#endif + goto skip_output; + + /* +diff -Nura php-5.1.5/main/spprintf.c hardening-patch-5.1.5-0.4.15/main/spprintf.c +--- php-5.1.5/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/main/spprintf.c 2006-09-05 20:31:24.000000000 +0200 +@@ -630,7 +630,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = xbuf->len; ++#endif + goto skip_output; + + /* +diff -Nura php-5.1.5/pear/Makefile.frag hardening-patch-5.1.5-0.4.15/pear/Makefile.frag +--- php-5.1.5/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/pear/Makefile.frag 2006-09-05 20:31:24.000000000 +0200 +@@ -3,7 +3,7 @@ + peardir=$(PEAR_INSTALLDIR) + + # Skip all php.ini files altogether +-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 ++PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar + + install-pear-installer: $(SAPI_CLI_PATH) + @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" +diff -Nura php-5.1.5/php.ini-dist hardening-patch-5.1.5-0.4.15/php.ini-dist +--- php-5.1.5/php.ini-dist 2006-08-14 20:40:19.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/php.ini-dist 2006-09-05 20:31:24.000000000 +0200 +@@ -1198,6 +1198,209 @@ + ; instead of original one. + soap.wsdl_cache_ttl=86400 + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-5.1.5/php.ini-recommended hardening-patch-5.1.5-0.4.15/php.ini-recommended +--- php-5.1.5/php.ini-recommended 2006-08-14 20:40:19.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/php.ini-recommended 2006-09-05 20:31:24.000000000 +0200 +@@ -1256,6 +1256,209 @@ + ; instead of original one. + soap.wsdl_cache_ttl=86400 + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-5.1.5/run-tests.php hardening-patch-5.1.5-0.4.15/run-tests.php +--- php-5.1.5/run-tests.php 2006-05-03 23:37:16.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/run-tests.php 2006-09-05 20:31:24.000000000 +0200 +@@ -161,6 +161,10 @@ + 'error_reporting=4095', + 'display_errors=1', + 'log_errors=0', ++ 'hphp.executor.include.whitelist=cookietest', ++ 'hphp.log.syslog=0', ++ 'hphp.log.sapi=0', ++ 'hphp.log.script=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=1', +diff -Nura php-5.1.5/sapi/apache/mod_php5.c hardening-patch-5.1.5-0.4.15/sapi/apache/mod_php5.c +--- php-5.1.5/sapi/apache/mod_php5.c 2006-05-14 00:03:51.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/sapi/apache/mod_php5.c 2006-09-05 20:31:26.000000000 +0200 +@@ -482,7 +482,7 @@ + sapi_apache_get_fd, + sapi_apache_force_http_10, + sapi_apache_get_target_uid, +- sapi_apache_get_target_gid ++ sapi_apache_get_target_gid, + }; + /* }}} */ + +@@ -936,7 +936,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component("PHP/" PHP_VERSION); ++#endif + } + } + #endif +diff -Nura php-5.1.5/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.5-0.4.15/sapi/apache2filter/sapi_apache2.c +--- php-5.1.5/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:31:26.000000000 +0200 +@@ -573,7 +573,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-5.1.5/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.5-0.4.15/sapi/apache2handler/sapi_apache2.c +--- php-5.1.5/sapi/apache2handler/sapi_apache2.c 2006-08-08 15:11:39.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:31:26.000000000 +0200 +@@ -341,7 +341,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-5.1.5/sapi/cgi/cgi_main.c hardening-patch-5.1.5-0.4.15/sapi/cgi/cgi_main.c +--- php-5.1.5/sapi/cgi/cgi_main.c 2006-05-24 09:55:38.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:31:26.000000000 +0200 +@@ -1448,10 +1448,18 @@ + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } ++#if HARDENING_PATCH + #if ZEND_DEBUG +- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); ++ 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()); + #else +- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); ++ 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()); ++#endif ++#else ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif + #endif + php_end_ob_buffers(1 TSRMLS_CC); + exit(0); +diff -Nura php-5.1.5/sapi/cli/php_cli.c hardening-patch-5.1.5-0.4.15/sapi/cli/php_cli.c +--- php-5.1.5/sapi/cli/php_cli.c 2006-05-12 00:11:17.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:31:26.000000000 +0200 +@@ -754,8 +754,14 @@ + goto err; + } + ++#if HARDENING_PATCH ++ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", ++ PHP_VERSION, HARDENING_PATCH_VERSION, ++#else + php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", +- PHP_VERSION, sapi_module.name, __DATE__, __TIME__, ++ PHP_VERSION, ++#endif ++ sapi_module.name, __DATE__, __TIME__, + #if ZEND_DEBUG && defined(HAVE_GCOV) + "(DEBUG GCOV)", + #elif ZEND_DEBUG +diff -Nura php-5.1.5/TSRM/TSRM.h hardening-patch-5.1.5-0.4.15/TSRM/TSRM.h +--- php-5.1.5/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/TSRM/TSRM.h 2006-09-05 20:31:26.000000000 +0200 +@@ -33,6 +33,13 @@ + # define TSRM_API + #endif + ++#if HARDENING_PATCH ++# if HAVE_REALPATH ++# undef realpath ++# define realpath php_realpath ++# endif ++#endif ++ + /* Only compile multi-threading functions if we're in ZTS mode */ + #ifdef ZTS + +@@ -88,6 +95,7 @@ + + #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts + ++ + #ifdef __cplusplus + extern "C" { + #endif +diff -Nura php-5.1.5/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.c +--- php-5.1.5/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:31:26.000000000 +0200 +@@ -163,6 +163,7 @@ + static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) + { + CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state); ++ cwd_globals->realpath_cache_disable = 0; + cwd_globals->realpath_cache_size = 0; + cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE; + cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL; +@@ -201,6 +202,176 @@ + return p; + } + ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved) ++{ ++ struct stat sb; ++ char *p, *q, *s; ++ size_t left_len, resolved_len; ++ unsigned symlinks; ++ int serrno, slen; ++ int is_dir = 1; ++ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; ++ ++ serrno = errno; ++ symlinks = 0; ++ if (path[0] == '/') { ++ resolved[0] = '/'; ++ resolved[1] = '\0'; ++ if (path[1] == '\0') ++ return (resolved); ++ resolved_len = 1; ++ left_len = strlcpy(left, path + 1, sizeof(left)); ++ } else { ++ if (getcwd(resolved, PATH_MAX) == NULL) { ++ strlcpy(resolved, ".", PATH_MAX); ++ return (NULL); ++ } ++ resolved_len = strlen(resolved); ++ left_len = strlcpy(left, path, sizeof(left)); ++ } ++ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ ++ /* ++ * Iterate over path components in `left'. ++ */ ++ while (left_len != 0) { ++ /* ++ * Extract the next path component and adjust `left' ++ * and its length. ++ */ ++ p = strchr(left, '/'); ++ s = p ? p : left + left_len; ++ if (s - left >= sizeof(next_token)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ memcpy(next_token, left, s - left); ++ next_token[s - left] = '\0'; ++ left_len -= s - left; ++ if (p != NULL) ++ memmove(left, s + 1, left_len + 1); ++ if (resolved[resolved_len - 1] != '/') { ++ if (resolved_len + 1 >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ resolved[resolved_len++] = '/'; ++ resolved[resolved_len] = '\0'; ++ } ++ if (next_token[0] == '\0') ++ continue; ++ else if (strcmp(next_token, ".") == 0) ++ continue; ++ else if (strcmp(next_token, "..") == 0) { ++ /* ++ * Strip the last path component except when we have ++ * single "/" ++ */ ++ if (!is_dir) { ++ errno = ENOENT; ++ return (NULL); ++ } ++ if (resolved_len > 1) { ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ continue; ++ } ++ ++ /* ++ * Append the next path component and lstat() it. If ++ * lstat() fails we still can return successfully if ++ * there are no more path components left. ++ */ ++ resolved_len = strlcat(resolved, next_token, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ if (lstat(resolved, &sb) != 0) { ++ if (errno == ENOENT) { ++ if (p == NULL) { ++ errno = serrno; ++ return (resolved); ++ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { ++ resolved_len = strlcat(resolved, "/", PATH_MAX); ++ resolved_len = strlcat(resolved, left, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ errno = serrno; ++ return (resolved); ++ } ++ } ++ return (NULL); ++ } ++ if (S_ISLNK(sb.st_mode)) { ++ if (symlinks++ > MAXSYMLINKS) { ++ errno = ELOOP; ++ return (NULL); ++ } ++ slen = readlink(resolved, symlink, sizeof(symlink) - 1); ++ if (slen < 0) ++ return (NULL); ++ symlink[slen] = '\0'; ++ if (symlink[0] == '/') { ++ resolved[1] = 0; ++ resolved_len = 1; ++ } else if (resolved_len > 1) { ++ /* Strip the last path component. */ ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ ++ /* ++ * If there are any path components left, then ++ * append them to symlink. The result is placed ++ * in `left'. ++ */ ++ if (p != NULL) { ++ if (symlink[slen - 1] != '/') { ++ if (slen + 1 >= sizeof(symlink)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ symlink[slen] = '/'; ++ symlink[slen + 1] = 0; ++ } ++ left_len = strlcat(symlink, left, sizeof(left)); ++ if (left_len >= sizeof(left)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ } ++ left_len = strlcpy(left, symlink, sizeof(left)); ++ } else { ++ if (S_ISDIR(sb.st_mode)) { ++ is_dir = 1; ++ } else { ++ is_dir = 0; ++ } ++ } ++ } ++ ++ /* ++ * Remove trailing slash except when the resolved pathname ++ * is a single "/". ++ */ ++ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') ++ resolved[resolved_len - 1] = '\0'; ++ return (resolved); ++} ++#endif ++ + CWD_API void virtual_cwd_startup(void) + { + char cwd[MAXPATHLEN]; +@@ -381,22 +552,33 @@ + #endif + char orig_path[MAXPATHLEN]; + int orig_path_len = 0; ++ int use_realpath_cache = 1; + realpath_cache_bucket *bucket; + time_t t = 0; + TSRMLS_FETCH(); + + if (path_length == 0) + return (0); +- if (path_length >= MAXPATHLEN) ++ if (path_length >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return (1); ++ } ++ ++ /* Disable realpath cache if safe_mode or open_basedir are set */ ++ if (CWDG(realpath_cache_disable)) { ++ use_realpath_cache = 0; ++ } + +- if (use_realpath && CWDG(realpath_cache_size_limit)) { ++ if (use_realpath && use_realpath_cache) { + if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { + memcpy(orig_path, path, path_length+1); + orig_path_len = path_length; + } else { + orig_path_len = path_length + state->cwd_length + 1; + if (orig_path_len >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(orig_path, state->cwd, state->cwd_length); +@@ -414,6 +596,8 @@ + if (verify_path && verify_path(state)) { + CWD_STATE_FREE(state); + *state = old_state; ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } else { + CWD_STATE_FREE(&old_state); +@@ -431,8 +615,9 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + } else { /* Concat current directory with relative path and then run realpath() on it */ +@@ -441,6 +626,8 @@ + + ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); + if (!tmp) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(ptr, state->cwd, state->cwd_length); +@@ -451,6 +638,8 @@ + *ptr = '\0'; + if (strlen(tmp) >= MAXPATHLEN) { + free(tmp); ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + if (use_realpath) { +@@ -458,9 +647,10 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now + free(tmp); +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + free(tmp); +@@ -599,7 +789,7 @@ + #endif + free(free_path); + +- if (use_realpath && CWDG(realpath_cache_size_limit)) { ++ if (use_realpath && use_realpath_cache) { + realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); + } + +diff -Nura php-5.1.5/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.h +--- php-5.1.5/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:31:26.000000000 +0200 +@@ -127,6 +127,22 @@ + + typedef int (*verify_path_func)(const cwd_state *); + ++#ifndef HAVE_STRLCPY ++CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); ++#undef strlcpy ++#define strlcpy php_strlcpy ++#endif ++ ++#ifndef HAVE_STRLCAT ++CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); ++#undef strlcat ++#define strlcat php_strlcat ++#endif ++ ++ ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved); ++#endif + CWD_API void virtual_cwd_startup(void); + CWD_API void virtual_cwd_shutdown(void); + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); +@@ -199,6 +215,7 @@ + long realpath_cache_size_limit; + long realpath_cache_ttl; + realpath_cache_bucket *realpath_cache[1024]; ++ int realpath_cache_disable; + } virtual_cwd_globals; + + #ifdef ZTS +diff -Nura php-5.1.5/Zend/zend_alloc.c hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.c +--- php-5.1.5/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.c 2006-09-05 20:31:26.000000000 +0200 +@@ -64,6 +64,11 @@ + # define END_MAGIC_SIZE 0 + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++# define CANARY_SIZE sizeof(unsigned int) ++#else ++# define CANARY_SIZE 0 ++#endif + + # if MEMORY_LIMIT + # if ZEND_DEBUG +@@ -72,7 +77,15 @@ + #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) + # endif + +-#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ ++#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ ++ if (file) { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ ++ } else { \ ++ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ ++ } \ ++ exit(1); \ ++ } \ ++ AG(allocated_memory) += rs;\ + if (AG(memory_limit)pNext; \ + } else { \ ++ if (p != p->pLast->pNext) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pLast->pNext = p->pNext; \ + } \ + if (p->pNext) { \ ++ if (p != p->pNext->pLast) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pNext->pLast = p->pLast; \ + } + #else +@@ -127,7 +148,7 @@ + #endif + + #define DECLARE_CACHE_VARS() \ +- unsigned int real_size; \ ++ size_t real_size; \ + unsigned int cache_index + + #define REAL_SIZE(size) ((size+7) & ~0x7) +@@ -142,12 +163,22 @@ + + ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { +- zend_mem_header *p; ++ zend_mem_header *p = NULL; + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { ++ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); ++ exit(1); ++ } ++#endif + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + ++ if (size > INT_MAX || SIZE < size) { ++ goto emalloc_error; ++ } ++ + #if !ZEND_DISABLE_MEMORY_CACHE + if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { + p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; +@@ -164,6 +195,10 @@ + AG(cache_stats)[CACHE_INDEX][1]++; + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } else { +@@ -179,11 +214,13 @@ + AG(allocated_memory_peak) = AG(allocated_memory); + } + #endif +- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); + #if !ZEND_DISABLE_MEMORY_CACHE + } + #endif + ++emalloc_error: ++ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (!p) { +@@ -210,7 +247,10 @@ + # endif + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif +- ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } +@@ -238,6 +278,10 @@ + } + } + ++ ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); ++#endif + zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset); + return 0; + } +@@ -270,9 +314,25 @@ + + ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); ++ ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++efree_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); ++ exit(1); ++ } ++ /* to catch double efree()s */ ++ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); ++ p->canary = 0; ++#endif + + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { +@@ -313,23 +373,35 @@ + + ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { +- void *p; +- int final_size = size*nmemb; ++ char *p; ++ size_t _size = nmemb * size; ++ ++ if (nmemb && (_size/nmemb!=size)) { ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); ++#endif ++ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); ++#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID ++ kill(getpid(), SIGSEGV); ++#else ++ exit(1); ++#endif ++ } + +- HANDLE_BLOCK_INTERRUPTIONS(); +- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); +- if (!p) { +- HANDLE_UNBLOCK_INTERRUPTIONS(); +- return (void *) p; ++ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); ++ if (p) { ++ memset(p, 0, _size); + } +- memset(p, 0, final_size); +- HANDLE_UNBLOCK_INTERRUPTIONS(); +- return p; ++ ++ return ((void *)p); + } + + + ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p; + zend_mem_header *orig; + DECLARE_CACHE_VARS(); +@@ -341,6 +413,16 @@ + + p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++erealloc_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); ++ exit(1); ++ } ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + void *new_p; +@@ -357,6 +439,13 @@ + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + + HANDLE_BLOCK_INTERRUPTIONS(); ++ ++ if (size > INT_MAX || SIZE < size) { ++ REMOVE_POINTER_FROM_LIST(p); ++ p = NULL; ++ goto erealloc_error; ++ } ++ + #if MEMORY_LIMIT + CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); + if (AG(allocated_memory) > AG(allocated_memory_peak)) { +@@ -364,7 +453,8 @@ + } + #endif + REMOVE_POINTER_FROM_LIST(p); +- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); ++erealloc_error: + if (!p) { + if (!allow_failure) { + fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); +@@ -386,6 +476,9 @@ + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + + HANDLE_UNBLOCK_INTERRUPTIONS(); +@@ -460,6 +553,10 @@ + { + AG(head) = NULL; + ++#if HARDENING_PATCH_MM_PROTECT ++ HG(canary_1) = zend_canary(); ++ HG(canary_2) = zend_canary(); ++#endif + #if MEMORY_LIMIT + AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ + AG(allocated_memory) = 0; +diff -Nura php-5.1.5/Zend/zend_alloc.h hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.h +--- php-5.1.5/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.h 2006-09-05 20:31:26.000000000 +0200 +@@ -35,6 +35,9 @@ + #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL + + typedef struct _zend_mem_header { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary; ++#endif + #if ZEND_DEBUG + long magic; + char *filename; +diff -Nura php-5.1.5/Zend/zend_API.h hardening-patch-5.1.5-0.4.15/Zend/zend_API.h +--- php-5.1.5/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_API.h 2006-09-05 20:31:26.000000000 +0200 +@@ -47,6 +47,7 @@ + #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) + + #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 }, ++#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 }, + + #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0) + #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0) +diff -Nura php-5.1.5/Zend/zend_builtin_functions.c hardening-patch-5.1.5-0.4.15/Zend/zend_builtin_functions.c +--- php-5.1.5/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:31:26.000000000 +0200 +@@ -53,6 +53,9 @@ + static ZEND_FUNCTION(crash); + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++static ZEND_FUNCTION(heap_overflow); ++#endif + static ZEND_FUNCTION(get_included_files); + static ZEND_FUNCTION(is_subclass_of); + static ZEND_FUNCTION(is_a); +@@ -113,6 +116,9 @@ + ZEND_FE(crash, NULL) + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ ZEND_FE(heap_overflow, NULL) ++#endif + ZEND_FE(get_included_files, NULL) + ZEND_FALIAS(get_required_files, get_included_files, NULL) + ZEND_FE(is_subclass_of, NULL) +@@ -1103,6 +1109,19 @@ + + #endif /* ZEND_DEBUG */ + ++ ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ZEND_FUNCTION(heap_overflow) ++{ ++ char *nowhere = emalloc(10); ++ ++ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); ++ ++ efree(nowhere); ++} ++#endif ++ ++ + /* {{{ proto array get_included_files(void) + Returns an array with the file names that were include_once()'d */ + ZEND_FUNCTION(get_included_files) +diff -Nura php-5.1.5/Zend/zend.c hardening-patch-5.1.5-0.4.15/Zend/zend.c +--- php-5.1.5/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend.c 2006-09-05 20:31:26.000000000 +0200 +@@ -55,6 +55,12 @@ + ZEND_API void (*zend_unblock_interruptions)(void); + ZEND_API void (*zend_ticks_function)(int ticks); + ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); ++#if HARDENING_PATCH ++ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); + ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); + +@@ -74,9 +80,391 @@ + return SUCCESS; + } + ++#if HARDENING_PATCH ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; ++ } else { ++ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_facility) = LOG_USER; ++ } else { ++ EG(hphp_log_syslog_facility) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_priority) = LOG_ALERT; ++ } else { ++ EG(hphp_log_syslog_priority) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_sapi) ++{ ++ if (!new_value) { ++ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; ++ } else { ++ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_script) ++{ ++ if (!new_value) { ++ EG(hphp_log_script) = S_ALL & ~S_MEMORY; ++ } else { ++ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) ++{ ++ if (EG(hphp_log_scriptname)) { ++ pefree(EG(hphp_log_scriptname),1); ++ } ++ EG(hphp_log_scriptname) = NULL; ++ if (new_value) { ++ EG(hphp_log_scriptname) = pestrdup(new_value,1); ++ } ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_whitelist_destroy: ++ if (HG(include_whitelist)) { ++ zend_hash_destroy(HG(include_whitelist)); ++ pefree(HG(include_whitelist),1); ++ } ++ HG(include_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_whitelist_destroy; ++ } ++ ++ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_blacklist_destroy: ++ if (HG(include_blacklist)) { ++ zend_hash_destroy(HG(include_blacklist)); ++ pefree(HG(include_blacklist),1); ++ } ++ HG(include_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_blacklist_destroy; ++ } ++ ++ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_whitelist_destroy: ++ if (HG(eval_whitelist)) { ++ zend_hash_destroy(HG(eval_whitelist)); ++ pefree(HG(eval_whitelist),1); ++ } ++ HG(eval_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_whitelist_destroy; ++ } ++ ++ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_blacklist_destroy: ++ if (HG(eval_blacklist)) { ++ zend_hash_destroy(HG(eval_blacklist)); ++ pefree(HG(eval_blacklist), 1); ++ } ++ HG(eval_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_blacklist_destroy; ++ } ++ ++ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_whitelist_destroy: ++ if (HG(func_whitelist)) { ++ zend_hash_destroy(HG(func_whitelist)); ++ pefree(HG(func_whitelist),1); ++ } ++ HG(func_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_whitelist_destroy; ++ } ++ ++ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_blacklist_destroy: ++ if (HG(func_blacklist)) { ++ zend_hash_destroy(HG(func_blacklist)); ++ pefree(HG(func_blacklist),1); ++ } ++ HG(func_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_blacklist_destroy; ++ } ++ ++ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++#endif + + ZEND_INI_BEGIN() + ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) ++#if HARDENING_PATCH ++ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) ++ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) ++ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) ++ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) ++ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) ++ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) ++ 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) ++ ++ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) ++ ++ 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) ++ 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) ++ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) ++ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) ++#endif + STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals) + #ifdef ZEND_MULTIBYTE + STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) +@@ -501,9 +889,13 @@ + EG(user_error_handler) = NULL; + EG(user_exception_handler) = NULL; + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(in_autoload) = NULL; + EG(current_execute_data) = NULL; + EG(current_module) = NULL; ++#if HARDENING_PATCH ++ EG(hphp_log_scriptname) = NULL; ++#endif + } + + +@@ -574,6 +966,14 @@ + extern zend_scanner_globals language_scanner_globals; + #endif + ++ /* Set up Hardening-Patch utility functions first */ ++#if HARDENING_PATCH ++ zend_security_log = utility_functions->security_log_function; ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ zend_is_valid_include = utility_functions->is_valid_include; ++#endif ++ + #ifdef ZTS + ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + #else +@@ -777,6 +1177,7 @@ + } + CG(unclean_shutdown) = 1; + CG(in_compilation) = EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(current_execute_data) = NULL; + longjmp(EG(bailout), FAILURE); + } +diff -Nura php-5.1.5/Zend/zend_canary.c hardening-patch-5.1.5-0.4.15/Zend/zend_canary.c +--- php-5.1.5/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_canary.c 2006-09-05 20:31:26.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ ++ ++#include "zend.h" ++ ++#include ++#include ++ ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++ZEND_API unsigned int zend_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.5/Zend/zend_compile.c hardening-patch-5.1.5-0.4.15/Zend/zend_compile.c +--- php-5.1.5/Zend/zend_compile.c 2006-03-27 10:09:18.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_compile.c 2006-09-05 20:31:26.000000000 +0200 +@@ -1092,6 +1092,13 @@ + op_array.prototype = NULL; + + op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array.created_by_eval = 1; ++ } else { ++ op_array.created_by_eval = 0; ++ } ++#endif + + if (is_method) { + char *short_class_name = CG(active_class_entry)->name; +diff -Nura php-5.1.5/Zend/zend_compile.h hardening-patch-5.1.5-0.4.15/Zend/zend_compile.h +--- php-5.1.5/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_compile.h 2006-09-05 20:31:26.000000000 +0200 +@@ -217,6 +217,9 @@ + zend_uint doc_comment_len; + + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; ++#if HARDENING_PATCH ++ zend_bool created_by_eval; ++#endif + }; + + +@@ -295,6 +298,8 @@ + zval ***CVs; + zend_bool original_in_execution; + HashTable *symbol_table; ++ zend_uint original_in_code_type; ++ zend_uint execute_depth; + struct _zend_execute_data *prev_execute_data; + zval *old_error_reporting; + }; +@@ -617,6 +622,7 @@ + #define ZEND_OVERLOADED_FUNCTION 3 + #define ZEND_EVAL_CODE 4 + #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5 ++#define ZEND_SANDBOX_CODE 6 + + #define ZEND_INTERNAL_CLASS 1 + #define ZEND_USER_CLASS 2 +diff -Nura php-5.1.5/Zend/zend_constants.c hardening-patch-5.1.5-0.4.15/Zend/zend_constants.c +--- php-5.1.5/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_constants.c 2006-09-05 20:31:26.000000000 +0200 +@@ -109,6 +109,74 @@ + REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); + + REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); ++ ++ /* error levels */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); ++ /* facility: type of program logging the message */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NEWS ++ /* No LOG_NEWS on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ ++#endif ++#ifdef LOG_UUCP ++ /* No LOG_UUCP on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_CRON ++ /* apparently some systems don't have this one */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_AUTHPRIV ++ /* AIX doesn't have LOG_AUTHPRIV */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); ++#endif ++#if !defined(PHP_WIN32) && !defined(NETWARE) ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); ++#endif ++ /* options */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NOWAIT ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_PERROR ++ /* AIX doesn't have LOG_PERROR */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ ++#endif ++#endif + + /* true/false constants */ + { +diff -Nura php-5.1.5/Zend/zend_errors.h hardening-patch-5.1.5-0.4.15/Zend/zend_errors.h +--- php-5.1.5/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_errors.h 2006-09-05 20:31:26.000000000 +0200 +@@ -38,6 +38,19 @@ + #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) + #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) + ++#if HARDENING_PATCH ++#define S_MEMORY (1<<0L) ++#define S_VARS (1<<1L) ++#define S_FILES (1<<2L) ++#define S_INCLUDE (1<<3L) ++#define S_SQL (1<<4L) ++#define S_EXECUTOR (1<<5L) ++#define S_MAIL (1<<6L) ++#define S_MISC (1<<30L) ++#define S_INTERNAL (1<<29L) ++#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) ++#endif ++ + #endif /* ZEND_ERRORS_H */ + + /* +diff -Nura php-5.1.5/Zend/zend_execute_API.c hardening-patch-5.1.5-0.4.15/Zend/zend_execute_API.c +--- php-5.1.5/Zend/zend_execute_API.c 2006-03-17 09:47:41.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:31:26.000000000 +0200 +@@ -142,6 +142,7 @@ + EG(class_table) = CG(class_table); + + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(in_autoload) = NULL; + EG(autoload_func) = NULL; + +@@ -784,6 +785,39 @@ + if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) { + EX(function_state).function = NULL; + } ++#if HARDENING_PATCH ++ else { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + efree(function_name_lc); + } + +@@ -1076,7 +1110,7 @@ + return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC); + } + +-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC) + { + zval pv; + zend_op_array *new_op_array; +@@ -1109,6 +1143,7 @@ + zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); + zend_op **original_opline_ptr = EG(opline_ptr); + ++ new_op_array->type = type; + EG(return_value_ptr_ptr) = &local_retval_ptr; + EG(active_op_array) = new_op_array; + EG(no_extensions)=1; +@@ -1143,6 +1178,12 @@ + } + + ++ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++{ ++ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); ++} ++ ++ + ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) + { + int result; +diff -Nura php-5.1.5/Zend/zend_execute.c hardening-patch-5.1.5-0.4.15/Zend/zend_execute.c +--- php-5.1.5/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_execute.c 2006-09-05 20:31:26.000000000 +0200 +@@ -1351,6 +1351,37 @@ + /* OBJ-TBI - doesn't support new object model! */ + zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + return 0; + } +@@ -1396,6 +1427,7 @@ + efree(EX(Ts)); \ + } \ + EG(in_execution) = EX(original_in_execution); \ ++ EG(in_code_type) = EX(original_in_code_type); \ + EG(current_execute_data) = EX(prev_execute_data); \ + ZEND_VM_RETURN() + +diff -Nura php-5.1.5/Zend/zend_extensions.c hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.c +--- php-5.1.5/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.c 2006-09-05 20:31:26.000000000 +0200 +@@ -55,23 +55,44 @@ + return FAILURE; + } + ++ /* check if module is compiled against Hardening-Patch */ ++ if (extension_version_info->zend_extension_api_no < 1000000000) { ++ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } ++ ++ ++ /* check if module is compiled against correct Hardening-Patch version */ ++ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { ++ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ extension_version_info->zend_extension_api_no, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } + + /* allow extension to proclaim compatibility with any Zend version */ +- 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)) { +- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { ++ 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)) { ++ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is outdated.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO); + DL_UNLOAD(handle); + return FAILURE; +- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { ++ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is newer.\n" + "Contact %s at %s for a later version of %s.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO, + new_extension->author, + new_extension->URL, +diff -Nura php-5.1.5/Zend/zend_extensions.h hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.h +--- php-5.1.5/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.h 2006-09-05 20:31:26.000000000 +0200 +@@ -24,9 +24,11 @@ + + #include "zend_compile.h" + +-/* The first number is the engine version and the rest is the date. ++/* The first API number is a flag saying that Hardening-Patch is used. ++ * The second number is the engine version and the date. + * This way engine 2 API no. is always greater than engine 1 API no.. + */ ++#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106 + #define ZEND_EXTENSION_API_NO 220051025 + + typedef struct _zend_extension_version_info { +@@ -34,6 +36,7 @@ + char *required_zend_version; + unsigned char thread_safe; + unsigned char debug; ++ int real_zend_extension_api_no; + } zend_extension_version_info; + + +@@ -101,7 +104,7 @@ + + + #define ZEND_EXTENSION() \ +- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } ++ 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 } + + #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 + #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 +diff -Nura php-5.1.5/Zend/zend_globals.h hardening-patch-5.1.5-0.4.15/Zend/zend_globals.h +--- php-5.1.5/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_globals.h 2006-09-05 20:31:26.000000000 +0200 +@@ -180,6 +180,16 @@ + + int error_reporting; + int orig_error_reporting; ++#if HARDENING_PATCH ++ int hphp_log_syslog; ++ int hphp_log_syslog_facility; ++ int hphp_log_syslog_priority; ++ int hphp_log_sapi; ++ int hphp_log_script; ++ char *hphp_log_scriptname; ++ zend_bool hphp_log_use_x_forwarded_for; ++ long hphp_executor_max_depth; ++#endif + int exit_status; + + zend_op_array *active_op_array; +@@ -197,6 +207,7 @@ + int ticks_count; + + zend_bool in_execution; ++ zend_uint in_code_type; + HashTable *in_autoload; + zend_function *autoload_func; + zend_bool bailout_set; +diff -Nura php-5.1.5/Zend/zend.h hardening-patch-5.1.5-0.4.15/Zend/zend.h +--- php-5.1.5/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend.h 2006-09-05 20:31:26.000000000 +0200 +@@ -297,6 +297,7 @@ + /* Variable information */ + zvalue_value value; /* value */ + zend_uint refcount; ++ zend_ushort flags; + zend_uchar type; /* active type */ + zend_uchar is_ref; + }; +@@ -382,6 +383,12 @@ + int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); + int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); + char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); ++#if HARDENING_PATCH ++ void (*security_log_function)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ int (*is_valid_include)(zval *z); ++#endif + } zend_utility_functions; + + +@@ -519,7 +526,16 @@ + extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); + extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); + extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); ++#if HARDENING_PATCH ++extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++extern ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ZEND_API unsigned int zend_canary(void); ++#endif + + ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); + +@@ -644,6 +660,11 @@ + + #include "zend_variables.h" + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#include "php_syslog.h" ++#endif ++ + #endif /* ZEND_H */ + + /* +diff -Nura php-5.1.5/Zend/zend_hash.c hardening-patch-5.1.5-0.4.15/Zend/zend_hash.c +--- php-5.1.5/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_hash.c 2006-09-05 20:31:26.000000000 +0200 +@@ -21,6 +21,18 @@ + + #include "zend.h" + ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int zend_hash_canary = 0x1234567; ++ zend_bool zend_hash_canary_inited = 0; ++#endif ++ ++#define CHECK_HASH_CANARY(hash) \ ++ if (zend_hash_canary != (hash)->canary) { \ ++ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++ + #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ + (element)->pNext = (list_head); \ + (element)->pLast = NULL; \ +@@ -138,6 +150,9 @@ + { + uint i = 3; + Bucket **tmp; ++#if HARDENING_PATCH_HASH_PROTECT ++ TSRMLS_FETCH(); ++#endif + + SET_INCONSISTENT(HT_OK); + +@@ -147,6 +162,13 @@ + + ht->nTableSize = 1 << i; + ht->nTableMask = ht->nTableSize - 1; ++#if HARDENING_PATCH_HASH_PROTECT ++ if (zend_hash_canary_inited==0) { ++ zend_hash_canary = zend_canary(); ++ zend_hash_canary_inited = 1; ++ } ++ ht->canary = zend_hash_canary; ++#endif + ht->pDestructor = pDestructor; + ht->arBuckets = NULL; + ht->pListHead = NULL; +@@ -226,6 +248,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -291,6 +316,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -366,6 +394,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -414,7 +445,7 @@ + IS_CONSISTENT(ht); + + if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ +- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); ++ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); + if (t) { + HANDLE_BLOCK_INTERRUPTIONS(); + ht->arBuckets = t; +@@ -424,6 +455,7 @@ + HANDLE_UNBLOCK_INTERRUPTIONS(); + return SUCCESS; + } ++ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); + return FAILURE; + } + return SUCCESS; +@@ -489,6 +521,9 @@ + ht->pInternalPointer = p->pListNext; + } + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (p->pData != &p->pDataPtr) { +@@ -513,6 +548,11 @@ + + SET_INCONSISTENT(HT_IS_DESTROYING); + ++#if HARDENING_PATCH_HASH_PROTECT ++ if (ht->pDestructor) { ++ CHECK_HASH_CANARY(ht); ++ } ++#endif + p = ht->pListHead; + while (p != NULL) { + q = p; +@@ -539,6 +579,11 @@ + + SET_INCONSISTENT(HT_CLEANING); + ++#if HARDENING_PATCH_HASH_PROTECT ++ if (ht->pDestructor) { ++ CHECK_HASH_CANARY(ht); ++ } ++#endif + p = ht->pListHead; + while (p != NULL) { + q = p; +@@ -573,6 +618,9 @@ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (p->pData != &p->pDataPtr) { +diff -Nura php-5.1.5/Zend/zend_hash.h hardening-patch-5.1.5-0.4.15/Zend/zend_hash.h +--- php-5.1.5/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_hash.h 2006-09-05 20:31:26.000000000 +0200 +@@ -58,6 +58,9 @@ + } Bucket; + + typedef struct _hashtable { ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int canary; ++#endif + uint nTableSize; + uint nTableMask; + uint nNumOfElements; +diff -Nura php-5.1.5/Zend/zend_ini.c hardening-patch-5.1.5-0.4.15/Zend/zend_ini.c +--- php-5.1.5/Zend/zend_ini.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_ini.c 2006-09-07 19:12:58.000000000 +0200 +@@ -256,7 +256,8 @@ + zend_ini_entry *ini_entry; + TSRMLS_FETCH(); + +- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { ++ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || ++ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) { + return FAILURE; + } + +diff -Nura php-5.1.5/Zend/zend_language_scanner.l hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.l +--- php-5.1.5/Zend/zend_language_scanner.l 2006-01-17 10:39:57.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:31:26.000000000 +0200 +@@ -389,6 +389,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-5.1.5/Zend/zend_language_scanner.c hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.c +--- php-5.1.5/Zend/zend_language_scanner.c 2006-08-15 14:55:43.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:31:26.000000000 +0200 +@@ -3075,6 +3075,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-5.1.5/Zend/zend_llist.c hardening-patch-5.1.5-0.4.15/Zend/zend_llist.c +--- php-5.1.5/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_llist.c 2006-09-05 20:31:26.000000000 +0200 +@@ -22,9 +22,49 @@ + #include "zend.h" + #include "zend_llist.h" + #include "zend_qsort.h" ++#include "zend_globals.h" ++ ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int zend_llist_canary_1 = 0x1234567; ++ unsigned int zend_llist_canary_2 = 0x1553425; ++ zend_bool zend_llist_canary_inited = 0; ++#endif ++ ++#define CHECK_LIST_CANARY(list) \ ++ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ ++ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ ++ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++#define CHECK_LISTELEMENT_CANARY(elem, list) \ ++ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ ++ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ ++ exit(1); \ ++ } ++ + + ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ ++ if (persistent) { ++ if (!zend_llist_canary_inited) { ++ /* do not change order to ensure thread safety */ ++ zend_llist_canary_1 = zend_canary(); ++ zend_llist_canary_2 = zend_canary(); ++ zend_llist_canary_inited = 1; ++ } ++ } else ++ if (!HG(ll_canary_inited)) { ++ HG(canary_3) = zend_canary(); ++ HG(canary_4) = zend_canary(); ++ HG(ll_canary_inited) = 1; ++ } ++ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); ++ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); ++#endif + l->head = NULL; + l->tail = NULL; + l->count = 0; +@@ -38,6 +78,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->prev = l->tail; + tmp->next = NULL; + if (l->tail) { +@@ -56,6 +101,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->next = l->head; + tmp->prev = NULL; + if (l->head) { +@@ -93,10 +143,20 @@ + zend_llist_element *current=l->head; + zend_llist_element *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (compare(current->data, element)) { + DEL_LLIST_ELEMENT(current, l); ++#if HARDENING_PATCH_LL_PROTECT ++ current->canary = 0; ++#endif + break; + } + current = next; +@@ -108,7 +168,14 @@ + { + zend_llist_element *current=l->head, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (l->dtor) { + l->dtor(current->data); +@@ -133,7 +200,14 @@ + zend_llist_element *old_tail; + void *data; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if ((old_tail = l->tail)) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(old_tail, l) ++#endif + if (l->tail->prev) { + l->tail->prev->next = NULL; + } +@@ -159,9 +233,16 @@ + { + zend_llist_element *ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(src) ++#endif + zend_llist_init(dst, src->size, src->dtor, src->persistent); + ptr = src->head; + while (ptr) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(ptr, src) ++#endif + zend_llist_add_element(dst, ptr->data); + ptr = ptr->next; + } +@@ -172,11 +253,21 @@ + { + zend_llist_element *element, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + element=l->head; + while (element) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + next = element->next; + if (func(element->data)) { + DEL_LLIST_ELEMENT(element, l); ++#if HARDENING_PATCH_LL_PROTECT ++ element->canary = 0; ++#endif + } + element = next; + } +@@ -187,7 +278,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data TSRMLS_CC); + } + } +@@ -199,6 +296,9 @@ + zend_llist_element **elements; + zend_llist_element *element, **ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + if (l->count <= 0) { + return; + } +@@ -208,6 +308,9 @@ + ptr = &elements[0]; + + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + *ptr++ = element; + } + +@@ -230,7 +333,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, arg TSRMLS_CC); + } + } +@@ -241,8 +350,14 @@ + zend_llist_element *element; + va_list args; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + va_start(args, num_args); + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, num_args, args TSRMLS_CC); + } + va_end(args); +@@ -251,6 +366,10 @@ + + ZEND_API int zend_llist_count(zend_llist *l) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + return l->count; + } + +@@ -259,8 +378,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->head; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -272,8 +398,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->tail; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -285,9 +418,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->next; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +@@ -299,9 +442,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->prev; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +diff -Nura php-5.1.5/Zend/zend_llist.h hardening-patch-5.1.5-0.4.15/Zend/zend_llist.h +--- php-5.1.5/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_llist.h 2006-09-05 20:31:26.000000000 +0200 +@@ -23,6 +23,9 @@ + #define ZEND_LLIST_H + + typedef struct _zend_llist_element { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary, padding; ++#endif + struct _zend_llist_element *next; + struct _zend_llist_element *prev; + char data[1]; /* Needs to always be last in the struct */ +@@ -35,6 +38,9 @@ + typedef void (*llist_apply_func_t)(void * TSRMLS_DC); + + typedef struct _zend_llist { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_h; /* head */ ++#endif + zend_llist_element *head; + zend_llist_element *tail; + size_t count; +@@ -42,6 +48,9 @@ + llist_dtor_func_t dtor; + unsigned char persistent; + zend_llist_element *traverse_ptr; ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_t; /* tail */ ++#endif + } zend_llist; + + typedef zend_llist_element* zend_llist_position; +diff -Nura php-5.1.5/Zend/zend_modules.h hardening-patch-5.1.5-0.4.15/Zend/zend_modules.h +--- php-5.1.5/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_modules.h 2006-09-05 20:31:26.000000000 +0200 +@@ -39,6 +39,7 @@ + extern struct _zend_arg_info fifth_arg_force_ref[6]; + extern struct _zend_arg_info all_args_by_ref[1]; + ++#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106 + #define ZEND_MODULE_API_NO 20050922 + #ifdef ZTS + #define USING_ZTS 1 +@@ -46,13 +47,13 @@ + #define USING_ZTS 0 + #endif + +-#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS ++#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS + #define STANDARD_MODULE_HEADER \ + STANDARD_MODULE_HEADER_EX, NULL, NULL + #define ZE2_STANDARD_MODULE_HEADER \ + STANDARD_MODULE_HEADER_EX, ini_entries, NULL + +-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 ++#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO + + #define STANDARD_MODULE_PROPERTIES \ + NULL, STANDARD_MODULE_PROPERTIES_EX +@@ -87,6 +88,7 @@ + unsigned char type; + void *handle; + int module_number; ++ unsigned int real_zend_api; + }; + + #define MODULE_DEP_REQUIRED 1 +diff -Nura php-5.1.5/Zend/zend_opcode.c hardening-patch-5.1.5-0.4.15/Zend/zend_opcode.c +--- php-5.1.5/Zend/zend_opcode.c 2006-03-14 12:24:45.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_opcode.c 2006-09-05 20:31:26.000000000 +0200 +@@ -98,6 +98,9 @@ + op_array->uses_this = 0; + + op_array->start_op = NULL; ++#if HARDENING_PATCH ++ op_array->created_by_eval = 0; ++#endif + + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); + } +diff -Nura php-5.1.5/Zend/zend_vm_def.h hardening-patch-5.1.5-0.4.15/Zend/zend_vm_def.h +--- php-5.1.5/Zend/zend_vm_def.h 2006-03-15 12:12:45.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_vm_def.h 2006-09-05 20:31:26.000000000 +0200 +@@ -1769,6 +1769,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (OP2_TYPE != IS_CONST) { +@@ -1994,6 +2025,34 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++#endif ++ + EX(object) = NULL; + + FREE_OP1(); +@@ -2709,7 +2768,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -2734,6 +2798,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +diff -Nura php-5.1.5/Zend/zend_vm_execute.h hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.h +--- php-5.1.5/Zend/zend_vm_execute.h 2006-03-15 12:12:45.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.h 2006-09-05 20:31:26.000000000 +0200 +@@ -56,6 +56,16 @@ + EX(symbol_table) = EG(active_symbol_table); + EX(prev_execute_data) = EG(current_execute_data); + EG(current_execute_data) = &execute_data; ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif + + EG(in_execution) = 1; + if (op_array->start_op) { +@@ -81,6 +91,18 @@ + */ + EX(function_state).function_symbol_table = NULL; + #endif ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif + + while (1) { + #ifdef ZEND_WIN32 +@@ -724,6 +746,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_CONST != IS_CONST) { +@@ -925,6 +978,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_TMP_VAR != IS_CONST) { +@@ -1083,6 +1167,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_VAR != IS_CONST) { +@@ -1330,6 +1445,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_CV != IS_CONST) { +@@ -1635,6 +1781,34 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++#endif ++ + EX(object) = NULL; + + return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +@@ -1914,7 +2088,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -1939,6 +2118,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -4332,7 +4516,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -4357,6 +4546,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -7332,7 +7526,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -7357,6 +7556,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -19429,7 +19633,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -19454,6 +19663,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +diff -Nura php-5.1.5/Zend/zend_vm_execute.skl hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.skl +--- php-5.1.5/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100 ++++ hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.skl 2006-09-05 20:31:26.000000000 +0200 +@@ -27,6 +27,16 @@ + EX(symbol_table) = EG(active_symbol_table); + EX(prev_execute_data) = EG(current_execute_data); + EG(current_execute_data) = &execute_data; ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif + + EG(in_execution) = 1; + if (op_array->start_op) { +@@ -52,6 +62,18 @@ + */ + EX(function_state).function_symbol_table = NULL; + #endif ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif + + while (1) { + {%ZEND_VM_CONTINUE_LABEL%} diff --git a/0.4.15/hardening-patch-5.1.6-0.4.15.patch b/0.4.15/hardening-patch-5.1.6-0.4.15.patch new file mode 100644 index 0000000..dff3280 --- /dev/null +++ b/0.4.15/hardening-patch-5.1.6-0.4.15.patch @@ -0,0 +1,8759 @@ +diff -Nura php-5.1.6/Changelog.hphp hardening-patch-5.1.6-0.4.15/Changelog.hphp +--- php-5.1.6/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Changelog.hphp 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,61 @@ ++Changelog of the Hardening-Patch ++-------------------------------- ++ ++0.4.15 - 07. September 2006 ++ ++ PHP4: ++ [+] Fix for potential DOS in handling of include blacklists ++ ++ PHP4+5: ++ [+] Backported a fix for open_basedir problems with insanse PHP scripts ++ [+] Added a fix for ini_restore() PHP security vulnerability ++ ++0.4.14 - 11. August 2006 ++ ++ PHP4: ++ [+] Remove unecessary call to AC_BROKEN_REALPATH ++ ++ PHP5: ++ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant ++ ++ PHP4+5: ++ [+] Added a few PHP security fixes / see changelog.secfix for details ++ [+] Fixed the memory_limit protection for systems with different perdir memory_limits ++ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments ++ ++0.4.13 - 07. August 2006 ++ ++ PHP4+5: ++ [+] Added a fix for a compile problem on solaris due to missing strcasestr() ++ ++0.4.12 - 19. July 2006 ++ ++ PHP4: ++ [+] Added fixes from sf4 security patch / see changelog.secfix for details ++ ++ PHP5: ++ [+] Added fixes from sf5 security patch / see changelog.secfix for details ++ ++ PHP4+5: ++ [+] Added anti mail spam feature ++ [+] Speedup of zend_hash canary (clear/destroy) ++ [+] Added a fix for a DOS in the handling of URL blacklists ++ ++0.4.11 - 13. May 2006 ++ ++ PHP5: ++ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache ++ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 ++ ++ PHP4+5: ++ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories ++ ++ ++0.4.10 - 11. May 2006 ++ ++ PHP4: ++ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed ++ ++ PHP4+5: ++ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir ++ +diff -Nura php-5.1.6/Changelog.secfix hardening-patch-5.1.6-0.4.15/Changelog.secfix +--- php-5.1.6/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Changelog.secfix 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,40 @@ ++Changelog of PHP 5.1.4 Security Fixes ++ ++Release 6 - 11. August 2006 ++ ++ [+] Added IMAP open_basedir/safe_mode check ++ [+] Added a fix for previous ext/session fixes ++ [+] Added upstream fix to ext/socket ++ [+] Added sscanf() security fix ++ [+] Added fixes for handling of corrupt .gif files to gdlib ++ ++Release 5 - 13. July 2006 ++ ++ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode ++ ++Release 4 - 13. July 2006 ++ ++ [+] Added a recursive array printing fix to the phpinfo() XSS fix ++ [+] Added a fix for stat() on non existing files in safe_mode ++ ++Release 3 - 07. July 2006 ++ ++ [+] Added a fix for an integer overflow in str_repeat() ++ [+] Added a *working* wordwrap() fix ++ [+] Added code to make memory_limit work on 64bit systems ++ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability ++ [+] Added a fix for overlong tempfilename ++ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl ++ [+] Added a high characters fix to ext/wddx ++ ++Release 2 - 16. May 2006 ++ ++ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP ++ tarball got updated ++ ++Release 1 - 13. May 2006 ++ ++ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball ++ and is downloaded when make install is called (usually as root -> security risk) ++ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache ++ +diff -Nura php-5.1.6/configure hardening-patch-5.1.6-0.4.15/configure +--- php-5.1.6/configure 2006-08-23 14:55:02.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/configure 2006-09-07 19:41:16.000000000 +0200 +@@ -942,6 +942,16 @@ + ac_help="$ac_help + --with-libdir=NAME Look for libraries in .../NAME rather than .../lib" + ac_help="$ac_help ++ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." ++ac_help="$ac_help ++ --disable-hardening-patch-ll-protect Disable the Linked List protection." ++ac_help="$ac_help ++ --disable-hardening-patch-inc-protect Disable include/require protection." ++ac_help="$ac_help ++ --disable-hardening-patch-fmt-protect Disable format string protection." ++ac_help="$ac_help ++ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." ++ac_help="$ac_help + + SAPI modules: + " +@@ -1410,6 +1420,8 @@ + ac_help="$ac_help + --enable-wddx Enable WDDX support" + ac_help="$ac_help ++ --disable-varfilter Disable Hardening-Patch's variable filter" ++ac_help="$ac_help + --disable-xml Disable XML support" + ac_help="$ac_help + --with-libxml-dir=DIR XML: libxml2 install prefix" +@@ -3618,6 +3630,157 @@ + + + ++# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. ++if test "${enable_hardening_patch_mm_protect+set}" = set; then ++ enableval="$enable_hardening_patch_mm_protect" ++ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. ++if test "${enable_hardening_patch_ll_protect+set}" = set; then ++ enableval="$enable_hardening_patch_ll_protect" ++ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. ++if test "${enable_hardening_patch_inc_protect+set}" = set; then ++ enableval="$enable_hardening_patch_inc_protect" ++ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. ++if test "${enable_hardening_patch_fmt_protect+set}" = set; then ++ enableval="$enable_hardening_patch_fmt_protect" ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++ ++fi ++ ++ ++# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. ++if test "${enable_hardening_patch_hash_protect+set}" = set; then ++ enableval="$enable_hardening_patch_hash_protect" ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++ ++else ++ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++ ++fi ++ ++ ++echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 ++echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 ++echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 ++echo "configure:2733: checking whether to protect include/require statements" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect PHP Format String functions" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 ++ ++echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 ++echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 ++echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 ++ ++ ++cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH 1 ++EOF ++ ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_MM_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_LL_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_INC_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_FMT_PROTECT 0 ++EOF ++ ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 1 ++EOF ++ ++else ++ cat >> confdefs.h <<\EOF ++#define HARDENING_PATCH_HASH_PROTECT 0 ++EOF ++ ++fi + + + +@@ -18607,6 +18770,62 @@ + fi + + ++ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 ++echo "configure:14928: checking whether realpath is broken" >&5 ++if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then ++ echo $ac_n "(cached) $ac_c" 1>&6 ++else ++ ++ if test "$cross_compiling" = yes; then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null ++then ++ ++ ac_cv_broken_realpath=no ++ ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -fr conftest* ++ ++ ac_cv_broken_realpath=yes ++ ++fi ++rm -fr conftest* ++fi ++ ++ ++fi ++ ++echo "$ac_t""$ac_cv_broken_realpath" 1>&6 ++ if test "$ac_cv_broken_realpath" = "yes"; then ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 1 ++EOF ++ ++ else ++ cat >> confdefs.h <<\EOF ++#define PHP_BROKEN_REALPATH 0 ++EOF ++ ++ fi ++ ++ + echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 + echo "configure:18612: checking for declared timezone" >&5 + if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then +@@ -89422,7 +89641,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + cat >> confdefs.h <&6 ++echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 ++# Check whether --enable-varfilter or --disable-varfilter was given. ++if test "${enable_varfilter+set}" = set; then ++ enableval="$enable_varfilter" ++ PHP_VARFILTER=$enableval ++else ++ ++ PHP_VARFILTER=yes ++ ++ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then ++ PHP_VARFILTER=$PHP_ENABLE_ALL ++ fi ++ ++fi ++ ++ ++ ++ext_output="yes, shared" ++ext_shared=yes ++case $PHP_VARFILTER in ++shared,*) ++ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` ++ ;; ++shared) ++ PHP_VARFILTER=yes ++ ;; ++no) ++ ext_output=no ++ ext_shared=no ++ ;; ++*) ++ ext_output=yes ++ ext_shared=no ++ ;; ++esac ++ ++ ++ ++echo "$ac_t""$ext_output" 1>&6 ++ ++ ++ ++ ++if test "$PHP_VARFILTER" != "no"; then ++ cat >> confdefs.h <<\EOF ++#define HAVE_VARFILTER 1 ++EOF ++ ++ ++ ext_builddir=ext/varfilter ++ ext_srcdir=$abs_srcdir/ext/varfilter ++ ++ ac_extra= ++ ++ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then ++ ++ ++ ++ case ext/varfilter in ++ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; ++ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; ++ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; ++ esac ++ ++ ++ ++ b_c_pre=$php_c_pre ++ b_cxx_pre=$php_cxx_pre ++ b_c_meta=$php_c_meta ++ b_cxx_meta=$php_cxx_meta ++ b_c_post=$php_c_post ++ b_cxx_post=$php_cxx_post ++ b_lo=$php_lo ++ ++ ++ old_IFS=$IFS ++ for ac_src in varfilter.c; do ++ ++ IFS=. ++ set $ac_src ++ ac_obj=$1 ++ IFS=$old_IFS ++ ++ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" ++ ++ case $ac_src in ++ *.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" ;; ++ *.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" ;; ++ esac ++ ++ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 +@@ -112351,7 +112829,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + network.c php_open_temporary_file.c php_logos.c \ +- output.c ; do ++ output.c hardening_patch.c ; do + + IFS=. + set $ac_src +@@ -112596,7 +113074,7 @@ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ + zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ +- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do ++ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do + + IFS=. + set $ac_src +diff -Nura php-5.1.6/configure.in hardening-patch-5.1.6-0.4.15/configure.in +--- php-5.1.6/configure.in 2006-08-23 15:17:36.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/configure.in 2006-09-07 19:41:16.000000000 +0200 +@@ -209,7 +209,7 @@ + + sinclude(Zend/Zend.m4) + sinclude(TSRM/tsrm.m4) +- ++sinclude(main/hardening_patch.m4) + + divert(2) + +@@ -1275,7 +1275,7 @@ + php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ + strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ + network.c php_open_temporary_file.c php_logos.c \ +- output.c ) ++ output.c hardening_patch.c ) + + PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ + plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c) +@@ -1302,7 +1302,7 @@ + zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ + zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ + zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ +- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c) ++ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c ) + + if test -r "$abs_srcdir/Zend/zend_objects.c"; then + PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \ +diff -Nura php-5.1.6/ext/curl/interface.c hardening-patch-5.1.6-0.4.15/ext/curl/interface.c +--- php-5.1.6/ext/curl/interface.c 2006-08-10 19:16:35.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/curl/interface.c 2006-09-07 19:41:16.000000000 +0200 +@@ -172,6 +172,11 @@ + RETURN_FALSE; \ + } \ + \ ++ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ ++ RETURN_FALSE; \ ++ } \ ++ \ + if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ + (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ + ) { \ +diff -Nura php-5.1.6/ext/fbsql/php_fbsql.c hardening-patch-5.1.6-0.4.15/ext/fbsql/php_fbsql.c +--- php-5.1.6/ext/fbsql/php_fbsql.c 2006-08-14 20:40:20.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/fbsql/php_fbsql.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1949,8 +1949,24 @@ + } + else if (fbcmdErrorsFound(md)) + { ++#if HARDENING_PATCH ++ char* query_copy; ++ int i; ++#endif + FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); + char* emg = fbcemdAllErrorMessages(emd); ++#if HARDENING_PATCH ++ query_copy=estrdup(query_copy); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ free(emg); ++ fbcemdRelease(emd); ++ result = 0; ++ zend_bailout(); ++ } ++#endif + if (FB_SQL_G(generateWarnings)) + { + if (emg) +diff -Nura php-5.1.6/ext/imap/php_imap.c hardening-patch-5.1.6-0.4.15/ext/imap/php_imap.c +--- php-5.1.6/ext/imap/php_imap.c 2006-08-11 17:07:13.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/imap/php_imap.c 2006-09-07 19:41:16.000000000 +0200 +@@ -768,6 +768,13 @@ + RETURN_FALSE; + } + ++ /* local filename, need to perform open_basedir and safe_mode checks */ ++ if (Z_STRVAL_PP(mailbox)[0] != '{' && ++ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || ++ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { ++ RETURN_FALSE; ++ } ++ + IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); + IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); + +diff -Nura php-5.1.6/ext/mysql/php_mysql.c hardening-patch-5.1.6-0.4.15/ext/mysql/php_mysql.c +--- php-5.1.6/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/mysql/php_mysql.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1231,6 +1231,8 @@ + { + php_mysql_conn *mysql; + MYSQL_RES *mysql_result; ++ char *copy_query; ++ int i; + + ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); + +@@ -1281,6 +1283,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #else +@@ -1291,6 +1300,13 @@ + php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); + } + } ++ copy_query = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; ++ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); ++ efree(copy_query); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } + RETURN_FALSE; + } + #endif +diff -Nura php-5.1.6/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.6-0.4.15/ext/mysqli/mysqli_nonapi.c +--- php-5.1.6/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/mysqli/mysqli_nonapi.c 2006-09-07 19:41:16.000000000 +0200 +@@ -184,6 +184,17 @@ + if (mysql_real_query(mysql->mysql, query, query_len)) { + char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; + unsigned int s_errno; ++#if HARDENING_PATCH ++ char *query_copy = estrdup(query); ++ int i; ++ ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } ++#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + + /* we have to save error information, cause +@@ -234,6 +245,17 @@ + MYSQLI_DISABLE_MQ; + + if (mysql_real_query(mysql->mysql, query, query_len)) { ++#if HARDENING_PATCH ++ char *query_copy = estrdup(query); ++ int i; ++ ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ zend_bailout(); ++ } ++#endif + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_FALSE; + } +diff -Nura php-5.1.6/ext/pgsql/pgsql.c hardening-patch-5.1.6-0.4.15/ext/pgsql/pgsql.c +--- php-5.1.6/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/pgsql/pgsql.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1152,10 +1152,28 @@ + case PGRES_EMPTY_QUERY: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: +- case PGRES_FATAL_ERROR: +- PHP_PQ_ERROR("Query failed: %s", pgsql); +- PQclear(pgsql_result); +- RETURN_FALSE; ++ case PGRES_FATAL_ERROR: ++ { ++#if HARDENING_PATCH ++ int i; ++ char *query_copy; ++#endif ++ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); ++ PQclear(pgsql_result); ++#if HARDENING_PATCH ++ query_copy = estrdup(Z_STRVAL_PP(query)); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ efree(msgbuf); ++ zend_bailout(); ++ } ++#endif ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); ++ efree(msgbuf); ++ RETURN_FALSE; ++ } + break; + case PGRES_COMMAND_OK: /* successful command that did not return rows */ + default: +diff -Nura php-5.1.6/ext/session/mod_files.c hardening-patch-5.1.6-0.4.15/ext/session/mod_files.c +--- php-5.1.6/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/session/mod_files.c 2006-09-07 19:41:16.000000000 +0200 +@@ -152,6 +152,7 @@ + + if (!ps_files_valid_key(key)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); ++ PS(invalid_session_id) = 1; + return; + } + if (!ps_files_path_create(buf, sizeof(buf), data, key)) +@@ -401,7 +402,12 @@ + ps_files_close(data); + + if (VCWD_UNLINK(buf) == -1) { +- return FAILURE; ++ /* This is a little safety check for instances when we are dealing with a regenerated session ++ * that was not yet written to disk ++ */ ++ if (!VCWD_ACCESS(buf, F_OK)) { ++ return FAILURE; ++ } + } + } + +@@ -422,6 +428,35 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(files) ++{ ++ char buf[MAXPATHLEN]; ++ int fd; ++ PS_FILES_DATA; ++ ++ if (!ps_files_valid_key(key)) { ++ return FAILURE; ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { ++ return FAILURE; ++ } ++ ++ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, ++ data->filemode); ++ ++ if (fd != -1) { ++ close(fd); ++ return SUCCESS; ++ } ++ ++ return FAILURE; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-5.1.6/ext/session/mod_mm.c hardening-patch-5.1.6-0.4.15/ext/session/mod_mm.c +--- php-5.1.6/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/session/mod_mm.c 2006-09-07 19:41:16.000000000 +0200 +@@ -425,6 +425,42 @@ + return SUCCESS; + } + ++PS_VALIDATE_SID_FUNC(mm) ++{ ++ PS_MM_DATA; ++ ps_sd *sd; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ } ++ } ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ mm_lock(data->mm, MM_LOCK_RD); ++ ++ sd = ps_sd_lookup(data, key, 0); ++ if (sd) { ++ mm_unlock(data->mm); ++ return SUCCESS; ++ } ++ ++ mm_unlock(data->mm); ++ ++ return FAILURE; ++} ++ + #endif + + /* +diff -Nura php-5.1.6/ext/session/mod_user.c hardening-patch-5.1.6-0.4.15/ext/session/mod_user.c +--- php-5.1.6/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/session/mod_user.c 2006-09-07 19:41:16.000000000 +0200 +@@ -23,7 +23,7 @@ + #include "mod_user.h" + + ps_module ps_mod_user = { +- PS_MOD(user) ++ PS_MOD_SID(user) + }; + + #define SESS_ZVAL_LONG(val, a) \ +@@ -174,6 +174,83 @@ + FINISH; + } + ++PS_CREATE_SID_FUNC(user) ++{ ++ int i; ++ char *val = NULL; ++ zval *retval; ++ ps_user *mdata = PS_GET_MOD_DATA(); ++ ++ if (!mdata) ++ return estrndup("", 0); ++ ++ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { ++ return php_session_create_id(mod_data, newlen TSRMLS_CC); ++ } ++ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); ++ ++ if (retval) { ++ if (Z_TYPE_P(retval) == IS_STRING) { ++ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); ++ } else { ++ val = estrndup("", 0); ++ } ++ zval_ptr_dtor(&retval); ++ } else { ++ val = estrndup("", 0); ++ } ++ ++ return val; ++} ++ ++static int ps_user_valid_key(const char *key TSRMLS_DC) ++{ ++ size_t len; ++ const char *p; ++ char c; ++ int ret = SUCCESS; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ ret = FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ ret = FAILURE; ++ ++ return ret; ++} ++ ++PS_VALIDATE_SID_FUNC(user) ++{ ++ zval *args[1]; ++ STDVARS; ++ ++ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { ++ return ps_user_valid_key(key TSRMLS_CC); ++ } ++ SESS_ZVAL_STRING(key, args[0]); ++ ++ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); ++ ++ if (retval) { ++ convert_to_long(retval); ++ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; ++ zval_ptr_dtor(&retval); ++ } ++ ++ return ret; ++} ++ + /* + * Local variables: + * tab-width: 4 +diff -Nura php-5.1.6/ext/session/mod_user.h hardening-patch-5.1.6-0.4.15/ext/session/mod_user.h +--- php-5.1.6/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/session/mod_user.h 2006-09-07 19:41:16.000000000 +0200 +@@ -22,7 +22,7 @@ + #define MOD_USER_H + + typedef union { +- zval *names[6]; ++ zval *names[8]; + struct { + zval *ps_open; + zval *ps_close; +@@ -30,6 +30,8 @@ + zval *ps_write; + zval *ps_destroy; + zval *ps_gc; ++ zval *ps_create; ++ zval *ps_validate; + } name; + } ps_user; + +diff -Nura php-5.1.6/ext/session/php_session.h hardening-patch-5.1.6-0.4.15/ext/session/php_session.h +--- php-5.1.6/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/session/php_session.h 2006-09-07 19:41:16.000000000 +0200 +@@ -23,7 +23,7 @@ + + #include "ext/standard/php_var.h" + +-#define PHP_SESSION_API 20020330 ++#define PHP_SESSION_API 20051121 + + #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC + #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC +@@ -32,6 +32,7 @@ + #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC + #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC + #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC ++#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC + + /* default create id function */ + PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); +@@ -45,6 +46,7 @@ + int (*s_destroy)(PS_DESTROY_ARGS); + int (*s_gc)(PS_GC_ARGS); + char *(*s_create_sid)(PS_CREATE_SID_ARGS); ++ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); + } ps_module; + + #define PS_GET_MOD_DATA() *mod_data +@@ -57,6 +59,7 @@ + #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) + #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) + #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) ++#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) + + #define PS_FUNCS(x) \ + PS_OPEN_FUNC(x); \ +@@ -65,11 +68,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID_FUNC(x) + + #define PS_MOD(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, php_session_create_id ++ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x + + /* SID enabled module handler definitions */ + #define PS_FUNCS_SID(x) \ +@@ -79,11 +83,12 @@ + PS_WRITE_FUNC(x); \ + PS_DESTROY_FUNC(x); \ + PS_GC_FUNC(x); \ +- PS_CREATE_SID_FUNC(x) ++ PS_CREATE_SID_FUNC(x); \ ++ PS_VALIDATE_SID(x) + + #define PS_MOD_SID(x) \ + #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ +- ps_delete_##x, ps_gc_##x, ps_create_sid_##x ++ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x + + typedef enum { + php_session_disabled, +@@ -120,11 +125,13 @@ + zend_bool use_only_cookies; + zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ ++ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + + long hash_func; + long hash_bits_per_character; + int send_cookie; + int define_sid; ++ zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ + } php_ps_globals; + + typedef php_ps_globals zend_ps_globals; +diff -Nura php-5.1.6/ext/session/session.c hardening-patch-5.1.6-0.4.15/ext/session/session.c +--- php-5.1.6/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/session/session.c 2006-09-07 19:41:16.000000000 +0200 +@@ -166,6 +166,7 @@ + STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) ++ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals) +@@ -280,9 +281,13 @@ + PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) + { + zval **sym_track = NULL; +- +- zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, +- (void *) &sym_track); ++ ++ IF_SESSION_VARS() { ++ zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, ++ (void *) &sym_track); ++ } else { ++ return; ++ } + + /* + * Set up a proper reference between $_SESSION["x"] and $x. +@@ -758,9 +763,23 @@ + return; + } + ++ /* If there is an ID, use session module to verify it */ ++ if (PS(id)) { ++ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { ++ efree(PS(id)); ++ PS(id) = NULL; ++ PS(send_cookie) = 1; ++ } ++ } ++ + /* If there is no ID, use session module to create one */ +- if (!PS(id)) ++ if (!PS(id)) { ++new_session: + PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); ++ if (PS(use_cookies)) { ++ PS(send_cookie) = 1; ++ } ++ } + + /* Read data */ + /* Question: if you create a SID here, should you also try to read data? +@@ -769,9 +788,14 @@ + * session information + */ + php_session_track_init(TSRMLS_C); ++ PS(invalid_session_id) = 0; + if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) { + php_session_decode(val, vallen TSRMLS_CC); + efree(val); ++ } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */ ++ PS(invalid_session_id) = 0; ++ efree(PS(id)); ++ goto new_session; + } + } + +@@ -1377,22 +1401,29 @@ + } + /* }}} */ + +-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) ++/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) + Sets user-level functions */ + PHP_FUNCTION(session_set_save_handler) + { +- zval **args[6]; +- int i; ++ zval **args[8]; ++ int i, numargs; + ps_user *mdata; + char *name; + +- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) ++ numargs = ZEND_NUM_ARGS(); ++ args[6] = NULL; ++ args[7] = NULL; ++ ++ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) + WRONG_PARAM_COUNT; + + if (PS(session_status) != php_session_none) + RETURN_FALSE; + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ continue; ++ } + if (!zend_is_callable(*args[i], 0, &name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); + efree(name); +@@ -1405,7 +1436,11 @@ + + mdata = emalloc(sizeof(*mdata)); + +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 8; i++) { ++ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { ++ mdata->names[i] = NULL; ++ continue; ++ } + ZVAL_ADDREF(*args[i]); + mdata->names[i] = *args[i]; + } +@@ -1475,6 +1510,11 @@ + WRONG_PARAM_COUNT; + } + ++ if (SG(headers_sent)) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); ++ RETURN_FALSE; ++ } ++ + if (PS(session_status) == php_session_active) { + if (PS(id)) { + if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { +@@ -1531,8 +1571,8 @@ + WRONG_PARAM_COUNT; + + if (ac == 1) { +- convert_to_long_ex(p_cache_expire); +- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); ++ convert_to_string_ex(p_cache_expire); ++ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + } + + RETVAL_LONG(old); +diff -Nura php-5.1.6/ext/session/tests/014.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/014.phpt +--- php-5.1.6/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/session/tests/014.phpt 2006-09-07 19:41:16.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.bug_compat_42=1 +diff -Nura php-5.1.6/ext/session/tests/015.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/015.phpt +--- php-5.1.6/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/session/tests/015.phpt 2006-09-07 19:41:16.000000000 +0200 +@@ -5,6 +5,7 @@ + --INI-- + session.use_trans_sid=1 + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + arg_separator.output=& + session.name=PHPSESSID +diff -Nura php-5.1.6/ext/session/tests/018.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/018.phpt +--- php-5.1.6/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/session/tests/018.phpt 2006-09-07 19:41:16.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + session.name=PHPSESSID +diff -Nura php-5.1.6/ext/session/tests/019.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/019.phpt +--- php-5.1.6/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/session/tests/019.phpt 2006-09-07 19:41:16.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + register_globals=1 + session.serialize_handler=php +diff -Nura php-5.1.6/ext/session/tests/020.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/020.phpt +--- php-5.1.6/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/session/tests/020.phpt 2006-09-07 19:41:16.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + arg_separator.output=& +diff -Nura php-5.1.6/ext/session/tests/021.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/021.phpt +--- php-5.1.6/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/session/tests/021.phpt 2006-09-07 19:41:16.000000000 +0200 +@@ -4,6 +4,7 @@ + + --INI-- + session.use_cookies=0 ++session.use_strict_mode=0 + session.cache_limiter= + session.use_trans_sid=1 + url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" +diff -Nura php-5.1.6/ext/session/tests/bug38377.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/bug38377.phpt +--- php-5.1.6/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/session/tests/bug38377.phpt 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,13 @@ ++--TEST-- ++bug #38377 (session_destroy() gives warning after session_regenerate_id()) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECT-- ++Done +diff -Nura php-5.1.6/ext/sockets/sockets.c hardening-patch-5.1.6-0.4.15/ext/sockets/sockets.c +--- php-5.1.6/ext/sockets/sockets.c 2006-04-07 16:04:36.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/sockets/sockets.c 2006-09-07 19:41:16.000000000 +0200 +@@ -533,6 +533,7 @@ + { + zval **element; + php_socket *php_sock; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -547,9 +548,10 @@ + if (php_sock->bsd_socket > *max_fd) { + *max_fd = php_sock->bsd_socket; + } ++ num++; + } + +- return 1; ++ return num ? 1 : 0; + } + + static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) +@@ -558,6 +560,7 @@ + zval **dest_element; + php_socket *php_sock; + HashTable *new_hash; ++ int num = 0; + + if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; + +@@ -575,6 +578,7 @@ + zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); + if (dest_element) zval_add_ref(dest_element); + } ++ num++; + } + + /* Destroy old array, add new one */ +@@ -584,7 +588,7 @@ + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(sock_array) = new_hash; + +- return 1; ++ return num ? 1 : 0; + } + + /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds, int tv_sec[, int tv_usec]) +diff -Nura php-5.1.6/ext/sqlite/sess_sqlite.c hardening-patch-5.1.6-0.4.15/ext/sqlite/sess_sqlite.c +--- php-5.1.6/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/sqlite/sess_sqlite.c 2006-09-07 19:41:16.000000000 +0200 +@@ -185,6 +185,76 @@ + return SQLITE_RETVAL(rv); + } + ++PS_VALIDATE_SID_FUNC(sqlite) ++{ ++ PS_SQLITE_DATA; ++ char *query; ++ const char *tail; ++ sqlite_vm *vm; ++ int colcount, result; ++ const char **rowdata, **colnames; ++ char *error; ++ size_t len; ++ const char *p; ++ char c; ++ int ret = FAILURE; ++ ++ for (p = key; (c = *p); p++) { ++ /* valid characters are a..z,A..Z,0..9 */ ++ if (!((c >= 'a' && c <= 'z') ++ || (c >= 'A' && c <= 'Z') ++ || (c >= '0' && c <= '9') ++ || c == ',' ++ || c == '-')) { ++ return FAILURE; ++ break; ++ } ++ } ++ ++ len = p - key; ++ ++ if (len == 0) ++ return FAILURE; ++ ++ if (!PS(use_strict_mode)) { ++ return SUCCESS; ++ } ++ ++ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key); ++ if (query == NULL) { ++ /* no memory */ ++ return FAILURE; ++ } ++ ++ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error); ++ sqlite_freemem(error); ++ sqlite_freemem(query); ++ return FAILURE; ++ } ++ ++ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) { ++ case SQLITE_ROW: ++ if (rowdata[0] != NULL) { ++ ret = SUCCESS; ++ } ++ break; ++ default: ++ sqlite_freemem(error); ++ error = NULL; ++ } ++ ++ if (SQLITE_OK != sqlite_finalize(vm, &error)) { ++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error); ++ sqlite_freemem(error); ++ error = NULL; ++ } ++ ++ sqlite_freemem(query); ++ ++ return ret; ++} ++ + #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */ + + /* +diff -Nura php-5.1.6/ext/sqlite/sqlite.c hardening-patch-5.1.6-0.4.15/ext/sqlite/sqlite.c +--- php-5.1.6/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/sqlite/sqlite.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1530,6 +1530,19 @@ + db->last_err_code = ret; + + if (ret != SQLITE_OK) { ++#if HARDENING_PATCH ++ char *query_copy; ++ int i; ++ ++ query_copy = estrdup(sql); ++ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; ++ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy); ++ efree(query_copy); ++ if (HG(hphp_sql_bailout_on_error)) { ++ sqlite_freemem(errtext); ++ zend_bailout(); ++ } ++#endif + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext); + if (errmsg) { + ZVAL_STRING(errmsg, errtext, 1); +diff -Nura php-5.1.6/ext/standard/array.c hardening-patch-5.1.6-0.4.15/ext/standard/array.c +--- php-5.1.6/ext/standard/array.c 2006-06-03 20:59:55.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/array.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1297,6 +1297,32 @@ + } + } + } ++ ++ if (var_name[0] == 'H') { ++ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_VARS")==0)|| ++ (strcmp(var_name, "HTTP_POST_FILES")==0)|| ++ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { ++ return 0; ++ } ++ } else if (var_name[0] == '_') { ++ if ((strcmp(var_name, "_COOKIE")==0)|| ++ (strcmp(var_name, "_ENV")==0)|| ++ (strcmp(var_name, "_FILES")==0)|| ++ (strcmp(var_name, "_GET")==0)|| ++ (strcmp(var_name, "_POST")==0)|| ++ (strcmp(var_name, "_REQUEST")==0)|| ++ (strcmp(var_name, "_SESSION")==0)|| ++ (strcmp(var_name, "_SERVER")==0)) { ++ return 0; ++ } ++ } else if (strcmp(var_name, "GLOBALS")==0) { ++ return 0; ++ } + + return 1; + } +diff -Nura php-5.1.6/ext/standard/basic_functions.c hardening-patch-5.1.6-0.4.15/ext/standard/basic_functions.c +--- php-5.1.6/ext/standard/basic_functions.c 2006-06-29 00:08:59.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:41:16.000000000 +0200 +@@ -151,12 +151,14 @@ + typedef struct _php_shutdown_function_entry { + zval **arguments; + int arg_count; ++ zend_bool created_by_eval; + } php_shutdown_function_entry; + + typedef struct _user_tick_function_entry { + zval **arguments; + int arg_count; + int calling; ++ zend_bool created_by_eval; + } user_tick_function_entry; + + /* some prototypes for local functions */ +@@ -188,6 +190,8 @@ + PHP_FE(get_html_translation_table, NULL) + PHP_FE(sha1, NULL) + PHP_FE(sha1_file, NULL) ++ PHP_FE(sha256, NULL) ++ PHP_FE(sha256_file, NULL) + PHP_NAMED_FE(md5,php_if_md5, NULL) + PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) + PHP_NAMED_FE(crc32,php_if_crc32, NULL) +@@ -632,7 +636,7 @@ + PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) + + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +- PHP_FE(realpath, NULL) ++ PHP_STATIC_FE("realpath", zif_real_path, NULL) + #endif + + #ifdef HAVE_FNMATCH +@@ -2279,6 +2283,13 @@ + { + zval retval; + char *function_name = NULL; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (shutdown_function_entry->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { + php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); +@@ -2294,6 +2305,9 @@ + if (function_name) { + efree(function_name); + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + return 0; + } + +@@ -2301,6 +2315,13 @@ + { + zval retval; + zval *function = tick_fe->arguments[0]; ++#if HARDENING_PATCH ++ zend_uint orig_code_type = EG(in_code_type); ++ ++ if (tick_fe->created_by_eval) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } ++#endif + + /* Prevent reentrant calls to the same user ticks function */ + if (! tick_fe->calling) { +@@ -2332,6 +2353,9 @@ + + tick_fe->calling = 0; + } ++#if HARDENING_PATCH ++ EG(in_code_type) = orig_code_type; ++#endif + } + + static void run_user_tick_functions(int tick_count) +@@ -2395,6 +2419,13 @@ + } + + shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ shutdown_function_entry.created_by_eval = 1; ++ } else { ++ shutdown_function_entry.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { + efree(shutdown_function_entry.arguments); +@@ -2722,6 +2753,15 @@ + + convert_to_string_ex(varname); + ++ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ ++ if (PG(safe_mode)) { ++ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || ++ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || ++ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { ++ RETURN_FALSE; ++ } ++ } ++ + zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); + } + /* }}} */ +@@ -2979,6 +3019,13 @@ + } + + tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ tick_fe.created_by_eval = 1; ++ } else { ++ tick_fe.created_by_eval = 0; ++ } ++#endif + + if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { + efree(tick_fe.arguments); +@@ -3282,6 +3329,35 @@ + new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); + } + ++ if (new_key[0] == 'H') { ++ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_VARS")==0)|| ++ (strcmp(new_key, "HTTP_POST_FILES")==0)|| ++ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| ++ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| ++ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| ++ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (new_key[0] == '_') { ++ if ((strcmp(new_key, "_COOKIE")==0)|| ++ (strcmp(new_key, "_ENV")==0)|| ++ (strcmp(new_key, "_FILES")==0)|| ++ (strcmp(new_key, "_GET")==0)|| ++ (strcmp(new_key, "_POST")==0)|| ++ (strcmp(new_key, "_REQUEST")==0)|| ++ (strcmp(new_key, "_SESSION")==0)|| ++ (strcmp(new_key, "_SERVER")==0)) { ++ efree(new_key); ++ return 0; ++ } ++ } else if (strcmp(new_key, "GLOBALS")==0) { ++ efree(new_key); ++ return 0; ++ } ++ + zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); + ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); + +diff -Nura php-5.1.6/ext/standard/config.m4 hardening-patch-5.1.6-0.4.15/ext/standard/config.m4 +--- php-5.1.6/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/config.m4 2006-09-07 19:41:16.000000000 +0200 +@@ -203,7 +203,7 @@ + if test "$ac_cv_crypt_blowfish" = "yes"; then + ac_result=1 + else +- ac_result=0 ++ ac_result=1 + fi + AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) + ]) +@@ -489,7 +489,7 @@ + incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ + http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ + var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ +- filters.c proc_open.c streamsfuncs.c http.c) ++ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ) + + PHP_ADD_MAKEFILE_FRAGMENT + +diff -Nura php-5.1.6/ext/standard/config.w32 hardening-patch-5.1.6-0.4.15/ext/standard/config.w32 +--- php-5.1.6/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/config.w32 2006-09-07 19:41:16.000000000 +0200 +@@ -16,5 +16,5 @@ + url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ + php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ + user_filters.c uuencode.c filters.c proc_open.c \ +- streamsfuncs.c http.c", false /* never shared */); ++ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */); + +diff -Nura php-5.1.6/ext/standard/crypt_blowfish.c hardening-patch-5.1.6-0.4.15/ext/standard/crypt_blowfish.c +--- php-5.1.6/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/crypt_blowfish.c 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,748 @@ ++/* ++ * This code comes from John the Ripper password cracker, with reentrant ++ * and crypt(3) interfaces added, but optimizations specific to password ++ * cracking removed. ++ * ++ * Written by Solar Designer in 1998-2002 and ++ * placed in the public domain. ++ * ++ * There's absolutely no warranty. ++ * ++ * It is my intent that you should be able to use this on your system, ++ * as a part of a software package, or anywhere else to improve security, ++ * ensure compatibility, or for any other purpose. I would appreciate ++ * it if you give credit where it is due and keep your modifications in ++ * the public domain as well, but I don't require that in order to let ++ * you place this code and any modifications you make under a license ++ * of your choice. ++ * ++ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) ++ * by Niels Provos , and uses some of his ++ * ideas. The password hashing algorithm was designed by David Mazieres ++ * . ++ * ++ * There's a paper on the algorithm that explains its design decisions: ++ * ++ * http://www.usenix.org/events/usenix99/provos.html ++ * ++ * Some of the tricks in BF_ROUND might be inspired by Eric Young's ++ * Blowfish library (I can't be sure if I would think of something if I ++ * hadn't seen his code). ++ */ ++ ++#include ++ ++#include ++#ifndef __set_errno ++#define __set_errno(val) errno = (val) ++#endif ++ ++#undef __CONST ++#ifdef __GNUC__ ++#define __CONST __const ++#else ++#define __CONST ++#endif ++ ++#ifdef __i386__ ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#elif defined(__alpha__) || defined(__hppa__) ++#define BF_ASM 0 ++#define BF_SCALE 1 ++#else ++#define BF_ASM 0 ++#define BF_SCALE 0 ++#endif ++ ++typedef unsigned int BF_word; ++ ++/* Number of Blowfish rounds, this is also hardcoded into a few places */ ++#define BF_N 16 ++ ++typedef BF_word BF_key[BF_N + 2]; ++ ++typedef struct { ++ BF_word S[4][0x100]; ++ BF_key P; ++} BF_ctx; ++ ++/* ++ * Magic IV for 64 Blowfish encryptions that we do at the end. ++ * The string is "OrpheanBeholderScryDoubt" on big-endian. ++ */ ++static BF_word BF_magic_w[6] = { ++ 0x4F727068, 0x65616E42, 0x65686F6C, ++ 0x64657253, 0x63727944, 0x6F756274 ++}; ++ ++/* ++ * P-box and S-box tables initialized with digits of Pi. ++ */ ++static BF_ctx BF_init_state = { ++ { ++ { ++ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, ++ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, ++ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, ++ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, ++ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, ++ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, ++ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, ++ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, ++ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, ++ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, ++ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, ++ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, ++ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, ++ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, ++ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, ++ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, ++ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, ++ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, ++ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, ++ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, ++ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, ++ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, ++ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, ++ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, ++ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, ++ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, ++ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, ++ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, ++ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, ++ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, ++ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, ++ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, ++ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, ++ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, ++ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, ++ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, ++ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, ++ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, ++ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, ++ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, ++ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, ++ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, ++ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, ++ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, ++ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, ++ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, ++ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, ++ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, ++ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, ++ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, ++ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, ++ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, ++ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, ++ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, ++ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, ++ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, ++ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, ++ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, ++ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, ++ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, ++ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, ++ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, ++ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, ++ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a ++ }, { ++ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, ++ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, ++ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, ++ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, ++ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, ++ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, ++ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, ++ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, ++ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, ++ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, ++ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, ++ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, ++ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, ++ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, ++ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, ++ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, ++ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, ++ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, ++ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, ++ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, ++ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, ++ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, ++ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, ++ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, ++ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, ++ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, ++ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, ++ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, ++ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, ++ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, ++ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, ++ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, ++ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, ++ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, ++ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, ++ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, ++ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, ++ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, ++ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, ++ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, ++ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, ++ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, ++ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, ++ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, ++ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, ++ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, ++ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, ++ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, ++ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, ++ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, ++ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, ++ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, ++ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, ++ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, ++ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, ++ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, ++ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, ++ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, ++ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, ++ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, ++ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, ++ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, ++ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, ++ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 ++ }, { ++ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, ++ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, ++ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, ++ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, ++ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, ++ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, ++ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, ++ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, ++ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, ++ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, ++ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, ++ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, ++ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, ++ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, ++ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, ++ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, ++ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, ++ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, ++ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, ++ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, ++ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, ++ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, ++ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, ++ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, ++ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, ++ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, ++ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, ++ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, ++ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, ++ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, ++ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, ++ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, ++ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, ++ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, ++ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, ++ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, ++ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, ++ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, ++ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, ++ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, ++ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, ++ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, ++ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, ++ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, ++ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, ++ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, ++ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, ++ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, ++ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, ++ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, ++ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, ++ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, ++ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, ++ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, ++ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, ++ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, ++ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, ++ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, ++ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, ++ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, ++ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, ++ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, ++ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, ++ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 ++ }, { ++ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, ++ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, ++ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, ++ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, ++ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, ++ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, ++ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, ++ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, ++ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, ++ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, ++ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, ++ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, ++ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, ++ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, ++ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, ++ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, ++ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, ++ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, ++ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, ++ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, ++ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, ++ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, ++ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, ++ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, ++ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, ++ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, ++ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, ++ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, ++ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, ++ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, ++ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, ++ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, ++ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, ++ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, ++ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, ++ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, ++ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, ++ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, ++ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, ++ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, ++ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, ++ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, ++ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, ++ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, ++ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, ++ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, ++ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, ++ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, ++ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, ++ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, ++ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, ++ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, ++ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, ++ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, ++ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, ++ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, ++ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, ++ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, ++ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, ++ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, ++ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, ++ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, ++ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, ++ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 ++ } ++ }, { ++ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, ++ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, ++ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, ++ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, ++ 0x9216d5d9, 0x8979fb1b ++ } ++}; ++ ++static unsigned char BF_itoa64[64 + 1] = ++ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ++ ++static unsigned char BF_atoi64[0x60] = { ++ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, ++ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, ++ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ++ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, ++ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, ++ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 ++}; ++ ++/* ++ * This may be optimized out if built with function inlining and no BF_ASM. ++ */ ++static void clean(void *data, int size) ++{ ++#if BF_ASM ++ extern void _BF_clean(void *data); ++#endif ++ memset(data, 0, size); ++#if BF_ASM ++ _BF_clean(data); ++#endif ++} ++ ++#define BF_safe_atoi64(dst, src) \ ++{ \ ++ tmp = (unsigned char)(src); \ ++ if (tmp == '$') break; \ ++ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ ++ tmp = BF_atoi64[tmp]; \ ++ if (tmp > 63) return -1; \ ++ (dst) = tmp; \ ++} ++ ++static int BF_decode(BF_word *dst, __CONST char *src, int size) ++{ ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned char *end = dptr + size; ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned int tmp, c1, c2, c3, c4; ++ ++ do { ++ BF_safe_atoi64(c1, *sptr++); ++ BF_safe_atoi64(c2, *sptr++); ++ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c3, *sptr++); ++ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); ++ if (dptr >= end) break; ++ ++ BF_safe_atoi64(c4, *sptr++); ++ *dptr++ = ((c3 & 0x03) << 6) | c4; ++ } while (dptr < end); ++ ++ while (dptr < end) ++ *dptr++ = 0; ++ ++ return 0; ++} ++ ++static void BF_encode(char *dst, __CONST BF_word *src, int size) ++{ ++ unsigned char *sptr = (unsigned char *)src; ++ unsigned char *end = sptr + size; ++ unsigned char *dptr = (unsigned char *)dst; ++ unsigned int c1, c2; ++ ++ do { ++ c1 = *sptr++; ++ *dptr++ = BF_itoa64[c1 >> 2]; ++ c1 = (c1 & 0x03) << 4; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 4; ++ *dptr++ = BF_itoa64[c1]; ++ c1 = (c2 & 0x0f) << 2; ++ if (sptr >= end) { ++ *dptr++ = BF_itoa64[c1]; ++ break; ++ } ++ ++ c2 = *sptr++; ++ c1 |= c2 >> 6; ++ *dptr++ = BF_itoa64[c1]; ++ *dptr++ = BF_itoa64[c2 & 0x3f]; ++ } while (sptr < end); ++} ++ ++static void BF_swap(BF_word *x, int count) ++{ ++ static int endianness_check = 1; ++ char *is_little_endian = (char *)&endianness_check; ++ BF_word tmp; ++ ++ if (*is_little_endian) ++ do { ++ tmp = *x; ++ tmp = (tmp << 16) | (tmp >> 16); ++ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); ++ } while (--count); ++} ++ ++#if BF_SCALE ++/* Architectures which can shift addresses left by 2 bits with no extra cost */ ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp2 = L >> 8; \ ++ tmp2 &= 0xFF; \ ++ tmp3 = L >> 16; \ ++ tmp3 &= 0xFF; \ ++ tmp4 = L >> 24; \ ++ tmp1 = data.ctx.S[3][tmp1]; \ ++ tmp2 = data.ctx.S[2][tmp2]; \ ++ tmp3 = data.ctx.S[1][tmp3]; \ ++ tmp3 += data.ctx.S[0][tmp4]; \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#else ++/* Architectures with no complicated addressing modes supported */ ++#define BF_INDEX(S, i) \ ++ (*((BF_word *)(((unsigned char *)S) + (i)))) ++#define BF_ROUND(L, R, N) \ ++ tmp1 = L & 0xFF; \ ++ tmp1 <<= 2; \ ++ tmp2 = L >> 6; \ ++ tmp2 &= 0x3FC; \ ++ tmp3 = L >> 14; \ ++ tmp3 &= 0x3FC; \ ++ tmp4 = L >> 22; \ ++ tmp4 &= 0x3FC; \ ++ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ ++ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ ++ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ ++ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ ++ tmp3 ^= tmp2; \ ++ R ^= data.ctx.P[N + 1]; \ ++ tmp3 += tmp1; \ ++ R ^= tmp3; ++#endif ++ ++/* ++ * Encrypt one block, BF_N is hardcoded here. ++ */ ++#define BF_ENCRYPT \ ++ L ^= data.ctx.P[0]; \ ++ BF_ROUND(L, R, 0); \ ++ BF_ROUND(R, L, 1); \ ++ BF_ROUND(L, R, 2); \ ++ BF_ROUND(R, L, 3); \ ++ BF_ROUND(L, R, 4); \ ++ BF_ROUND(R, L, 5); \ ++ BF_ROUND(L, R, 6); \ ++ BF_ROUND(R, L, 7); \ ++ BF_ROUND(L, R, 8); \ ++ BF_ROUND(R, L, 9); \ ++ BF_ROUND(L, R, 10); \ ++ BF_ROUND(R, L, 11); \ ++ BF_ROUND(L, R, 12); \ ++ BF_ROUND(R, L, 13); \ ++ BF_ROUND(L, R, 14); \ ++ BF_ROUND(R, L, 15); \ ++ tmp4 = R; \ ++ R = L; \ ++ L = tmp4 ^ data.ctx.P[BF_N + 1]; ++ ++#if BF_ASM ++#define BF_body() \ ++ _BF_body_r(&data.ctx); ++#else ++#define BF_body() \ ++ L = R = 0; \ ++ ptr = data.ctx.P; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.P[BF_N + 2]); \ ++\ ++ ptr = data.ctx.S[0]; \ ++ do { \ ++ ptr += 2; \ ++ BF_ENCRYPT; \ ++ *(ptr - 2) = L; \ ++ *(ptr - 1) = R; \ ++ } while (ptr < &data.ctx.S[3][0xFF]); ++#endif ++ ++static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) ++{ ++ __CONST char *ptr = key; ++ int i, j; ++ BF_word tmp; ++ ++ for (i = 0; i < BF_N + 2; i++) { ++ tmp = 0; ++ for (j = 0; j < 4; j++) { ++ tmp <<= 8; ++ tmp |= *ptr; ++ ++ if (!*ptr) ptr = key; else ptr++; ++ } ++ ++ expanded[i] = tmp; ++ initial[i] = BF_init_state.P[i] ^ tmp; ++ } ++} ++ ++char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, ++ char *output, int size) ++{ ++#if BF_ASM ++ extern void _BF_body_r(BF_ctx *ctx); ++#endif ++ struct { ++ BF_ctx ctx; ++ BF_key expanded_key; ++ union { ++ BF_word salt[4]; ++ BF_word output[6]; ++ } binary; ++ } data; ++ BF_word L, R; ++ BF_word tmp1, tmp2, tmp3, tmp4; ++ BF_word *ptr; ++ BF_word count; ++ int i; ++ ++ if (size < 7 + 22 + 31 + 1) { ++ __set_errno(ERANGE); ++ return NULL; ++ } ++ ++ if (setting[0] != '$' || ++ setting[1] != '2' || ++ setting[2] != 'a' || ++ setting[3] != '$' || ++ setting[4] < '0' || setting[4] > '3' || ++ setting[5] < '0' || setting[5] > '9' || ++ setting[6] != '$') { ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); ++ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { ++ clean(data.binary.salt, sizeof(data.binary.salt)); ++ __set_errno(EINVAL); ++ return NULL; ++ } ++ ++ BF_swap(data.binary.salt, 4); ++ ++ BF_set_key(key, data.expanded_key, data.ctx.P); ++ ++ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); ++ ++ L = R = 0; ++ for (i = 0; i < BF_N + 2; i += 2) { ++ L ^= data.binary.salt[i & 2]; ++ R ^= data.binary.salt[(i & 2) + 1]; ++ BF_ENCRYPT; ++ data.ctx.P[i] = L; ++ data.ctx.P[i + 1] = R; ++ } ++ ++ ptr = data.ctx.S[0]; ++ do { ++ ptr += 4; ++ L ^= data.binary.salt[(BF_N + 2) & 3]; ++ R ^= data.binary.salt[(BF_N + 3) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 4) = L; ++ *(ptr - 3) = R; ++ ++ L ^= data.binary.salt[(BF_N + 4) & 3]; ++ R ^= data.binary.salt[(BF_N + 5) & 3]; ++ BF_ENCRYPT; ++ *(ptr - 2) = L; ++ *(ptr - 1) = R; ++ } while (ptr < &data.ctx.S[3][0xFF]); ++ ++ do { ++ data.ctx.P[0] ^= data.expanded_key[0]; ++ data.ctx.P[1] ^= data.expanded_key[1]; ++ data.ctx.P[2] ^= data.expanded_key[2]; ++ data.ctx.P[3] ^= data.expanded_key[3]; ++ data.ctx.P[4] ^= data.expanded_key[4]; ++ data.ctx.P[5] ^= data.expanded_key[5]; ++ data.ctx.P[6] ^= data.expanded_key[6]; ++ data.ctx.P[7] ^= data.expanded_key[7]; ++ data.ctx.P[8] ^= data.expanded_key[8]; ++ data.ctx.P[9] ^= data.expanded_key[9]; ++ data.ctx.P[10] ^= data.expanded_key[10]; ++ data.ctx.P[11] ^= data.expanded_key[11]; ++ data.ctx.P[12] ^= data.expanded_key[12]; ++ data.ctx.P[13] ^= data.expanded_key[13]; ++ data.ctx.P[14] ^= data.expanded_key[14]; ++ data.ctx.P[15] ^= data.expanded_key[15]; ++ data.ctx.P[16] ^= data.expanded_key[16]; ++ data.ctx.P[17] ^= data.expanded_key[17]; ++ ++ BF_body(); ++ ++ tmp1 = data.binary.salt[0]; ++ tmp2 = data.binary.salt[1]; ++ tmp3 = data.binary.salt[2]; ++ tmp4 = data.binary.salt[3]; ++ data.ctx.P[0] ^= tmp1; ++ data.ctx.P[1] ^= tmp2; ++ data.ctx.P[2] ^= tmp3; ++ data.ctx.P[3] ^= tmp4; ++ data.ctx.P[4] ^= tmp1; ++ data.ctx.P[5] ^= tmp2; ++ data.ctx.P[6] ^= tmp3; ++ data.ctx.P[7] ^= tmp4; ++ data.ctx.P[8] ^= tmp1; ++ data.ctx.P[9] ^= tmp2; ++ data.ctx.P[10] ^= tmp3; ++ data.ctx.P[11] ^= tmp4; ++ data.ctx.P[12] ^= tmp1; ++ data.ctx.P[13] ^= tmp2; ++ data.ctx.P[14] ^= tmp3; ++ data.ctx.P[15] ^= tmp4; ++ data.ctx.P[16] ^= tmp1; ++ data.ctx.P[17] ^= tmp2; ++ ++ BF_body(); ++ } while (--count); ++ ++ for (i = 0; i < 6; i += 2) { ++ L = BF_magic_w[i]; ++ R = BF_magic_w[i + 1]; ++ ++ count = 64; ++ do { ++ BF_ENCRYPT; ++ } while (--count); ++ ++ data.binary.output[i] = L; ++ data.binary.output[i + 1] = R; ++ } ++ ++ memcpy(output, setting, 7 + 22 - 1); ++ output[7 + 22 - 1] = BF_itoa64[(int) ++ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; ++ ++/* This has to be bug-compatible with the original implementation, so ++ * only encode 23 of the 24 bytes. :-) */ ++ BF_swap(data.binary.output, 6); ++ BF_encode(&output[7 + 22], data.binary.output, 23); ++ output[7 + 22 + 31] = '\0'; ++ ++/* Overwrite the most obvious sensitive data we have on the stack. Note ++ * that this does not guarantee there's no sensitive data left on the ++ * stack and/or in registers; I'm not aware of portable code that does. */ ++ clean(&data, sizeof(data)); ++ ++ return output; ++} ++ ++char *_crypt_gensalt_blowfish_rn(unsigned long count, ++ __CONST char *input, int size, char *output, int output_size) ++{ ++ if (size < 16 || output_size < 7 + 22 + 1 || ++ (count && (count < 4 || count > 31))) { ++ if (output_size > 0) output[0] = '\0'; ++ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); ++ return NULL; ++ } ++ ++ if (!count) count = 5; ++ ++ output[0] = '$'; ++ output[1] = '2'; ++ output[2] = 'a'; ++ output[3] = '$'; ++ output[4] = '0' + count / 10; ++ output[5] = '0' + count % 10; ++ output[6] = '$'; ++ ++ BF_encode(&output[7], (BF_word *)input, 16); ++ output[7 + 22] = '\0'; ++ ++ return output; ++} +diff -Nura php-5.1.6/ext/standard/crypt.c hardening-patch-5.1.6-0.4.15/ext/standard/crypt.c +--- php-5.1.6/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/crypt.c 2006-09-07 19:41:16.000000000 +0200 +@@ -100,6 +100,8 @@ + return SUCCESS; + } + ++char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); ++char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); + + static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +@@ -135,7 +137,14 @@ + + /* The automatic salt generation only covers standard DES and md5-crypt */ + if(!*salt) { +-#if PHP_MD5_CRYPT ++#if PHP_BLOWFISH_CRYPT ++ char randat[16]; ++ int i; ++ ++ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; ++ ++ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); ++#elif PHP_MD5_CRYPT + strcpy(salt, "$1$"); + php_to64(&salt[3], PHP_CRYPT_RAND, 4); + php_to64(&salt[7], PHP_CRYPT_RAND, 4); +@@ -145,8 +154,24 @@ + salt[2] = '\0'; + #endif + } +- +- RETVAL_STRING(crypt(str, salt), 1); ++ ++ if (salt[0] == '$' && ++ salt[1] == '2' && ++ salt[2] == 'a' && ++ salt[3] == '$' && ++ salt[4] >= '0' && salt[4] <= '3' && ++ salt[5] >= '0' && salt[5] <= '9' && ++ salt[6] == '$') { ++ ++ char output[PHP_MAX_SALT_LEN+1]; ++ ++ output[0] = 0; ++ _crypt_blowfish_rn(str, salt, output, sizeof(output)); ++ RETVAL_STRING(output, 1); ++ ++ } else { ++ RETVAL_STRING(crypt(str, salt), 1); ++ } + } + /* }}} */ + #endif +diff -Nura php-5.1.6/ext/standard/dl.c hardening-patch-5.1.6-0.4.15/ext/standard/dl.c +--- php-5.1.6/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/dl.c 2006-09-07 19:41:16.000000000 +0200 +@@ -164,8 +164,35 @@ + RETURN_FALSE; + } + module_entry = get_module(); ++ ++ /* check if Hardening-Patch is installed */ ++ if (module_entry->zend_api < 1000000000) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ ++ /* check if correct Hardening-Patch is installed */ ++ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { ++ php_error_docref(NULL TSRMLS_CC, error_type, ++ "%s: Unable to initialize module\n" ++ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" ++ "These options need to match\n", ++ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, ++ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); ++ DL_UNLOAD(handle); ++ RETURN_FALSE; ++ } ++ + if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) +- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { ++ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { + /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ + struct pre_4_1_0_module_entry { + char *name; +@@ -199,7 +226,7 @@ + zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; + } else { + name = module_entry->name; +- zend_api = module_entry->zend_api; ++ zend_api = module_entry->real_zend_api; + zend_debug = module_entry->zend_debug; + zts = module_entry->zts; + } +diff -Nura php-5.1.6/ext/standard/file.c hardening-patch-5.1.6-0.4.15/ext/standard/file.c +--- php-5.1.6/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/file.c 2006-09-07 19:41:16.000000000 +0200 +@@ -2302,7 +2302,7 @@ + #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) + /* {{{ proto string realpath(string path) + Return the resolved path */ +-PHP_FUNCTION(realpath) ++PHP_FUNCTION(real_path) + { + zval **path; + char resolved_path_buff[MAXPATHLEN]; +diff -Nura php-5.1.6/ext/standard/file.h hardening-patch-5.1.6-0.4.15/ext/standard/file.h +--- php-5.1.6/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/file.h 2006-09-07 19:41:16.000000000 +0200 +@@ -61,7 +61,7 @@ + PHP_FUNCTION(fd_set); + PHP_FUNCTION(fd_isset); + #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) +-PHP_FUNCTION(realpath); ++PHP_FUNCTION(real_path); + PHP_FUNCTION(fnmatch); + #endif + PHP_NAMED_FUNCTION(php_if_ftruncate); +diff -Nura php-5.1.6/ext/standard/head.c hardening-patch-5.1.6-0.4.15/ext/standard/head.c +--- php-5.1.6/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/head.c 2006-09-07 19:41:16.000000000 +0200 +@@ -45,7 +45,7 @@ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, + &ctr.line_len, &rep, &ctr.response_code) == FAILURE) + return; +- ++ + sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); + } + /* }}} */ +diff -Nura php-5.1.6/ext/standard/info.c hardening-patch-5.1.6-0.4.15/ext/standard/info.c +--- php-5.1.6/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/info.c 2006-09-07 19:41:16.000000000 +0200 +@@ -154,7 +154,7 @@ + if (Z_TYPE_PP(tmp) == IS_ARRAY) { + if (!sapi_module.phpinfo_as_text) { + PUTS("
");
+-					zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
++					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
+ 					PUTS("
"); + } else { + zend_print_zval_r(*tmp, 0 TSRMLS_CC); +@@ -411,7 +411,7 @@ + + if (flag & PHP_INFO_GENERAL) { + char *zend_version = get_zend_version(); +- char temp_api[10]; ++ char temp_api[11]; + char *logo_guid; + + php_uname = php_get_uname('a'); +@@ -434,11 +434,22 @@ + PUTS("\" alt=\"PHP Logo\" />"); + } + ++#if HARDENING_PATCH ++ if (!sapi_module.phpinfo_as_text) { ++ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); ++ } else { ++ char temp_ver[40]; ++ ++ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); ++ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); ++ } ++#else + if (!sapi_module.phpinfo_as_text) { + php_printf("

PHP Version %s

\n", PHP_VERSION); + } else { + php_info_print_table_row(2, "PHP Version", PHP_VERSION); +- } ++ } ++#endif + php_info_print_box_end(); + php_info_print_table_start(); + php_info_print_table_row(2, "System", php_uname ); +diff -Nura php-5.1.6/ext/standard/mail.c hardening-patch-5.1.6-0.4.15/ext/standard/mail.c +--- php-5.1.6/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/mail.c 2006-09-07 19:41:16.000000000 +0200 +@@ -78,6 +78,25 @@ + } + /* }}} */ + ++/* {{{ hphp_strcasestr */ ++char *hphp_strcasestr(char *haystack, char *needle) ++{ ++ unsigned char *t, *h, *n; ++ ++ h = (unsigned char *) haystack; ++conts: ++ while (*h) { ++ n = (unsigned char *) needle; ++ for (t=h++; *n && *h; t++, n++) { ++ if (toupper(*t) != toupper(*n)) goto conts; ++ } ++ return ((char*)h-1); ++ } ++ ++ return (NULL); ++} ++/* }}} */ ++ + /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) + Send an email message */ + PHP_FUNCTION(mail) +@@ -104,6 +123,44 @@ + return; + } + ++ if (HG(hphp_mailprotect) > 0) { ++ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { ++ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ /* check for spam attempts with buggy webforms */ ++ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { ++ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); ++ RETURN_FALSE; ++ } ++ ++ if (HG(hphp_mailprotect) > 1) { ++ /* search for to, cc or bcc headers */ ++ if (headers_len > 0 && headers != NULL) { ++ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { ++ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { ++ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ ++ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { ++ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); ++ RETURN_FALSE; ++ } ++ } ++ } ++ } ++ + if (to_len > 0) { + to_r = estrndup(to, to_len); + for (; to_len; to_len--) { +diff -Nura php-5.1.6/ext/standard/php_standard.h hardening-patch-5.1.6-0.4.15/ext/standard/php_standard.h +--- php-5.1.6/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/php_standard.h 2006-09-07 19:41:16.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "php_mail.h" + #include "md5.h" + #include "sha1.h" ++#include "sha256.h" + #include "html.h" + #include "exec.h" + #include "file.h" +diff -Nura php-5.1.6/ext/standard/sha256.c hardening-patch-5.1.6-0.4.15/ext/standard/sha256.c +--- php-5.1.6/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/sha256.c 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,388 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ ++ ++#include "php.h" ++ ++/* This code is heavily based on the PHP md5/sha1 implementations */ ++ ++#include "sha256.h" ++ ++PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ sprintf(sha256str, "%02x", digest[i]); ++ sha256str += 2; ++ } ++ ++ *sha256str = '\0'; ++} ++ ++/* {{{ proto string sha256(string str [, bool raw_output]) ++ Calculate the sha256 hash of a string */ ++PHP_FUNCTION(sha256) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ PHP_SHA256_CTX context; ++ unsigned char digest[32]; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ sha256str[0] = '\0'; ++ PHP_SHA256Init(&context); ++ PHP_SHA256Update(&context, arg, arg_len); ++ PHP_SHA256Final(digest, &context); ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++ ++} ++ ++/* }}} */ ++ ++/* {{{ proto string sha256_file(string filename [, bool raw_output]) ++ Calculate the sha256 hash of given filename */ ++PHP_FUNCTION(sha256_file) ++{ ++ char *arg; ++ int arg_len; ++ zend_bool raw_output = 0; ++ char sha256str[65]; ++ unsigned char buf[1024]; ++ unsigned char digest[32]; ++ PHP_SHA256_CTX context; ++ int n; ++ php_stream *stream; ++ ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ++ return; ++ } ++ ++ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); ++ if (!stream) { ++ RETURN_FALSE; ++ } ++ ++ PHP_SHA256Init(&context); ++ ++ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ++ PHP_SHA256Update(&context, buf, n); ++ } ++ ++ PHP_SHA256Final(digest, &context); ++ ++ php_stream_close(stream); ++ ++ if (n<0) { ++ RETURN_FALSE; ++ } ++ ++ if (raw_output) { ++ RETURN_STRINGL(digest, 32, 1); ++ } else { ++ make_sha256_digest(sha256str, digest); ++ RETVAL_STRING(sha256str, 1); ++ } ++} ++/* }}} */ ++ ++ ++static void SHA256Transform(php_uint32[8], const unsigned char[64]); ++static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); ++static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); ++ ++static unsigned char PADDING[64] = ++{ ++ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++/* F, G, H and I are basic SHA256 functions. ++ */ ++#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) ++#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) ++#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) ++#define I(x, y, z) (((x) & (y)) | ((~x) & z)) ++ ++/* ROTATE_RIGHT rotates x right n bits. ++ */ ++#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) ++ ++/* W[i] ++ */ ++#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ ++ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ ++ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) ++ ++/* ROUND function of sha256 ++ */ ++ ++#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ ++ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ ++ (h) = F((a)) + G((a), (b), (c)) + t1; \ ++ (d) += t1; \ ++ } ++ ++ ++/* {{{ PHP_SHA256Init ++ * SHA256 initialization. Begins an SHA256 operation, writing a new context. ++ */ ++static void PHP_SHA256Init(PHP_SHA256_CTX * context) ++{ ++ context->count[0] = context->count[1] = 0; ++ /* Load magic initialization constants. ++ */ ++ context->state[0] = 0x6a09e667; ++ context->state[1] = 0xbb67ae85; ++ context->state[2] = 0x3c6ef372; ++ context->state[3] = 0xa54ff53a; ++ context->state[4] = 0x510e527f; ++ context->state[5] = 0x9b05688c; ++ context->state[6] = 0x1f83d9ab; ++ context->state[7] = 0x5be0cd19; ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Update ++ SHA256 block update operation. Continues an SHA256 message-digest ++ operation, processing another message block, and updating the ++ context. ++ */ ++static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, ++ unsigned int inputLen) ++{ ++ unsigned int i, index, partLen; ++ ++ /* Compute number of bytes mod 64 */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ++ ++ /* Update number of bits */ ++ if ((context->count[0] += ((php_uint32) inputLen << 3)) ++ < ((php_uint32) inputLen << 3)) ++ context->count[1]++; ++ context->count[1] += ((php_uint32) inputLen >> 29); ++ ++ partLen = 64 - index; ++ ++ /* Transform as many times as possible. ++ */ ++ if (inputLen >= partLen) { ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ++ SHA256Transform(context->state, context->buffer); ++ ++ for (i = partLen; i + 63 < inputLen; i += 64) ++ SHA256Transform(context->state, &input[i]); ++ ++ index = 0; ++ } else ++ i = 0; ++ ++ /* Buffer remaining input */ ++ memcpy ++ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], ++ inputLen - i); ++} ++/* }}} */ ++ ++/* {{{ PHP_SHA256Final ++ SHA256 finalization. Ends an SHA256 message-digest operation, writing the ++ the message digest and zeroizing the context. ++ */ ++static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) ++{ ++ unsigned char bits[8]; ++ unsigned int index, padLen; ++ ++ /* Save number of bits */ ++ bits[7] = context->count[0] & 0xFF; ++ bits[6] = (context->count[0] >> 8) & 0xFF; ++ bits[5] = (context->count[0] >> 16) & 0xFF; ++ bits[4] = (context->count[0] >> 24) & 0xFF; ++ bits[3] = context->count[1] & 0xFF; ++ bits[2] = (context->count[1] >> 8) & 0xFF; ++ bits[1] = (context->count[1] >> 16) & 0xFF; ++ bits[0] = (context->count[1] >> 24) & 0xFF; ++ ++ /* Pad out to 56 mod 64. ++ */ ++ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ++ padLen = (index < 56) ? (56 - index) : (120 - index); ++ PHP_SHA256Update(context, PADDING, padLen); ++ ++ /* Append length (before padding) */ ++ PHP_SHA256Update(context, bits, 8); ++ ++ /* Store state in digest */ ++ SHA256Encode(digest, context->state, 32); ++ ++ /* Zeroize sensitive information. ++ */ ++ memset((unsigned char*) context, 0, sizeof(*context)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Transform ++ * SHA256 basic transformation. Transforms state based on block. ++ */ ++static void SHA256Transform(state, block) ++php_uint32 state[8]; ++const unsigned char block[64]; ++{ ++ php_uint32 a = state[0], b = state[1], c = state[2]; ++ php_uint32 d = state[3], e = state[4], f = state[5]; ++ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; ++ ++ SHA256Decode(x, block, 64); ++ ++ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) ++ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) ++ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) ++ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) ++ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) ++ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) ++ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) ++ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) ++ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) ++ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) ++ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) ++ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) ++ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) ++ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) ++ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) ++ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) ++ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) ++ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) ++ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) ++ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) ++ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) ++ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) ++ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) ++ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) ++ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) ++ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) ++ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) ++ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) ++ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) ++ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) ++ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) ++ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) ++ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) ++ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) ++ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) ++ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) ++ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) ++ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) ++ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) ++ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) ++ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) ++ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) ++ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) ++ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) ++ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) ++ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) ++ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) ++ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) ++ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) ++ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) ++ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) ++ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) ++ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) ++ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) ++ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) ++ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) ++ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) ++ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) ++ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) ++ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) ++ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) ++ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) ++ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) ++ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) ++ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ state[5] += f; ++ state[6] += g; ++ state[7] += h; ++ ++ /* Zeroize sensitive information. */ ++ memset((unsigned char*) x, 0, sizeof(x)); ++} ++/* }}} */ ++ ++/* {{{ SHA256Encode ++ Encodes input (php_uint32) into output (unsigned char). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Encode(output, input, len) ++unsigned char *output; ++php_uint32 *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) { ++ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); ++ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); ++ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); ++ output[j + 3] = (unsigned char) (input[i] & 0xff); ++ } ++} ++/* }}} */ ++ ++/* {{{ SHA256Decode ++ Decodes input (unsigned char) into output (php_uint32). Assumes len is ++ a multiple of 4. ++ */ ++static void SHA256Decode(output, input, len) ++php_uint32 *output; ++const unsigned char *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) ++ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | ++ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.6/ext/standard/sha256.h hardening-patch-5.1.6-0.4.15/ext/standard/sha256.h +--- php-5.1.6/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/sha256.h 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | PHP Version 5 | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 1997-2004 The PHP Group | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 3.0 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available through the world-wide-web at the following url: | ++ | http://www.php.net/license/3_0.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++*/ ++ ++/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ ++ ++#ifndef SHA256_H ++#define SHA256_H ++ ++#include "ext/standard/basic_functions.h" ++ ++/* SHA1 context. */ ++typedef struct { ++ php_uint32 state[8]; /* state (ABCD) */ ++ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ++ unsigned char buffer[64]; /* input buffer */ ++} PHP_SHA256_CTX; ++ ++static void PHP_SHA256Init(PHP_SHA256_CTX *); ++static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); ++static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); ++ ++PHP_FUNCTION(sha256); ++PHP_FUNCTION(sha256_file); ++ ++#endif +diff -Nura php-5.1.6/ext/standard/syslog.c hardening-patch-5.1.6-0.4.15/ext/standard/syslog.c +--- php-5.1.6/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/standard/syslog.c 2006-09-07 19:41:16.000000000 +0200 +@@ -42,6 +42,7 @@ + */ + PHP_MINIT_FUNCTION(syslog) + { ++#if !HARDENING_PATCH + /* error levels */ + REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ + REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ +@@ -97,6 +98,7 @@ + /* AIX doesn't have LOG_PERROR */ + REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ + #endif ++#endif + BG(syslog_device)=NULL; + + return SUCCESS; +diff -Nura php-5.1.6/ext/varfilter/config.m4 hardening-patch-5.1.6-0.4.15/ext/varfilter/config.m4 +--- php-5.1.6/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/varfilter/config.m4 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,11 @@ ++dnl ++dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++dnl ++ ++PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, ++[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) ++ ++if test "$PHP_VARFILTER" != "no"; then ++ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) ++ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) ++fi +diff -Nura php-5.1.6/ext/varfilter/CREDITS hardening-patch-5.1.6-0.4.15/ext/varfilter/CREDITS +--- php-5.1.6/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/varfilter/CREDITS 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,2 @@ ++varfilter ++Stefan Esser +\ Kein Zeilenumbruch am Dateiende. +diff -Nura php-5.1.6/ext/varfilter/php_varfilter.h hardening-patch-5.1.6-0.4.15/ext/varfilter/php_varfilter.h +--- php-5.1.6/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/varfilter/php_varfilter.h 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,144 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifndef PHP_VARFILTER_H ++#define PHP_VARFILTER_H ++ ++extern zend_module_entry varfilter_module_entry; ++#define phpext_varfilter_ptr &varfilter_module_entry ++ ++#ifdef PHP_WIN32 ++#define PHP_VARFILTER_API __declspec(dllexport) ++#else ++#define PHP_VARFILTER_API ++#endif ++ ++#ifdef ZTS ++#include "TSRM.h" ++#endif ++ ++#include "SAPI.h" ++ ++#include "php_variables.h" ++ ++#ifdef ZEND_ENGINE_2 ++#define HASH_HTTP_GET_VARS 0x2095733f ++#define HASH_HTTP_POST_VARS 0xbfee1265 ++#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 ++#define HASH_HTTP_ENV_VARS 0x1fe186a8 ++#define HASH_HTTP_SERVER_VARS 0xc987afd6 ++#define HASH_HTTP_SESSION_VARS 0x7aba0d43 ++#define HASH_HTTP_POST_FILES 0x98eb1ddc ++#define HASH_HTTP_RAW_POST_DATA 0xdd633fec ++#else ++#define HASH_HTTP_GET_VARS 0x8d8645bd ++#define HASH_HTTP_POST_VARS 0x7c699bf3 ++#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f ++#define HASH_HTTP_ENV_VARS 0x84da3016 ++#define HASH_HTTP_SERVER_VARS 0x6dbf964e ++#define HASH_HTTP_SESSION_VARS 0x322906f5 ++#define HASH_HTTP_POST_FILES 0xe4e4ce70 ++#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e ++#endif ++ ++PHP_MINIT_FUNCTION(varfilter); ++PHP_MSHUTDOWN_FUNCTION(varfilter); ++PHP_RINIT_FUNCTION(varfilter); ++PHP_RSHUTDOWN_FUNCTION(varfilter); ++PHP_MINFO_FUNCTION(varfilter); ++ ++ ++ZEND_BEGIN_MODULE_GLOBALS(varfilter) ++/* request variables */ ++ long max_request_variables; ++ long cur_request_variables; ++ long max_varname_length; ++ long max_totalname_length; ++ long max_value_length; ++ long max_array_depth; ++ long max_array_index_length; ++ zend_bool disallow_nul; ++/* cookie variables */ ++ long max_cookie_vars; ++ long cur_cookie_vars; ++ long max_cookie_name_length; ++ long max_cookie_totalname_length; ++ long max_cookie_value_length; ++ long max_cookie_array_depth; ++ long max_cookie_array_index_length; ++ zend_bool disallow_cookie_nul; ++/* get variables */ ++ long max_get_vars; ++ long cur_get_vars; ++ long max_get_name_length; ++ long max_get_totalname_length; ++ long max_get_value_length; ++ long max_get_array_depth; ++ long max_get_array_index_length; ++ zend_bool disallow_get_nul; ++/* post variables */ ++ long max_post_vars; ++ long cur_post_vars; ++ long max_post_name_length; ++ long max_post_totalname_length; ++ long max_post_value_length; ++ long max_post_array_depth; ++ long max_post_array_index_length; ++ zend_bool disallow_post_nul; ++/* fileupload */ ++ long max_uploads; ++ long cur_uploads; ++ zend_bool disallow_elf_files; ++ char *verification_script; ++ ++ zend_bool no_more_variables; ++ zend_bool no_more_get_variables; ++ zend_bool no_more_post_variables; ++ zend_bool no_more_cookie_variables; ++ zend_bool no_more_uploads; ++ ++ZEND_END_MODULE_GLOBALS(varfilter) ++ ++ ++#ifdef ZTS ++#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) ++#else ++#define VARFILTER_G(v) (varfilter_globals.v) ++#endif ++ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); ++SAPI_TREAT_DATA_FUNC(varfilter_treat_data); ++ ++ ++ ++#endif /* PHP_VARFILTER_H */ ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: t ++ * End: ++ */ +diff -Nura php-5.1.6/ext/varfilter/varfilter.c hardening-patch-5.1.6-0.4.15/ext/varfilter/varfilter.c +--- php-5.1.6/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/ext/varfilter/varfilter.c 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,915 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardened-PHP Project's varfilter extension | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ ++ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ ++*/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "php.h" ++#include "php_ini.h" ++#include "ext/standard/info.h" ++#include "php_varfilter.h" ++#include "hardening_patch.h" ++ ++ZEND_DECLARE_MODULE_GLOBALS(varfilter) ++ ++/* True global resources - no need for thread safety here */ ++static int le_varfilter; ++ ++static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; ++static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; ++static zend_bool hooked = 0; ++ ++/* {{{ varfilter_module_entry ++ */ ++zend_module_entry varfilter_module_entry = { ++#if ZEND_MODULE_API_NO >= 20010901 ++ STANDARD_MODULE_HEADER, ++#endif ++ "varfilter", ++ NULL, ++ PHP_MINIT(varfilter), ++ PHP_MSHUTDOWN(varfilter), ++ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ ++ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ ++ PHP_MINFO(varfilter), ++#if ZEND_MODULE_API_NO >= 20010901 ++ "0.4.15", /* Replace with version number for your extension */ ++#endif ++ STANDARD_MODULE_PROPERTIES ++}; ++/* }}} */ ++ ++#ifdef COMPILE_DL_VARFILTER ++ZEND_GET_MODULE(varfilter) ++#endif ++ ++/* {{{ PHP_INI ++ */ ++PHP_INI_BEGIN() ++ /* for backward compatibility */ ++ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) ++ 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) ++ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) ++ ++ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) ++ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) ++ ++ ++PHP_INI_END() ++/* }}} */ ++ ++/* {{{ php_varfilter_init_globals ++ */ ++static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) ++{ ++ varfilter_globals->max_request_variables = 200; ++ varfilter_globals->max_varname_length = 64; ++ varfilter_globals->max_value_length = 10000; ++ varfilter_globals->max_array_depth = 100; ++ varfilter_globals->max_totalname_length = 256; ++ varfilter_globals->max_array_index_length = 64; ++ varfilter_globals->disallow_nul = 1; ++ ++ varfilter_globals->max_cookie_vars = 100; ++ varfilter_globals->max_cookie_name_length = 64; ++ varfilter_globals->max_cookie_totalname_length = 256; ++ varfilter_globals->max_cookie_value_length = 10000; ++ varfilter_globals->max_cookie_array_depth = 100; ++ varfilter_globals->max_cookie_array_index_length = 64; ++ varfilter_globals->disallow_cookie_nul = 1; ++ ++ varfilter_globals->max_get_vars = 100; ++ varfilter_globals->max_get_name_length = 64; ++ varfilter_globals->max_get_totalname_length = 256; ++ varfilter_globals->max_get_value_length = 512; ++ varfilter_globals->max_get_array_depth = 50; ++ varfilter_globals->max_get_array_index_length = 64; ++ varfilter_globals->disallow_get_nul = 1; ++ ++ varfilter_globals->max_post_vars = 200; ++ varfilter_globals->max_post_name_length = 64; ++ varfilter_globals->max_post_totalname_length = 256; ++ varfilter_globals->max_post_value_length = 65000; ++ varfilter_globals->max_post_array_depth = 100; ++ varfilter_globals->max_post_array_index_length = 64; ++ varfilter_globals->disallow_post_nul = 1; ++ ++ varfilter_globals->max_uploads = 25; ++ varfilter_globals->disallow_elf_files = 1; ++ varfilter_globals->verification_script = NULL; ++ ++ varfilter_globals->no_more_variables = 0; ++ varfilter_globals->no_more_get_variables = 0; ++ varfilter_globals->no_more_post_variables = 0; ++ varfilter_globals->no_more_cookie_variables = 0; ++ varfilter_globals->no_more_uploads = 0; ++ ++ varfilter_globals->cur_request_variables = 0; ++ varfilter_globals->cur_get_vars = 0; ++ varfilter_globals->cur_post_vars = 0; ++ varfilter_globals->cur_cookie_vars = 0; ++ ++ varfilter_globals->cur_uploads = 0; ++ ++} ++/* }}} */ ++ ++ ++void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) ++{ ++ HashTable *svars; ++ int retval, failure=0; ++ ++ orig_register_server_variables(track_vars_array TSRMLS_CC); ++ ++ svars = Z_ARRVAL_P(track_vars_array); ++ ++ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); ++ if (retval == SUCCESS) failure = 1; ++ ++ if (failure) { ++ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); ++ } ++} ++ ++int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) ++{ ++ int retval = SAPI_HEADER_ADD, i; ++ char *tmp; ++ ++ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { ++ ++ tmp = sapi_header->header; ++ for (i=0; iheader_len; i++, tmp++) { ++ if (tmp[0] == 0) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); ++ sapi_header->header_len = i; ++ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { ++ char *fname = get_active_function_name(TSRMLS_C); ++ ++ if (!fname) { ++ fname = "unknown"; ++ } ++ ++ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); ++ sapi_header->header_len = i; ++ tmp[0] = 0; ++ } ++ } ++ } ++ ++ if (orig_header_handler) { ++ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); ++ } ++ ++ return retval; ++} ++ ++/* {{{ PHP_MINIT_FUNCTION ++ */ ++PHP_MINIT_FUNCTION(varfilter) ++{ ++ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); ++ REGISTER_INI_ENTRIES(); ++ ++ if (!hooked) { ++ void *temp; ++ hooked = 1; ++ ++ temp = (void *)sapi_module.register_server_variables; ++ if (temp != varfilter_register_server_variables) { ++ orig_register_server_variables = temp; ++ } ++ temp = (void *)sapi_module.header_handler; ++ if (temp != varfilter_header_handler) { ++ orig_header_handler = temp; ++ } ++ } ++ ++ sapi_register_input_filter(varfilter_input_filter); ++ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); ++ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); ++ sapi_register_upload_content_filter(varfilter_upload_content_filter); ++ sapi_register_post_upload_filter(varfilter_post_upload_filter); ++ ++ sapi_module.header_handler = varfilter_header_handler; ++ sapi_module.register_server_variables = varfilter_register_server_variables; ++ ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MSHUTDOWN_FUNCTION ++ */ ++PHP_MSHUTDOWN_FUNCTION(varfilter) ++{ ++ UNREGISTER_INI_ENTRIES(); ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request start */ ++/* {{{ PHP_RINIT_FUNCTION ++ */ ++PHP_RINIT_FUNCTION(varfilter) ++{ ++ VARFILTER_G(cur_request_variables) = 0; ++ VARFILTER_G(cur_get_vars) = 0; ++ VARFILTER_G(cur_post_vars) = 0; ++ VARFILTER_G(cur_cookie_vars) = 0; ++ ++ VARFILTER_G(cur_uploads) = 0; ++ ++ VARFILTER_G(no_more_variables) = 0; ++ VARFILTER_G(no_more_get_variables) = 0; ++ VARFILTER_G(no_more_post_variables) = 0; ++ VARFILTER_G(no_more_cookie_variables) = 0; ++ VARFILTER_G(no_more_uploads) = 0; ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* Remove if there's nothing to do at request end */ ++/* {{{ PHP_RSHUTDOWN_FUNCTION ++ */ ++PHP_RSHUTDOWN_FUNCTION(varfilter) ++{ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ PHP_MINFO_FUNCTION ++ */ ++PHP_MINFO_FUNCTION(varfilter) ++{ ++ php_info_print_table_start(); ++ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); ++ php_info_print_table_end(); ++ ++ DISPLAY_INI_ENTRIES(); ++} ++/* }}} */ ++ ++/* {{{ normalize_varname ++ */ ++static void normalize_varname(char *varname) ++{ ++ char *s=varname, *index=NULL, *indexend=NULL, *p; ++ ++ /* overjump leading space */ ++ while (*s == ' ') { ++ s++; ++ } ++ ++ /* and remove it */ ++ if (s != varname) { ++ memmove(varname, s, strlen(s)+1); ++ } ++ ++ for (p=varname; *p && *p != '['; p++) { ++ switch(*p) { ++ case ' ': ++ case '.': ++ *p='_'; ++ break; ++ } ++ } ++ ++ /* find index */ ++ index = strchr(varname, '['); ++ if (index) { ++ index++; ++ s=index; ++ } else { ++ return; ++ } ++ ++ /* done? */ ++ while (index) { ++ ++ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { ++ index++; ++ } ++ indexend = strchr(index, ']'); ++ indexend = indexend ? indexend + 1 : index + strlen(index); ++ ++ if (s != index) { ++ memmove(s, index, strlen(index)+1); ++ s += indexend-index; ++ } else { ++ s = indexend; ++ } ++ ++ if (*s == '[') { ++ s++; ++ index = s; ++ } else { ++ index = NULL; ++ } ++ } ++ *s++='\0'; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC ++ */ ++SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) ++{ ++ char *index, *prev_index = NULL, *var; ++ unsigned int var_len, total_len, depth = 0; ++ ++ var = estrdup(varname); ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); ++ ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); ++ goto return_failure; ++ } ++ ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; ++ break; ++ } ++ ++ efree(var); ++ return SUCCESS; ++protected_varname2: ++ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); ++return_failure: ++ efree(var); ++ return FAILURE; ++} ++/* }}} */ ++ ++/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC ++ */ ++SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) ++{ ++ /* Drop if no more variables flag is set */ ++ if (VARFILTER_G(no_more_uploads)) { ++ return FAILURE; ++ } ++ /* Drop this fileupload if the limit is reached */ ++ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { ++ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); ++ VARFILTER_G(no_more_uploads) = 1; ++ return FAILURE; ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC ++ */ ++SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) ++{ ++ ++ if (VARFILTER_G(disallow_elf_files)) { ++ ++ if (offset == 0 && buffer_len > 10) { ++ ++ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { ++ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); ++ return FAILURE; ++ } ++ } ++ ++ } ++ ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC ++ */ ++SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) ++{ ++ int retval = SUCCESS; ++ ++ if (VARFILTER_G(verification_script)) { ++ char cmd[8192]; ++ FILE *in; ++ int first=1; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); ++ return FAILURE; ++ } ++ ++ retval = FAILURE; ++ ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ if (first) { ++ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; ++ first = 0; ++ } ++ } ++ pclose(in); ++ } ++ ++ if (retval != SUCCESS) { ++ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); ++ return FAILURE; ++ } ++ ++ VARFILTER_G(cur_uploads)++; ++ return SUCCESS; ++} ++/* }}} */ ++ ++/* {{{ SAPI_INPUT_FILTER_FUNC ++ */ ++SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) ++{ ++ char *index, *prev_index = NULL; ++ unsigned int var_len, total_len, depth = 0; ++ ++ /* Drop this variable if the limit was reached */ ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(no_more_get_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(no_more_post_variables)) { ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(no_more_cookie_variables)) { ++ return 0; ++ } ++ break; ++ default: /* we do not want to protect parse_str() and friends */ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ return 1; ++ } ++ if (VARFILTER_G(no_more_variables)) { ++ return 0; ++ } ++ ++ /* Drop this variable if the limit is now reached */ ++ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { ++ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_variables) = 1; ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { ++ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_get_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { ++ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_cookie_variables) = 1; ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { ++ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); ++ VARFILTER_G(no_more_post_variables) = 1; ++ return 0; ++ } ++ break; ++ } ++ ++ ++ /* Drop this variable if it exceeds the value length limit */ ++ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { ++ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { ++ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { ++ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { ++ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Normalize the variable name */ ++ normalize_varname(var); ++ ++ /* Find length of variable name */ ++ index = strchr(var, '['); ++ total_len = strlen(var); ++ var_len = index ? index-var : total_len; ++ ++ /* Drop this variable if it exceeds the varname/total length limit */ ++ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { ++ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { ++ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { ++ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Find out array depth */ ++ while (index) { ++ unsigned int index_length; ++ ++ depth++; ++ index = strchr(index+1, '['); ++ ++ if (prev_index) { ++ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); ++ ++ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { ++ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ prev_index = index; ++ } ++ ++ } ++ ++ /* Drop this variable if it exceeds the array depth limit */ ++ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { ++ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { ++ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { ++ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { ++ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ ++ /* Check if variable value is truncated by a \0 */ ++ ++ if (val && *val && val_len != strlen(*val)) { ++ ++ if (VARFILTER_G(disallow_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); ++ return 0; ++ } ++ switch (arg) { ++ case PARSE_GET: ++ if (VARFILTER_G(disallow_get_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_COOKIE: ++ if (VARFILTER_G(disallow_cookie_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ case PARSE_POST: ++ if (VARFILTER_G(disallow_post_nul)) { ++ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); ++ return 0; ++ } ++ break; ++ } ++ } ++ ++ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ ++ /* This is to protect several silly scripts that do globalizing themself */ ++ ++ switch (var_len) { ++ case 18: ++ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; ++ break; ++ case 17: ++ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; ++ break; ++ case 16: ++ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; ++ break; ++ case 15: ++ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; ++ break; ++ case 14: ++ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; ++ break; ++ case 13: ++ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; ++ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; ++ break; ++ case 8: ++ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; ++ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; ++ break; ++ case 7: ++ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; ++ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; ++ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; ++ break; ++ case 6: ++ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; ++ break; ++ case 5: ++ if (memcmp(var, "_POST", 5)==0) goto protected_varname; ++ break; ++ case 4: ++ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; ++ if (memcmp(var, "_GET", 4)==0) goto protected_varname; ++ break; ++ } ++ ++ /* Okay let PHP register this variable */ ++ VARFILTER_G(cur_request_variables)++; ++ switch (arg) { ++ case PARSE_GET: ++ VARFILTER_G(cur_get_vars)++; ++ break; ++ case PARSE_COOKIE: ++ VARFILTER_G(cur_cookie_vars)++; ++ break; ++ case PARSE_POST: ++ VARFILTER_G(cur_post_vars)++; ++ break; ++ } ++ ++ if (new_val_len) { ++ *new_val_len = val_len; ++ } ++ ++ return 1; ++protected_varname: ++ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); ++ return 0; ++} ++/* }}} */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: noet sw=4 ts=4 fdm=marker ++ * vim<600: noet sw=4 ts=4 ++ */ ++ ++ +diff -Nura php-5.1.6/ext/wddx/wddx.c hardening-patch-5.1.6-0.4.15/ext/wddx/wddx.c +--- php-5.1.6/ext/wddx/wddx.c 2006-05-25 12:01:30.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/ext/wddx/wddx.c 2006-09-07 19:41:16.000000000 +0200 +@@ -399,9 +399,9 @@ + break; + + default: +- if (iscntrl((int)*(unsigned char *)p)) { ++ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) { + FLUSH_BUF(); +- sprintf(control_buf, WDDX_CHAR, *p); ++ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); + php_wddx_add_chunk(packet, control_buf); + } else + buf[l++] = *p; +diff -Nura php-5.1.6/main/fopen_wrappers.c hardening-patch-5.1.6-0.4.15/main/fopen_wrappers.c +--- php-5.1.6/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/fopen_wrappers.c 2006-09-07 19:41:16.000000000 +0200 +@@ -104,7 +104,10 @@ + } + + /* Resolve the real path into resolved_name */ +- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { ++ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { ++ return -2; ++ } ++ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { + /* Handler for basedirs that end with a / */ + resolved_basedir_len = strlen(resolved_basedir); + if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { +@@ -114,14 +117,20 @@ + } + } + ++ resolved_name_len = strlen(resolved_name); + if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { +- resolved_name_len = strlen(resolved_name); + if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { + resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; + resolved_name[++resolved_name_len] = '\0'; + } + } + ++ if (resolved_name_len == resolved_basedir_len - 1) { ++ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { ++ resolved_basedir_len--; ++ } ++ } ++ + /* Check the path */ + #if defined(PHP_WIN32) || defined(NETWARE) + if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { +@@ -135,7 +144,7 @@ + } + } else { + /* Unable to resolve the real path, return -1 */ +- return -1; ++ return -3; + } + } + /* }}} */ +@@ -154,22 +163,44 @@ + char *pathbuf; + char *ptr; + char *end; ++ char path_copy[MAXPATHLEN]; ++ int path_len; ++ ++ /* Special case path ends with a trailing slash */ ++ path_len = strlen(path); ++ if (path_len >= MAXPATHLEN) { ++ errno = EPERM; /* we deny permission to open it */ ++ return -1; ++ } ++ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { ++ memcpy(path_copy, path, path_len+1); ++ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; ++ path_copy[path_len] = '\0'; ++ path = (const char *)&path_copy; ++ } + + pathbuf = estrdup(PG(open_basedir)); + + ptr = pathbuf; + + while (ptr && *ptr) { ++ int res; + end = strchr(ptr, DEFAULT_DIR_SEPARATOR); + if (end != NULL) { + *end = '\0'; + end++; + } + +- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { ++ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); ++ if (res == 0) { + efree(pathbuf); + return 0; + } ++ if (res == -2) { ++ efree(pathbuf); ++ errno = EPERM; ++ return -1; ++ } + + ptr = end; + } +diff -Nura php-5.1.6/main/hardened_globals.h hardening-patch-5.1.6-0.4.15/main/hardened_globals.h +--- php-5.1.6/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/hardened_globals.h 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENED_GLOBALS_H ++#define HARDENED_GLOBALS_H ++ ++typedef struct _hardened_globals hardened_globals_struct; ++ ++#ifdef ZTS ++# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) ++extern int hardened_globals_id; ++#else ++# define HG(v) (hardened_globals.v) ++extern struct _hardened_globals hardened_globals; ++#endif ++ ++ ++struct _hardened_globals { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_1; ++ unsigned int canary_2; ++#endif ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_3; ++ unsigned int canary_4; ++ unsigned int ll_canary_inited; ++#endif ++ zend_bool hphp_sql_bailout_on_error; ++ zend_bool hphp_multiheader; ++ unsigned long hphp_mailprotect; ++ long hard_memory_limit; ++ HashTable *eval_whitelist; ++ HashTable *eval_blacklist; ++ HashTable *func_whitelist; ++ HashTable *func_blacklist; ++ HashTable *include_whitelist; ++ HashTable *include_blacklist; ++ unsigned int dummy; ++}; ++ ++ ++#endif /* HARDENED_GLOBALS_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-5.1.6/main/hardening_patch.c hardening-patch-5.1.6-0.4.15/main/hardening_patch.c +--- php-5.1.6/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/hardening_patch.c 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,430 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ ++ ++#include "php.h" ++ ++#include ++#include ++ ++#if HAVE_UNISTD_H ++#include ++#endif ++#include "SAPI.h" ++#include "php_globals.h" ++ ++#if HARDENING_PATCH ++ ++#ifdef HAVE_SYS_SOCKET_H ++#include ++#endif ++ ++#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) ++#undef AF_UNIX ++#endif ++ ++#if defined(AF_UNIX) ++#include ++#endif ++ ++#define SYSLOG_PATH "/dev/log" ++ ++#include "snprintf.h" ++ ++#include "hardening_patch.h" ++ ++#ifdef ZTS ++#include "hardened_globals.h" ++int hardened_globals_id; ++#else ++struct _hardened_globals hardened_globals; ++#endif ++ ++static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) ++{ ++ memset(hardened_globals, 0, sizeof(*hardened_globals)); ++} ++ ++ ++PHPAPI void hardened_startup() ++{ ++#ifdef ZTS ++ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); ++#else ++ hardened_globals_ctor(&hardened_globals TSRMLS_CC); ++#endif ++} ++ ++PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) ++{ ++ HG(canary_1) = php_canary(); ++ HG(canary_2) = php_canary(); ++} ++ ++char *loglevel2string(int loglevel) ++{ ++ switch (loglevel) { ++ case S_FILES: ++ return "FILES"; ++ case S_INCLUDE: ++ return "INCLUDE"; ++ case S_MEMORY: ++ return "MEMORY"; ++ case S_MISC: ++ return "MISC"; ++ case S_SQL: ++ return "SQL"; ++ case S_EXECUTOR: ++ return "EXECUTOR"; ++ case S_VARS: ++ return "VARS"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++PHPAPI void php_security_log(int loglevel, char *fmt, ...) ++{ ++#if defined(AF_UNIX) ++ int s, r, i=0; ++ struct sockaddr_un saun; ++ char buf[4096+64]; ++ char error[4096+100]; ++ char *ip_address; ++ char *fname; ++ int lineno; ++ va_list ap; ++ TSRMLS_FETCH(); ++ ++ if (EG(hphp_log_use_x_forwarded_for)) { ++ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "X-FORWARDED-FOR not set"; ++ } ++ } else { ++ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); ++ if (ip_address == NULL) { ++ ip_address = "REMOTE_ADDR not set"; ++ } ++ } ++ ++ ++ va_start(ap, fmt); ++ ap_php_vsnprintf(error, sizeof(error), fmt, ap); ++ va_end(ap); ++ while (error[i]) { ++ if (error[i] < 32) error[i] = '.'; ++ i++; ++ } ++ ++ if (zend_is_executing(TSRMLS_C)) { ++ lineno = zend_get_executed_lineno(TSRMLS_C); ++ fname = zend_get_executed_filename(TSRMLS_C); ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); ++ } else { ++ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); ++ if (fname==NULL) { ++ fname = "unknown"; ++ } ++ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); ++ } ++ ++ /* Syslog-Logging disabled? */ ++ if ((EG(hphp_log_syslog) & loglevel)==0) { ++ goto log_sapi; ++ } ++ ++ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); ++ ++ s = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ s = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (s == -1) { ++ goto log_sapi; ++ } ++ ++ memset(&saun, 0, sizeof(saun)); ++ saun.sun_family = AF_UNIX; ++ strcpy(saun.sun_path, SYSLOG_PATH); ++ /*saun.sun_len = sizeof(saun);*/ ++ ++ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); ++ if (r) { ++ close(s); ++ goto log_sapi; ++ } ++ } ++ send(s, error, strlen(error), 0); ++ ++ close(s); ++ ++log_sapi: ++ /* SAPI Logging activated? */ ++ if ((EG(hphp_log_sapi) & loglevel)!=0) { ++ sapi_module.log_message(buf); ++ } ++ ++log_script: ++ /* script logging activaed? */ ++ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { ++ char cmd[8192], *cmdpos, *bufpos; ++ FILE *in; ++ int space; ++ ++ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); ++ space = sizeof(cmd) - strlen(cmd); ++ cmdpos = cmd + strlen(cmd); ++ bufpos = buf; ++ if (space <= 1) return; ++ while (space > 2 && *bufpos) { ++ if (*bufpos == '\'') { ++ if (space<=5) break; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\\'; ++ *cmdpos++ = '\''; ++ *cmdpos++ = '\''; ++ bufpos++; ++ space-=4; ++ } else { ++ *cmdpos++ = *bufpos++; ++ space--; ++ } ++ } ++ *cmdpos++ = '\''; ++ *cmdpos = 0; ++ ++ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { ++ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); ++ return; ++ } ++ /* read and forget the result */ ++ while (1) { ++ int readbytes = fread(cmd, 1, sizeof(cmd), in); ++ if (readbytes<=0) { ++ break; ++ } ++ } ++ pclose(in); ++ } ++ ++#endif ++} ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++PHPAPI unsigned int php_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++ ++PHPAPI int php_is_valid_include(zval *z) ++{ ++ char *filename; ++ int len, i; ++ TSRMLS_FETCH(); ++ ++ /* must be of type string */ ++ if (z->type != IS_STRING || z->value.str.val == NULL) { ++ return (0); ++ } ++ ++ /* short cut */ ++ filename = z->value.str.val; ++ len = z->value.str.len; ++ ++ /* 1. must be shorter than MAXPATHLEN */ ++ if (len > MAXPATHLEN) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 2. must not be cutted */ ++ if (len != strlen(filename)) { ++ char *fname = estrndup(filename, len); ++ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; ++ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ ++ if (strstr(filename, "://")) { ++ char *fname = estrndup(filename, len); ++ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; ++ ++ /* no black or whitelist then disallow all */ ++ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); ++ efree(fname); ++ return (0); ++ } ++ ++ /* whitelist is stronger than blacklist */ ++ if (HG(include_whitelist)) { ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ zend_bool isOk = 0; ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_whitelist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ isOk = 1; ++ break; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_whitelist)); ++ } while (1); ++ ++ /* not found in whitelist */ ++ if (!isOk) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); ++ efree(fname); ++ return 0; ++ } ++ ++ s = h + 3; ++ } while (1); ++ } else { ++ /* okay then handle the blacklist */ ++ char *s, *t, *h, *index; ++ uint indexlen; ++ ulong numindex; ++ ++ s = filename; ++ ++ do { ++ int tlen; ++ ++ t = h = strstr(s, "://"); ++ if (h == NULL) break; ++ ++ ++ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { ++ t--; ++ } ++ ++ tlen = strlen(t); ++ ++ zend_hash_internal_pointer_reset(HG(include_blacklist)); ++ do { ++ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); ++ ++ if (r==HASH_KEY_NON_EXISTANT) { ++ break; ++ } ++ if (r==HASH_KEY_IS_STRING) { ++ if (h-t <= indexlen-1 && tlen>=indexlen-1) { ++ if (strncmp(t, index, indexlen-1)==0) { ++ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); ++ efree(fname); ++ return 0; ++ } ++ } ++ } ++ ++ zend_hash_move_forward(HG(include_blacklist)); ++ } while (1); ++ ++ s = h + 3; ++ } while (1); ++ } ++ ++ efree(fname); ++ } ++ ++ /* 4. must not be an uploaded file */ ++ if (SG(rfc1867_uploaded_files)) { ++ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { ++ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); ++ return (0); ++ } ++ } ++ ++ /* passed all tests */ ++ return (1); ++} ++ ++#endif ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.6/main/hardening_patch.h hardening-patch-5.1.6-0.4.15/main/hardening_patch.h +--- php-5.1.6/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/hardening_patch.h 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++ ++#ifndef HARDENING_PATCH_H ++#define HARDENING_PATCH_H ++ ++#include "zend.h" ++ ++#if HARDENING_PATCH ++PHPAPI void php_security_log(int loglevel, char *fmt, ...); ++PHPAPI void hardened_startup(); ++#define HARDENING_PATCH_VERSION "0.4.15" ++ ++#endif ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++PHPAPI unsigned int php_canary(); ++#endif ++ ++#if HARDENING_PATCH_INC_PROTECT ++PHPAPI int php_is_valid_include(zval *z); ++#endif ++ ++#endif /* HARDENING_PATCH_H */ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ */ +diff -Nura php-5.1.6/main/hardening_patch.m4 hardening-patch-5.1.6-0.4.15/main/hardening_patch.m4 +--- php-5.1.6/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/hardening_patch.m4 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,95 @@ ++dnl ++dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ ++dnl ++dnl This file contains Hardening Patch for PHP specific autoconf functions. ++dnl ++ ++AC_ARG_ENABLE(hardening-patch-mm-protect, ++[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ ++ DO_HARDENING_PATCH_MM_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_MM_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-ll-protect, ++[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ ++ DO_HARDENING_PATCH_LL_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_LL_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-inc-protect, ++[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ ++ DO_HARDENING_PATCH_INC_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_INC_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-fmt-protect, ++[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_FMT_PROTECT=yes ++]) ++ ++AC_ARG_ENABLE(hardening-patch-hash-protect, ++[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=$enableval ++],[ ++ DO_HARDENING_PATCH_HASH_PROTECT=yes ++]) ++ ++AC_MSG_CHECKING(whether to protect the Zend Memory Manager) ++AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the Zend Linked Lists) ++AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect include/require statements) ++AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect PHP Format String functions) ++AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) ++ ++AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) ++AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) ++ ++ ++AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ ++ ++if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) ++fi ++ ++if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then ++dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) ++else ++ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) ++fi ++ +diff -Nura php-5.1.6/main/main.c hardening-patch-5.1.6-0.4.15/main/main.c +--- php-5.1.6/main/main.c 2006-08-10 23:49:56.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/main/main.c 2006-09-07 19:41:16.000000000 +0200 +@@ -85,6 +85,10 @@ + + #include "SAPI.h" + #include "rfc1867.h" ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#endif ++ + /* }}} */ + + #ifndef ZTS +@@ -109,17 +113,39 @@ + */ + static PHP_INI_MH(OnChangeMemoryLimit) + { ++#if HARDENING_PATCH ++ long hard_memory_limit = 1<<30; ++ ++ if (stage == ZEND_INI_STAGE_RUNTIME) { ++ if (HG(hard_memory_limit) == 0) { ++ HG(hard_memory_limit) = PG(memory_limit); ++ } ++ hard_memory_limit = HG(hard_memory_limit); ++ } else { ++ HG(hard_memory_limit) = 0; ++ } ++#endif + if (new_value) { + PG(memory_limit) = zend_atoi(new_value, new_value_length); ++#if HARDENING_PATCH ++ if (PG(memory_limit) > hard_memory_limit) { ++ PG(memory_limit) = hard_memory_limit; ++ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); ++ return FAILURE; ++ } ++#endif + } else { ++#if HARDENING_PATCH ++ PG(memory_limit) = hard_memory_limit; ++#else + PG(memory_limit) = 1<<30; /* effectively, no limit */ ++#endif + } + return zend_set_memory_limit(PG(memory_limit)); + } + /* }}} */ + #endif + +- + /* {{{ php_disable_functions + */ + static void php_disable_functions(TSRMLS_D) +@@ -1100,6 +1126,13 @@ + sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1); + } + ++ /* Disable realpath cache if safe_mode or open_basedir are set */ ++ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ++ CWDG(realpath_cache_disable) = 1; ++ } else { ++ CWDG(realpath_cache_disable) = 0; ++ } ++ + if (PG(output_handler) && PG(output_handler)[0]) { + php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); + } else if (PG(output_buffering)) { +@@ -1227,6 +1260,9 @@ + + zend_try { + shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); ++#if HARDENING_PATCH ++ hardened_clear_mm_canaries(TSRMLS_C); ++#endif + } zend_end_try(); + + zend_try { +@@ -1398,6 +1434,10 @@ + tsrm_ls = ts_resource(0); + #endif + ++#if HARDENING_PATCH ++ hardened_startup(); ++#endif ++ + module_shutdown = 0; + module_startup = 1; + sapi_initialize_empty_request(TSRMLS_C); +@@ -1411,6 +1451,12 @@ + + php_output_startup(); + ++#if HARDENING_PATCH_INC_PROTECT ++ zuf.is_valid_include = php_is_valid_include; ++#endif ++#if HARDENING_PATCH ++ zuf.security_log_function = php_security_log; ++#endif + zuf.error_function = php_error_cb; + zuf.printf_function = php_printf; + zuf.write_function = php_body_write_wrapper; +@@ -1481,7 +1527,9 @@ + + /* Disable realpath cache if safe_mode or open_basedir are set */ + if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { +- CWDG(realpath_cache_size_limit) = 0; ++ CWDG(realpath_cache_disable) = 1; ++ } else { ++ CWDG(realpath_cache_disable) = 0; + } + + /* initialize stream wrappers registry +@@ -1522,6 +1570,10 @@ + REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS); + 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); + REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); ++#endif + REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); +diff -Nura php-5.1.6/main/php_config.h.in hardening-patch-5.1.6-0.4.15/main/php_config.h.in +--- php-5.1.6/main/php_config.h.in 2006-08-23 14:55:05.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/main/php_config.h.in 2006-09-07 19:41:16.000000000 +0200 +@@ -788,6 +788,39 @@ + /* Enabling BIND8 compatibility for Panther */ + #undef BIND_8_COMPAT + ++/* Hardening-Patch for PHP */ ++#undef HARDENING_PATCH ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Memory Manager Protection */ ++#undef HARDENING_PATCH_MM_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Linked List Protection */ ++#undef HARDENING_PATCH_LL_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Include/Require Protection */ ++#undef HARDENING_PATCH_INC_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* Fmt String Protection */ ++#undef HARDENING_PATCH_FMT_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ ++/* HashTable DTOR Protection */ ++#undef HARDENING_PATCH_HASH_PROTECT ++ + /* Whether you have AOLserver */ + #undef HAVE_AOLSERVER + +@@ -1131,6 +1164,12 @@ + /* Define if you have the getaddrinfo function */ + #undef HAVE_GETADDRINFO + ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ ++/* Whether realpath is broken */ ++#undef PHP_BROKEN_REALPATH ++ + /* Whether system headers declare timezone */ + #undef HAVE_DECLARED_TIMEZONE + +diff -Nura php-5.1.6/main/php.h hardening-patch-5.1.6-0.4.15/main/php.h +--- php-5.1.6/main/php.h 2006-03-07 23:37:53.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/php.h 2006-09-07 19:41:16.000000000 +0200 +@@ -35,11 +35,19 @@ + #include "zend_qsort.h" + #include "php_compat.h" + ++ + #include "zend_API.h" + + #undef sprintf + #define sprintf php_sprintf + ++#if HARDENING_PATCH ++#if HAVE_REALPATH ++#undef realpath ++#define realpath php_realpath ++#endif ++#endif ++ + /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ + #undef PHP_DEBUG + #define PHP_DEBUG ZEND_DEBUG +@@ -338,6 +346,7 @@ + #define PHP_FUNCTION ZEND_FUNCTION + #define PHP_METHOD ZEND_METHOD + ++#define PHP_STATIC_FE ZEND_STATIC_FE + #define PHP_NAMED_FE ZEND_NAMED_FE + #define PHP_FE ZEND_FE + #define PHP_DEP_FE ZEND_DEP_FE +@@ -447,6 +456,10 @@ + #endif + #endif /* !XtOffsetOf */ + ++#if HARDENING_PATCH ++#include "hardening_patch.h" ++#endif ++ + #endif + + /* +diff -Nura php-5.1.6/main/php_variables.c hardening-patch-5.1.6-0.4.15/main/php_variables.c +--- php-5.1.6/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/main/php_variables.c 2006-09-07 19:41:16.000000000 +0200 +@@ -73,6 +73,10 @@ + symtable1 = Z_ARRVAL_P(track_vars_array); + } else if (PG(register_globals)) { + symtable1 = EG(active_symbol_table); ++ /* GLOBALS hijack attempt, reject parameter */ ++ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) { ++ symtable1 = NULL; ++ } + } + if (!symtable1) { + /* Nothing to do */ +@@ -513,7 +517,7 @@ + */ + static inline void php_register_server_variables(TSRMLS_D) + { +- zval *array_ptr = NULL; ++ zval *array_ptr = NULL, *vptr; + /* turn off magic_quotes while importing server variables */ + int magic_quotes_gpc = PG(magic_quotes_gpc); + +diff -Nura php-5.1.6/main/rfc1867.c hardening-patch-5.1.6-0.4.15/main/rfc1867.c +--- php-5.1.6/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/rfc1867.c 2006-09-07 19:41:16.000000000 +0200 +@@ -132,6 +132,7 @@ + #define UPLOAD_ERROR_D 4 /* No file uploaded */ + #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ + #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ ++#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */ + + void php_rfc1867_register_constants(TSRMLS_D) + { +@@ -142,6 +143,7 @@ + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); + REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); + } + + static void normalize_protected_variable(char *varname TSRMLS_DC) +@@ -854,6 +856,7 @@ + char buff[FILLUNIT]; + char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; + int blen=0, wlen=0; ++ unsigned long offset; + + zend_llist_clean(&header); + +@@ -970,7 +973,11 @@ + tmp++; + } + } +- ++ ++ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { ++ skip_upload = 1; ++ } ++ + total_bytes = cancel_upload = 0; + + if (!skip_upload) { +@@ -994,6 +1001,11 @@ + cancel_upload = UPLOAD_ERROR_D; + } + ++ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ ++ offset = 0; + end = 0; + while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) + { +@@ -1008,6 +1020,10 @@ + #endif + cancel_upload = UPLOAD_ERROR_B; + } else if (blen > 0) { ++ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + wlen = write(fd, buff, blen); + + if (wlen < blen) { +@@ -1036,6 +1052,10 @@ + } + #endif + ++ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { ++ cancel_upload = UPLOAD_ERROR_X; ++ } ++ + if (cancel_upload) { + if (temp_filename) { + if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ +diff -Nura php-5.1.6/main/SAPI.c hardening-patch-5.1.6-0.4.15/main/SAPI.c +--- php-5.1.6/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/SAPI.c 2006-09-07 19:41:16.000000000 +0200 +@@ -870,6 +870,36 @@ + post_entry->content_type_len+1); + } + ++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)) ++{ ++ sapi_module.input_filter = input_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) ++{ ++ sapi_module.upload_varname_filter = upload_varname_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) ++{ ++ sapi_module.pre_upload_filter = pre_upload_filter; ++ return SUCCESS; ++} ++ ++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)) ++{ ++ sapi_module.upload_content_filter = upload_content_filter; ++ return SUCCESS; ++} ++ ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) ++{ ++ sapi_module.post_upload_filter = post_upload_filter; ++ return SUCCESS; ++} ++ + + SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)) + { +@@ -884,11 +914,6 @@ + return SUCCESS; + } + +-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)) +-{ +- sapi_module.input_filter = input_filter; +- return SUCCESS; +-} + + SAPI_API int sapi_flush(TSRMLS_D) + { +diff -Nura php-5.1.6/main/SAPI.h hardening-patch-5.1.6-0.4.15/main/SAPI.h +--- php-5.1.6/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/SAPI.h 2006-09-07 19:41:16.000000000 +0200 +@@ -190,6 +190,10 @@ + SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); + 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)); + ++SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); ++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)); ++SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); ++ + SAPI_API int sapi_flush(TSRMLS_D); + SAPI_API struct stat *sapi_get_stat(TSRMLS_D); + SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC); +@@ -254,6 +258,11 @@ + int (*get_target_gid)(gid_t * TSRMLS_DC); + + unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); ++ ++ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); ++ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); ++ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); ++ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); + + void (*ini_defaults)(HashTable *configuration_hash); + int phpinfo_as_text; +@@ -279,7 +288,11 @@ + + #define SAPI_DEFAULT_MIMETYPE "text/html" + #define SAPI_DEFAULT_CHARSET "" ++#if HARDENING_PATCH ++#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" ++#else + #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION ++#endif + + #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) + #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) +@@ -287,6 +300,11 @@ + #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) + #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) + ++#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) ++#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) ++#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) ++#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) ++ + BEGIN_EXTERN_C() + SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); + SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); +diff -Nura php-5.1.6/main/snprintf.c hardening-patch-5.1.6-0.4.15/main/snprintf.c +--- php-5.1.6/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/snprintf.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1014,7 +1014,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = cc; ++#endif + goto skip_output; + + /* +diff -Nura php-5.1.6/main/spprintf.c hardening-patch-5.1.6-0.4.15/main/spprintf.c +--- php-5.1.6/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/main/spprintf.c 2006-09-07 19:41:16.000000000 +0200 +@@ -630,7 +630,11 @@ + + + case 'n': ++#if HARDENING_PATCH_FMT_PROTECT ++ php_security_log(S_MISC, "'n' specifier within format string"); ++#else + *(va_arg(ap, int *)) = xbuf->len; ++#endif + goto skip_output; + + /* +diff -Nura php-5.1.6/pear/Makefile.frag hardening-patch-5.1.6-0.4.15/pear/Makefile.frag +--- php-5.1.6/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/pear/Makefile.frag 2006-09-07 19:41:16.000000000 +0200 +@@ -3,7 +3,7 @@ + peardir=$(PEAR_INSTALLDIR) + + # Skip all php.ini files altogether +-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 ++PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar + + install-pear-installer: $(SAPI_CLI_PATH) + @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" +diff -Nura php-5.1.6/php.ini-dist hardening-patch-5.1.6-0.4.15/php.ini-dist +--- php-5.1.6/php.ini-dist 2006-08-14 20:40:19.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/php.ini-dist 2006-09-07 19:41:16.000000000 +0200 +@@ -1198,6 +1198,209 @@ + ; instead of original one. + soap.wsdl_cache_ttl=86400 + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-5.1.6/php.ini-recommended hardening-patch-5.1.6-0.4.15/php.ini-recommended +--- php-5.1.6/php.ini-recommended 2006-08-14 20:40:19.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/php.ini-recommended 2006-09-07 19:41:16.000000000 +0200 +@@ -1256,6 +1256,209 @@ + ; instead of original one. + soap.wsdl_cache_ttl=86400 + ++[hardening-patch] ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's logging ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; ++; hphp.log.syslog - Configures level for alerts reported through syslog ++; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog ++; hphp.log.script - Configures level for alerts reported through external script ++; ++; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. ++; Or each number up to get desired Hardening-Patch's reporting level ++; ++; S_ALL - All alerts ++; S_MEMORY - All canary violations and the safe unlink protection use this class ++; S_VARS - All variable filters trigger this class ++; S_FILES - All violation of uploaded files filter use this class ++; S_INCLUDE - The protection against malicious include filenames use this class ++; S_SQL - Failed SQL queries in MySQL are logged with this class ++; S_EXECUTOR - The execution depth protection uses this logging class ++; S_MISC - All other log messages (f.e. format string protection) use this class ++; ++; Example: ++; ++; - Report all alerts (except memory alerts) to the SAPI errorlog, ++; memory alerts through syslog and SQL+Include alerts fo the script ++; ++;hphp.log.syslog = S_MEMORY ++;hphp.log.sapi = S_ALL & ~S_MEMORY ++;hphp.log.script = S_INCLUDE | S_SQL ++; ++; Syslog logging: ++; ++; - Facility configuration: one of the following facilities ++; ++; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON ++; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS ++; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ++; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 ++; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID ++; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT ++; LOG_PERROR ++; ++; - Priority configuration: one of the followinf priorities ++; ++; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING ++; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR ++; ++hphp.log.syslog.priority = LOG_ALERT ++hphp.log.syslog.facility = LOG_USER ++; ++; Script logging: ++; ++;hphp.log.script.name = /home/hphp/log_script ++; ++; Alert configuration: ++; ++; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR ++; ++;hphp.log.use-x-forwarded-for = On ++; ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's Executor options ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Execution depth limit ++;hphp.executor.max_depth = 8000 ++ ++; White-/blacklist for function calls during normal execution ++;hphp.executor.func.whitelist = ord,chr ++;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for function calls during eval() execution ++;hphp.executor.eval.whitelist = ord,chr ++;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru ++ ++; White-/blacklist for URLs allowes in include filenames ++; ++; - When both options are not set all URLs are forbidden ++; ++; - When both options are set whitelist is taken and blacklist ignored ++; ++; - An entry in the lists is either a URL sheme like: http, https ++; or the beginning of an URL like: php://input ++; ++;hphp.executor.include.whitelist = cookietest ++;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's REQUEST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of REQUEST variables ++hphp.request.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.request.max_varname_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.request.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.request.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.request.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.request.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.request.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's COOKIE variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.cookie.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.cookie.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.cookie.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.cookie.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.cookie.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.cookie.max_value_length = 10000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.cookie.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's GET variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of COOKIE variables ++hphp.get.max_vars = 100 ++ ++; Limits the length of variable names (without indices) ++hphp.get.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.get.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.get.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.get.max_array_depth = 50 ++ ++; Limits the length of variable values ++hphp.get.max_value_length = 512 ++ ++; Disallow ASCII-NUL characters in input ++hphp.get.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's POST variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of POST variables ++hphp.post.max_vars = 200 ++ ++; Limits the length of variable names (without indices) ++hphp.post.max_name_length = 64 ++ ++; Limits the length of complete variable names (with indices) ++hphp.post.max_totalname_length = 256 ++ ++; Limits the length of array indices ++hphp.post.max_array_index_length = 64 ++ ++; Limits the depth of arrays ++hphp.post.max_array_depth = 100 ++ ++; Limits the length of variable values ++hphp.post.max_value_length = 65000 ++ ++; Disallow ASCII-NUL characters in input ++hphp.post.disallow_nul = 1 ++ ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++; Hardening-Patch's fileupload variable filters ; ++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ++ ++; Limits the number of uploadable files ++hphp.upload.max_uploads = 25 ++ ++; Filter out the upload of ELF executables ++hphp.upload.disallow_elf_files = On ++ ++; External filterscript for upload verification ++;hphp.upload.verification_script = /home/hphp/verify_script ++ ++ + ; Local Variables: + ; tab-width: 4 + ; End: +diff -Nura php-5.1.6/run-tests.php hardening-patch-5.1.6-0.4.15/run-tests.php +--- php-5.1.6/run-tests.php 2006-08-23 14:43:53.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/run-tests.php 2006-09-07 19:41:16.000000000 +0200 +@@ -161,6 +161,10 @@ + 'error_reporting=4095', + 'display_errors=1', + 'log_errors=0', ++ 'hphp.executor.include.whitelist=cookietest', ++ 'hphp.log.syslog=0', ++ 'hphp.log.sapi=0', ++ 'hphp.log.script=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=1', +diff -Nura php-5.1.6/sapi/apache/mod_php5.c hardening-patch-5.1.6-0.4.15/sapi/apache/mod_php5.c +--- php-5.1.6/sapi/apache/mod_php5.c 2006-05-14 00:03:51.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/sapi/apache/mod_php5.c 2006-09-07 19:41:16.000000000 +0200 +@@ -482,7 +482,7 @@ + sapi_apache_get_fd, + sapi_apache_force_http_10, + sapi_apache_get_target_uid, +- sapi_apache_get_target_gid ++ sapi_apache_get_target_gid, + }; + /* }}} */ + +@@ -936,7 +936,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component("PHP/" PHP_VERSION); ++#endif + } + } + #endif +diff -Nura php-5.1.6/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.6-0.4.15/sapi/apache2filter/sapi_apache2.c +--- php-5.1.6/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-07 19:41:16.000000000 +0200 +@@ -573,7 +573,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-5.1.6/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.6-0.4.15/sapi/apache2handler/sapi_apache2.c +--- php-5.1.6/sapi/apache2handler/sapi_apache2.c 2006-08-08 15:11:39.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-07 19:41:16.000000000 +0200 +@@ -341,7 +341,11 @@ + { + TSRMLS_FETCH(); + if (PG(expose_php)) { ++#if HARDENING_PATCH ++ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); ++#else + ap_add_version_component(p, "PHP/" PHP_VERSION); ++#endif + } + } + +diff -Nura php-5.1.6/sapi/cgi/cgi_main.c hardening-patch-5.1.6-0.4.15/sapi/cgi/cgi_main.c +--- php-5.1.6/sapi/cgi/cgi_main.c 2006-05-24 09:55:38.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/sapi/cgi/cgi_main.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1448,10 +1448,18 @@ + SG(headers_sent) = 1; + SG(request_info).no_headers = 1; + } ++#if HARDENING_PATCH + #if ZEND_DEBUG +- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); ++ 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()); + #else +- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); ++ 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()); ++#endif ++#else ++#if ZEND_DEBUG ++ 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()); ++#else ++ 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()); ++#endif + #endif + php_end_ob_buffers(1 TSRMLS_CC); + exit(0); +diff -Nura php-5.1.6/sapi/cli/php_cli.c hardening-patch-5.1.6-0.4.15/sapi/cli/php_cli.c +--- php-5.1.6/sapi/cli/php_cli.c 2006-05-12 00:11:17.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/sapi/cli/php_cli.c 2006-09-07 19:41:16.000000000 +0200 +@@ -754,8 +754,14 @@ + goto err; + } + ++#if HARDENING_PATCH ++ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", ++ PHP_VERSION, HARDENING_PATCH_VERSION, ++#else + php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", +- PHP_VERSION, sapi_module.name, __DATE__, __TIME__, ++ PHP_VERSION, ++#endif ++ sapi_module.name, __DATE__, __TIME__, + #if ZEND_DEBUG && defined(HAVE_GCOV) + "(DEBUG GCOV)", + #elif ZEND_DEBUG +diff -Nura php-5.1.6/TSRM/TSRM.h hardening-patch-5.1.6-0.4.15/TSRM/TSRM.h +--- php-5.1.6/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/TSRM/TSRM.h 2006-09-07 19:41:16.000000000 +0200 +@@ -33,6 +33,13 @@ + # define TSRM_API + #endif + ++#if HARDENING_PATCH ++# if HAVE_REALPATH ++# undef realpath ++# define realpath php_realpath ++# endif ++#endif ++ + /* Only compile multi-threading functions if we're in ZTS mode */ + #ifdef ZTS + +@@ -88,6 +95,7 @@ + + #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts + ++ + #ifdef __cplusplus + extern "C" { + #endif +diff -Nura php-5.1.6/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.c +--- php-5.1.6/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-07 19:41:16.000000000 +0200 +@@ -163,6 +163,7 @@ + static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) + { + CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state); ++ cwd_globals->realpath_cache_disable = 0; + cwd_globals->realpath_cache_size = 0; + cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE; + cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL; +@@ -201,6 +202,176 @@ + return p; + } + ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved) ++{ ++ struct stat sb; ++ char *p, *q, *s; ++ size_t left_len, resolved_len; ++ unsigned symlinks; ++ int serrno, slen; ++ int is_dir = 1; ++ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; ++ ++ serrno = errno; ++ symlinks = 0; ++ if (path[0] == '/') { ++ resolved[0] = '/'; ++ resolved[1] = '\0'; ++ if (path[1] == '\0') ++ return (resolved); ++ resolved_len = 1; ++ left_len = strlcpy(left, path + 1, sizeof(left)); ++ } else { ++ if (getcwd(resolved, PATH_MAX) == NULL) { ++ strlcpy(resolved, ".", PATH_MAX); ++ return (NULL); ++ } ++ resolved_len = strlen(resolved); ++ left_len = strlcpy(left, path, sizeof(left)); ++ } ++ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ ++ /* ++ * Iterate over path components in `left'. ++ */ ++ while (left_len != 0) { ++ /* ++ * Extract the next path component and adjust `left' ++ * and its length. ++ */ ++ p = strchr(left, '/'); ++ s = p ? p : left + left_len; ++ if (s - left >= sizeof(next_token)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ memcpy(next_token, left, s - left); ++ next_token[s - left] = '\0'; ++ left_len -= s - left; ++ if (p != NULL) ++ memmove(left, s + 1, left_len + 1); ++ if (resolved[resolved_len - 1] != '/') { ++ if (resolved_len + 1 >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ resolved[resolved_len++] = '/'; ++ resolved[resolved_len] = '\0'; ++ } ++ if (next_token[0] == '\0') ++ continue; ++ else if (strcmp(next_token, ".") == 0) ++ continue; ++ else if (strcmp(next_token, "..") == 0) { ++ /* ++ * Strip the last path component except when we have ++ * single "/" ++ */ ++ if (!is_dir) { ++ errno = ENOENT; ++ return (NULL); ++ } ++ if (resolved_len > 1) { ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ continue; ++ } ++ ++ /* ++ * Append the next path component and lstat() it. If ++ * lstat() fails we still can return successfully if ++ * there are no more path components left. ++ */ ++ resolved_len = strlcat(resolved, next_token, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ if (lstat(resolved, &sb) != 0) { ++ if (errno == ENOENT) { ++ if (p == NULL) { ++ errno = serrno; ++ return (resolved); ++ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { ++ resolved_len = strlcat(resolved, "/", PATH_MAX); ++ resolved_len = strlcat(resolved, left, PATH_MAX); ++ if (resolved_len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ errno = serrno; ++ return (resolved); ++ } ++ } ++ return (NULL); ++ } ++ if (S_ISLNK(sb.st_mode)) { ++ if (symlinks++ > MAXSYMLINKS) { ++ errno = ELOOP; ++ return (NULL); ++ } ++ slen = readlink(resolved, symlink, sizeof(symlink) - 1); ++ if (slen < 0) ++ return (NULL); ++ symlink[slen] = '\0'; ++ if (symlink[0] == '/') { ++ resolved[1] = 0; ++ resolved_len = 1; ++ } else if (resolved_len > 1) { ++ /* Strip the last path component. */ ++ resolved[resolved_len - 1] = '\0'; ++ q = strrchr(resolved, '/'); ++ *q = '\0'; ++ resolved_len = q - resolved; ++ } ++ ++ /* ++ * If there are any path components left, then ++ * append them to symlink. The result is placed ++ * in `left'. ++ */ ++ if (p != NULL) { ++ if (symlink[slen - 1] != '/') { ++ if (slen + 1 >= sizeof(symlink)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ symlink[slen] = '/'; ++ symlink[slen + 1] = 0; ++ } ++ left_len = strlcat(symlink, left, sizeof(left)); ++ if (left_len >= sizeof(left)) { ++ errno = ENAMETOOLONG; ++ return (NULL); ++ } ++ } ++ left_len = strlcpy(left, symlink, sizeof(left)); ++ } else { ++ if (S_ISDIR(sb.st_mode)) { ++ is_dir = 1; ++ } else { ++ is_dir = 0; ++ } ++ } ++ } ++ ++ /* ++ * Remove trailing slash except when the resolved pathname ++ * is a single "/". ++ */ ++ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') ++ resolved[resolved_len - 1] = '\0'; ++ return (resolved); ++} ++#endif ++ + CWD_API void virtual_cwd_startup(void) + { + char cwd[MAXPATHLEN]; +@@ -381,22 +552,33 @@ + #endif + char orig_path[MAXPATHLEN]; + int orig_path_len = 0; ++ int use_realpath_cache = 1; + realpath_cache_bucket *bucket; + time_t t = 0; + TSRMLS_FETCH(); + + if (path_length == 0) + return (0); +- if (path_length >= MAXPATHLEN) ++ if (path_length >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return (1); ++ } ++ ++ /* Disable realpath cache if safe_mode or open_basedir are set */ ++ if (CWDG(realpath_cache_disable)) { ++ use_realpath_cache = 0; ++ } + +- if (use_realpath && CWDG(realpath_cache_size_limit)) { ++ if (use_realpath && use_realpath_cache) { + if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { + memcpy(orig_path, path, path_length+1); + orig_path_len = path_length; + } else { + orig_path_len = path_length + state->cwd_length + 1; + if (orig_path_len >= MAXPATHLEN) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(orig_path, state->cwd, state->cwd_length); +@@ -414,6 +596,8 @@ + if (verify_path && verify_path(state)) { + CWD_STATE_FREE(state); + *state = old_state; ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } else { + CWD_STATE_FREE(&old_state); +@@ -431,8 +615,9 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + } else { /* Concat current directory with relative path and then run realpath() on it */ +@@ -441,6 +626,8 @@ + + ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); + if (!tmp) { ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + memcpy(ptr, state->cwd, state->cwd_length); +@@ -451,6 +638,8 @@ + *ptr = '\0'; + if (strlen(tmp) >= MAXPATHLEN) { + free(tmp); ++ state->cwd[0] = 0; ++ state->cwd_length = 0; + return 1; + } + if (use_realpath) { +@@ -458,9 +647,10 @@ + path = resolved_path; + path_length = strlen(path); + } else { +- /* disable for now + free(tmp); +- return 1; */ ++ state->cwd[0] = 0; ++ state->cwd_length = 0; ++ return 1; + } + } + free(tmp); +@@ -599,7 +789,7 @@ + #endif + free(free_path); + +- if (use_realpath && CWDG(realpath_cache_size_limit)) { ++ if (use_realpath && use_realpath_cache) { + realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); + } + +diff -Nura php-5.1.6/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.h +--- php-5.1.6/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-07 19:41:16.000000000 +0200 +@@ -127,6 +127,22 @@ + + typedef int (*verify_path_func)(const cwd_state *); + ++#ifndef HAVE_STRLCPY ++CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); ++#undef strlcpy ++#define strlcpy php_strlcpy ++#endif ++ ++#ifndef HAVE_STRLCAT ++CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); ++#undef strlcat ++#define strlcat php_strlcat ++#endif ++ ++ ++#if HARDENING_PATCH ++CWD_API char *php_realpath(const char *path, char *resolved); ++#endif + CWD_API void virtual_cwd_startup(void); + CWD_API void virtual_cwd_shutdown(void); + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); +@@ -199,6 +215,7 @@ + long realpath_cache_size_limit; + long realpath_cache_ttl; + realpath_cache_bucket *realpath_cache[1024]; ++ int realpath_cache_disable; + } virtual_cwd_globals; + + #ifdef ZTS +diff -Nura php-5.1.6/Zend/zend_alloc.c hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.c +--- php-5.1.6/Zend/zend_alloc.c 2006-08-10 19:16:24.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.c 2006-09-07 19:46:06.000000000 +0200 +@@ -64,6 +64,11 @@ + # define END_MAGIC_SIZE 0 + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++# define CANARY_SIZE sizeof(unsigned int) ++#else ++# define CANARY_SIZE 0 ++#endif + + # if MEMORY_LIMIT + # if ZEND_DEBUG +@@ -113,9 +118,17 @@ + if (p==AG(head)) { \ + AG(head) = p->pNext; \ + } else { \ ++ if (p != p->pLast->pNext) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pLast->pNext = p->pNext; \ + } \ + if (p->pNext) { \ ++ if (p != p->pNext->pLast) { \ ++ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ ++ exit(1); \ ++ } \ + p->pNext->pLast = p->pLast; \ + } + #else +@@ -154,6 +167,12 @@ + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { ++ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); ++ exit(1); ++ } ++#endif + CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); + + if (size > INT_MAX || SIZE < size) { +@@ -176,6 +195,10 @@ + AG(cache_stats)[CACHE_INDEX][1]++; + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } else { +@@ -191,7 +214,7 @@ + AG(allocated_memory_peak) = AG(allocated_memory); + } + #endif +- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); + #if !ZEND_DISABLE_MEMORY_CACHE + } + #endif +@@ -224,7 +247,10 @@ + # endif + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif +- ++#if HARDENING_PATCH_MM_PROTECT ++ p->canary = HG(canary_1); ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); + return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); + } +@@ -252,6 +278,10 @@ + } + } + ++ ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); ++#endif + zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset); + return 0; + } +@@ -284,9 +314,25 @@ + + ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); + DECLARE_CACHE_VARS(); + TSRMLS_FETCH(); ++ ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++efree_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); ++ exit(1); ++ } ++ /* to catch double efree()s */ ++ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); ++ p->canary = 0; ++#endif + + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { +@@ -327,23 +373,35 @@ + + ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { +- void *p; +- int final_size = size*nmemb; ++ char *p; ++ size_t _size = nmemb * size; ++ ++ if (nmemb && (_size/nmemb!=size)) { ++#if HARDENING_PATCH ++ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); ++#endif ++ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); ++#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID ++ kill(getpid(), SIGSEGV); ++#else ++ exit(1); ++#endif ++ } + +- HANDLE_BLOCK_INTERRUPTIONS(); +- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); +- if (!p) { +- HANDLE_UNBLOCK_INTERRUPTIONS(); +- return (void *) p; ++ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); ++ if (p) { ++ memset(p, 0, _size); + } +- memset(p, 0, final_size); +- HANDLE_UNBLOCK_INTERRUPTIONS(); +- return p; ++ ++ return ((void *)p); + } + + + ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) + { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary_2; ++#endif + zend_mem_header *p; + zend_mem_header *orig; + DECLARE_CACHE_VARS(); +@@ -355,6 +413,16 @@ + + p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); + ++#if HARDENING_PATCH_MM_PROTECT ++ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; ++ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); ++ if (canary_2 != HG(canary_2)) { ++erealloc_canary_mismatch: ++ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); ++ exit(1); ++ } ++#endif ++ + #if defined(ZTS) && TSRM_DEBUG + if (p->thread_id != tsrm_thread_id()) { + void *new_p; +@@ -385,7 +453,7 @@ + } + #endif + REMOVE_POINTER_FROM_LIST(p); +- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); ++ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); + erealloc_error: + if (!p) { + if (!allow_failure) { +@@ -408,6 +476,9 @@ + memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); + #endif + ++#if HARDENING_PATCH_MM_PROTECT ++ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); ++#endif + p->size = size; + + HANDLE_UNBLOCK_INTERRUPTIONS(); +@@ -482,6 +553,10 @@ + { + AG(head) = NULL; + ++#if HARDENING_PATCH_MM_PROTECT ++ HG(canary_1) = zend_canary(); ++ HG(canary_2) = zend_canary(); ++#endif + #if MEMORY_LIMIT + AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ + AG(allocated_memory) = 0; +diff -Nura php-5.1.6/Zend/zend_alloc.h hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.h +--- php-5.1.6/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.h 2006-09-07 19:41:16.000000000 +0200 +@@ -35,6 +35,9 @@ + #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL + + typedef struct _zend_mem_header { ++#if HARDENING_PATCH_MM_PROTECT ++ unsigned int canary; ++#endif + #if ZEND_DEBUG + long magic; + char *filename; +diff -Nura php-5.1.6/Zend/zend_API.h hardening-patch-5.1.6-0.4.15/Zend/zend_API.h +--- php-5.1.6/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_API.h 2006-09-07 19:41:16.000000000 +0200 +@@ -47,6 +47,7 @@ + #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) + + #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 }, ++#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 }, + + #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0) + #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0) +diff -Nura php-5.1.6/Zend/zend_builtin_functions.c hardening-patch-5.1.6-0.4.15/Zend/zend_builtin_functions.c +--- php-5.1.6/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_builtin_functions.c 2006-09-07 19:41:16.000000000 +0200 +@@ -53,6 +53,9 @@ + static ZEND_FUNCTION(crash); + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++static ZEND_FUNCTION(heap_overflow); ++#endif + static ZEND_FUNCTION(get_included_files); + static ZEND_FUNCTION(is_subclass_of); + static ZEND_FUNCTION(is_a); +@@ -113,6 +116,9 @@ + ZEND_FE(crash, NULL) + #endif + #endif ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ ZEND_FE(heap_overflow, NULL) ++#endif + ZEND_FE(get_included_files, NULL) + ZEND_FALIAS(get_required_files, get_included_files, NULL) + ZEND_FE(is_subclass_of, NULL) +@@ -1103,6 +1109,19 @@ + + #endif /* ZEND_DEBUG */ + ++ ++#if HARDENING_PATCH_MM_PROTECT_DEBUG ++ZEND_FUNCTION(heap_overflow) ++{ ++ char *nowhere = emalloc(10); ++ ++ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); ++ ++ efree(nowhere); ++} ++#endif ++ ++ + /* {{{ proto array get_included_files(void) + Returns an array with the file names that were include_once()'d */ + ZEND_FUNCTION(get_included_files) +diff -Nura php-5.1.6/Zend/zend.c hardening-patch-5.1.6-0.4.15/Zend/zend.c +--- php-5.1.6/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend.c 2006-09-07 19:41:16.000000000 +0200 +@@ -55,6 +55,12 @@ + ZEND_API void (*zend_unblock_interruptions)(void); + ZEND_API void (*zend_ticks_function)(int ticks); + ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); ++#if HARDENING_PATCH ++ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); + ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); + +@@ -74,9 +80,391 @@ + return SUCCESS; + } + ++#if HARDENING_PATCH ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; ++ } else { ++ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_facility) = LOG_USER; ++ } else { ++ EG(hphp_log_syslog_facility) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) ++{ ++ if (!new_value) { ++ EG(hphp_log_syslog_priority) = LOG_ALERT; ++ } else { ++ EG(hphp_log_syslog_priority) = atoi(new_value); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_sapi) ++{ ++ if (!new_value) { ++ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; ++ } else { ++ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_script) ++{ ++ if (!new_value) { ++ EG(hphp_log_script) = S_ALL & ~S_MEMORY; ++ } else { ++ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); ++ } ++ return SUCCESS; ++} ++static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) ++{ ++ if (EG(hphp_log_scriptname)) { ++ pefree(EG(hphp_log_scriptname),1); ++ } ++ EG(hphp_log_scriptname) = NULL; ++ if (new_value) { ++ EG(hphp_log_scriptname) = pestrdup(new_value,1); ++ } ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_whitelist_destroy: ++ if (HG(include_whitelist)) { ++ zend_hash_destroy(HG(include_whitelist)); ++ pefree(HG(include_whitelist),1); ++ } ++ HG(include_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_whitelist_destroy; ++ } ++ ++ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++include_blacklist_destroy: ++ if (HG(include_blacklist)) { ++ zend_hash_destroy(HG(include_blacklist)); ++ pefree(HG(include_blacklist),1); ++ } ++ HG(include_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto include_blacklist_destroy; ++ } ++ ++ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_whitelist_destroy: ++ if (HG(eval_whitelist)) { ++ zend_hash_destroy(HG(eval_whitelist)); ++ pefree(HG(eval_whitelist),1); ++ } ++ HG(eval_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_whitelist_destroy; ++ } ++ ++ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++eval_blacklist_destroy: ++ if (HG(eval_blacklist)) { ++ zend_hash_destroy(HG(eval_blacklist)); ++ pefree(HG(eval_blacklist), 1); ++ } ++ HG(eval_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto eval_blacklist_destroy; ++ } ++ ++ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_whitelist_destroy: ++ if (HG(func_whitelist)) { ++ zend_hash_destroy(HG(func_whitelist)); ++ pefree(HG(func_whitelist),1); ++ } ++ HG(func_whitelist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_whitelist_destroy; ++ } ++ ++ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ return SUCCESS; ++} ++ ++static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) ++{ ++ char *s = NULL, *e, *val; ++ unsigned long dummy = 1; ++ ++ if (!new_value) { ++func_blacklist_destroy: ++ if (HG(func_blacklist)) { ++ zend_hash_destroy(HG(func_blacklist)); ++ pefree(HG(func_blacklist),1); ++ } ++ HG(func_blacklist) = NULL; ++ return SUCCESS; ++ } ++ if (!(*new_value)) { ++ goto func_blacklist_destroy; ++ } ++ ++ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); ++ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); ++ ++ val = zend_str_tolower_dup(new_value, strlen(new_value)); ++ e = val; ++ ++ while (*e) { ++ switch (*e) { ++ case ' ': ++ case ',': ++ if (s) { ++ *e = '\0'; ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ s = NULL; ++ } ++ break; ++ default: ++ if (!s) { ++ s = e; ++ } ++ break; ++ } ++ e++; ++ } ++ if (s) { ++ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); ++ } ++ efree(val); ++ ++ ++ return SUCCESS; ++} ++ ++#endif + + ZEND_INI_BEGIN() + ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) ++#if HARDENING_PATCH ++ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) ++ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) ++ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) ++ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) ++ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) ++ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) ++ 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) ++ ++ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) ++ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) ++ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) ++ ++ 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) ++ 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) ++ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) ++ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) ++#endif + STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals) + #ifdef ZEND_MULTIBYTE + STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) +@@ -501,9 +889,13 @@ + EG(user_error_handler) = NULL; + EG(user_exception_handler) = NULL; + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(in_autoload) = NULL; + EG(current_execute_data) = NULL; + EG(current_module) = NULL; ++#if HARDENING_PATCH ++ EG(hphp_log_scriptname) = NULL; ++#endif + } + + +@@ -574,6 +966,14 @@ + extern zend_scanner_globals language_scanner_globals; + #endif + ++ /* Set up Hardening-Patch utility functions first */ ++#if HARDENING_PATCH ++ zend_security_log = utility_functions->security_log_function; ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ zend_is_valid_include = utility_functions->is_valid_include; ++#endif ++ + #ifdef ZTS + ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + #else +@@ -777,6 +1177,7 @@ + } + CG(unclean_shutdown) = 1; + CG(in_compilation) = EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(current_execute_data) = NULL; + longjmp(EG(bailout), FAILURE); + } +diff -Nura php-5.1.6/Zend/zend_canary.c hardening-patch-5.1.6-0.4.15/Zend/zend_canary.c +--- php-5.1.6/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_canary.c 2006-09-07 19:41:16.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* ++ +----------------------------------------------------------------------+ ++ | Hardening-Patch for PHP | ++ +----------------------------------------------------------------------+ ++ | Copyright (c) 2004-2005 Stefan Esser | ++ +----------------------------------------------------------------------+ ++ | This source file is subject to version 2.02 of the PHP license, | ++ | that is bundled with this package in the file LICENSE, and is | ++ | available at through the world-wide-web at | ++ | http://www.php.net/license/2_02.txt. | ++ | If you did not receive a copy of the PHP license and are unable to | ++ | obtain it through the world-wide-web, please send a note to | ++ | license@php.net so we can mail you a copy immediately. | ++ +----------------------------------------------------------------------+ ++ | Author: Stefan Esser | ++ +----------------------------------------------------------------------+ ++ */ ++/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ ++ ++#include "zend.h" ++ ++#include ++#include ++ ++ ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ ++/* will be replaced later with more compatible method */ ++ZEND_API unsigned int zend_canary() ++{ ++ time_t t; ++ unsigned int canary; ++ int fd; ++ ++ fd = open("/dev/urandom", 0); ++ if (fd != -1) { ++ int r = read(fd, &canary, sizeof(canary)); ++ close(fd); ++ if (r == sizeof(canary)) { ++ return (canary); ++ } ++ } ++ /* not good but we never want to do this */ ++ time(&t); ++ canary = *(unsigned int *)&t + getpid() << 16; ++ return (canary); ++} ++#endif ++ ++ ++/* ++ * Local variables: ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * End: ++ * vim600: sw=4 ts=4 fdm=marker ++ * vim<600: sw=4 ts=4 ++ */ +diff -Nura php-5.1.6/Zend/zend_compile.c hardening-patch-5.1.6-0.4.15/Zend/zend_compile.c +--- php-5.1.6/Zend/zend_compile.c 2006-05-02 17:49:26.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_compile.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1093,6 +1093,13 @@ + op_array.prototype = NULL; + + op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array.created_by_eval = 1; ++ } else { ++ op_array.created_by_eval = 0; ++ } ++#endif + + if (is_method) { + char *short_class_name = CG(active_class_entry)->name; +diff -Nura php-5.1.6/Zend/zend_compile.h hardening-patch-5.1.6-0.4.15/Zend/zend_compile.h +--- php-5.1.6/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_compile.h 2006-09-07 19:41:16.000000000 +0200 +@@ -217,6 +217,9 @@ + zend_uint doc_comment_len; + + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; ++#if HARDENING_PATCH ++ zend_bool created_by_eval; ++#endif + }; + + +@@ -295,6 +298,8 @@ + zval ***CVs; + zend_bool original_in_execution; + HashTable *symbol_table; ++ zend_uint original_in_code_type; ++ zend_uint execute_depth; + struct _zend_execute_data *prev_execute_data; + zval *old_error_reporting; + }; +@@ -617,6 +622,7 @@ + #define ZEND_OVERLOADED_FUNCTION 3 + #define ZEND_EVAL_CODE 4 + #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5 ++#define ZEND_SANDBOX_CODE 6 + + #define ZEND_INTERNAL_CLASS 1 + #define ZEND_USER_CLASS 2 +diff -Nura php-5.1.6/Zend/zend_constants.c hardening-patch-5.1.6-0.4.15/Zend/zend_constants.c +--- php-5.1.6/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_constants.c 2006-09-07 19:41:16.000000000 +0200 +@@ -109,6 +109,74 @@ + REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); + + REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); ++#if HARDENING_PATCH ++ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); ++ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); ++ ++ /* error levels */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); ++ /* facility: type of program logging the message */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NEWS ++ /* No LOG_NEWS on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ ++#endif ++#ifdef LOG_UUCP ++ /* No LOG_UUCP on HP-UX */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_CRON ++ /* apparently some systems don't have this one */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_AUTHPRIV ++ /* AIX doesn't have LOG_AUTHPRIV */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); ++#endif ++#if !defined(PHP_WIN32) && !defined(NETWARE) ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); ++#endif ++ /* options */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); ++#ifdef LOG_NOWAIT ++ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); ++#endif ++#ifdef LOG_PERROR ++ /* AIX doesn't have LOG_PERROR */ ++ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ ++#endif ++#endif + + /* true/false constants */ + { +diff -Nura php-5.1.6/Zend/zend_errors.h hardening-patch-5.1.6-0.4.15/Zend/zend_errors.h +--- php-5.1.6/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_errors.h 2006-09-07 19:41:16.000000000 +0200 +@@ -38,6 +38,19 @@ + #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) + #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) + ++#if HARDENING_PATCH ++#define S_MEMORY (1<<0L) ++#define S_VARS (1<<1L) ++#define S_FILES (1<<2L) ++#define S_INCLUDE (1<<3L) ++#define S_SQL (1<<4L) ++#define S_EXECUTOR (1<<5L) ++#define S_MAIL (1<<6L) ++#define S_MISC (1<<30L) ++#define S_INTERNAL (1<<29L) ++#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) ++#endif ++ + #endif /* ZEND_ERRORS_H */ + + /* +diff -Nura php-5.1.6/Zend/zend_execute_API.c hardening-patch-5.1.6-0.4.15/Zend/zend_execute_API.c +--- php-5.1.6/Zend/zend_execute_API.c 2006-04-21 00:49:20.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_execute_API.c 2006-09-07 19:41:16.000000000 +0200 +@@ -142,6 +142,7 @@ + EG(class_table) = CG(class_table); + + EG(in_execution) = 0; ++ EG(in_code_type) = 0; + EG(in_autoload) = NULL; + EG(autoload_func) = NULL; + +@@ -784,6 +785,39 @@ + if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) { + EX(function_state).function = NULL; + } ++#if HARDENING_PATCH ++ else { ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc); ++ efree(function_name_lc); ++ zend_bailout(); ++ } ++ } ++ } ++#endif + efree(function_name_lc); + } + +@@ -1076,7 +1110,7 @@ + return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC); + } + +-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC) + { + zval pv; + zend_op_array *new_op_array; +@@ -1109,6 +1143,7 @@ + zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); + zend_op **original_opline_ptr = EG(opline_ptr); + ++ new_op_array->type = type; + EG(return_value_ptr_ptr) = &local_retval_ptr; + EG(active_op_array) = new_op_array; + EG(no_extensions)=1; +@@ -1143,6 +1178,12 @@ + } + + ++ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) ++{ ++ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); ++} ++ ++ + ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) + { + int result; +diff -Nura php-5.1.6/Zend/zend_execute.c hardening-patch-5.1.6-0.4.15/Zend/zend_execute.c +--- php-5.1.6/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_execute.c 2006-09-07 19:41:16.000000000 +0200 +@@ -1351,6 +1351,37 @@ + /* OBJ-TBI - doesn't support new object model! */ + zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + return 0; + } +@@ -1396,6 +1427,7 @@ + efree(EX(Ts)); \ + } \ + EG(in_execution) = EX(original_in_execution); \ ++ EG(in_code_type) = EX(original_in_code_type); \ + EG(current_execute_data) = EX(prev_execute_data); \ + ZEND_VM_RETURN() + +diff -Nura php-5.1.6/Zend/zend_extensions.c hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.c +--- php-5.1.6/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.c 2006-09-07 19:41:16.000000000 +0200 +@@ -55,23 +55,44 @@ + return FAILURE; + } + ++ /* check if module is compiled against Hardening-Patch */ ++ if (extension_version_info->zend_extension_api_no < 1000000000) { ++ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } ++ ++ ++ /* check if module is compiled against correct Hardening-Patch version */ ++ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { ++ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" ++ "The Hardening-Patch version %d is installed.\n\n", ++ new_extension->name, ++ extension_version_info->zend_extension_api_no, ++ HARDENING_PATCH_ZEND_EXTENSION_API_NO); ++ DL_UNLOAD(handle); ++ return FAILURE; ++ } + + /* allow extension to proclaim compatibility with any Zend version */ +- 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)) { +- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { ++ 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)) { ++ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is outdated.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO); + DL_UNLOAD(handle); + return FAILURE; +- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { ++ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { + fprintf(stderr, "%s requires Zend Engine API version %d.\n" + "The Zend Engine API version %d which is installed, is newer.\n" + "Contact %s at %s for a later version of %s.\n\n", + new_extension->name, +- extension_version_info->zend_extension_api_no, ++ extension_version_info->real_zend_extension_api_no, + ZEND_EXTENSION_API_NO, + new_extension->author, + new_extension->URL, +diff -Nura php-5.1.6/Zend/zend_extensions.h hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.h +--- php-5.1.6/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.h 2006-09-07 19:41:16.000000000 +0200 +@@ -24,9 +24,11 @@ + + #include "zend_compile.h" + +-/* The first number is the engine version and the rest is the date. ++/* The first API number is a flag saying that Hardening-Patch is used. ++ * The second number is the engine version and the date. + * This way engine 2 API no. is always greater than engine 1 API no.. + */ ++#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106 + #define ZEND_EXTENSION_API_NO 220051025 + + typedef struct _zend_extension_version_info { +@@ -34,6 +36,7 @@ + char *required_zend_version; + unsigned char thread_safe; + unsigned char debug; ++ int real_zend_extension_api_no; + } zend_extension_version_info; + + +@@ -101,7 +104,7 @@ + + + #define ZEND_EXTENSION() \ +- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } ++ 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 } + + #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 + #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 +diff -Nura php-5.1.6/Zend/zend_globals.h hardening-patch-5.1.6-0.4.15/Zend/zend_globals.h +--- php-5.1.6/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_globals.h 2006-09-07 19:41:16.000000000 +0200 +@@ -180,6 +180,16 @@ + + int error_reporting; + int orig_error_reporting; ++#if HARDENING_PATCH ++ int hphp_log_syslog; ++ int hphp_log_syslog_facility; ++ int hphp_log_syslog_priority; ++ int hphp_log_sapi; ++ int hphp_log_script; ++ char *hphp_log_scriptname; ++ zend_bool hphp_log_use_x_forwarded_for; ++ long hphp_executor_max_depth; ++#endif + int exit_status; + + zend_op_array *active_op_array; +@@ -197,6 +207,7 @@ + int ticks_count; + + zend_bool in_execution; ++ zend_uint in_code_type; + HashTable *in_autoload; + zend_function *autoload_func; + zend_bool bailout_set; +diff -Nura php-5.1.6/Zend/zend.h hardening-patch-5.1.6-0.4.15/Zend/zend.h +--- php-5.1.6/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend.h 2006-09-07 19:41:16.000000000 +0200 +@@ -297,6 +297,7 @@ + /* Variable information */ + zvalue_value value; /* value */ + zend_uint refcount; ++ zend_ushort flags; + zend_uchar type; /* active type */ + zend_uchar is_ref; + }; +@@ -382,6 +383,12 @@ + int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); + int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); + char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); ++#if HARDENING_PATCH ++ void (*security_log_function)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++ int (*is_valid_include)(zval *z); ++#endif + } zend_utility_functions; + + +@@ -519,7 +526,16 @@ + extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); + extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); + extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); ++#if HARDENING_PATCH ++extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); ++#endif ++#if HARDENING_PATCH_INC_PROTECT ++extern ZEND_API int (*zend_is_valid_include)(zval *z); ++#endif + ++#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT ++ZEND_API unsigned int zend_canary(void); ++#endif + + ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); + +@@ -644,6 +660,11 @@ + + #include "zend_variables.h" + ++#if HARDENING_PATCH ++#include "hardened_globals.h" ++#include "php_syslog.h" ++#endif ++ + #endif /* ZEND_H */ + + /* +diff -Nura php-5.1.6/Zend/zend_hash.c hardening-patch-5.1.6-0.4.15/Zend/zend_hash.c +--- php-5.1.6/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_hash.c 2006-09-07 19:41:16.000000000 +0200 +@@ -21,6 +21,18 @@ + + #include "zend.h" + ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int zend_hash_canary = 0x1234567; ++ zend_bool zend_hash_canary_inited = 0; ++#endif ++ ++#define CHECK_HASH_CANARY(hash) \ ++ if (zend_hash_canary != (hash)->canary) { \ ++ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++ + #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ + (element)->pNext = (list_head); \ + (element)->pLast = NULL; \ +@@ -138,6 +150,9 @@ + { + uint i = 3; + Bucket **tmp; ++#if HARDENING_PATCH_HASH_PROTECT ++ TSRMLS_FETCH(); ++#endif + + SET_INCONSISTENT(HT_OK); + +@@ -147,6 +162,13 @@ + + ht->nTableSize = 1 << i; + ht->nTableMask = ht->nTableSize - 1; ++#if HARDENING_PATCH_HASH_PROTECT ++ if (zend_hash_canary_inited==0) { ++ zend_hash_canary = zend_canary(); ++ zend_hash_canary_inited = 1; ++ } ++ ht->canary = zend_hash_canary; ++#endif + ht->pDestructor = pDestructor; + ht->arBuckets = NULL; + ht->pListHead = NULL; +@@ -226,6 +248,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -291,6 +316,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -366,6 +394,9 @@ + } + #endif + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + UPDATE_DATA(ht, p, pData, nDataSize); +@@ -414,7 +445,7 @@ + IS_CONSISTENT(ht); + + if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ +- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); ++ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); + if (t) { + HANDLE_BLOCK_INTERRUPTIONS(); + ht->arBuckets = t; +@@ -424,6 +455,7 @@ + HANDLE_UNBLOCK_INTERRUPTIONS(); + return SUCCESS; + } ++ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); + return FAILURE; + } + return SUCCESS; +@@ -489,6 +521,9 @@ + ht->pInternalPointer = p->pListNext; + } + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (p->pData != &p->pDataPtr) { +@@ -513,6 +548,11 @@ + + SET_INCONSISTENT(HT_IS_DESTROYING); + ++#if HARDENING_PATCH_HASH_PROTECT ++ if (ht->pDestructor) { ++ CHECK_HASH_CANARY(ht); ++ } ++#endif + p = ht->pListHead; + while (p != NULL) { + q = p; +@@ -539,6 +579,11 @@ + + SET_INCONSISTENT(HT_CLEANING); + ++#if HARDENING_PATCH_HASH_PROTECT ++ if (ht->pDestructor) { ++ CHECK_HASH_CANARY(ht); ++ } ++#endif + p = ht->pListHead; + while (p != NULL) { + q = p; +@@ -573,6 +618,9 @@ + HANDLE_BLOCK_INTERRUPTIONS(); + + if (ht->pDestructor) { ++#if HARDENING_PATCH_HASH_PROTECT ++ CHECK_HASH_CANARY(ht); ++#endif + ht->pDestructor(p->pData); + } + if (p->pData != &p->pDataPtr) { +diff -Nura php-5.1.6/Zend/zend_hash.h hardening-patch-5.1.6-0.4.15/Zend/zend_hash.h +--- php-5.1.6/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_hash.h 2006-09-07 19:41:16.000000000 +0200 +@@ -58,6 +58,9 @@ + } Bucket; + + typedef struct _hashtable { ++#if HARDENING_PATCH_HASH_PROTECT ++ unsigned int canary; ++#endif + uint nTableSize; + uint nTableMask; + uint nNumOfElements; +diff -Nura php-5.1.6/Zend/zend_ini.c hardening-patch-5.1.6-0.4.15/Zend/zend_ini.c +--- php-5.1.6/Zend/zend_ini.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_ini.c 2006-09-07 19:41:16.000000000 +0200 +@@ -256,7 +256,8 @@ + zend_ini_entry *ini_entry; + TSRMLS_FETCH(); + +- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { ++ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || ++ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) { + return FAILURE; + } + +diff -Nura php-5.1.6/Zend/zend_language_scanner.l hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.l +--- php-5.1.6/Zend/zend_language_scanner.l 2006-04-13 15:48:28.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.l 2006-09-07 19:41:16.000000000 +0200 +@@ -389,6 +389,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-5.1.6/Zend/zend_language_scanner.c hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.c +--- php-5.1.6/Zend/zend_language_scanner.c 2006-08-23 14:55:05.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.c 2006-09-07 19:41:16.000000000 +0200 +@@ -3075,6 +3075,13 @@ + compilation_successful=0; + } else { + init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); ++#if HARDENING_PATCH ++ if (EG(in_code_type)==ZEND_EVAL_CODE) { ++ op_array->created_by_eval = 1; ++ } else { ++ op_array->created_by_eval = 0; ++ } ++#endif + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + compiler_result = zendparse(TSRMLS_C); +diff -Nura php-5.1.6/Zend/zend_llist.c hardening-patch-5.1.6-0.4.15/Zend/zend_llist.c +--- php-5.1.6/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_llist.c 2006-09-07 19:41:16.000000000 +0200 +@@ -22,9 +22,49 @@ + #include "zend.h" + #include "zend_llist.h" + #include "zend_qsort.h" ++#include "zend_globals.h" ++ ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int zend_llist_canary_1 = 0x1234567; ++ unsigned int zend_llist_canary_2 = 0x1553425; ++ zend_bool zend_llist_canary_inited = 0; ++#endif ++ ++#define CHECK_LIST_CANARY(list) \ ++ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ ++ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ ++ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ ++ exit(1); \ ++ } ++ ++#define CHECK_LISTELEMENT_CANARY(elem, list) \ ++ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ ++ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ ++ exit(1); \ ++ } ++ + + ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ ++ if (persistent) { ++ if (!zend_llist_canary_inited) { ++ /* do not change order to ensure thread safety */ ++ zend_llist_canary_1 = zend_canary(); ++ zend_llist_canary_2 = zend_canary(); ++ zend_llist_canary_inited = 1; ++ } ++ } else ++ if (!HG(ll_canary_inited)) { ++ HG(canary_3) = zend_canary(); ++ HG(canary_4) = zend_canary(); ++ HG(ll_canary_inited) = 1; ++ } ++ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); ++ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); ++#endif + l->head = NULL; + l->tail = NULL; + l->count = 0; +@@ -38,6 +78,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->prev = l->tail; + tmp->next = NULL; + if (l->tail) { +@@ -56,6 +101,11 @@ + { + zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); ++#endif + tmp->next = l->head; + tmp->prev = NULL; + if (l->head) { +@@ -93,10 +143,20 @@ + zend_llist_element *current=l->head; + zend_llist_element *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (compare(current->data, element)) { + DEL_LLIST_ELEMENT(current, l); ++#if HARDENING_PATCH_LL_PROTECT ++ current->canary = 0; ++#endif + break; + } + current = next; +@@ -108,7 +168,14 @@ + { + zend_llist_element *current=l->head, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + while (current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(current, l) ++#endif + next = current->next; + if (l->dtor) { + l->dtor(current->data); +@@ -133,7 +200,14 @@ + zend_llist_element *old_tail; + void *data; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if ((old_tail = l->tail)) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(old_tail, l) ++#endif + if (l->tail->prev) { + l->tail->prev->next = NULL; + } +@@ -159,9 +233,16 @@ + { + zend_llist_element *ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(src) ++#endif + zend_llist_init(dst, src->size, src->dtor, src->persistent); + ptr = src->head; + while (ptr) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(ptr, src) ++#endif + zend_llist_add_element(dst, ptr->data); + ptr = ptr->next; + } +@@ -172,11 +253,21 @@ + { + zend_llist_element *element, *next; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + element=l->head; + while (element) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + next = element->next; + if (func(element->data)) { + DEL_LLIST_ELEMENT(element, l); ++#if HARDENING_PATCH_LL_PROTECT ++ element->canary = 0; ++#endif + } + element = next; + } +@@ -187,7 +278,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data TSRMLS_CC); + } + } +@@ -199,6 +296,9 @@ + zend_llist_element **elements; + zend_llist_element *element, **ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + if (l->count <= 0) { + return; + } +@@ -208,6 +308,9 @@ + ptr = &elements[0]; + + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + *ptr++ = element; + } + +@@ -230,7 +333,13 @@ + { + zend_llist_element *element; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, arg TSRMLS_CC); + } + } +@@ -241,8 +350,14 @@ + zend_llist_element *element; + va_list args; + ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LIST_CANARY(l) ++#endif + va_start(args, num_args); + for (element=l->head; element; element=element->next) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(element, l) ++#endif + func(element->data, num_args, args TSRMLS_CC); + } + va_end(args); +@@ -251,6 +366,10 @@ + + ZEND_API int zend_llist_count(zend_llist *l) + { ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + return l->count; + } + +@@ -259,8 +378,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->head; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -272,8 +398,15 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + *current = l->tail; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } else { + return NULL; +@@ -285,9 +418,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->next; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +@@ -299,9 +442,19 @@ + { + zend_llist_position *current = pos ? pos : &l->traverse_ptr; + ++#if HARDENING_PATCH_LL_PROTECT ++ TSRMLS_FETCH(); ++ CHECK_LIST_CANARY(l) ++#endif + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + *current = (*current)->prev; + if (*current) { ++#if HARDENING_PATCH_LL_PROTECT ++ CHECK_LISTELEMENT_CANARY(*current, l) ++#endif + return (*current)->data; + } + } +diff -Nura php-5.1.6/Zend/zend_llist.h hardening-patch-5.1.6-0.4.15/Zend/zend_llist.h +--- php-5.1.6/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_llist.h 2006-09-07 19:41:16.000000000 +0200 +@@ -23,6 +23,9 @@ + #define ZEND_LLIST_H + + typedef struct _zend_llist_element { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary, padding; ++#endif + struct _zend_llist_element *next; + struct _zend_llist_element *prev; + char data[1]; /* Needs to always be last in the struct */ +@@ -35,6 +38,9 @@ + typedef void (*llist_apply_func_t)(void * TSRMLS_DC); + + typedef struct _zend_llist { ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_h; /* head */ ++#endif + zend_llist_element *head; + zend_llist_element *tail; + size_t count; +@@ -42,6 +48,9 @@ + llist_dtor_func_t dtor; + unsigned char persistent; + zend_llist_element *traverse_ptr; ++#if HARDENING_PATCH_LL_PROTECT ++ unsigned int canary_t; /* tail */ ++#endif + } zend_llist; + + typedef zend_llist_element* zend_llist_position; +diff -Nura php-5.1.6/Zend/zend_modules.h hardening-patch-5.1.6-0.4.15/Zend/zend_modules.h +--- php-5.1.6/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_modules.h 2006-09-07 19:41:16.000000000 +0200 +@@ -39,6 +39,7 @@ + extern struct _zend_arg_info fifth_arg_force_ref[6]; + extern struct _zend_arg_info all_args_by_ref[1]; + ++#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106 + #define ZEND_MODULE_API_NO 20050922 + #ifdef ZTS + #define USING_ZTS 1 +@@ -46,13 +47,13 @@ + #define USING_ZTS 0 + #endif + +-#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS ++#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS + #define STANDARD_MODULE_HEADER \ + STANDARD_MODULE_HEADER_EX, NULL, NULL + #define ZE2_STANDARD_MODULE_HEADER \ + STANDARD_MODULE_HEADER_EX, ini_entries, NULL + +-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 ++#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO + + #define STANDARD_MODULE_PROPERTIES \ + NULL, STANDARD_MODULE_PROPERTIES_EX +@@ -87,6 +88,7 @@ + unsigned char type; + void *handle; + int module_number; ++ unsigned int real_zend_api; + }; + + #define MODULE_DEP_REQUIRED 1 +diff -Nura php-5.1.6/Zend/zend_opcode.c hardening-patch-5.1.6-0.4.15/Zend/zend_opcode.c +--- php-5.1.6/Zend/zend_opcode.c 2006-04-10 14:26:53.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_opcode.c 2006-09-07 19:41:16.000000000 +0200 +@@ -98,6 +98,9 @@ + op_array->uses_this = 0; + + op_array->start_op = NULL; ++#if HARDENING_PATCH ++ op_array->created_by_eval = 0; ++#endif + + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); + } +diff -Nura php-5.1.6/Zend/zend_vm_def.h hardening-patch-5.1.6-0.4.15/Zend/zend_vm_def.h +--- php-5.1.6/Zend/zend_vm_def.h 2006-07-06 17:39:23.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_vm_def.h 2006-09-07 19:41:16.000000000 +0200 +@@ -1771,6 +1771,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (OP2_TYPE != IS_CONST) { +@@ -1996,6 +2027,34 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++#endif ++ + EX(object) = NULL; + + FREE_OP1(); +@@ -2711,7 +2770,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -2736,6 +2800,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +diff -Nura php-5.1.6/Zend/zend_vm_execute.h hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.h +--- php-5.1.6/Zend/zend_vm_execute.h 2006-07-06 17:39:23.000000000 +0200 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.h 2006-09-07 19:42:45.000000000 +0200 +@@ -56,6 +56,16 @@ + EX(symbol_table) = EG(active_symbol_table); + EX(prev_execute_data) = EG(current_execute_data); + EG(current_execute_data) = &execute_data; ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif + + EG(in_execution) = 1; + if (op_array->start_op) { +@@ -81,6 +91,18 @@ + */ + EX(function_state).function_symbol_table = NULL; + #endif ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif + + while (1) { + #ifdef ZEND_WIN32 +@@ -724,6 +746,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_CONST != IS_CONST) { +@@ -925,6 +978,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_TMP_VAR != IS_CONST) { +@@ -1083,6 +1167,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_VAR != IS_CONST) { +@@ -1330,6 +1445,37 @@ + efree(lcname); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); ++ efree(lcname); ++ zend_bailout(); ++ } ++ } ++#endif + + efree(lcname); + if (IS_CV != IS_CONST) { +@@ -1635,6 +1781,34 @@ + if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { + zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); + } ++#if HARDENING_PATCH ++ if (EG(in_code_type) == ZEND_EVAL_CODE) { ++ if (HG(eval_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(eval_blacklist) != NULL) { ++ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++ } ++ ++ if (HG(func_whitelist) != NULL) { ++ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } else if (HG(func_blacklist) != NULL) { ++ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { ++ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); ++ zend_bailout(); ++ } ++ } ++#endif ++ + EX(object) = NULL; + + return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +@@ -1914,7 +2088,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -1939,6 +2118,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -4345,7 +4529,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -4370,6 +4559,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -7358,7 +7552,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -7383,6 +7582,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +@@ -19486,7 +19690,12 @@ + int dummy = 1; + zend_file_handle file_handle; + +- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#if HARDENING_PATCH_INC_PROTECT ++ if (zend_is_valid_include(inc_filename) ++ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { ++#else ++ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { ++#endif + + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); +@@ -19511,6 +19720,11 @@ + break; + case ZEND_INCLUDE: + case ZEND_REQUIRE: ++#if HARDENING_PATCH_INC_PROTECT ++ if (!zend_is_valid_include(inc_filename)) { ++ break; ++ } ++#endif + new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); + break; + case ZEND_EVAL: { +diff -Nura php-5.1.6/Zend/zend_vm_execute.skl hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.skl +--- php-5.1.6/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100 ++++ hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.skl 2006-09-07 19:41:16.000000000 +0200 +@@ -27,6 +27,16 @@ + EX(symbol_table) = EG(active_symbol_table); + EX(prev_execute_data) = EG(current_execute_data); + EG(current_execute_data) = &execute_data; ++#if HARDENING_PATCH ++ EX(execute_depth) = 0; ++ ++ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_EVAL_CODE; ++ } else if (op_array->type == ZEND_SANDBOX_CODE) { ++ EG(in_code_type) = ZEND_SANDBOX_CODE; ++ op_array->type = ZEND_EVAL_CODE; ++ } ++#endif + + EG(in_execution) = 1; + if (op_array->start_op) { +@@ -52,6 +62,18 @@ + */ + EX(function_state).function_symbol_table = NULL; + #endif ++#if HARDENING_PATCH ++ if (EX(prev_execute_data) == NULL) { ++ EX(execute_depth) = 0; ++ } else { ++ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; ++ } ++ ++ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { ++ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); ++ zend_bailout(); ++ } ++#endif + + while (1) { + {%ZEND_VM_CONTINUE_LABEL%} diff --git a/hardening-patch-4.4.2-0.4.15.patch b/hardening-patch-4.4.2-0.4.15.patch deleted file mode 100644 index 206dcfa..0000000 --- a/hardening-patch-4.4.2-0.4.15.patch +++ /dev/null @@ -1,9419 +0,0 @@ -diff -Nura php-4.4.2/Changelog.hphp hardening-patch-4.4.2-0.4.15/Changelog.hphp ---- php-4.4.2/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Changelog.hphp 2006-09-07 19:33:12.000000000 +0200 -@@ -0,0 +1,61 @@ -+Changelog of the Hardening-Patch -+-------------------------------- -+ -+0.4.15 - 07. September 2006 -+ -+ PHP4: -+ [+] Fix for potential DOS in handling of include blacklists -+ -+ PHP4+5: -+ [+] Backported a fix for open_basedir problems with insanse PHP scripts -+ [+] Added a fix for ini_restore() PHP security vulnerability -+ -+0.4.14 - 11. August 2006 -+ -+ PHP4: -+ [+] Remove unecessary call to AC_BROKEN_REALPATH -+ -+ PHP5: -+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant -+ -+ PHP4+5: -+ [+] Added a few PHP security fixes / see changelog.secfix for details -+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits -+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments -+ -+0.4.13 - 07. August 2006 -+ -+ PHP4+5: -+ [+] Added a fix for a compile problem on solaris due to missing strcasestr() -+ -+0.4.12 - 19. July 2006 -+ -+ PHP4: -+ [+] Added fixes from sf4 security patch / see changelog.secfix for details -+ -+ PHP5: -+ [+] Added fixes from sf5 security patch / see changelog.secfix for details -+ -+ PHP4+5: -+ [+] Added anti mail spam feature -+ [+] Speedup of zend_hash canary (clear/destroy) -+ [+] Added a fix for a DOS in the handling of URL blacklists -+ -+0.4.11 - 13. May 2006 -+ -+ PHP5: -+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache -+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 -+ -+ PHP4+5: -+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories -+ -+ -+0.4.10 - 11. May 2006 -+ -+ PHP4: -+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed -+ -+ PHP4+5: -+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir -+ -diff -Nura php-4.4.2/Changelog.secfix hardening-patch-4.4.2-0.4.15/Changelog.secfix ---- php-4.4.2/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Changelog.secfix 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,38 @@ -+Changelog of PHP 4.4.2 Security Fixes -+ -+Release 5 - 11. August 2006 -+ -+ [+] Added IMAP open_basedir/safe_mode check -+ [+] Added a upstream fix for previous ext/session fixes -+ [+] Added upstream fix to ext/socket -+ [+] Added sscanf() security fix -+ [+] Added fixes for handling of corrupt .gif files to gdlib -+ -+Release 4 - 13. July 2006 -+ -+ [+] Added recursive array printing fix to phpinfo() XSS fix -+ -+Release 3 - 08. July 2006 -+ -+ [+] Added a fix for an overflow in the bundled libmysql on win32 systems -+ [+] Added a fix for overlong tempfilename -+ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl -+ [+] Added a fix for an integer overflow in str_repeat() -+ [+] Added a variable initialisation in stream factory code -+ [+] Added a fix for crashbugs in http_fopen_wrapper -+ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability -+ [+] Added a *working* wordwrap() fix -+ [+] Added code to make memory_limit work on 64bit systems -+ [+] Added bufferoverflow and high character fix to ext/wddx -+ -+Release 2 - 10. May 2006 -+ -+ [+] Added a fix for the serious zend_hash_del() vulnerability -+ [+] Added a fix for another ext/curl open_basedir/safe_mode bypass vulnerability -+ [+] Added a wordwrap() bufferoverflow fix -+ [+] Added a phpinfo() XSS fix -+ [+] Added html_entity_decode() binary safety fix -+ [+] Added safe_mode/open_basedir fixes to tempnam() and copy() -+ [+] Added check for invalid characters in session identifiers to ext/session -+ [+] Added a fix for a double file unlink in ext/session -+ -diff -Nura php-4.4.2/configure hardening-patch-4.4.2-0.4.15/configure ---- php-4.4.2/configure 2006-01-12 19:24:23.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/configure 2006-09-05 20:30:33.000000000 +0200 -@@ -402,6 +402,16 @@ - ac_default_prefix=/usr/local - # Any additions from configure.in: - ac_help="$ac_help -+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." -+ac_help="$ac_help -+ --disable-hardening-patch-ll-protect Disable the Linked List protection." -+ac_help="$ac_help -+ --disable-hardening-patch-inc-protect Disable include/require protection." -+ac_help="$ac_help -+ --disable-hardening-patch-fmt-protect Disable format string protection." -+ac_help="$ac_help -+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." -+ac_help="$ac_help - - SAPI modules: - " -@@ -854,6 +864,8 @@ - ac_help="$ac_help - --disable-tokenizer Disable tokenizer support" - ac_help="$ac_help -+ --disable-varfilter Disable Hardening-Patch's variable filter" -+ac_help="$ac_help - --enable-wddx Enable WDDX support." - ac_help="$ac_help - --disable-xml Disable XML support using bundled expat lib" -@@ -2942,6 +2954,157 @@ - - - -+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. -+if test "${enable_hardening_patch_mm_protect+set}" = set; then -+ enableval="$enable_hardening_patch_mm_protect" -+ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. -+if test "${enable_hardening_patch_ll_protect+set}" = set; then -+ enableval="$enable_hardening_patch_ll_protect" -+ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. -+if test "${enable_hardening_patch_inc_protect+set}" = set; then -+ enableval="$enable_hardening_patch_inc_protect" -+ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. -+if test "${enable_hardening_patch_fmt_protect+set}" = set; then -+ enableval="$enable_hardening_patch_fmt_protect" -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. -+if test "${enable_hardening_patch_hash_protect+set}" = set; then -+ enableval="$enable_hardening_patch_hash_protect" -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+ -+fi -+ -+ -+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 -+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 -+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 -+echo "configure:2733: checking whether to protect include/require statements" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect PHP Format String functions" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 -+ -+ -+cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH 1 -+EOF -+ -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 0 -+EOF -+ -+fi - - - -@@ -16017,6 +16180,62 @@ - fi - - -+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 -+echo "configure:14928: checking whether realpath is broken" >&5 -+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then -+ echo $ac_n "(cached) $ac_c" 1>&6 -+else -+ -+ if test "$cross_compiling" = yes; then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -+then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ echo "configure: failed program was:" >&5 -+ cat conftest.$ac_ext >&5 -+ rm -fr conftest* -+ -+ ac_cv_broken_realpath=yes -+ -+fi -+rm -fr conftest* -+fi -+ -+ -+fi -+ -+echo "$ac_t""$ac_cv_broken_realpath" 1>&6 -+ if test "$ac_cv_broken_realpath" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 1 -+EOF -+ -+ else -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 0 -+EOF -+ -+ fi -+ -+ - echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 - echo "configure:16022: checking for declared timezone" >&5 - if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then -@@ -86718,7 +86937,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - cat >> confdefs.h <&6 -+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 -+# Check whether --enable-varfilter or --disable-varfilter was given. -+if test "${enable_varfilter+set}" = set; then -+ enableval="$enable_varfilter" -+ PHP_VARFILTER=$enableval -+else -+ -+ PHP_VARFILTER=yes -+ -+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then -+ PHP_VARFILTER=$PHP_ENABLE_ALL -+ fi -+ -+fi -+ -+ -+ -+ext_output="yes, shared" -+ext_shared=yes -+case $PHP_VARFILTER in -+shared,*) -+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` -+ ;; -+shared) -+ PHP_VARFILTER=yes -+ ;; -+no) -+ ext_output=no -+ ext_shared=no -+ ;; -+*) -+ ext_output=yes -+ ext_shared=no -+ ;; -+esac -+ -+ -+ -+echo "$ac_t""$ext_output" 1>&6 -+ -+ -+ -+ -+if test "$PHP_VARFILTER" != "no"; then -+ cat >> confdefs.h <<\EOF -+#define HAVE_VARFILTER 1 -+EOF -+ -+ -+ ext_builddir=ext/varfilter -+ ext_srcdir=$abs_srcdir/ext/varfilter -+ -+ ac_extra= -+ -+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then -+ -+ -+ -+ case ext/varfilter in -+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; -+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; -+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; -+ esac -+ -+ -+ -+ b_c_pre=$php_c_pre -+ b_cxx_pre=$php_cxx_pre -+ b_c_meta=$php_c_meta -+ b_cxx_meta=$php_cxx_meta -+ b_c_post=$php_c_post -+ b_cxx_post=$php_cxx_post -+ b_lo=$php_lo -+ -+ -+ old_IFS=$IFS -+ for ac_src in varfilter.c; do -+ -+ IFS=. -+ set $ac_src -+ ac_obj=$1 -+ IFS=$old_IFS -+ -+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" -+ -+ case $ac_src in -+ *.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" ;; -+ *.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" ;; -+ esac -+ -+ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 -@@ -104088,7 +104566,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - streams.c network.c php_open_temporary_file.c php_logos.c \ -- output.c memory_streams.c user_streams.c; do -+ output.c memory_streams.c user_streams.c hardening_patch.c; do - - IFS=. - set $ac_src -@@ -104273,7 +104751,7 @@ - zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ -- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do -+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do - - IFS=. - set $ac_src -diff -Nura php-4.4.2/configure.in hardening-patch-4.4.2-0.4.15/configure.in ---- php-4.4.2/configure.in 2006-01-12 18:52:29.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/configure.in 2006-09-05 20:30:33.000000000 +0200 -@@ -247,7 +247,7 @@ - sinclude(Zend/acinclude.m4) - sinclude(Zend/Zend.m4) - sinclude(TSRM/tsrm.m4) -- -+sinclude(main/hardening_patch.m4) - - - divert(2) -@@ -621,6 +621,7 @@ - AC_FUNC_ALLOCA - dnl PHP_AC_BROKEN_SPRINTF - dnl PHP_AC_BROKEN_SNPRINTF -+dnl PHP_AC_BROKEN_REALPATH - PHP_DECLARED_TIMEZONE - PHP_TIME_R_TYPE - PHP_READDIR_R_TYPE -@@ -1260,7 +1261,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - streams.c network.c php_open_temporary_file.c php_logos.c \ -- output.c memory_streams.c user_streams.c) -+ output.c memory_streams.c user_streams.c hardening_patch.c) - PHP_ADD_SOURCES(/main, internal_functions.c,, sapi) - case $host_alias in - *netware*) -@@ -1281,7 +1282,7 @@ - zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ -- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c) -+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c ) - - if test -r "$abs_srcdir/Zend/zend_objects.c"; then - PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c) -diff -Nura php-4.4.2/ext/curl/curl.c hardening-patch-4.4.2-0.4.15/ext/curl/curl.c ---- php-4.4.2/ext/curl/curl.c 2006-01-05 19:03:18.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/curl/curl.c 2006-09-05 20:30:33.000000000 +0200 -@@ -87,6 +87,7 @@ - #define SMART_STR_PREALLOC 4096 - - #include "ext/standard/php_smart_str.h" -+#include "ext/standard/php_string.h" - #include "ext/standard/info.h" - #include "ext/standard/file.h" - #include "ext/standard/url.h" -@@ -111,7 +112,7 @@ - - #define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \ - if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \ -- strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \ -+ strncasecmp(str, "file:", sizeof("file:") - 1) == 0) \ - { \ - php_url *tmp_url; \ - \ -@@ -119,6 +120,11 @@ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid url '%s'", str); \ - RETURN_FALSE; \ - } \ -+ \ -+ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ -+ RETURN_FALSE; \ -+ } \ - \ - if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ - (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ -@@ -839,7 +845,6 @@ - case CURLOPT_FTPLISTONLY: - case CURLOPT_FTPAPPEND: - case CURLOPT_NETRC: -- case CURLOPT_FOLLOWLOCATION: - case CURLOPT_PUT: - #if CURLOPT_MUTE != 0 - case CURLOPT_MUTE: -@@ -876,6 +881,16 @@ - convert_to_long_ex(zvalue); - error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); - break; -+ case CURLOPT_FOLLOWLOCATION: -+ convert_to_long_ex(zvalue); -+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { -+ if (Z_LVAL_PP(zvalue) != 0) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set"); -+ RETURN_FALSE; -+ } -+ } -+ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); -+ break; - case CURLOPT_URL: - case CURLOPT_PROXY: - case CURLOPT_USERPWD: -diff -Nura php-4.4.2/ext/curl/curlstreams.c hardening-patch-4.4.2-0.4.15/ext/curl/curlstreams.c ---- php-4.4.2/ext/curl/curlstreams.c 2006-01-01 14:46:50.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/curl/curlstreams.c 2006-09-05 20:30:33.000000000 +0200 -@@ -297,7 +297,11 @@ - curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream); - - /* currently buggy (bug is in curl) */ -- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); -+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { -+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); -+ } else { -+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); -+ } - - curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr); - curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0); -diff -Nura php-4.4.2/ext/fbsql/php_fbsql.c hardening-patch-4.4.2-0.4.15/ext/fbsql/php_fbsql.c ---- php-4.4.2/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1797,8 +1797,24 @@ - } - else if (fbcmdErrorsFound(md)) - { -+#if HARDENING_PATCH -+ char* query_copy; -+ int i; -+#endif - FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); - char* emg = fbcemdAllErrorMessages(emd); -+#if HARDENING_PATCH -+ query_copy=estrdup(query_copy); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ free(emg); -+ fbcemdRelease(emd); -+ result = 0; -+ zend_bailout(); -+ } -+#endif - if (FB_SQL_G(generateWarnings)) - { - if (emg) -diff -Nura php-4.4.2/ext/gd/libgd/gd_gif_in.c hardening-patch-4.4.2-0.4.15/ext/gd/libgd/gd_gif_in.c ---- php-4.4.2/ext/gd/libgd/gd_gif_in.c 2005-09-25 14:13:49.000000000 +0200 -+++ hardening-patch-4.4.2-0.4.15/ext/gd/libgd/gd_gif_in.c 2006-09-05 20:30:33.000000000 +0200 -@@ -212,6 +212,12 @@ - if (!im) { - return 0; - } -+ -+ if (!im->colorsTotal) { -+ gdImageDestroy(im); -+ return 0; -+ } -+ - /* Check for open colors at the end, so - we can reduce colorsTotal and ultimately - BitsPerPixel */ -@@ -502,6 +508,19 @@ - int v; - int xpos = 0, ypos = 0, pass = 0; - int i; -+ -+ /* -+ ** Initialize the Compression routines -+ */ -+ if (! ReadOK(fd,&c,1)) { -+ return; -+ } -+ -+ if (c > MAX_LWZ_BITS) { -+ return; -+ } -+ -+ - /* Stash the color map into the image */ - for (i=0; (ired[i] = cmap[CM_RED][i]; -@@ -511,12 +530,7 @@ - } - /* Many (perhaps most) of these colors will remain marked open. */ - im->colorsTotal = gdMaxColors; -- /* -- ** Initialize the Compression routines -- */ -- if (! ReadOK(fd,&c,1)) { -- return; -- } -+ - if (LWZReadByte(fd, TRUE, c) < 0) { - return; - } -diff -Nura php-4.4.2/ext/gd/tests/bug38112.gif hardening-patch-4.4.2-0.4.15/ext/gd/tests/bug38112.gif ---- php-4.4.2/ext/gd/tests/bug38112.gif 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/gd/tests/bug38112.gif 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,140 @@ -+GIF89a}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M -+ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuutt! NETSCAPE2.0!d,}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M -+ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuuttq]sH6U~F7Jػ|[rEwЫ*4;W(ƺj -+Ȗ֨_x֚hyvVyxc-%Bak(XF(yv aϑ@HZkhڊ'M )Zk[0K\G%y,l [6%F2 >ǾUI?6N>MhغCJ -+JmڶiIeʑ%~!T"2ZU -+禅^@-BAYVY0KTFXLs)rR+0l-BV%UrÜ Jmy@-QYŦm1%ΤOjvr3hm!1`0WDJj%To4Qə%)0 *Ƌ%LTt9sWKș#D(Qѧ_NGPHx#{ -+1He{"˥Z\U+Mf#HPB -+B}1wV$.[zsJ'MN("Os$R'D!EA=#L!`0[S6wL`AxPN* Q+9DŽ"X=R\20Z-ٕ hLRK 8R,QEX:$< -+@p&$ x d\ݵ@HyD5C*sY: -+ auc%l!F!Zr9BH  eP# Q -+!EG}Apk)lĞzZYn,A~*nY( ׌ƨ*1&r\gb*TS%~ZP}DÐhk;`BAkF.g- G!X` DD+8PA\0 -+";_BeI-ൂZ8A6 Mgv͚JG:Rױ` `څ,Ȁ-3bZ5A 7ÈR -+e!0/Jl!@tuACj< P>[[%^:uph ꀄ:`!XY, x/T†{33@46jX`!B0A/h^G) d{c4<J0q+*"ȼZPNaA,7;PHs7x1y 1@XTUnEX"$Q-jJM C@I܀ HD& :d" -+`G*`VgP`CXѰl3_ώ=𙛔f'}K1 F&`GFbL*0ف. @^0d';IPTd0|a˟*R6WpfF&UE_()=pOԻ [KS-Y&KG)$[UB%+Up/*1t5%[¡P ]y^"ZM8uX1Yb}C&mJP W9n2чzjTax9́,8R  Lp -+p"TUf %o,l(kPW$> ;Pp@ -+:>=#^db "Vxq?e+ﶓNCHK؁ -+l"?a @AOK*G:K!ƎƊ'8HB])ƞD?TVp \b1Fᰔ4ӨH7߹"mW~9 E.cM[F/W b׮WƤm335 PssP( TH;cyQr Đ'`1dS(m({frK Me D :  s%x 0' 3cSyp' -+vYao78yd0L zB-I qz=Cy0;9>d=`Fk^0@cƒ9Wpw03 ..@ -+)03f\@@阽 "o9 з l臙 S9gl e+c0S5_G0G9CZ@%P6E9@‖:=lD 03 i3EG0P!d05B#o 919ڐӣP:+WK*_' -+=ß5 &`~S vF= C8 1 sIp#PΖ@p̝X3WA`\=,ࢤT3 -+0l x@@ -+X m 0x茎 -+^qP鸪Epk Y8P0  oXS벎 Hc|i. +l?+\ I@ܐ   lѠ1/=0ݮv@O_n\ݾ@*֖-K -+Ќ g) : \ފ Nm^` h @_RK Z -+Mc5 a ΀ l0x > ? OVG c<^>N` -@`_R Pc@8ofmO?/)@T`r񒰻c^PHM VP{P, c0 -+UiDbb -+ Њ/\mbT]0#U(a0 -+Yij j25_Oߗ?`V{q mysm᮪t1OseXtk~> Q̖ەT;,tؗjzNUHYPIaSsZ*-)6:$NJHP>2Tšd2Z2^Q"XfRrS[p ./4:yd_Z[QP>4HTpwws>ȨNB!s7Q@ ,~G ocC\pC' /%_"RLDvDBK7;13nC}~dkTA  Ê@|3*A2L EA &D;rC2մ!E=a -+7ފSm#HOIC]y3RcorKXO$՚kD +zk#ˀ.ɂ" 7]{tL)[G-w -8E^ۂt@!0#őd ȉ#a"!"$C7 5B fN u&P~ 4 ex|%+փNE["W[(hALv9T0PaG#,?~ r&,Ra$\2љi\,Q3x惆EeVCѶI.CAh$,I%r9lA3)yws8uV`K(Oѭܭ m=Z8ڀ9}1? >)S\zA UV`d`h'57Za| 4_ҧ "blD4]h,PXnfAR"`@؉ ( R.@E4 m8B `m!J}CL np r6]aÞiF(DuB,q8aQrxceO@E`xa yM88(b f\6xE 6AD"r3_N!%(hu:D2I0ґ+4IJZh,@av{8 -+zs-Sqb!Ѕ I,?[:C.`n` @ b@Ϙ6JiJy387X͐t \KS ⴆ+ЇKAPEpP,s{ =eO|^"i;BJ#A9}TchX1qxD$Jno{DK\I2BQ -+?Bf-,6?VS@/B5=V@or -+umD0 %^ vs;DRja kF/vS>ܓ/X5?M+ H#lpH -+Hhwu 3;X+X} 9x!4 $ [uجg7)k08D1-bq@# ~#pacMF=a%9,nWF^|n7._6P0bw/#L!؄z]jj~ԕ_Uz`ЈFCXtI!d,կιǩUXuًȫȣdr*/>ç-Qȫ6AXIRbg *лۭΚʱțyۤsȑ炎ϯ운ΐë›랼ػࢮ柫ֳܐӢȜz;HPҩߟ^hkٟڧԢW^^nqq쮰ɭvzy7D@޹痛خHJ>zilTοȣĘþסϰHp?! OEQ2Zl%*D CII JMD% '>ɳ'Ot+JԪRDV"A|JJU!eC-[֠A4'V V]˶ ʔQLUZ$ -+,%+yռ5+&b!*. #2Ԗk<Bd+է')H]s!zѠ#TT Ÿ \9ViDK/sn ڵ+ z8zdb$ ,,DpJ >Vp:v Tn+M?b׿ gԒL7Ǝ6`2 Q\r, ^rtb+G $ZP3H86hc  hO+&LMp0BG刘XÄsM; g`lӎ)OL)h` }x$g d NCS1,M.#;: qTS©z~&X'|( B1nin&PB ,w\RB3*Ab¶ά`0 A|x!#IrW.fB8D`0 7`> l60 -+R # |ĻRRK-,.@8Ks7HPp hL/C ;|S, \J@^0 =QC&5/1VvD @ќ ? -+=0=G~"Jd[xm 5US! ,7D =| 1C6x(nB|*Mᆧ"!Ik,B+Ov݁Ag08?Km?LfJdL S0_,Ъ>PX -+ĥ'LO~:唑 eBiA,Ε?aKaWO*[(*G-`C8+TP0ZV: q&-,@MY>` 0 ۝$(5gD٪4<0G5!]0Ġ:"08P D>PX)UĀ @{ -+`uXwe`pu !w9Wɶf> Vǀ` -|XFטroi  !"MuP~oƚ5 } OL0&khnk}X -+ JP!D͸" -+@w `|wlوo tls{jmښ5igugLو&GPAř Z5H8v|EH"/,eG  Zz q@ -+` $ -+Pʉ Jn>#RzcPj?Z ` ZVpiC 500}z?i !| Z>==%X1k1 *=YFcT=SE `0((vN mQ;ziPYY+U1v fp0ԝ Н{P 0~ Q5`;|%μʵA ۻ{&ߪ0Xg Fc`NPό>IJR)Іhp@Q-0+sݚ 4f#L&,J -+0 t̆Z@1] [}K} @ -+in`*'` (geWf`0ˌ@g -+ uW͘ P,x- -+ƀWΓ[ˆ -b,i `?{  -+$p ix KA @`Гp݈ɻoSKPѱ=ؙjnDFS/dL$GG@, -+o FO4 -+ ߭4qݩݽ-4M00p -+,k p -+  -+ }0U02ߥ -+ -+Q_P˻Kr@m%fY  P =[Y՗  @ ; VJ@z, xݭ=^ބI,HC -+0 x PJNH*Pt q -+0j>\ڭ u -h *@Ϡ }XQ  -+@ 劮 _^ 6]i~ݞ;`p ,v P  -+R j 0^ h400uR "!`0 ^խuY @ 티 ޾ P߾z@8| -+y -+@5S~ > _nm{ -+n%  훀R H@8 L -+P[Dp'~`EɀV -+%P [ k  -+BLS? ^x! -+dPž_]0O%Udpp & -+jPP& y -+QY -+L0x]- _Qd =h S .> ppS@uk`bQ͏Ⱥyb6,\\ *eR#Y]PR叢:&}4)Dx>TPE- -+!kգ'iɱUp%!e&O -+J.3rϠTɲ̘4 F'OH FlSy@`ҭSh,W,DYDB`9I4FZ8[vK)WiIa Cpbő2m[Yٛg71& yȸE6TPcŴb)1*I^܊\;𞴌pk z FgyXt tl x .aDKJRJi7] Kd?"%21 4o>4@yF:nitx-MDeE1U|/1ы0jizܱBG ,)ďg&n@^|>>J!J`@`R\F9adH X N(>)Er9 "XÏ5@@MW 7Ƌ/@Xj֦HVXT -+f 5>‚qa|e@B -+)ָcK\c pj=E 9(bi|GtcU)=m8cYc>?ذd -+$\>PKreP& 45WL!v(`x?06W,=Qfy -+wB -+aM61 $`.ÎH`H vCjԏ^UjkX%k>f)= 0) X@fo^Jo-(e!ዖM߂{G%lܝayrH<#Lp e#H@EuBqtl/Ekd%]Gs#'>;LЂ(a 8d! w$;x `}R -+L~8 >f?# {8hD#d|%";XCB0~  ą1*l,5P_lYXyr*pz'b$|pEQ -+X@&mX0v` gFIr;F#$y-. -+Qz K(=/yUHMZ(>^s?sE0x84%{D@!KAtXk8 -+H }[)Bb>"G0*tPCE8hQ9xZ(Z# -+~H[Y2x`P?;@5BB*A0kF\2k4̃U}@7C@Z(\!W`x`opGxH:͢)Bp70#_a8CXd dDP;0/C(Gkdl`4 1Ss obX̃kFq?`TȪ8X -+--FILE-- -+ -+--EXPECTF-- -+Warning: imagecreatefromgif() [%s]: '%sbug38112.gif' is not a valid GIF file in %sbug38112.php on line %d -diff -Nura php-4.4.2/ext/imap/php_imap.c hardening-patch-4.4.2-0.4.15/ext/imap/php_imap.c ---- php-4.4.2/ext/imap/php_imap.c 2006-01-05 01:50:19.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/imap/php_imap.c 2006-09-05 20:30:33.000000000 +0200 -@@ -26,7 +26,7 @@ - | PHP 4.0 updates: Zeev Suraski | - +----------------------------------------------------------------------+ - */ --/* $Id: php_imap.c,v 1.142.2.44.2.4 2006/01/05 00:50:19 iliaa Exp $ */ -+/* $Id: php_imap.c,v 1.142.2.44.2.5 2006/08/04 20:32:44 iliaa Exp $ */ - - #define IMAP41 - -@@ -731,6 +731,13 @@ - efree(IMAPG(imap_password)); - } - -+ /* local filename, need to perform open_basedir and safe_mode checks */ -+ if (Z_STRVAL_PP(mailbox)[0] != '{' && -+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || -+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { -+ RETURN_FALSE; -+ } -+ - IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); - IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); - -diff -Nura php-4.4.2/ext/mbstring/mbstring.c hardening-patch-4.4.2-0.4.15/ext/mbstring/mbstring.c ---- php-4.4.2/ext/mbstring/mbstring.c 2006-01-01 14:46:54.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/mbstring/mbstring.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1488,6 +1488,7 @@ - char *strtok_buf = NULL, **val_list; - zval *array_ptr = (zval *) arg; - int n, num, val_len, *len_list; -+ unsigned int new_val_len; - enum mbfl_no_encoding from_encoding; - mbfl_string string, resvar, resval; - mbfl_encoding_detector *identd = NULL; -@@ -1610,8 +1611,14 @@ - val_len = len_list[n]; - } - n++; -- /* add variable to symbol table */ -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ /* we need val to be emalloc()ed */ -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ /* add variable to symbol table */ -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); -+ - if (convd != NULL){ - mbfl_string_clear(&resvar); - mbfl_string_clear(&resval); -diff -Nura php-4.4.2/ext/mysql/libmysql/libmysql.c hardening-patch-4.4.2-0.4.15/ext/mysql/libmysql/libmysql.c ---- php-4.4.2/ext/mysql/libmysql/libmysql.c 2003-07-28 09:28:55.000000000 +0200 -+++ hardening-patch-4.4.2-0.4.15/ext/mysql/libmysql/libmysql.c 2006-09-05 20:30:33.000000000 +0200 -@@ -213,6 +213,10 @@ - if (!host || !strcmp(host,LOCAL_HOST)) - host=LOCAL_HOST_NAMEDPIPE; - -+ if (sizeof(szPipeName) <= (strlen(host) + strlen(unix_socket) + sizeof("\\\\\\pipe\\"))) { -+ return INVALID_HANDLE_VALUE; -+ } -+ - sprintf( szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket); - DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s", - host, unix_socket)); -diff -Nura php-4.4.2/ext/mysql/php_mysql.c hardening-patch-4.4.2-0.4.15/ext/mysql/php_mysql.c ---- php-4.4.2/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1218,6 +1218,8 @@ - { - php_mysql_conn *mysql; - MYSQL_RES *mysql_result; -+ char *copy_query; -+ int i; - - ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); - -@@ -1268,6 +1270,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #else -@@ -1275,12 +1284,20 @@ - /* check possible error */ - if (MySG(trace_mode)){ - if (mysql_errno(&mysql->conn)){ -- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn)); -+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #endif -+ - if(use_store == MYSQL_USE_RESULT) { - mysql_result=mysql_use_result(&mysql->conn); - } else { -diff -Nura php-4.4.2/ext/pgsql/pgsql.c hardening-patch-4.4.2-0.4.15/ext/pgsql/pgsql.c ---- php-4.4.2/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1001,10 +1001,28 @@ - case PGRES_EMPTY_QUERY: - case PGRES_BAD_RESPONSE: - case PGRES_NONFATAL_ERROR: -- case PGRES_FATAL_ERROR: -- PHP_PQ_ERROR("Query failed: %s", pgsql); -- PQclear(pgsql_result); -- RETURN_FALSE; -+ case PGRES_FATAL_ERROR: -+ { -+#if HARDENING_PATCH -+ int i; -+ char *query_copy; -+#endif -+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); -+ PQclear(pgsql_result); -+#if HARDENING_PATCH -+ query_copy = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ efree(msgbuf); -+ zend_bailout(); -+ } -+#endif -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); -+ efree(msgbuf); -+ RETURN_FALSE; -+ } - break; - case PGRES_COMMAND_OK: /* successful command that did not return rows */ - default: -diff -Nura php-4.4.2/ext/session/mod_files.c hardening-patch-4.4.2-0.4.15/ext/session/mod_files.c ---- php-4.4.2/ext/session/mod_files.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/mod_files.c 2006-09-05 20:30:33.000000000 +0200 -@@ -16,7 +16,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: mod_files.c,v 1.83.2.9.2.2 2006/01/01 13:46:56 sniper Exp $ */ -+/* $Id: mod_files.c,v 1.83.2.9.2.4 2006/08/08 14:57:04 iliaa Exp $ */ - - #include "php.h" - -@@ -364,10 +364,17 @@ - if (!ps_files_path_create(buf, sizeof(buf), data, key)) - return FAILURE; - -- ps_files_close(data); -+ if (data->fd != -1) { -+ ps_files_close(data); - -- if (VCWD_UNLINK(buf) == -1) { -- return FAILURE; -+ if (VCWD_UNLINK(buf) == -1) { -+ /* This is a little safety check for instances when we are dealing with a regenerated session -+ * that was not yet written to disk -+ */ -+ if (!VCWD_ACCESS(buf, F_OK)) { -+ return FAILURE; -+ } -+ } - } - - return SUCCESS; -@@ -389,6 +396,34 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(files) -+{ -+ char buf[MAXPATHLEN]; -+ int fd; -+ PS_FILES_DATA; -+ -+ if (!ps_files_valid_key(key)) { -+ return FAILURE; -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { -+ return FAILURE; -+ } -+ -+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600); -+ -+ if (fd != -1) { -+ close(fd); -+ return SUCCESS; -+ } -+ -+ return FAILURE; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-4.4.2/ext/session/mod_mm.c hardening-patch-4.4.2-0.4.15/ext/session/mod_mm.c ---- php-4.4.2/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/mod_mm.c 2006-09-05 20:30:33.000000000 +0200 -@@ -425,6 +425,42 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(mm) -+{ -+ PS_MM_DATA; -+ ps_sd *sd; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ } -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ mm_lock(data->mm, MM_LOCK_RD); -+ -+ sd = ps_sd_lookup(data, key, 0); -+ if (sd) { -+ mm_unlock(data->mm); -+ return SUCCESS; -+ } -+ -+ mm_unlock(data->mm); -+ -+ return FAILURE; -+} -+ - #endif - - /* -diff -Nura php-4.4.2/ext/session/mod_user.c hardening-patch-4.4.2-0.4.15/ext/session/mod_user.c ---- php-4.4.2/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/mod_user.c 2006-09-05 20:30:33.000000000 +0200 -@@ -23,7 +23,7 @@ - #include "mod_user.h" - - ps_module ps_mod_user = { -- PS_MOD(user) -+ PS_MOD_SID(user) - }; - - #define SESS_ZVAL_LONG(val, a) \ -@@ -174,6 +174,83 @@ - FINISH; - } - -+PS_CREATE_SID_FUNC(user) -+{ -+ int i; -+ char *val = NULL; -+ zval *retval; -+ ps_user *mdata = PS_GET_MOD_DATA(); -+ -+ if (!mdata) -+ return estrndup("", 0); -+ -+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { -+ return php_session_create_id(mod_data, newlen TSRMLS_CC); -+ } -+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); -+ -+ if (retval) { -+ if (Z_TYPE_P(retval) == IS_STRING) { -+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); -+ } else { -+ val = estrndup("", 0); -+ } -+ zval_ptr_dtor(&retval); -+ } else { -+ val = estrndup("", 0); -+ } -+ -+ return val; -+} -+ -+static int ps_user_valid_key(const char *key TSRMLS_DC) -+{ -+ size_t len; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ ret = FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ ret = FAILURE; -+ -+ return ret; -+} -+ -+PS_VALIDATE_SID_FUNC(user) -+{ -+ zval *args[1]; -+ STDVARS; -+ -+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { -+ return ps_user_valid_key(key TSRMLS_CC); -+ } -+ SESS_ZVAL_STRING(key, args[0]); -+ -+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); -+ -+ if (retval) { -+ convert_to_long(retval); -+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; -+ zval_ptr_dtor(&retval); -+ } -+ -+ return ret; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-4.4.2/ext/session/mod_user.h hardening-patch-4.4.2-0.4.15/ext/session/mod_user.h ---- php-4.4.2/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/mod_user.h 2006-09-05 20:30:33.000000000 +0200 -@@ -22,7 +22,7 @@ - #define MOD_USER_H - - typedef union { -- zval *names[6]; -+ zval *names[8]; - struct { - zval *ps_open; - zval *ps_close; -@@ -30,6 +30,8 @@ - zval *ps_write; - zval *ps_destroy; - zval *ps_gc; -+ zval *ps_create; -+ zval *ps_validate; - } name; - } ps_user; - -diff -Nura php-4.4.2/ext/session/php_session.h hardening-patch-4.4.2-0.4.15/ext/session/php_session.h ---- php-4.4.2/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/php_session.h 2006-09-05 20:30:33.000000000 +0200 -@@ -23,7 +23,7 @@ - - #include "ext/standard/php_var.h" - --#define PHP_SESSION_API 20020330 -+#define PHP_SESSION_API 20051121 - - #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC - #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC -@@ -32,6 +32,7 @@ - #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC - #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC - #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC -+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC - - /* default create id function */ - char *php_session_create_id(PS_CREATE_SID_ARGS); -@@ -45,6 +46,7 @@ - int (*s_destroy)(PS_DESTROY_ARGS); - int (*s_gc)(PS_GC_ARGS); - char *(*s_create_sid)(PS_CREATE_SID_ARGS); -+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); - } ps_module; - - #define PS_GET_MOD_DATA() *mod_data -@@ -57,6 +59,7 @@ - #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) - #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) - #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) -+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) - - #define PS_FUNCS(x) \ - PS_OPEN_FUNC(x); \ -@@ -65,11 +68,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID_FUNC(x) - - #define PS_MOD(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, php_session_create_id -+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x - - /* SID enabled module handler definitions */ - #define PS_FUNCS_SID(x) \ -@@ -79,11 +83,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID(x) - - #define PS_MOD_SID(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, ps_create_sid_##x -+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x - - typedef enum { - php_session_disabled, -@@ -120,6 +125,7 @@ - zend_bool use_only_cookies; - zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ - zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ -+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ - int send_cookie; - int define_sid; - } php_ps_globals; -diff -Nura php-4.4.2/ext/session/session.c hardening-patch-4.4.2-0.4.15/ext/session/session.c ---- php-4.4.2/ext/session/session.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/session.c 2006-09-05 20:30:33.000000000 +0200 -@@ -17,7 +17,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: session.c,v 1.336.2.53.2.4 2006/01/01 13:46:56 sniper Exp $ */ -+/* $Id: session.c,v 1.336.2.53.2.5 2006/01/15 16:52:10 iliaa Exp $ */ - - #ifdef HAVE_CONFIG_H - #include "config.h" -@@ -155,6 +155,7 @@ - STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) -+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals) -@@ -626,6 +627,12 @@ - char *val; - int vallen; - -+ /* check session name for invalid characters */ -+ if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) { -+ efree(PS(id)); -+ PS(id) = NULL; -+ } -+ - if (!PS(mod)) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session."); - return; -@@ -637,6 +644,15 @@ - return; - } - -+ /* If there is an ID, use session module to verify it */ -+ if (PS(id)) { -+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ efree(PS(id)); -+ PS(id) = NULL; -+ PS(send_cookie) = 1; -+ } -+ } -+ - /* If there is no ID, use session module to create one */ - if (!PS(id)) - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); -@@ -1256,22 +1272,31 @@ - } - /* }}} */ - --/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) -+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) - Sets user-level functions */ - PHP_FUNCTION(session_set_save_handler) - { -- zval **args[6]; -- int i; -+ zval **args[8]; -+ int i, numargs; - ps_user *mdata; - char *name; - -+ numargs = ZEND_NUM_ARGS(); -+ args[6] = NULL; -+ args[7] = NULL; -+ -+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) -+ WRONG_PARAM_COUNT; - if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) - WRONG_PARAM_COUNT; - - if (PS(session_status) != php_session_none) - RETURN_FALSE; - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ continue; -+ } - if (!zend_is_callable(*args[i], 0, &name)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); - efree(name); -@@ -1284,7 +1309,11 @@ - - mdata = emalloc(sizeof(*mdata)); - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ mdata->names[i] = NULL; -+ continue; -+ } - ZVAL_ADDREF(*args[i]); - mdata->names[i] = *args[i]; - } -@@ -1345,8 +1374,20 @@ - Update the current session id with a newly generated one. */ - PHP_FUNCTION(session_regenerate_id) - { -+ zend_bool del_ses = 0; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) { -+ WRONG_PARAM_COUNT; -+ } -+ - if (PS(session_status) == php_session_active) { -- if (PS(id)) efree(PS(id)); -+ if (PS(id)) { -+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed"); -+ RETURN_FALSE; -+ } -+ efree(PS(id)); -+ } - - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); - -@@ -1395,8 +1436,8 @@ - WRONG_PARAM_COUNT; - - if (ac == 1) { -- convert_to_long_ex(p_cache_expire); -- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); -+ convert_to_string_ex(p_cache_expire); -+ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - } - - RETVAL_LONG(old); -diff -Nura php-4.4.2/ext/session/tests/014.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/014.phpt ---- php-4.4.2/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:30:33.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.bug_compat_42=1 -diff -Nura php-4.4.2/ext/session/tests/015.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/015.phpt ---- php-4.4.2/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:30:33.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - arg_separator.output=& - session.name=PHPSESSID -diff -Nura php-4.4.2/ext/session/tests/018.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/018.phpt ---- php-4.4.2/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:30:33.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - session.name=PHPSESSID -diff -Nura php-4.4.2/ext/session/tests/020.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/020.phpt ---- php-4.4.2/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:30:33.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - arg_separator.output=& -diff -Nura php-4.4.2/ext/session/tests/021.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/021.phpt ---- php-4.4.2/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:30:33.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" -diff -Nura php-4.4.2/ext/session/tests/bug38377.phpt hardening-patch-4.4.2-0.4.15/ext/session/tests/bug38377.phpt ---- php-4.4.2/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+bug #38377 (session_destroy() gives warning after session_regenerate_id()) -+--SKIPIF-- -+ -+--FILE-- -+ -+--EXPECT-- -+Done -diff -Nura php-4.4.2/ext/sockets/sockets.c hardening-patch-4.4.2-0.4.15/ext/sockets/sockets.c ---- php-4.4.2/ext/sockets/sockets.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/sockets/sockets.c 2006-09-05 20:30:33.000000000 +0200 -@@ -19,7 +19,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: sockets.c,v 1.125.2.29.2.3 2006/01/01 13:46:56 sniper Exp $ */ -+/* $Id: sockets.c,v 1.125.2.29.2.6 2006/08/01 12:04:14 tony2001 Exp $ */ - - #ifdef HAVE_CONFIG_H - #include "config.h" -@@ -515,6 +515,7 @@ - int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, SOCKET *max_fd TSRMLS_DC) { - zval **element; - php_socket *php_sock; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -529,9 +530,10 @@ - if (php_sock->bsd_socket > *max_fd) { - *max_fd = php_sock->bsd_socket; - } -+ num++; - } - -- return 1; -+ return num ? 1 : 0; - } - - int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) { -@@ -539,6 +541,8 @@ - zval **dest_element; - php_socket *php_sock; - HashTable *new_hash; -+ int num = 0; -+ - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - - ALLOC_HASHTABLE(new_hash); -@@ -555,6 +559,7 @@ - zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); - if (dest_element) zval_add_ref(dest_element); - } -+ num++; - } - - /* Destroy old array, add new one */ -@@ -564,7 +569,7 @@ - zend_hash_internal_pointer_reset(new_hash); - Z_ARRVAL_P(sock_array) = new_hash; - -- return 1; -+ return num ? 1 : 0; - } - - -diff -Nura php-4.4.2/ext/standard/array.c hardening-patch-4.4.2-0.4.15/ext/standard/array.c ---- php-4.4.2/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/array.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1162,6 +1162,32 @@ - } - } - } -+ -+ if (var_name[0] == 'H') { -+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_FILES")==0)|| -+ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { -+ return 0; -+ } -+ } else if (var_name[0] == '_') { -+ if ((strcmp(var_name, "_COOKIE")==0)|| -+ (strcmp(var_name, "_ENV")==0)|| -+ (strcmp(var_name, "_FILES")==0)|| -+ (strcmp(var_name, "_GET")==0)|| -+ (strcmp(var_name, "_POST")==0)|| -+ (strcmp(var_name, "_REQUEST")==0)|| -+ (strcmp(var_name, "_SESSION")==0)|| -+ (strcmp(var_name, "_SERVER")==0)) { -+ return 0; -+ } -+ } else if (strcmp(var_name, "GLOBALS")==0) { -+ return 0; -+ } - - return 1; - } -diff -Nura php-4.4.2/ext/standard/basic_functions.c hardening-patch-4.4.2-0.4.15/ext/standard/basic_functions.c ---- php-4.4.2/ext/standard/basic_functions.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:35:15.000000000 +0200 -@@ -107,12 +107,14 @@ - typedef struct _php_shutdown_function_entry { - zval **arguments; - int arg_count; -+ zend_bool created_by_eval; - } php_shutdown_function_entry; - - typedef struct _user_tick_function_entry { - zval **arguments; - int arg_count; - int calling; -+ zend_bool created_by_eval; - } user_tick_function_entry; - - /* some prototypes for local functions */ -@@ -295,6 +297,8 @@ - PHP_FE(get_html_translation_table, NULL) - PHP_FE(sha1, NULL) - PHP_FE(sha1_file, NULL) -+ PHP_FE(sha256, NULL) -+ PHP_FE(sha256_file, NULL) - PHP_NAMED_FE(md5,php_if_md5, NULL) - PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) - PHP_NAMED_FE(crc32,php_if_crc32, NULL) -@@ -676,7 +680,7 @@ - PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) - - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) -- PHP_FE(realpath, NULL) -+ PHP_STATIC_FE("realpath", zif_real_path, NULL) - #endif - - #ifdef HAVE_FNMATCH -@@ -1866,7 +1870,7 @@ - break; - - case 3: /*save to a file */ -- stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); -+ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); - if (!stream) - return FAILURE; - php_stream_write(stream, message, strlen(message)); -@@ -2096,6 +2100,13 @@ - { - zval retval; - char *function_name = NULL; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (shutdown_function_entry->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { - php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); -@@ -2111,6 +2122,9 @@ - if (function_name) { - efree(function_name); - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - return 0; - } - -@@ -2118,6 +2132,13 @@ - { - zval retval; - zval *function = tick_fe->arguments[0]; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (tick_fe->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - /* Prevent reentrant calls to the same user ticks function */ - if (! tick_fe->calling) { -@@ -2149,6 +2170,9 @@ - - tick_fe->calling = 0; - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - } - - static void run_user_tick_functions(int tick_count) -@@ -2216,6 +2240,13 @@ - if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { - RETURN_FALSE; - } -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ shutdown_function_entry.created_by_eval = 1; -+ } else { -+ shutdown_function_entry.created_by_eval = 0; -+ } -+#endif - - /* Prevent entering of anything but valid callback (syntax check only!) */ - if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { -@@ -2497,6 +2528,15 @@ - - convert_to_string_ex(varname); - -+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ -+ if (PG(safe_mode)) { -+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || -+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || -+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { -+ RETURN_FALSE; -+ } -+ } -+ - zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); - } - /* }}} */ -@@ -2753,6 +2793,13 @@ - } - - tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ tick_fe.created_by_eval = 1; -+ } else { -+ tick_fe.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { - RETURN_FALSE; -@@ -3050,6 +3097,35 @@ - new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); - } - -+ if (new_key[0] == 'H') { -+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_FILES")==0)|| -+ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (new_key[0] == '_') { -+ if ((strcmp(new_key, "_COOKIE")==0)|| -+ (strcmp(new_key, "_ENV")==0)|| -+ (strcmp(new_key, "_FILES")==0)|| -+ (strcmp(new_key, "_GET")==0)|| -+ (strcmp(new_key, "_POST")==0)|| -+ (strcmp(new_key, "_REQUEST")==0)|| -+ (strcmp(new_key, "_SESSION")==0)|| -+ (strcmp(new_key, "_SERVER")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (strcmp(new_key, "GLOBALS")==0) { -+ efree(new_key); -+ return 0; -+ } -+ - zend_hash_del(&EG(symbol_table), new_key, new_key_len); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); - -diff -Nura php-4.4.2/ext/standard/config.m4 hardening-patch-4.4.2-0.4.15/ext/standard/config.m4 ---- php-4.4.2/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/config.m4 2006-09-05 20:30:33.000000000 +0200 -@@ -203,7 +203,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) - ]) -@@ -419,6 +419,6 @@ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ -- var_unserializer.c ftok.c aggregation.c sha1.c ) -+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ) - - PHP_ADD_MAKEFILE_FRAGMENT -diff -Nura php-4.4.2/ext/standard/crypt_blowfish.c hardening-patch-4.4.2-0.4.15/ext/standard/crypt_blowfish.c ---- php-4.4.2/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,748 @@ -+/* -+ * This code comes from John the Ripper password cracker, with reentrant -+ * and crypt(3) interfaces added, but optimizations specific to password -+ * cracking removed. -+ * -+ * Written by Solar Designer in 1998-2002 and -+ * placed in the public domain. -+ * -+ * There's absolutely no warranty. -+ * -+ * It is my intent that you should be able to use this on your system, -+ * as a part of a software package, or anywhere else to improve security, -+ * ensure compatibility, or for any other purpose. I would appreciate -+ * it if you give credit where it is due and keep your modifications in -+ * the public domain as well, but I don't require that in order to let -+ * you place this code and any modifications you make under a license -+ * of your choice. -+ * -+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) -+ * by Niels Provos , and uses some of his -+ * ideas. The password hashing algorithm was designed by David Mazieres -+ * . -+ * -+ * There's a paper on the algorithm that explains its design decisions: -+ * -+ * http://www.usenix.org/events/usenix99/provos.html -+ * -+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's -+ * Blowfish library (I can't be sure if I would think of something if I -+ * hadn't seen his code). -+ */ -+ -+#include -+ -+#include -+#ifndef __set_errno -+#define __set_errno(val) errno = (val) -+#endif -+ -+#undef __CONST -+#ifdef __GNUC__ -+#define __CONST __const -+#else -+#define __CONST -+#endif -+ -+#ifdef __i386__ -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#elif defined(__alpha__) || defined(__hppa__) -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#else -+#define BF_ASM 0 -+#define BF_SCALE 0 -+#endif -+ -+typedef unsigned int BF_word; -+ -+/* Number of Blowfish rounds, this is also hardcoded into a few places */ -+#define BF_N 16 -+ -+typedef BF_word BF_key[BF_N + 2]; -+ -+typedef struct { -+ BF_word S[4][0x100]; -+ BF_key P; -+} BF_ctx; -+ -+/* -+ * Magic IV for 64 Blowfish encryptions that we do at the end. -+ * The string is "OrpheanBeholderScryDoubt" on big-endian. -+ */ -+static BF_word BF_magic_w[6] = { -+ 0x4F727068, 0x65616E42, 0x65686F6C, -+ 0x64657253, 0x63727944, 0x6F756274 -+}; -+ -+/* -+ * P-box and S-box tables initialized with digits of Pi. -+ */ -+static BF_ctx BF_init_state = { -+ { -+ { -+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, -+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, -+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, -+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, -+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, -+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, -+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, -+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, -+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, -+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, -+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, -+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, -+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, -+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, -+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, -+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, -+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, -+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, -+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, -+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, -+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, -+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, -+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, -+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, -+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, -+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, -+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, -+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, -+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, -+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, -+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, -+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, -+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, -+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, -+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, -+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, -+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, -+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, -+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, -+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, -+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, -+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, -+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, -+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, -+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, -+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, -+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, -+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, -+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, -+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, -+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, -+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, -+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, -+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, -+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, -+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, -+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, -+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, -+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, -+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, -+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, -+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, -+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, -+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a -+ }, { -+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, -+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, -+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, -+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, -+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, -+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, -+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, -+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, -+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, -+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, -+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, -+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, -+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, -+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, -+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, -+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, -+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, -+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, -+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, -+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, -+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, -+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, -+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, -+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, -+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, -+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, -+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, -+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, -+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, -+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, -+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, -+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, -+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, -+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, -+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, -+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, -+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, -+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, -+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, -+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, -+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, -+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, -+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, -+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, -+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, -+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, -+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, -+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, -+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, -+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, -+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, -+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, -+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, -+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, -+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, -+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, -+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, -+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, -+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, -+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, -+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, -+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, -+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, -+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 -+ }, { -+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, -+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, -+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, -+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, -+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, -+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, -+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, -+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, -+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, -+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, -+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, -+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, -+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, -+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, -+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, -+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, -+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, -+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, -+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, -+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, -+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, -+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, -+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, -+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, -+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, -+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, -+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, -+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, -+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, -+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, -+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, -+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, -+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, -+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, -+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, -+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, -+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, -+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, -+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, -+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, -+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, -+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, -+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, -+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, -+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, -+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, -+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, -+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, -+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, -+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, -+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, -+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, -+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, -+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, -+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, -+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, -+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, -+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, -+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, -+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, -+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, -+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, -+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, -+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 -+ }, { -+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, -+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, -+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, -+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, -+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, -+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, -+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, -+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, -+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, -+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, -+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, -+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, -+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, -+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, -+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, -+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, -+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, -+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, -+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, -+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, -+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, -+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, -+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, -+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, -+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, -+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, -+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, -+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, -+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, -+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, -+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, -+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, -+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, -+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, -+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, -+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, -+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, -+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, -+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, -+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, -+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, -+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, -+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, -+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, -+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, -+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, -+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, -+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, -+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, -+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, -+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, -+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, -+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, -+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, -+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, -+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, -+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, -+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, -+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, -+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, -+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, -+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, -+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, -+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 -+ } -+ }, { -+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, -+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, -+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, -+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, -+ 0x9216d5d9, 0x8979fb1b -+ } -+}; -+ -+static unsigned char BF_itoa64[64 + 1] = -+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -+ -+static unsigned char BF_atoi64[0x60] = { -+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, -+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, -+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, -+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, -+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -+}; -+ -+/* -+ * This may be optimized out if built with function inlining and no BF_ASM. -+ */ -+static void clean(void *data, int size) -+{ -+#if BF_ASM -+ extern void _BF_clean(void *data); -+#endif -+ memset(data, 0, size); -+#if BF_ASM -+ _BF_clean(data); -+#endif -+} -+ -+#define BF_safe_atoi64(dst, src) \ -+{ \ -+ tmp = (unsigned char)(src); \ -+ if (tmp == '$') break; \ -+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ -+ tmp = BF_atoi64[tmp]; \ -+ if (tmp > 63) return -1; \ -+ (dst) = tmp; \ -+} -+ -+static int BF_decode(BF_word *dst, __CONST char *src, int size) -+{ -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned char *end = dptr + size; -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned int tmp, c1, c2, c3, c4; -+ -+ do { -+ BF_safe_atoi64(c1, *sptr++); -+ BF_safe_atoi64(c2, *sptr++); -+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c3, *sptr++); -+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c4, *sptr++); -+ *dptr++ = ((c3 & 0x03) << 6) | c4; -+ } while (dptr < end); -+ -+ while (dptr < end) -+ *dptr++ = 0; -+ -+ return 0; -+} -+ -+static void BF_encode(char *dst, __CONST BF_word *src, int size) -+{ -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned char *end = sptr + size; -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned int c1, c2; -+ -+ do { -+ c1 = *sptr++; -+ *dptr++ = BF_itoa64[c1 >> 2]; -+ c1 = (c1 & 0x03) << 4; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 4; -+ *dptr++ = BF_itoa64[c1]; -+ c1 = (c2 & 0x0f) << 2; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 6; -+ *dptr++ = BF_itoa64[c1]; -+ *dptr++ = BF_itoa64[c2 & 0x3f]; -+ } while (sptr < end); -+} -+ -+static void BF_swap(BF_word *x, int count) -+{ -+ static int endianness_check = 1; -+ char *is_little_endian = (char *)&endianness_check; -+ BF_word tmp; -+ -+ if (*is_little_endian) -+ do { -+ tmp = *x; -+ tmp = (tmp << 16) | (tmp >> 16); -+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); -+ } while (--count); -+} -+ -+#if BF_SCALE -+/* Architectures which can shift addresses left by 2 bits with no extra cost */ -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp2 = L >> 8; \ -+ tmp2 &= 0xFF; \ -+ tmp3 = L >> 16; \ -+ tmp3 &= 0xFF; \ -+ tmp4 = L >> 24; \ -+ tmp1 = data.ctx.S[3][tmp1]; \ -+ tmp2 = data.ctx.S[2][tmp2]; \ -+ tmp3 = data.ctx.S[1][tmp3]; \ -+ tmp3 += data.ctx.S[0][tmp4]; \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#else -+/* Architectures with no complicated addressing modes supported */ -+#define BF_INDEX(S, i) \ -+ (*((BF_word *)(((unsigned char *)S) + (i)))) -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp1 <<= 2; \ -+ tmp2 = L >> 6; \ -+ tmp2 &= 0x3FC; \ -+ tmp3 = L >> 14; \ -+ tmp3 &= 0x3FC; \ -+ tmp4 = L >> 22; \ -+ tmp4 &= 0x3FC; \ -+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ -+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ -+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ -+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#endif -+ -+/* -+ * Encrypt one block, BF_N is hardcoded here. -+ */ -+#define BF_ENCRYPT \ -+ L ^= data.ctx.P[0]; \ -+ BF_ROUND(L, R, 0); \ -+ BF_ROUND(R, L, 1); \ -+ BF_ROUND(L, R, 2); \ -+ BF_ROUND(R, L, 3); \ -+ BF_ROUND(L, R, 4); \ -+ BF_ROUND(R, L, 5); \ -+ BF_ROUND(L, R, 6); \ -+ BF_ROUND(R, L, 7); \ -+ BF_ROUND(L, R, 8); \ -+ BF_ROUND(R, L, 9); \ -+ BF_ROUND(L, R, 10); \ -+ BF_ROUND(R, L, 11); \ -+ BF_ROUND(L, R, 12); \ -+ BF_ROUND(R, L, 13); \ -+ BF_ROUND(L, R, 14); \ -+ BF_ROUND(R, L, 15); \ -+ tmp4 = R; \ -+ R = L; \ -+ L = tmp4 ^ data.ctx.P[BF_N + 1]; -+ -+#if BF_ASM -+#define BF_body() \ -+ _BF_body_r(&data.ctx); -+#else -+#define BF_body() \ -+ L = R = 0; \ -+ ptr = data.ctx.P; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.P[BF_N + 2]); \ -+\ -+ ptr = data.ctx.S[0]; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.S[3][0xFF]); -+#endif -+ -+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) -+{ -+ __CONST char *ptr = key; -+ int i, j; -+ BF_word tmp; -+ -+ for (i = 0; i < BF_N + 2; i++) { -+ tmp = 0; -+ for (j = 0; j < 4; j++) { -+ tmp <<= 8; -+ tmp |= *ptr; -+ -+ if (!*ptr) ptr = key; else ptr++; -+ } -+ -+ expanded[i] = tmp; -+ initial[i] = BF_init_state.P[i] ^ tmp; -+ } -+} -+ -+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, -+ char *output, int size) -+{ -+#if BF_ASM -+ extern void _BF_body_r(BF_ctx *ctx); -+#endif -+ struct { -+ BF_ctx ctx; -+ BF_key expanded_key; -+ union { -+ BF_word salt[4]; -+ BF_word output[6]; -+ } binary; -+ } data; -+ BF_word L, R; -+ BF_word tmp1, tmp2, tmp3, tmp4; -+ BF_word *ptr; -+ BF_word count; -+ int i; -+ -+ if (size < 7 + 22 + 31 + 1) { -+ __set_errno(ERANGE); -+ return NULL; -+ } -+ -+ if (setting[0] != '$' || -+ setting[1] != '2' || -+ setting[2] != 'a' || -+ setting[3] != '$' || -+ setting[4] < '0' || setting[4] > '3' || -+ setting[5] < '0' || setting[5] > '9' || -+ setting[6] != '$') { -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); -+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { -+ clean(data.binary.salt, sizeof(data.binary.salt)); -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ BF_swap(data.binary.salt, 4); -+ -+ BF_set_key(key, data.expanded_key, data.ctx.P); -+ -+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); -+ -+ L = R = 0; -+ for (i = 0; i < BF_N + 2; i += 2) { -+ L ^= data.binary.salt[i & 2]; -+ R ^= data.binary.salt[(i & 2) + 1]; -+ BF_ENCRYPT; -+ data.ctx.P[i] = L; -+ data.ctx.P[i + 1] = R; -+ } -+ -+ ptr = data.ctx.S[0]; -+ do { -+ ptr += 4; -+ L ^= data.binary.salt[(BF_N + 2) & 3]; -+ R ^= data.binary.salt[(BF_N + 3) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 4) = L; -+ *(ptr - 3) = R; -+ -+ L ^= data.binary.salt[(BF_N + 4) & 3]; -+ R ^= data.binary.salt[(BF_N + 5) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 2) = L; -+ *(ptr - 1) = R; -+ } while (ptr < &data.ctx.S[3][0xFF]); -+ -+ do { -+ data.ctx.P[0] ^= data.expanded_key[0]; -+ data.ctx.P[1] ^= data.expanded_key[1]; -+ data.ctx.P[2] ^= data.expanded_key[2]; -+ data.ctx.P[3] ^= data.expanded_key[3]; -+ data.ctx.P[4] ^= data.expanded_key[4]; -+ data.ctx.P[5] ^= data.expanded_key[5]; -+ data.ctx.P[6] ^= data.expanded_key[6]; -+ data.ctx.P[7] ^= data.expanded_key[7]; -+ data.ctx.P[8] ^= data.expanded_key[8]; -+ data.ctx.P[9] ^= data.expanded_key[9]; -+ data.ctx.P[10] ^= data.expanded_key[10]; -+ data.ctx.P[11] ^= data.expanded_key[11]; -+ data.ctx.P[12] ^= data.expanded_key[12]; -+ data.ctx.P[13] ^= data.expanded_key[13]; -+ data.ctx.P[14] ^= data.expanded_key[14]; -+ data.ctx.P[15] ^= data.expanded_key[15]; -+ data.ctx.P[16] ^= data.expanded_key[16]; -+ data.ctx.P[17] ^= data.expanded_key[17]; -+ -+ BF_body(); -+ -+ tmp1 = data.binary.salt[0]; -+ tmp2 = data.binary.salt[1]; -+ tmp3 = data.binary.salt[2]; -+ tmp4 = data.binary.salt[3]; -+ data.ctx.P[0] ^= tmp1; -+ data.ctx.P[1] ^= tmp2; -+ data.ctx.P[2] ^= tmp3; -+ data.ctx.P[3] ^= tmp4; -+ data.ctx.P[4] ^= tmp1; -+ data.ctx.P[5] ^= tmp2; -+ data.ctx.P[6] ^= tmp3; -+ data.ctx.P[7] ^= tmp4; -+ data.ctx.P[8] ^= tmp1; -+ data.ctx.P[9] ^= tmp2; -+ data.ctx.P[10] ^= tmp3; -+ data.ctx.P[11] ^= tmp4; -+ data.ctx.P[12] ^= tmp1; -+ data.ctx.P[13] ^= tmp2; -+ data.ctx.P[14] ^= tmp3; -+ data.ctx.P[15] ^= tmp4; -+ data.ctx.P[16] ^= tmp1; -+ data.ctx.P[17] ^= tmp2; -+ -+ BF_body(); -+ } while (--count); -+ -+ for (i = 0; i < 6; i += 2) { -+ L = BF_magic_w[i]; -+ R = BF_magic_w[i + 1]; -+ -+ count = 64; -+ do { -+ BF_ENCRYPT; -+ } while (--count); -+ -+ data.binary.output[i] = L; -+ data.binary.output[i + 1] = R; -+ } -+ -+ memcpy(output, setting, 7 + 22 - 1); -+ output[7 + 22 - 1] = BF_itoa64[(int) -+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; -+ -+/* This has to be bug-compatible with the original implementation, so -+ * only encode 23 of the 24 bytes. :-) */ -+ BF_swap(data.binary.output, 6); -+ BF_encode(&output[7 + 22], data.binary.output, 23); -+ output[7 + 22 + 31] = '\0'; -+ -+/* Overwrite the most obvious sensitive data we have on the stack. Note -+ * that this does not guarantee there's no sensitive data left on the -+ * stack and/or in registers; I'm not aware of portable code that does. */ -+ clean(&data, sizeof(data)); -+ -+ return output; -+} -+ -+char *_crypt_gensalt_blowfish_rn(unsigned long count, -+ __CONST char *input, int size, char *output, int output_size) -+{ -+ if (size < 16 || output_size < 7 + 22 + 1 || -+ (count && (count < 4 || count > 31))) { -+ if (output_size > 0) output[0] = '\0'; -+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); -+ return NULL; -+ } -+ -+ if (!count) count = 5; -+ -+ output[0] = '$'; -+ output[1] = '2'; -+ output[2] = 'a'; -+ output[3] = '$'; -+ output[4] = '0' + count / 10; -+ output[5] = '0' + count % 10; -+ output[6] = '$'; -+ -+ BF_encode(&output[7], (BF_word *)input, 16); -+ output[7 + 22] = '\0'; -+ -+ return output; -+} -diff -Nura php-4.4.2/ext/standard/crypt.c hardening-patch-4.4.2-0.4.15/ext/standard/crypt.c ---- php-4.4.2/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/crypt.c 2006-09-05 20:30:33.000000000 +0200 -@@ -100,6 +100,8 @@ - return SUCCESS; - } - -+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); -+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); - - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -@@ -135,7 +137,14 @@ - - /* The automatic salt generation only covers standard DES and md5-crypt */ - if(!*salt) { --#if PHP_MD5_CRYPT -+#if PHP_BLOWFISH_CRYPT -+ char randat[16]; -+ int i; -+ -+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; -+ -+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); -+#elif PHP_MD5_CRYPT - strcpy(salt, "$1$"); - php_to64(&salt[3], PHP_CRYPT_RAND, 4); - php_to64(&salt[7], PHP_CRYPT_RAND, 4); -@@ -145,8 +154,24 @@ - salt[2] = '\0'; - #endif - } -- -- RETVAL_STRING(crypt(str, salt), 1); -+ -+ if (salt[0] == '$' && -+ salt[1] == '2' && -+ salt[2] == 'a' && -+ salt[3] == '$' && -+ salt[4] >= '0' && salt[4] <= '3' && -+ salt[5] >= '0' && salt[5] <= '9' && -+ salt[6] == '$') { -+ -+ char output[PHP_MAX_SALT_LEN+1]; -+ -+ output[0] = 0; -+ _crypt_blowfish_rn(str, salt, output, sizeof(output)); -+ RETVAL_STRING(output, 1); -+ -+ } else { -+ RETVAL_STRING(crypt(str, salt), 1); -+ } - } - /* }}} */ - #endif -diff -Nura php-4.4.2/ext/standard/dl.c hardening-patch-4.4.2-0.4.15/ext/standard/dl.c ---- php-4.4.2/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/dl.c 2006-09-05 20:30:33.000000000 +0200 -@@ -160,8 +160,35 @@ - RETURN_FALSE; - } - module_entry = get_module(); -+ -+ /* check if Hardening-Patch is installed */ -+ if (module_entry->zend_api < 1000000000) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ -+ /* check if correct Hardening-Patch is installed */ -+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ - if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) -- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { -+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { - /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ - struct pre_4_1_0_module_entry { - char *name; -@@ -195,7 +222,7 @@ - zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; - } else { - name = module_entry->name; -- zend_api = module_entry->zend_api; -+ zend_api = module_entry->real_zend_api; - zend_debug = module_entry->zend_debug; - zts = module_entry->zts; - } -diff -Nura php-4.4.2/ext/standard/file.c hardening-patch-4.4.2-0.4.15/ext/standard/file.c ---- php-4.4.2/ext/standard/file.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/file.c 2006-09-05 20:30:33.000000000 +0200 -@@ -21,7 +21,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: file.c,v 1.279.2.70.2.3 2006/01/01 13:46:57 sniper Exp $ */ -+/* $Id: file.c,v 1.279.2.70.2.7 2006/04/14 17:46:59 pollita Exp $ */ - - /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ - -@@ -552,7 +552,7 @@ - pval **arg1, **arg2; - char *d; - char *opened_path; -- char p[64]; -+ char *p; - FILE *fp; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) { -@@ -566,7 +566,11 @@ - } - - d = estrndup(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1)); -- strlcpy(p, Z_STRVAL_PP(arg2), sizeof(p)); -+ -+ p = php_basename(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2), NULL, 0); -+ if (strlen(p) > 64) { -+ p[63] = '\0'; -+ } - - if ((fp = php_open_temporary_file(d, p, &opened_path TSRMLS_CC))) { - fclose(fp); -@@ -574,6 +578,7 @@ - } else { - RETVAL_FALSE; - } -+ efree(p); - efree(d); - } - /* }}} */ -@@ -819,7 +824,7 @@ - - /* If seconds is not set to null, build the timeval, else we wait indefinitely */ - if (sec != NULL) { -- convert_to_long_ex(&sec); -+ convert_to_long(sec); - - if (usec > 999999) { - tv.tv_sec = Z_LVAL_P(sec) + (usec / 1000000); -@@ -2196,7 +2201,7 @@ - safe_to_copy: - - srcstream = php_stream_open_wrapper(src, "rb", -- STREAM_DISABLE_OPEN_BASEDIR | REPORT_ERRORS, -+ ENFORCE_SAFE_MODE | REPORT_ERRORS, - NULL); - - if (!srcstream) -@@ -2522,7 +2527,7 @@ - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) - /* {{{ proto string realpath(string path) - Return the resolved path */ --PHP_FUNCTION(realpath) -+PHP_FUNCTION(real_path) - { - zval **path; - char resolved_path_buff[MAXPATHLEN]; -diff -Nura php-4.4.2/ext/standard/file.h hardening-patch-4.4.2-0.4.15/ext/standard/file.h ---- php-4.4.2/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/file.h 2006-09-05 20:30:33.000000000 +0200 -@@ -64,7 +64,7 @@ - PHP_FUNCTION(fd_set); - PHP_FUNCTION(fd_isset); - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) --PHP_FUNCTION(realpath); -+PHP_FUNCTION(real_path); - #endif - #ifdef HAVE_FNMATCH - PHP_FUNCTION(fnmatch); -diff -Nura php-4.4.2/ext/standard/head.c hardening-patch-4.4.2-0.4.15/ext/standard/head.c ---- php-4.4.2/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/head.c 2006-09-05 20:30:33.000000000 +0200 -@@ -44,7 +44,7 @@ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, - &ctr.line_len, &rep, &ctr.response_code) == FAILURE) - return; -- -+ - sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); - } - /* }}} */ -diff -Nura php-4.4.2/ext/standard/html.c hardening-patch-4.4.2-0.4.15/ext/standard/html.c ---- php-4.4.2/ext/standard/html.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/html.c 2006-09-05 20:30:33.000000000 +0200 -@@ -18,7 +18,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: html.c,v 1.63.2.23.2.1 2006/01/01 13:46:57 sniper Exp $ */ -+/* $Id: html.c,v 1.63.2.23.2.2 2006/02/25 21:33:06 rasmus Exp $ */ - - /* - * HTML entity resources: -@@ -793,7 +793,7 @@ - enum entity_charset charset = determine_charset(hint_charset TSRMLS_CC); - unsigned char replacement[15]; - -- ret = estrdup(old); -+ ret = estrndup(old, oldlen); - retlen = oldlen; - if (!retlen) { - goto empty_source; -diff -Nura php-4.4.2/ext/standard/http_fopen_wrapper.c hardening-patch-4.4.2-0.4.15/ext/standard/http_fopen_wrapper.c ---- php-4.4.2/ext/standard/http_fopen_wrapper.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/http_fopen_wrapper.c 2006-09-05 20:30:33.000000000 +0200 -@@ -18,7 +18,7 @@ - | Wez Furlong | - +----------------------------------------------------------------------+ - */ --/* $Id: http_fopen_wrapper.c,v 1.53.2.20.2.5 2006/01/01 13:46:57 sniper Exp $ */ -+/* $Id: http_fopen_wrapper.c,v 1.53.2.20.2.9 2006/04/16 17:45:55 iliaa Exp $ */ - - #include "php.h" - #include "php_globals.h" -@@ -339,7 +339,7 @@ - size_t tmp_line_len; - /* get response header */ - -- if (_php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len TSRMLS_CC) != NULL) { -+ if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) { - zval *http_response; - int response_code; - -@@ -353,6 +353,7 @@ - } - switch(response_code) { - case 200: -+ case 206: /* partial content */ - case 302: - case 301: - reqok = 1; -@@ -394,7 +395,7 @@ - - while (!body && !php_stream_eof(stream)) { - size_t http_header_line_length; -- if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length TSRMLS_CC) && *http_header_line != '\n' && *http_header_line != '\r') { -+ if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') { - char *e = http_header_line + http_header_line_length - 1; - while (*e == '\n' || *e == '\r') { - e--; -@@ -502,9 +503,11 @@ - } \ - } \ - /* check for control characters in login, password & path */ -- CHECK_FOR_CNTRL_CHARS(resource->user) -- CHECK_FOR_CNTRL_CHARS(resource->pass) -- CHECK_FOR_CNTRL_CHARS(resource->path) -+ if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) { -+ CHECK_FOR_CNTRL_CHARS(resource->user) -+ CHECK_FOR_CNTRL_CHARS(resource->pass) -+ CHECK_FOR_CNTRL_CHARS(resource->path) -+ } - - stream = php_stream_url_wrap_http_ex(NULL, new_path, mode, options, opened_path, context, --redirect_max, 0 STREAMS_CC TSRMLS_CC); - if (stream && stream->wrapperdata) { -diff -Nura php-4.4.2/ext/standard/info.c hardening-patch-4.4.2-0.4.15/ext/standard/info.c ---- php-4.4.2/ext/standard/info.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/info.c 2006-09-05 20:30:33.000000000 +0200 -@@ -18,7 +18,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: info.c,v 1.218.2.18.2.6 2006/01/01 13:46:57 sniper Exp $ */ -+/* $Id: info.c,v 1.218.2.18.2.7 2006/06/28 13:12:09 derick Exp $ */ - - #include "php.h" - #include "php_ini.h" -@@ -58,6 +58,23 @@ - - PHPAPI extern char *php_ini_opened_path; - PHPAPI extern char *php_ini_scanned_files; -+ -+static int php_info_write_wrapper(const char *str, uint str_length) -+{ -+ int new_len, written; -+ char *elem_esc; -+ -+ TSRMLS_FETCH(); -+ -+ elem_esc = php_escape_html_entities((char *)str, str_length, &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC); -+ -+ written = php_body_write(elem_esc, new_len TSRMLS_CC); -+ -+ efree(elem_esc); -+ -+ return written; -+} -+ - - /* {{{ _display_module_info - */ -@@ -133,23 +150,12 @@ - PUTS(" => "); - } - if (Z_TYPE_PP(tmp) == IS_ARRAY) { -- zval *tmp3; -- MAKE_STD_ZVAL(tmp3); - if (!sapi_module.phpinfo_as_text) { - PUTS("
");
--				}
--				php_start_ob_buffer(NULL, 4096, 1 TSRMLS_CC);
--				zend_print_zval_r(*tmp, 0);
--				php_ob_get_buffer(tmp3 TSRMLS_CC);
--				php_end_ob_buffer(0, 0 TSRMLS_CC);
--				
--				elem_esc = php_info_html_esc(Z_STRVAL_P(tmp3) TSRMLS_CC);
--				PUTS(elem_esc);
--				efree(elem_esc);
--				zval_ptr_dtor(&tmp3);
--
--				if (!sapi_module.phpinfo_as_text) {
-+					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
- 					PUTS("
"); -+ } else { -+ zend_print_zval_r(*tmp, 0); - } - } else if (Z_TYPE_PP(tmp) != IS_STRING) { - tmp2 = **tmp; -@@ -408,7 +414,7 @@ - - if (flag & PHP_INFO_GENERAL) { - char *zend_version = get_zend_version(); -- char temp_api[9]; -+ char temp_api[11]; - - php_uname = php_get_uname('a'); - -@@ -430,11 +436,22 @@ - } - } - -+#if HARDENING_PATCH -+ if (!sapi_module.phpinfo_as_text) { -+ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); -+ } else { -+ char temp_ver[40]; -+ -+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); -+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); -+ } -+#else - if (!sapi_module.phpinfo_as_text) { - php_printf("

PHP Version %s

\n", PHP_VERSION); - } else { - php_info_print_table_row(2, "PHP Version", PHP_VERSION); - } -+#endif - php_info_print_box_end(); - php_info_print_table_start(); - php_info_print_table_row(2, "System", php_uname ); -diff -Nura php-4.4.2/ext/standard/mail.c hardening-patch-4.4.2-0.4.15/ext/standard/mail.c ---- php-4.4.2/ext/standard/mail.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/mail.c 2006-09-05 20:30:33.000000000 +0200 -@@ -78,6 +78,25 @@ - } - /* }}} */ - -+/* {{{ hphp_strcasestr */ -+char *hphp_strcasestr(char *haystack, char *needle) -+{ -+ unsigned char *t, *h, *n; -+ -+ h = (unsigned char *) haystack; -+conts: -+ while (*h) { -+ n = (unsigned char *) needle; -+ for (t=h++; *n && *h; t++, n++) { -+ if (toupper(*t) != toupper(*n)) goto conts; -+ } -+ return ((char*)h-1); -+ } -+ -+ return (NULL); -+} -+/* }}} */ -+ - /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) - Send an email message */ - PHP_FUNCTION(mail) -@@ -103,6 +122,44 @@ - return; - } - -+ if (HG(hphp_mailprotect) > 0) { -+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { -+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ /* check for spam attempts with buggy webforms */ -+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (HG(hphp_mailprotect) > 1) { -+ /* search for to, cc or bcc headers */ -+ if (headers_len > 0 && headers != NULL) { -+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { -+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { -+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { -+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ } -+ } -+ } -+ - if (to_len > 0) { - to_r = estrndup(to, to_len); - for (; to_len; to_len--) { -diff -Nura php-4.4.2/ext/standard/pack.c hardening-patch-4.4.2-0.4.15/ext/standard/pack.c ---- php-4.4.2/ext/standard/pack.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/pack.c 2006-09-05 20:30:33.000000000 +0200 -@@ -15,7 +15,7 @@ - | Author: Chris Schneider | - +----------------------------------------------------------------------+ - */ --/* $Id: pack.c,v 1.40.2.7.2.4 2006/01/01 13:46:57 sniper Exp $ */ -+/* $Id: pack.c,v 1.40.2.7.2.5 2006/01/26 15:47:31 iliaa Exp $ */ - - #include "php.h" - -@@ -693,7 +693,9 @@ - len = size * 2; - } - -- len -= argb % 2; -+ if (argb > 0) { -+ len -= argb % 2; -+ } - - buf = emalloc(len + 1); - -diff -Nura php-4.4.2/ext/standard/php_standard.h hardening-patch-4.4.2-0.4.15/ext/standard/php_standard.h ---- php-4.4.2/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/php_standard.h 2006-09-05 20:30:33.000000000 +0200 -@@ -28,6 +28,7 @@ - #include "php_mail.h" - #include "md5.h" - #include "sha1.h" -+#include "sha256.h" - #include "html.h" - #include "exec.h" - #include "file.h" -diff -Nura php-4.4.2/ext/standard/scanf.c hardening-patch-4.4.2-0.4.15/ext/standard/scanf.c ---- php-4.4.2/ext/standard/scanf.c 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/scanf.c 2006-09-05 20:30:33.000000000 +0200 -@@ -16,7 +16,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: scanf.c,v 1.16.4.9.2.1 2006/01/01 13:46:58 sniper Exp $ */ -+/* $Id: scanf.c,v 1.16.4.9.2.2 2006/08/04 11:59:50 tony2001 Exp $ */ - - /* - scanf.c -- -@@ -732,7 +732,7 @@ - if (*end == '$') { - format = end+1; - ch = format++; -- objIndex = varStart + value; -+ objIndex = varStart + value - 1; - } - } - -@@ -762,8 +762,10 @@ - switch (*ch) { - case 'n': - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -- current = args[objIndex++]; -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { -+ current = args[objIndex++]; - zval_dtor( *current ); - ZVAL_LONG( *current, (long)(string - baseString) ); - } else { -@@ -883,8 +885,10 @@ - } - } - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -- current = args[objIndex++]; -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { -+ current = args[objIndex++]; - zval_dtor( *current ); - ZVAL_STRINGL( *current, string, end-string, 1); - } else { -@@ -922,7 +926,9 @@ - goto done; - } - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - zval_dtor( *current ); - ZVAL_STRINGL( *current, string, end-string, 1); -@@ -1079,8 +1085,10 @@ - value = (int) (*fn)(buf, NULL, base); - if ((flags & SCAN_UNSIGNED) && (value < 0)) { - sprintf(buf, "%u", value); /* INTL: ISO digit */ -- if (numVars) { -- /* change passed value type to string */ -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { -+ /* change passed value type to string */ - current = args[objIndex++]; - convert_to_string( *current ); - ZVAL_STRING( *current, buf, 1 ); -@@ -1088,7 +1096,9 @@ - add_index_string(*return_value, objIndex++, buf, 1); - } - } else { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - convert_to_long( *current ); - Z_LVAL(**current) = value; -@@ -1196,7 +1206,9 @@ - double dvalue; - *end = '\0'; - dvalue = zend_strtod(buf, NULL); -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - convert_to_double( *current ); - Z_DVAL_PP( current ) = dvalue; -diff -Nura php-4.4.2/ext/standard/sha256.c hardening-patch-4.4.2-0.4.15/ext/standard/sha256.c ---- php-4.4.2/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/sha256.c 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,398 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ -+ -+#include -+#include "php.h" -+ -+/* This code is heavily based on the PHP md5/sha1 implementations */ -+ -+#include "sha256.h" -+ -+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ sprintf(sha256str, "%02x", digest[i]); -+ sha256str += 2; -+ } -+ -+ *sha256str = '\0'; -+} -+ -+/* {{{ proto string sha256(string str [, bool raw_output]) -+ Calculate the sha256 hash of a string */ -+PHP_FUNCTION(sha256) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ PHP_SHA256_CTX context; -+ unsigned char digest[32]; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ sha256str[0] = '\0'; -+ PHP_SHA256Init(&context); -+ PHP_SHA256Update(&context, arg, arg_len); -+ PHP_SHA256Final(digest, &context); -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+ -+} -+ -+/* }}} */ -+ -+/* {{{ proto string sha256_file(string filename [, bool raw_output]) -+ Calculate the sha256 hash of given filename */ -+PHP_FUNCTION(sha256_file) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ unsigned char buf[1024]; -+ unsigned char digest[32]; -+ PHP_SHA256_CTX context; -+ int n; -+ FILE *fp; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { -+ RETURN_FALSE; -+ } -+ -+ if (php_check_open_basedir(arg TSRMLS_CC)) { -+ RETURN_FALSE; -+ } -+ -+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); -+ RETURN_FALSE; -+ } -+ -+ PHP_SHA256Init(&context); -+ -+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { -+ PHP_SHA256Update(&context, buf, n); -+ } -+ -+ PHP_SHA256Final(digest, &context); -+ -+ if (ferror(fp)) { -+ fclose(fp); -+ RETURN_FALSE; -+ } -+ -+ fclose(fp); -+ -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+} -+/* }}} */ -+ -+ -+static void SHA256Transform(php_uint32[8], const unsigned char[64]); -+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); -+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); -+ -+static unsigned char PADDING[64] = -+{ -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* F, G, H and I are basic SHA256 functions. -+ */ -+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) -+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) -+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) -+#define I(x, y, z) (((x) & (y)) | ((~x) & z)) -+ -+/* ROTATE_RIGHT rotates x right n bits. -+ */ -+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) -+ -+/* W[i] -+ */ -+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ -+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ -+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) -+ -+/* ROUND function of sha256 -+ */ -+ -+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ -+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ -+ (h) = F((a)) + G((a), (b), (c)) + t1; \ -+ (d) += t1; \ -+ } -+ -+ -+/* {{{ PHP_SHA256Init -+ * SHA256 initialization. Begins an SHA256 operation, writing a new context. -+ */ -+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context) -+{ -+ context->count[0] = context->count[1] = 0; -+ /* Load magic initialization constants. -+ */ -+ context->state[0] = 0x6a09e667; -+ context->state[1] = 0xbb67ae85; -+ context->state[2] = 0x3c6ef372; -+ context->state[3] = 0xa54ff53a; -+ context->state[4] = 0x510e527f; -+ context->state[5] = 0x9b05688c; -+ context->state[6] = 0x1f83d9ab; -+ context->state[7] = 0x5be0cd19; -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Update -+ SHA256 block update operation. Continues an SHA256 message-digest -+ operation, processing another message block, and updating the -+ context. -+ */ -+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, -+ unsigned int inputLen) -+{ -+ unsigned int i, index, partLen; -+ -+ /* Compute number of bytes mod 64 */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); -+ -+ /* Update number of bits */ -+ if ((context->count[0] += ((php_uint32) inputLen << 3)) -+ < ((php_uint32) inputLen << 3)) -+ context->count[1]++; -+ context->count[1] += ((php_uint32) inputLen >> 29); -+ -+ partLen = 64 - index; -+ -+ /* Transform as many times as possible. -+ */ -+ if (inputLen >= partLen) { -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); -+ SHA256Transform(context->state, context->buffer); -+ -+ for (i = partLen; i + 63 < inputLen; i += 64) -+ SHA256Transform(context->state, &input[i]); -+ -+ index = 0; -+ } else -+ i = 0; -+ -+ /* Buffer remaining input */ -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], -+ inputLen - i); -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Final -+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the -+ the message digest and zeroizing the context. -+ */ -+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) -+{ -+ unsigned char bits[8]; -+ unsigned int index, padLen; -+ -+ /* Save number of bits */ -+ bits[7] = context->count[0] & 0xFF; -+ bits[6] = (context->count[0] >> 8) & 0xFF; -+ bits[5] = (context->count[0] >> 16) & 0xFF; -+ bits[4] = (context->count[0] >> 24) & 0xFF; -+ bits[3] = context->count[1] & 0xFF; -+ bits[2] = (context->count[1] >> 8) & 0xFF; -+ bits[1] = (context->count[1] >> 16) & 0xFF; -+ bits[0] = (context->count[1] >> 24) & 0xFF; -+ -+ /* Pad out to 56 mod 64. -+ */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); -+ padLen = (index < 56) ? (56 - index) : (120 - index); -+ PHP_SHA256Update(context, PADDING, padLen); -+ -+ /* Append length (before padding) */ -+ PHP_SHA256Update(context, bits, 8); -+ -+ /* Store state in digest */ -+ SHA256Encode(digest, context->state, 32); -+ -+ /* Zeroize sensitive information. -+ */ -+ memset((unsigned char*) context, 0, sizeof(*context)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Transform -+ * SHA256 basic transformation. Transforms state based on block. -+ */ -+static void SHA256Transform(state, block) -+php_uint32 state[8]; -+const unsigned char block[64]; -+{ -+ php_uint32 a = state[0], b = state[1], c = state[2]; -+ php_uint32 d = state[3], e = state[4], f = state[5]; -+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; -+ -+ SHA256Decode(x, block, 64); -+ -+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) -+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) -+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) -+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) -+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) -+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) -+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) -+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) -+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) -+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) -+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) -+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) -+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) -+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) -+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) -+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) -+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) -+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) -+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) -+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) -+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) -+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) -+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) -+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) -+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) -+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) -+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) -+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) -+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) -+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) -+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) -+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) -+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) -+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) -+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) -+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) -+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) -+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) -+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) -+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) -+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) -+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) -+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) -+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) -+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) -+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) -+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) -+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) -+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) -+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) -+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) -+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) -+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) -+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) -+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) -+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) -+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) -+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) -+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) -+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) -+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) -+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) -+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) -+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) -+ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ state[4] += e; -+ state[5] += f; -+ state[6] += g; -+ state[7] += h; -+ -+ /* Zeroize sensitive information. */ -+ memset((unsigned char*) x, 0, sizeof(x)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Encode -+ Encodes input (php_uint32) into output (unsigned char). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Encode(output, input, len) -+unsigned char *output; -+php_uint32 *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) { -+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); -+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); -+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); -+ output[j + 3] = (unsigned char) (input[i] & 0xff); -+ } -+} -+/* }}} */ -+ -+/* {{{ SHA256Decode -+ Decodes input (unsigned char) into output (php_uint32). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Decode(output, input, len) -+php_uint32 *output; -+const unsigned char *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) -+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | -+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.2/ext/standard/sha256.h hardening-patch-4.4.2-0.4.15/ext/standard/sha256.h ---- php-4.4.2/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/sha256.h 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ -+ -+#ifndef SHA256_H -+#define SHA256_H -+ -+#include "ext/standard/basic_functions.h" -+ -+/* SHA1 context. */ -+typedef struct { -+ php_uint32 state[8]; /* state (ABCD) */ -+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ -+ unsigned char buffer[64]; /* input buffer */ -+} PHP_SHA256_CTX; -+ -+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *); -+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); -+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); -+ -+PHP_FUNCTION(sha256); -+PHP_FUNCTION(sha256_file); -+ -+#endif -diff -Nura php-4.4.2/ext/standard/string.c hardening-patch-4.4.2-0.4.15/ext/standard/string.c ---- php-4.4.2/ext/standard/string.c 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/string.c 2006-09-05 20:30:33.000000000 +0200 -@@ -18,7 +18,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: string.c,v 1.333.2.52.2.3 2006/01/01 13:46:58 sniper Exp $ */ -+/* $Id: string.c,v 1.333.2.52.2.4 2006/03/13 14:41:27 iliaa Exp $ */ - - /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ - -@@ -628,7 +628,8 @@ - { - const char *text, *breakchar = "\n"; - char *newtext; -- int textlen, breakcharlen = 1, newtextlen, alloced, chk; -+ int textlen, breakcharlen = 1, newtextlen, chk; -+ size_t alloced; - long current = 0, laststart = 0, lastspace = 0; - long linelength = 75; - zend_bool docut = 0; -@@ -672,15 +673,13 @@ - /* Multiple character line break or forced cut */ - if (linelength > 0) { - chk = (int)(textlen/linelength + 1); -+ newtext = safe_emalloc(chk, breakcharlen, textlen + 1); - alloced = textlen + chk * breakcharlen + 1; - } else { - chk = textlen; -+ newtext = safe_emalloc(textlen, (breakcharlen + 1), 1); - alloced = textlen * (breakcharlen + 1) + 1; - } -- if (alloced <= 0) { -- RETURN_FALSE; -- } -- newtext = emalloc(alloced); - - /* now keep track of the actual new text length */ - newtextlen = 0; -@@ -3515,7 +3514,7 @@ - zval **input_str; /* Input string */ - zval **mult; /* Multiplier */ - char *result; /* Resulting string */ -- int result_len; /* Length of the resulting string */ -+ size_t result_len; /* Length of the resulting string */ - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { - WRONG_PARAM_COUNT; -@@ -3540,11 +3539,7 @@ - - /* Initialize the result string */ - result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); -- if (result_len < 1) { -- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes"); -- RETURN_FALSE; -- } -- result = (char *)emalloc(result_len + 1); -+ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1); - - /* Heavy optimization for situations where input string is 1 byte long */ - if (Z_STRLEN_PP(input_str) == 1) { -diff -Nura php-4.4.2/ext/standard/syslog.c hardening-patch-4.4.2-0.4.15/ext/standard/syslog.c ---- php-4.4.2/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/syslog.c 2006-09-05 20:30:33.000000000 +0200 -@@ -42,6 +42,8 @@ - */ - PHP_MINIT_FUNCTION(syslog) - { -+ -+#if !HARDENING_PATCH - /* error levels */ - REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ - REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -@@ -97,7 +99,7 @@ - /* AIX doesn't have LOG_PERROR */ - REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ - #endif -- -+#endif - return SUCCESS; - } - /* }}} */ -diff -Nura php-4.4.2/ext/standard/tests/strings/bug38322.phpt hardening-patch-4.4.2-0.4.15/ext/standard/tests/strings/bug38322.phpt ---- php-4.4.2/ext/standard/tests/strings/bug38322.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/tests/strings/bug38322.phpt 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+Bug #38322 (reading past array in sscanf() leads to segfault/arbitary code execution) -+--FILE-- -+ -+--EXPECTF-- -+int(1) -+Done -diff -Nura php-4.4.2/ext/standard/url.c hardening-patch-4.4.2-0.4.15/ext/standard/url.c ---- php-4.4.2/ext/standard/url.c 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/standard/url.c 2006-09-05 20:30:33.000000000 +0200 -@@ -15,7 +15,7 @@ - | Author: Jim Winstead | - +----------------------------------------------------------------------+ - */ --/* $Id: url.c,v 1.58.2.21.2.2 2006/01/01 13:46:58 sniper Exp $ */ -+/* $Id: url.c,v 1.58.2.21.2.3 2006/02/12 16:43:03 iliaa Exp $ */ - - #include - #include -@@ -137,7 +137,7 @@ - p++; - } - -- if ((*p) == '\0' || *p == '/') { -+ if ((*p == '\0' || *p == '/') && (p - e) < 7) { - goto parse_port; - } - -diff -Nura php-4.4.2/ext/varfilter/config.m4 hardening-patch-4.4.2-0.4.15/ext/varfilter/config.m4 ---- php-4.4.2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/varfilter/config.m4 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,11 @@ -+dnl -+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+dnl -+ -+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, -+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) -+ -+if test "$PHP_VARFILTER" != "no"; then -+ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) -+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) -+fi -diff -Nura php-4.4.2/ext/varfilter/CREDITS hardening-patch-4.4.2-0.4.15/ext/varfilter/CREDITS ---- php-4.4.2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,2 @@ -+varfilter -+Stefan Esser -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-4.4.2/ext/varfilter/php_varfilter.h hardening-patch-4.4.2-0.4.15/ext/varfilter/php_varfilter.h ---- php-4.4.2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,144 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifndef PHP_VARFILTER_H -+#define PHP_VARFILTER_H -+ -+extern zend_module_entry varfilter_module_entry; -+#define phpext_varfilter_ptr &varfilter_module_entry -+ -+#ifdef PHP_WIN32 -+#define PHP_VARFILTER_API __declspec(dllexport) -+#else -+#define PHP_VARFILTER_API -+#endif -+ -+#ifdef ZTS -+#include "TSRM.h" -+#endif -+ -+#include "SAPI.h" -+ -+#include "php_variables.h" -+ -+#ifdef ZEND_ENGINE_2 -+#define HASH_HTTP_GET_VARS 0x2095733f -+#define HASH_HTTP_POST_VARS 0xbfee1265 -+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 -+#define HASH_HTTP_ENV_VARS 0x1fe186a8 -+#define HASH_HTTP_SERVER_VARS 0xc987afd6 -+#define HASH_HTTP_SESSION_VARS 0x7aba0d43 -+#define HASH_HTTP_POST_FILES 0x98eb1ddc -+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec -+#else -+#define HASH_HTTP_GET_VARS 0x8d8645bd -+#define HASH_HTTP_POST_VARS 0x7c699bf3 -+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f -+#define HASH_HTTP_ENV_VARS 0x84da3016 -+#define HASH_HTTP_SERVER_VARS 0x6dbf964e -+#define HASH_HTTP_SESSION_VARS 0x322906f5 -+#define HASH_HTTP_POST_FILES 0xe4e4ce70 -+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e -+#endif -+ -+PHP_MINIT_FUNCTION(varfilter); -+PHP_MSHUTDOWN_FUNCTION(varfilter); -+PHP_RINIT_FUNCTION(varfilter); -+PHP_RSHUTDOWN_FUNCTION(varfilter); -+PHP_MINFO_FUNCTION(varfilter); -+ -+ -+ZEND_BEGIN_MODULE_GLOBALS(varfilter) -+/* request variables */ -+ long max_request_variables; -+ long cur_request_variables; -+ long max_varname_length; -+ long max_totalname_length; -+ long max_value_length; -+ long max_array_depth; -+ long max_array_index_length; -+ zend_bool disallow_nul; -+/* cookie variables */ -+ long max_cookie_vars; -+ long cur_cookie_vars; -+ long max_cookie_name_length; -+ long max_cookie_totalname_length; -+ long max_cookie_value_length; -+ long max_cookie_array_depth; -+ long max_cookie_array_index_length; -+ zend_bool disallow_cookie_nul; -+/* get variables */ -+ long max_get_vars; -+ long cur_get_vars; -+ long max_get_name_length; -+ long max_get_totalname_length; -+ long max_get_value_length; -+ long max_get_array_depth; -+ long max_get_array_index_length; -+ zend_bool disallow_get_nul; -+/* post variables */ -+ long max_post_vars; -+ long cur_post_vars; -+ long max_post_name_length; -+ long max_post_totalname_length; -+ long max_post_value_length; -+ long max_post_array_depth; -+ long max_post_array_index_length; -+ zend_bool disallow_post_nul; -+/* fileupload */ -+ long max_uploads; -+ long cur_uploads; -+ zend_bool disallow_elf_files; -+ char *verification_script; -+ -+ zend_bool no_more_variables; -+ zend_bool no_more_get_variables; -+ zend_bool no_more_post_variables; -+ zend_bool no_more_cookie_variables; -+ zend_bool no_more_uploads; -+ -+ZEND_END_MODULE_GLOBALS(varfilter) -+ -+ -+#ifdef ZTS -+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) -+#else -+#define VARFILTER_G(v) (varfilter_globals.v) -+#endif -+ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); -+SAPI_TREAT_DATA_FUNC(varfilter_treat_data); -+ -+ -+ -+#endif /* PHP_VARFILTER_H */ -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * indent-tabs-mode: t -+ * End: -+ */ -diff -Nura php-4.4.2/ext/varfilter/varfilter.c hardening-patch-4.4.2-0.4.15/ext/varfilter/varfilter.c ---- php-4.4.2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:48:50.000000000 +0200 -@@ -0,0 +1,915 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "php.h" -+#include "php_ini.h" -+#include "ext/standard/info.h" -+#include "php_varfilter.h" -+#include "hardening_patch.h" -+ -+ZEND_DECLARE_MODULE_GLOBALS(varfilter) -+ -+/* True global resources - no need for thread safety here */ -+static int le_varfilter; -+ -+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; -+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; -+static zend_bool hooked = 0; -+ -+/* {{{ varfilter_module_entry -+ */ -+zend_module_entry varfilter_module_entry = { -+#if ZEND_MODULE_API_NO >= 20010901 -+ STANDARD_MODULE_HEADER, -+#endif -+ "varfilter", -+ NULL, -+ PHP_MINIT(varfilter), -+ PHP_MSHUTDOWN(varfilter), -+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ -+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ -+ PHP_MINFO(varfilter), -+#if ZEND_MODULE_API_NO >= 20010901 -+ "0.4.15", /* Replace with version number for your extension */ -+#endif -+ STANDARD_MODULE_PROPERTIES -+}; -+/* }}} */ -+ -+#ifdef COMPILE_DL_VARFILTER -+ZEND_GET_MODULE(varfilter) -+#endif -+ -+/* {{{ PHP_INI -+ */ -+PHP_INI_BEGIN() -+ /* for backward compatibility */ -+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) -+ -+ -+PHP_INI_END() -+/* }}} */ -+ -+/* {{{ php_varfilter_init_globals -+ */ -+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) -+{ -+ varfilter_globals->max_request_variables = 200; -+ varfilter_globals->max_varname_length = 64; -+ varfilter_globals->max_value_length = 10000; -+ varfilter_globals->max_array_depth = 100; -+ varfilter_globals->max_totalname_length = 256; -+ varfilter_globals->max_array_index_length = 64; -+ varfilter_globals->disallow_nul = 1; -+ -+ varfilter_globals->max_cookie_vars = 100; -+ varfilter_globals->max_cookie_name_length = 64; -+ varfilter_globals->max_cookie_totalname_length = 256; -+ varfilter_globals->max_cookie_value_length = 10000; -+ varfilter_globals->max_cookie_array_depth = 100; -+ varfilter_globals->max_cookie_array_index_length = 64; -+ varfilter_globals->disallow_cookie_nul = 1; -+ -+ varfilter_globals->max_get_vars = 100; -+ varfilter_globals->max_get_name_length = 64; -+ varfilter_globals->max_get_totalname_length = 256; -+ varfilter_globals->max_get_value_length = 512; -+ varfilter_globals->max_get_array_depth = 50; -+ varfilter_globals->max_get_array_index_length = 64; -+ varfilter_globals->disallow_get_nul = 1; -+ -+ varfilter_globals->max_post_vars = 200; -+ varfilter_globals->max_post_name_length = 64; -+ varfilter_globals->max_post_totalname_length = 256; -+ varfilter_globals->max_post_value_length = 65000; -+ varfilter_globals->max_post_array_depth = 100; -+ varfilter_globals->max_post_array_index_length = 64; -+ varfilter_globals->disallow_post_nul = 1; -+ -+ varfilter_globals->max_uploads = 25; -+ varfilter_globals->disallow_elf_files = 1; -+ varfilter_globals->verification_script = NULL; -+ -+ varfilter_globals->no_more_variables = 0; -+ varfilter_globals->no_more_get_variables = 0; -+ varfilter_globals->no_more_post_variables = 0; -+ varfilter_globals->no_more_cookie_variables = 0; -+ varfilter_globals->no_more_uploads = 0; -+ -+ varfilter_globals->cur_request_variables = 0; -+ varfilter_globals->cur_get_vars = 0; -+ varfilter_globals->cur_post_vars = 0; -+ varfilter_globals->cur_cookie_vars = 0; -+ -+ varfilter_globals->cur_uploads = 0; -+ -+} -+/* }}} */ -+ -+ -+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) -+{ -+ HashTable *svars; -+ int retval, failure=0; -+ -+ orig_register_server_variables(track_vars_array TSRMLS_CC); -+ -+ svars = Z_ARRVAL_P(track_vars_array); -+ -+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ -+ if (failure) { -+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); -+ } -+} -+ -+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) -+{ -+ int retval = SAPI_HEADER_ADD, i; -+ char *tmp; -+ -+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { -+ -+ tmp = sapi_header->header; -+ for (i=0; iheader_len; i++, tmp++) { -+ if (tmp[0] == 0) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); -+ sapi_header->header_len = i; -+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); -+ sapi_header->header_len = i; -+ tmp[0] = 0; -+ } -+ } -+ } -+ -+ if (orig_header_handler) { -+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); -+ } -+ -+ return retval; -+} -+ -+/* {{{ PHP_MINIT_FUNCTION -+ */ -+PHP_MINIT_FUNCTION(varfilter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); -+ REGISTER_INI_ENTRIES(); -+ -+ if (!hooked) { -+ void *temp; -+ hooked = 1; -+ -+ temp = (void *)sapi_module.register_server_variables; -+ if (temp != varfilter_register_server_variables) { -+ orig_register_server_variables = temp; -+ } -+ temp = (void *)sapi_module.header_handler; -+ if (temp != varfilter_header_handler) { -+ orig_header_handler = temp; -+ } -+ } -+ -+ sapi_register_input_filter(varfilter_input_filter); -+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); -+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); -+ sapi_register_upload_content_filter(varfilter_upload_content_filter); -+ sapi_register_post_upload_filter(varfilter_post_upload_filter); -+ -+ sapi_module.header_handler = varfilter_header_handler; -+ sapi_module.register_server_variables = varfilter_register_server_variables; -+ -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MSHUTDOWN_FUNCTION -+ */ -+PHP_MSHUTDOWN_FUNCTION(varfilter) -+{ -+ UNREGISTER_INI_ENTRIES(); -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request start */ -+/* {{{ PHP_RINIT_FUNCTION -+ */ -+PHP_RINIT_FUNCTION(varfilter) -+{ -+ VARFILTER_G(cur_request_variables) = 0; -+ VARFILTER_G(cur_get_vars) = 0; -+ VARFILTER_G(cur_post_vars) = 0; -+ VARFILTER_G(cur_cookie_vars) = 0; -+ -+ VARFILTER_G(cur_uploads) = 0; -+ -+ VARFILTER_G(no_more_variables) = 0; -+ VARFILTER_G(no_more_get_variables) = 0; -+ VARFILTER_G(no_more_post_variables) = 0; -+ VARFILTER_G(no_more_cookie_variables) = 0; -+ VARFILTER_G(no_more_uploads) = 0; -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request end */ -+/* {{{ PHP_RSHUTDOWN_FUNCTION -+ */ -+PHP_RSHUTDOWN_FUNCTION(varfilter) -+{ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MINFO_FUNCTION -+ */ -+PHP_MINFO_FUNCTION(varfilter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); -+ php_info_print_table_end(); -+ -+ DISPLAY_INI_ENTRIES(); -+} -+/* }}} */ -+ -+/* {{{ normalize_varname -+ */ -+static void normalize_varname(char *varname) -+{ -+ char *s=varname, *index=NULL, *indexend=NULL, *p; -+ -+ /* overjump leading space */ -+ while (*s == ' ') { -+ s++; -+ } -+ -+ /* and remove it */ -+ if (s != varname) { -+ memmove(varname, s, strlen(s)+1); -+ } -+ -+ for (p=varname; *p && *p != '['; p++) { -+ switch(*p) { -+ case ' ': -+ case '.': -+ *p='_'; -+ break; -+ } -+ } -+ -+ /* find index */ -+ index = strchr(varname, '['); -+ if (index) { -+ index++; -+ s=index; -+ } else { -+ return; -+ } -+ -+ /* done? */ -+ while (index) { -+ -+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { -+ index++; -+ } -+ indexend = strchr(index, ']'); -+ indexend = indexend ? indexend + 1 : index + strlen(index); -+ -+ if (s != index) { -+ memmove(s, index, strlen(index)+1); -+ s += indexend-index; -+ } else { -+ s = indexend; -+ } -+ -+ if (*s == '[') { -+ s++; -+ index = s; -+ } else { -+ index = NULL; -+ } -+ } -+ *s++='\0'; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC -+ */ -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) -+{ -+ char *index, *prev_index = NULL, *var; -+ unsigned int var_len, total_len, depth = 0; -+ -+ var = estrdup(varname); -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); -+ -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; -+ break; -+ } -+ -+ efree(var); -+ return SUCCESS; -+protected_varname2: -+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); -+return_failure: -+ efree(var); -+ return FAILURE; -+} -+/* }}} */ -+ -+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC -+ */ -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) -+{ -+ /* Drop if no more variables flag is set */ -+ if (VARFILTER_G(no_more_uploads)) { -+ return FAILURE; -+ } -+ /* Drop this fileupload if the limit is reached */ -+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { -+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); -+ VARFILTER_G(no_more_uploads) = 1; -+ return FAILURE; -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC -+ */ -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) -+{ -+ -+ if (VARFILTER_G(disallow_elf_files)) { -+ -+ if (offset == 0 && buffer_len > 10) { -+ -+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { -+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); -+ return FAILURE; -+ } -+ } -+ -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC -+ */ -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) -+{ -+ int retval = SUCCESS; -+ -+ if (VARFILTER_G(verification_script)) { -+ char cmd[8192]; -+ FILE *in; -+ int first=1; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); -+ return FAILURE; -+ } -+ -+ retval = FAILURE; -+ -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ if (first) { -+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; -+ first = 0; -+ } -+ } -+ pclose(in); -+ } -+ -+ if (retval != SUCCESS) { -+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); -+ return FAILURE; -+ } -+ -+ VARFILTER_G(cur_uploads)++; -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_INPUT_FILTER_FUNC -+ */ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) -+{ -+ char *index, *prev_index = NULL; -+ unsigned int var_len, total_len, depth = 0; -+ -+ /* Drop this variable if the limit was reached */ -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(no_more_get_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(no_more_post_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(no_more_cookie_variables)) { -+ return 0; -+ } -+ break; -+ default: /* we do not want to protect parse_str() and friends */ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ return 1; -+ } -+ if (VARFILTER_G(no_more_variables)) { -+ return 0; -+ } -+ -+ /* Drop this variable if the limit is now reached */ -+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { -+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_variables) = 1; -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { -+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_get_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { -+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_cookie_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { -+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_post_variables) = 1; -+ return 0; -+ } -+ break; -+ } -+ -+ -+ /* Drop this variable if it exceeds the value length limit */ -+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { -+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { -+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { -+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { -+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { -+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { -+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Check if variable value is truncated by a \0 */ -+ -+ if (val && *val && val_len != strlen(*val)) { -+ -+ if (VARFILTER_G(disallow_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(disallow_get_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(disallow_cookie_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(disallow_post_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ } -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname; -+ break; -+ } -+ -+ /* Okay let PHP register this variable */ -+ VARFILTER_G(cur_request_variables)++; -+ switch (arg) { -+ case PARSE_GET: -+ VARFILTER_G(cur_get_vars)++; -+ break; -+ case PARSE_COOKIE: -+ VARFILTER_G(cur_cookie_vars)++; -+ break; -+ case PARSE_POST: -+ VARFILTER_G(cur_post_vars)++; -+ break; -+ } -+ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ -+ return 1; -+protected_varname: -+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); -+ return 0; -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: noet sw=4 ts=4 fdm=marker -+ * vim<600: noet sw=4 ts=4 -+ */ -+ -+ -diff -Nura php-4.4.2/ext/wddx/wddx.c hardening-patch-4.4.2-0.4.15/ext/wddx/wddx.c ---- php-4.4.2/ext/wddx/wddx.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/ext/wddx/wddx.c 2006-09-05 20:30:33.000000000 +0200 -@@ -16,7 +16,11 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: wddx.c,v 1.96.2.6.2.3 2006/01/01 13:46:59 sniper Exp $ */ -+/* $Id: wddx.c,v 1.96.2.6.2.7 2006/05/26 01:55:26 iliaa Exp $ */ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif - - #include "php.h" - #include "php_wddx.h" -@@ -400,9 +404,9 @@ - break; - - default: -- if (iscntrl((int)*(unsigned char *)p)) { -+ if (iscntrl((int)*(unsigned char *)p) || (int)*(unsigned char *)p >= 127) { - FLUSH_BUF(); -- sprintf(control_buf, WDDX_CHAR, *p); -+ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); - php_wddx_add_chunk(packet, control_buf); - } else - buf[l++] = *p; -@@ -428,7 +432,7 @@ - tmp = *var; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); -- sprintf(tmp_buf, WDDX_NUMBER, Z_STRVAL(tmp)); -+ snprintf(tmp_buf, Z_STRLEN(tmp), WDDX_NUMBER, Z_STRVAL(tmp)); - zval_dtor(&tmp); - - php_wddx_add_chunk(packet, tmp_buf); -@@ -620,17 +624,19 @@ - */ - void php_wddx_serialize_var(wddx_packet *packet, zval *var, char *name, int name_len TSRMLS_DC) - { -- char tmp_buf[WDDX_BUF_LEN]; -+ char *tmp_buf; - char *name_esc; - int name_esc_len; - - if (name) { - name_esc = php_escape_html_entities(name, name_len, &name_esc_len, 0, ENT_QUOTES, NULL TSRMLS_CC); -- sprintf(tmp_buf, WDDX_VAR_S, name_esc); -+ tmp_buf = emalloc(name_esc_len + 1); -+ snprintf(tmp_buf, name_esc_len, WDDX_VAR_S, name_esc); - php_wddx_add_chunk(packet, tmp_buf); -+ efree(tmp_buf); - efree(name_esc); - } -- -+ - switch(Z_TYPE_P(var)) { - case IS_STRING: - php_wddx_serialize_string(packet, var); -diff -Nura php-4.4.2/main/fopen_wrappers.c hardening-patch-4.4.2-0.4.15/main/fopen_wrappers.c ---- php-4.4.2/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:23.000000000 +0200 -@@ -106,7 +106,10 @@ - } - - /* Resolve the real path into resolved_name */ -- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { -+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { -+ return -2; -+ } -+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { - /* Handler for basedirs that end with a / */ - resolved_basedir_len = strlen(resolved_basedir); - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { -@@ -116,14 +119,20 @@ - } - } - -+ resolved_name_len = strlen(resolved_name); - if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { -- resolved_name_len = strlen(resolved_name); - if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { - resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; - resolved_name[++resolved_name_len] = '\0'; - } - } - -+ if (resolved_name_len == resolved_basedir_len - 1) { -+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { -+ resolved_basedir_len--; -+ } -+ } -+ - /* Check the path */ - #ifdef PHP_WIN32 - if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { -@@ -137,7 +146,7 @@ - } - } else { - /* Unable to resolve the real path, return -1 */ -- return -1; -+ return -3; - } - } - /* }}} */ -@@ -156,22 +165,44 @@ - char *pathbuf; - char *ptr; - char *end; -+ char path_copy[MAXPATHLEN]; -+ int path_len; -+ -+ /* Special case path ends with a trailing slash */ -+ path_len = strlen(path); -+ if (path_len >= MAXPATHLEN) { -+ errno = EPERM; /* we deny permission to open it */ -+ return -1; -+ } -+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { -+ memcpy(path_copy, path, path_len+1); -+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; -+ path_copy[path_len] = '\0'; -+ path = (const char *)&path_copy; -+ } - - pathbuf = estrdup(PG(open_basedir)); - - ptr = pathbuf; - - while (ptr && *ptr) { -+ int res; - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - -- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { -+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); -+ if (res == 0) { - efree(pathbuf); - return 0; - } -+ if (res == -2) { -+ efree(pathbuf); -+ errno = EPERM; -+ return -1; -+ } - - ptr = end; - } -diff -Nura php-4.4.2/main/hardened_globals.h hardening-patch-4.4.2-0.4.15/main/hardened_globals.h ---- php-4.4.2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/hardened_globals.h 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,64 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENED_GLOBALS_H -+#define HARDENED_GLOBALS_H -+ -+typedef struct _hardened_globals hardened_globals_struct; -+ -+#ifdef ZTS -+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) -+extern int hardened_globals_id; -+#else -+# define HG(v) (hardened_globals.v) -+extern struct _hardened_globals hardened_globals; -+#endif -+ -+ -+struct _hardened_globals { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_1; -+ unsigned int canary_2; -+#endif -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_3; -+ unsigned int canary_4; -+ unsigned int ll_canary_inited; -+#endif -+ zend_bool hphp_sql_bailout_on_error; -+ zend_bool hphp_multiheader; -+ unsigned long hphp_mailprotect; -+ long hard_memory_limit; -+ HashTable *eval_whitelist; -+ HashTable *eval_blacklist; -+ HashTable *func_whitelist; -+ HashTable *func_blacklist; -+ HashTable *include_whitelist; -+ HashTable *include_blacklist; -+ unsigned int dummy; -+}; -+ -+ -+#endif /* HARDENED_GLOBALS_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-4.4.2/main/hardening_patch.c hardening-patch-4.4.2-0.4.15/main/hardening_patch.c ---- php-4.4.2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/hardening_patch.c 2006-09-07 18:48:28.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ -+ -+#include "php.h" -+ -+#include -+#include -+ -+#if HAVE_UNISTD_H -+#include -+#endif -+#include "SAPI.h" -+#include "php_globals.h" -+ -+#if HARDENING_PATCH -+ -+#ifdef HAVE_SYS_SOCKET_H -+#include -+#endif -+ -+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) -+#undef AF_UNIX -+#endif -+ -+#if defined(AF_UNIX) -+#include -+#endif -+ -+#define SYSLOG_PATH "/dev/log" -+ -+#include "snprintf.h" -+ -+#include "hardening_patch.h" -+ -+#ifdef ZTS -+#include "hardened_globals.h" -+int hardened_globals_id; -+#else -+struct _hardened_globals hardened_globals; -+#endif -+ -+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) -+{ -+ memset(hardened_globals, 0, sizeof(*hardened_globals)); -+} -+ -+ -+PHPAPI void hardened_startup() -+{ -+#ifdef ZTS -+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); -+#else -+ hardened_globals_ctor(&hardened_globals TSRMLS_CC); -+#endif -+} -+ -+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) -+{ -+ HG(canary_1) = php_canary(); -+ HG(canary_2) = php_canary(); -+} -+ -+char *loglevel2string(int loglevel) -+{ -+ switch (loglevel) { -+ case S_FILES: -+ return "FILES"; -+ case S_INCLUDE: -+ return "INCLUDE"; -+ case S_MEMORY: -+ return "MEMORY"; -+ case S_MISC: -+ return "MISC"; -+ case S_SQL: -+ return "SQL"; -+ case S_EXECUTOR: -+ return "EXECUTOR"; -+ case S_VARS: -+ return "VARS"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+PHPAPI void php_security_log(int loglevel, char *fmt, ...) -+{ -+#if defined(AF_UNIX) -+ int s, r, i=0; -+ struct sockaddr_un saun; -+ char buf[4096+64]; -+ char error[4096+100]; -+ char *ip_address; -+ char *fname; -+ int lineno; -+ va_list ap; -+ TSRMLS_FETCH(); -+ -+ if (EG(hphp_log_use_x_forwarded_for)) { -+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "X-FORWARDED-FOR not set"; -+ } -+ } else { -+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "REMOTE_ADDR not set"; -+ } -+ } -+ -+ -+ va_start(ap, fmt); -+ ap_php_vsnprintf(error, sizeof(error), fmt, ap); -+ va_end(ap); -+ while (error[i]) { -+ if (error[i] < 32) error[i] = '.'; -+ i++; -+ } -+ -+ if (zend_is_executing(TSRMLS_C)) { -+ lineno = zend_get_executed_lineno(TSRMLS_C); -+ fname = zend_get_executed_filename(TSRMLS_C); -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); -+ } else { -+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); -+ if (fname==NULL) { -+ fname = "unknown"; -+ } -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); -+ } -+ -+ /* Syslog-Logging disabled? */ -+ if ((EG(hphp_log_syslog) & loglevel)==0) { -+ goto log_sapi; -+ } -+ -+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); -+ -+ s = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ s = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ goto log_sapi; -+ } -+ } -+ send(s, error, strlen(error), 0); -+ -+ close(s); -+ -+log_sapi: -+ /* SAPI Logging activated? */ -+ if ((EG(hphp_log_sapi) & loglevel)!=0) { -+ sapi_module.log_message(buf); -+ } -+ -+log_script: -+ /* script logging activaed? */ -+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { -+ char cmd[8192], *cmdpos, *bufpos; -+ FILE *in; -+ int space; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); -+ space = sizeof(cmd) - strlen(cmd); -+ cmdpos = cmd + strlen(cmd); -+ bufpos = buf; -+ if (space <= 1) return; -+ while (space > 2 && *bufpos) { -+ if (*bufpos == '\'') { -+ if (space<=5) break; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\\'; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\''; -+ bufpos++; -+ space-=4; -+ } else { -+ *cmdpos++ = *bufpos++; -+ space--; -+ } -+ } -+ *cmdpos++ = '\''; -+ *cmdpos = 0; -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); -+ return; -+ } -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ } -+ pclose(in); -+ } -+ -+#endif -+} -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+PHPAPI unsigned int php_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+ -+PHPAPI int php_is_valid_include(zval *z) -+{ -+ char *filename; -+ int len, i; -+ TSRMLS_FETCH(); -+ -+ /* must be of type string */ -+ if (z->type != IS_STRING || z->value.str.val == NULL) { -+ return (0); -+ } -+ -+ /* short cut */ -+ filename = z->value.str.val; -+ len = z->value.str.len; -+ -+ /* 1. must be shorter than MAXPATHLEN */ -+ if (len > MAXPATHLEN) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 2. must not be cutted */ -+ if (len != strlen(filename)) { -+ char *fname = estrndup(filename, len); -+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ -+ if (strstr(filename, "://")) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ -+ /* no black or whitelist then disallow all */ -+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* whitelist is stronger than blacklist */ -+ if (HG(include_whitelist)) { -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ zend_bool isOk = 0; -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_whitelist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ isOk = 1; -+ break; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_whitelist)); -+ } while (1); -+ -+ /* not found in whitelist */ -+ if (!isOk) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); -+ efree(fname); -+ return 0; -+ } -+ -+ s = h + 3; -+ } while (1); -+ } else { -+ /* okay then handle the blacklist */ -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_blacklist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); -+ efree(fname); -+ return 0; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_blacklist)); -+ } while (1); -+ -+ s = h + 3; -+ } while (1); -+ } -+ -+ efree(fname); -+ } -+ -+ /* 4. must not be an uploaded file */ -+ if (SG(rfc1867_uploaded_files)) { -+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { -+ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); -+ return (0); -+ } -+ } -+ -+ /* passed all tests */ -+ return (1); -+} -+ -+#endif -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.2/main/hardening_patch.h hardening-patch-4.4.2-0.4.15/main/hardening_patch.h ---- php-4.4.2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/hardening_patch.h 2006-09-07 18:48:35.000000000 +0200 -@@ -0,0 +1,46 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENING_PATCH_H -+#define HARDENING_PATCH_H -+ -+#include "zend.h" -+ -+#if HARDENING_PATCH -+PHPAPI void php_security_log(int loglevel, char *fmt, ...); -+PHPAPI void hardened_startup(); -+#define HARDENING_PATCH_VERSION "0.4.15" -+ -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+PHPAPI unsigned int php_canary(); -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+PHPAPI int php_is_valid_include(zval *z); -+#endif -+ -+#endif /* HARDENING_PATCH_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-4.4.2/main/hardening_patch.m4 hardening-patch-4.4.2-0.4.15/main/hardening_patch.m4 ---- php-4.4.2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/hardening_patch.m4 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,95 @@ -+dnl -+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ -+dnl -+dnl This file contains Hardening Patch for PHP specific autoconf functions. -+dnl -+ -+AC_ARG_ENABLE(hardening-patch-mm-protect, -+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-ll-protect, -+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-inc-protect, -+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-fmt-protect, -+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-hash-protect, -+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+]) -+ -+AC_MSG_CHECKING(whether to protect the Zend Memory Manager) -+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the Zend Linked Lists) -+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect include/require statements) -+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect PHP Format String functions) -+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) -+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) -+ -+ -+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) -+fi -+ -diff -Nura php-4.4.2/main/main.c hardening-patch-4.4.2-0.4.15/main/main.c ---- php-4.4.2/main/main.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/main.c 2006-09-05 20:30:33.000000000 +0200 -@@ -92,6 +92,10 @@ - PHPAPI int core_globals_id; - #endif - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#endif -+ - #define ERROR_BUF_LEN 1024 - - typedef struct { -@@ -142,17 +146,39 @@ - */ - static PHP_INI_MH(OnChangeMemoryLimit) - { -+#if HARDENING_PATCH -+ long hard_memory_limit = 1<<30; -+ -+ if (stage == ZEND_INI_STAGE_RUNTIME) { -+ if (HG(hard_memory_limit) == 0) { -+ HG(hard_memory_limit) = PG(memory_limit); -+ } -+ hard_memory_limit = HG(hard_memory_limit); -+ } else { -+ HG(hard_memory_limit) = 0; -+ } -+#endif - if (new_value) { - PG(memory_limit) = zend_atoi(new_value, new_value_length); -+#if HARDENING_PATCH -+ if (PG(memory_limit) > hard_memory_limit) { -+ PG(memory_limit) = hard_memory_limit; -+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); -+ return FAILURE; -+ } -+#endif - } else { -+#if HARDENING_PATCH -+ PG(memory_limit) = hard_memory_limit; -+#else - PG(memory_limit) = 1<<30; /* effectively, no limit */ -+#endif - } - return zend_set_memory_limit(PG(memory_limit)); - } - /* }}} */ - #endif - -- - /* {{{ php_disable_functions - */ - static void php_disable_functions(TSRMLS_D) -@@ -1008,6 +1034,9 @@ - - zend_try { - shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); -+#if HARDENING_PATCH -+ hardened_clear_mm_canaries(TSRMLS_C); -+#endif - } zend_end_try(); - - zend_try { -@@ -1098,6 +1127,10 @@ - tsrm_ls = ts_resource(0); - #endif - -+#if HARDENING_PATCH -+ hardened_startup(); -+#endif -+ - sapi_initialize_empty_request(TSRMLS_C); - sapi_activate(TSRMLS_C); - -@@ -1110,6 +1143,12 @@ - php_output_startup(); - php_output_activate(TSRMLS_C); - -+#if HARDENING_PATCH_INC_PROTECT -+ zuf.is_valid_include = php_is_valid_include; -+#endif -+#if HARDENING_PATCH -+ zuf.security_log_function = php_security_log; -+#endif - zuf.error_function = php_error_cb; - zuf.printf_function = php_printf; - zuf.write_function = php_body_write_wrapper; -@@ -1211,6 +1250,10 @@ - REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS); - 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); - REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); -+#endif - REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); -@@ -1318,7 +1361,7 @@ - */ - static inline void php_register_server_variables(TSRMLS_D) - { -- zval *array_ptr=NULL; -+ zval *array_ptr=NULL, *vptr; - - ALLOC_ZVAL(array_ptr); - array_init(array_ptr); -diff -Nura php-4.4.2/main/php_config.h.in hardening-patch-4.4.2-0.4.15/main/php_config.h.in ---- php-4.4.2/main/php_config.h.in 2006-01-12 19:24:28.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/php_config.h.in 2006-09-05 20:30:33.000000000 +0200 -@@ -865,6 +865,39 @@ - /* Enabling BIND8 compatibility for Panther */ - #undef BIND_8_COMPAT - -+/* Hardening-Patch */ -+#undef HARDENING_PATCH -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ - /* Whether you have AOLserver */ - #undef HAVE_AOLSERVER - -@@ -1148,6 +1181,12 @@ - /* Define if you have the getaddrinfo function */ - #undef HAVE_GETADDRINFO - -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ - /* Whether system headers declare timezone */ - #undef HAVE_DECLARED_TIMEZONE - -diff -Nura php-4.4.2/main/php_content_types.c hardening-patch-4.4.2-0.4.15/main/php_content_types.c ---- php-4.4.2/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/php_content_types.c 2006-09-05 20:30:33.000000000 +0200 -@@ -77,6 +77,7 @@ - sapi_register_post_entries(php_post_entries); - sapi_register_default_post_reader(php_default_post_reader); - sapi_register_treat_data(php_default_treat_data); -+ sapi_register_input_filter(php_default_input_filter); - return SUCCESS; - } - /* }}} */ -diff -Nura php-4.4.2/main/php.h hardening-patch-4.4.2-0.4.15/main/php.h ---- php-4.4.2/main/php.h 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/php.h 2006-09-05 20:30:33.000000000 +0200 -@@ -35,11 +35,19 @@ - #include "zend_qsort.h" - #include "php_compat.h" - -+ - #include "zend_API.h" - - #undef sprintf - #define sprintf php_sprintf - -+#if HARDENING_PATCH -+#if HAVE_REALPATH -+#undef realpath -+#define realpath php_realpath -+#endif -+#endif -+ - /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ - #undef PHP_DEBUG - #define PHP_DEBUG ZEND_DEBUG -@@ -409,6 +417,10 @@ - #endif - #endif /* !XtOffsetOf */ - -+#if HARDENING_PATCH -+#include "hardening_patch.h" -+#endif -+ - #endif - - /* -diff -Nura php-4.4.2/main/php_open_temporary_file.c hardening-patch-4.4.2-0.4.15/main/php_open_temporary_file.c ---- php-4.4.2/main/php_open_temporary_file.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/php_open_temporary_file.c 2006-09-05 20:30:33.000000000 +0200 -@@ -16,7 +16,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: php_open_temporary_file.c,v 1.18.2.10.2.2 2006/01/01 13:46:59 sniper Exp $ */ -+/* $Id: php_open_temporary_file.c,v 1.18.2.10.2.3 2006/05/23 23:23:39 iliaa Exp $ */ - - #include "php.h" - -@@ -115,17 +115,16 @@ - - path_len = strlen(path); - -- if (!(opened_path = emalloc(MAXPATHLEN))) { -- return -1; -- } -- - if (!path_len || IS_SLASH(path[path_len - 1])) { - trailing_slash = ""; - } else { - trailing_slash = "/"; - } - -- (void)snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", path, trailing_slash, pfx); -+ if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", path, trailing_slash, pfx) >= MAXPATHLEN) { -+ efree(opened_path); -+ return -1; -+ } - - #ifdef PHP_WIN32 - if (GetTempFileName(path, pfx, 0, opened_path)) { -diff -Nura php-4.4.2/main/php_variables.c hardening-patch-4.4.2-0.4.15/main/php_variables.c ---- php-4.4.2/main/php_variables.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/php_variables.c 2006-09-05 20:30:33.000000000 +0200 -@@ -236,17 +236,28 @@ - while (var) { - val = strchr(var, '='); - if (val) { /* have a value */ -- int val_len; -+ unsigned int val_len, new_val_len; - - *val++ = '\0'; - php_url_decode(var, strlen(var)); - val_len = php_url_decode(val, strlen(val)); -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } - var = php_strtok_r(NULL, "&", &strtok_buf); - } - } - -+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) -+{ -+ /* TODO: check .ini setting here and apply user-defined input filter */ -+ *new_val_len = val_len; -+ return 1; -+} -+ - SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) - { - char *res = NULL, *var, *val, *separator=NULL; -@@ -324,15 +335,26 @@ - while (var) { - val = strchr(var, '='); - if (val) { /* have a value */ -- int val_len; -+ unsigned int val_len, new_val_len; - - *val++ = '\0'; - php_url_decode(var, strlen(var)); - val_len = php_url_decode(val, strlen(val)); -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } else { -+ unsigned int val_len, new_val_len; -+ - php_url_decode(var, strlen(var)); -- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC); -+ val_len = 0; -+ val = estrndup("", 0); -+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } - var = php_strtok_r(NULL, separator, &strtok_buf); - } -diff -Nura php-4.4.2/main/rfc1867.c hardening-patch-4.4.2-0.4.15/main/rfc1867.c ---- php-4.4.2/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/rfc1867.c 2006-09-05 20:30:33.000000000 +0200 -@@ -128,6 +128,8 @@ - #define UPLOAD_ERROR_D 4 /* No file uploaded */ - #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ - #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ -+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */ -+ - - void php_rfc1867_register_constants(TSRMLS_D) - { -@@ -138,6 +140,7 @@ - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); - } - - static void normalize_protected_variable(char *varname TSRMLS_DC) -@@ -849,6 +852,7 @@ - char buff[FILLUNIT]; - char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; - int blen=0, wlen=0; -+ unsigned long offset; - - zend_llist_clean(&header); - -@@ -897,21 +901,24 @@ - if (!filename && param) { - - char *value = multipart_buffer_read_body(mbuff TSRMLS_CC); -+ unsigned int new_val_len; /* Dummy variable */ - - if (!value) { - value = estrdup(""); - } - -+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) { - #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) -- if (php_mb_encoding_translation(TSRMLS_C)) { -- php_mb_gpc_stack_variable(param, value, &val_list, &len_list, -- &num_vars, &num_vars_max TSRMLS_CC); -- } else { -- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -- } -+ if (php_mb_encoding_translation(TSRMLS_C)) { -+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list, -+ &num_vars, &num_vars_max TSRMLS_CC); -+ } else { -+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -+ } - #else -- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); - #endif -+ } - if (!strcasecmp(param, "MAX_FILE_SIZE")) { - max_file_size = atol(value); - } -@@ -963,7 +970,11 @@ - tmp++; - } - } -- -+ -+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { -+ skip_upload = 1; -+ } -+ - total_bytes = cancel_upload = 0; - - if (!skip_upload) { -@@ -987,6 +998,11 @@ - cancel_upload = UPLOAD_ERROR_D; - } - -+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ -+ offset = 0; - end = 0; - while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) - { -@@ -997,6 +1013,11 @@ - sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); - cancel_upload = UPLOAD_ERROR_B; - } else if (blen > 0) { -+ -+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - wlen = write(fd, buff, blen); - - if (wlen < blen) { -@@ -1004,6 +1025,7 @@ - cancel_upload = UPLOAD_ERROR_F; - } else { - total_bytes += wlen; -+ offset += wlen; - } - } - } -@@ -1025,6 +1047,10 @@ - } - #endif - -+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - if (cancel_upload) { - if (temp_filename) { - if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ -diff -Nura php-4.4.2/main/SAPI.c hardening-patch-4.4.2-0.4.15/main/SAPI.c ---- php-4.4.2/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/SAPI.c 2006-09-05 20:30:33.000000000 +0200 -@@ -854,6 +854,37 @@ - return SUCCESS; - } - -+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)) -+{ -+ sapi_module.input_filter = input_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) -+{ -+ sapi_module.upload_varname_filter = upload_varname_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) -+{ -+ sapi_module.pre_upload_filter = pre_upload_filter; -+ return SUCCESS; -+} -+ -+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)) -+{ -+ sapi_module.upload_content_filter = upload_content_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) -+{ -+ sapi_module.post_upload_filter = post_upload_filter; -+ return SUCCESS; -+} -+ -+ - - SAPI_API int sapi_flush(TSRMLS_D) - { -diff -Nura php-4.4.2/main/SAPI.h hardening-patch-4.4.2-0.4.15/main/SAPI.h ---- php-4.4.2/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/SAPI.h 2006-09-05 20:30:33.000000000 +0200 -@@ -101,9 +101,10 @@ - char *current_user; - int current_user_length; - -- /* this is necessary for CLI module */ -- int argc; -- char **argv; -+ /* this is necessary for CLI module */ -+ int argc; -+ char **argv; -+ - } sapi_request_info; - - -@@ -177,6 +178,10 @@ - SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); - SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); - SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); - - SAPI_API int sapi_flush(TSRMLS_D); - SAPI_API struct stat *sapi_get_stat(TSRMLS_D); -@@ -238,8 +243,16 @@ - int (*get_target_uid)(uid_t * TSRMLS_DC); - int (*get_target_gid)(gid_t * TSRMLS_DC); - -+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); -+ -+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); -+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); -+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); -+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); -+ - void (*ini_defaults)(HashTable *configuration_hash); - int phpinfo_as_text; -+ - }; - - -@@ -262,16 +275,27 @@ - - #define SAPI_DEFAULT_MIMETYPE "text/html" - #define SAPI_DEFAULT_CHARSET "" -+ -+#if HARDENING_PATCH -+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" -+#else - #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION -+#endif - - #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) - #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) - - #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) -+#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) -+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) -+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) -+#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) -+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) - - SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); - SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); - SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); -+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter); - - #define STANDARD_SAPI_MODULE_PROPERTIES - -diff -Nura php-4.4.2/main/snprintf.c hardening-patch-4.4.2-0.4.15/main/snprintf.c ---- php-4.4.2/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/snprintf.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1014,7 +1014,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = cc; -+#endif - break; - - /* -diff -Nura php-4.4.2/main/spprintf.c hardening-patch-4.4.2-0.4.15/main/spprintf.c ---- php-4.4.2/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/spprintf.c 2006-09-05 20:30:33.000000000 +0200 -@@ -630,7 +630,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = xbuf->len; -+#endif - break; - - /* -diff -Nura php-4.4.2/main/streams.c hardening-patch-4.4.2-0.4.15/main/streams.c ---- php-4.4.2/main/streams.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/main/streams.c 2006-09-05 20:30:33.000000000 +0200 -@@ -20,7 +20,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: streams.c,v 1.125.2.100.2.2 2006/01/01 13:47:00 sniper Exp $ */ -+/* $Id: streams.c,v 1.125.2.100.2.3 2006/05/19 10:24:42 tony2001 Exp $ */ - - #define _GNU_SOURCE - #include "php.h" -@@ -445,7 +445,7 @@ - * charsets (for example) but still be able to provide them all as filters */ - PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, const char *filterparams, int filterparamslen, int persistent TSRMLS_DC) - { -- php_stream_filter_factory *factory; -+ php_stream_filter_factory *factory = NULL; - php_stream_filter *filter = NULL; - int n; - char *period; -diff -Nura php-4.4.2/php.ini-dist hardening-patch-4.4.2-0.4.15/php.ini-dist ---- php-4.4.2/php.ini-dist 2005-12-30 18:19:43.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/php.ini-dist 2006-09-05 20:30:33.000000000 +0200 -@@ -1114,6 +1114,209 @@ - ;exif.decode_jis_motorola = JIS - ;exif.decode_jis_intel = JIS - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-4.4.2/php.ini-recommended hardening-patch-4.4.2-0.4.15/php.ini-recommended ---- php-4.4.2/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/php.ini-recommended 2006-09-05 20:30:33.000000000 +0200 -@@ -1112,6 +1112,209 @@ - ;exif.decode_jis_motorola = JIS - ;exif.decode_jis_intel = JIS - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-4.4.2/README.input_filter hardening-patch-4.4.2-0.4.15/README.input_filter ---- php-4.4.2/README.input_filter 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/README.input_filter 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,193 @@ -+Input Filter Support ported from PHP 5 -+-------------------------------------- -+ -+XSS (Cross Site Scripting) hacks are becoming more and more prevalent, -+and can be quite difficult to prevent. Whenever you accept user data -+and somehow display this data back to users, you are likely vulnerable -+to XSS hacks. -+ -+The Input Filter support in PHP 5 is aimed at providing the framework -+through which a company-wide or site-wide security policy can be -+enforced. It is implemented as a SAPI hook and is called from the -+treat_data and post handler functions. To implement your own security -+policy you will need to write a standard PHP extension. -+ -+A simple implementation might look like the following. This stores the -+original raw user data and adds a my_get_raw() function while the normal -+$_POST, $_GET and $_COOKIE arrays are only populated with stripped -+data. In this simple example all I am doing is calling strip_tags() on -+the data. If register_globals is turned on, the default globals that -+are created will be stripped ($foo) while a $RAW_foo is created with the -+original user input. -+ -+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) -+ zval *post_array; -+ zval *get_array; -+ zval *cookie_array; -+ZEND_END_MODULE_GLOBALS(my_input_filter) -+ -+#ifdef ZTS -+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v) -+#else -+#define IF_G(v) (my_input_filter_globals.v) -+#endif -+ -+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter) -+ -+function_entry my_input_filter_functions[] = { -+ PHP_FE(my_get_raw, NULL) -+ {NULL, NULL, NULL} -+}; -+ -+zend_module_entry my_input_filter_module_entry = { -+ STANDARD_MODULE_HEADER, -+ "my_input_filter", -+ my_input_filter_functions, -+ PHP_MINIT(my_input_filter), -+ PHP_MSHUTDOWN(my_input_filter), -+ NULL, -+ PHP_RSHUTDOWN(my_input_filter), -+ PHP_MINFO(my_input_filter), -+ "0.1", -+ STANDARD_MODULE_PROPERTIES -+}; -+ -+PHP_MINIT_FUNCTION(my_input_filter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL); -+ -+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); -+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); -+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); -+ -+ sapi_register_input_filter(my_sapi_input_filter); -+ return SUCCESS; -+} -+ -+PHP_RSHUTDOWN_FUNCTION(my_input_filter) -+{ -+ if(IF_G(get_array)) { -+ zval_ptr_dtor(&IF_G(get_array)); -+ IF_G(get_array) = NULL; -+ } -+ if(IF_G(post_array)) { -+ zval_ptr_dtor(&IF_G(post_array)); -+ IF_G(post_array) = NULL; -+ } -+ if(IF_G(cookie_array)) { -+ zval_ptr_dtor(&IF_G(cookie_array)); -+ IF_G(cookie_array) = NULL; -+ } -+ return SUCCESS; -+} -+ -+PHP_MINFO_FUNCTION(my_input_filter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); -+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $"); -+ php_info_print_table_end(); -+} -+ -+/* The filter handler. If you return 1 from it, then PHP also registers the -+ * (modified) variable. Returning 0 prevents PHP from registering the variable; -+ * you can use this if your filter already registers the variable under a -+ * different name, or if you just don't want the variable registered at all. */ -+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter) -+{ -+ zval new_var; -+ zval *array_ptr = NULL; -+ char *raw_var; -+ int var_len; -+ -+ assert(*val != NULL); -+ -+ switch(arg) { -+ case PARSE_GET: -+ if(!IF_G(get_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(get_array) = array_ptr; -+ break; -+ case PARSE_POST: -+ if(!IF_G(post_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(post_array) = array_ptr; -+ break; -+ case PARSE_COOKIE: -+ if(!IF_G(cookie_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(cookie_array) = array_ptr; -+ break; -+ } -+ Z_STRLEN(new_var) = val_len; -+ Z_STRVAL(new_var) = estrndup(*val, val_len); -+ Z_TYPE(new_var) = IS_STRING; -+ -+ var_len = strlen(var); -+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ -+ strcpy(raw_var, "RAW_"); -+ strlcat(raw_var,var,var_len+5); -+ -+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC); -+ -+ php_strip_tags(*val, val_len, NULL, NULL, 0); -+ -+ *new_val_len = strlen(*val); -+ return 1; -+} -+ -+PHP_FUNCTION(my_get_raw) -+{ -+ long arg; -+ char *var; -+ int var_len; -+ zval **tmp; -+ zval *array_ptr = NULL; -+ HashTable *hash_ptr; -+ char *raw_var; -+ -+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) { -+ return; -+ } -+ -+ switch(arg) { -+ case PARSE_GET: -+ array_ptr = IF_G(get_array); -+ break; -+ case PARSE_POST: -+ array_ptr = IF_G(post_array); -+ break; -+ case PARSE_COOKIE: -+ array_ptr = IF_G(post_array); -+ break; -+ } -+ -+ if(!array_ptr) RETURN_FALSE; -+ -+ /* -+ * I'm changing the variable name here because when running with register_globals on, -+ * the variable will end up in the global symbol table -+ */ -+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ -+ strcpy(raw_var, "RAW_"); -+ strlcat(raw_var,var,var_len+5); -+ hash_ptr = HASH_OF(array_ptr); -+ -+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) { -+ *return_value = **tmp; -+ zval_copy_ctor(return_value); -+ } else { -+ RETVAL_FALSE; -+ } -+ efree(raw_var); -+} -+ -diff -Nura php-4.4.2/run-tests.php hardening-patch-4.4.2-0.4.15/run-tests.php ---- php-4.4.2/run-tests.php 2006-01-01 14:46:48.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/run-tests.php 2006-09-05 20:30:33.000000000 +0200 -@@ -152,6 +152,10 @@ - 'error_reporting=2047', - 'display_errors=1', - 'log_errors=0', -+ 'hphp.executor.include.whitelist=cookietest', -+ 'hphp.log.syslog=0', -+ 'hphp.log.sapi=0', -+ 'hphp.log.script=0', - 'html_errors=0', - 'track_errors=1', - 'report_memleaks=1', -diff -Nura php-4.4.2/sapi/apache/mod_php4.c hardening-patch-4.4.2-0.4.15/sapi/apache/mod_php4.c ---- php-4.4.2/sapi/apache/mod_php4.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/sapi/apache/mod_php4.c 2006-09-05 20:30:33.000000000 +0200 -@@ -452,7 +452,7 @@ - sapi_apache_get_fd, - sapi_apache_force_http_10, - sapi_apache_get_target_uid, -- sapi_apache_get_target_gid -+ sapi_apache_get_target_gid, - }; - /* }}} */ - -@@ -898,7 +898,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component("PHP/" PHP_VERSION); -+#endif - } - } - #endif -diff -Nura php-4.4.2/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.2-0.4.15/sapi/apache2filter/sapi_apache2.c ---- php-4.4.2/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:30:33.000000000 +0200 -@@ -562,7 +562,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-4.4.2/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.2-0.4.15/sapi/apache2handler/sapi_apache2.c ---- php-4.4.2/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:30:33.000000000 +0200 -@@ -340,7 +340,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-4.4.2/sapi/cgi/cgi_main.c hardening-patch-4.4.2-0.4.15/sapi/cgi/cgi_main.c ---- php-4.4.2/sapi/cgi/cgi_main.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1432,11 +1432,19 @@ - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - } -+#if HARDENING_PATCH -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif -+#else - #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #endif -+#endif - php_end_ob_buffers(1 TSRMLS_CC); - exit(0); - break; -diff -Nura php-4.4.2/sapi/cli/php_cli.c hardening-patch-4.4.2-0.4.15/sapi/cli/php_cli.c ---- php-4.4.2/sapi/cli/php_cli.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:30:33.000000000 +0200 -@@ -654,11 +654,19 @@ - if (php_request_startup(TSRMLS_C)==FAILURE) { - goto err; - } -+#if HARDENING_PATCH -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif -+#else - #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #endif -+#endif - php_end_ob_buffers(1 TSRMLS_CC); - exit_status=0; - goto out; -diff -Nura php-4.4.2/TSRM/TSRM.h hardening-patch-4.4.2-0.4.15/TSRM/TSRM.h ---- php-4.4.2/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200 -+++ hardening-patch-4.4.2-0.4.15/TSRM/TSRM.h 2006-09-05 20:30:33.000000000 +0200 -@@ -33,6 +33,13 @@ - # define TSRM_API - #endif - -+#if HARDENING_PATCH -+# if HAVE_REALPATH -+# undef realpath -+# define realpath php_realpath -+# endif -+#endif -+ - /* Only compile multi-threading functions if we're in ZTS mode */ - #ifdef ZTS - -@@ -84,6 +91,7 @@ - - #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts - -+ - #ifdef __cplusplus - extern "C" { - #endif -diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.c ---- php-4.4.2/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:30:33.000000000 +0200 -@@ -179,6 +179,178 @@ - return p; - } - -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved) -+{ -+ struct stat sb; -+ char *p, *q, *s; -+ size_t left_len, resolved_len; -+ unsigned symlinks; -+ int serrno, slen; -+ int is_dir = 1; -+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; -+ -+ serrno = errno; -+ symlinks = 0; -+ if (path[0] == '/') { -+ resolved[0] = '/'; -+ resolved[1] = '\0'; -+ if (path[1] == '\0') -+ return (resolved); -+ resolved_len = 1; -+ left_len = strlcpy(left, path + 1, sizeof(left)); -+ } else { -+ if (getcwd(resolved, PATH_MAX) == NULL) { -+ strlcpy(resolved, ".", PATH_MAX); -+ return (NULL); -+ } -+ resolved_len = strlen(resolved); -+ left_len = strlcpy(left, path, sizeof(left)); -+ } -+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ -+ /* -+ * Iterate over path components in `left'. -+ */ -+ while (left_len != 0) { -+ /* -+ * Extract the next path component and adjust `left' -+ * and its length. -+ */ -+ p = strchr(left, '/'); -+ s = p ? p : left + left_len; -+ if (s - left >= sizeof(next_token)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ memcpy(next_token, left, s - left); -+ next_token[s - left] = '\0'; -+ left_len -= s - left; -+ if (p != NULL) -+ memmove(left, s + 1, left_len + 1); -+ if (resolved[resolved_len - 1] != '/') { -+ if (resolved_len + 1 >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ resolved[resolved_len++] = '/'; -+ resolved[resolved_len] = '\0'; -+ } -+ if (next_token[0] == '\0') -+ continue; -+ else if (strcmp(next_token, ".") == 0) -+ continue; -+ else if (strcmp(next_token, "..") == 0) { -+ /* -+ * Strip the last path component except when we have -+ * single "/" -+ */ -+ if (!is_dir) { -+ errno = ENOENT; -+ return (NULL); -+ } -+ if (resolved_len > 1) { -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ continue; -+ } -+ -+ /* -+ * Append the next path component and lstat() it. If -+ * lstat() fails we still can return successfully if -+ * there are no more path components left. -+ */ -+ resolved_len = strlcat(resolved, next_token, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ if (lstat(resolved, &sb) != 0) { -+ if (errno == ENOENT) { -+ if (p == NULL) { -+ errno = serrno; -+ return (resolved); -+ } else -+ /* dirty hack to support a vanilla PHP feature */ -+ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { -+ resolved_len = strlcat(resolved, "/", PATH_MAX); -+ resolved_len = strlcat(resolved, left, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ errno = serrno; -+ return (resolved); -+ } -+ } -+ return (NULL); -+ } -+ if (S_ISLNK(sb.st_mode)) { -+ if (symlinks++ > MAXSYMLINKS) { -+ errno = ELOOP; -+ return (NULL); -+ } -+ slen = readlink(resolved, symlink, sizeof(symlink) - 1); -+ if (slen < 0) -+ return (NULL); -+ symlink[slen] = '\0'; -+ if (symlink[0] == '/') { -+ resolved[1] = 0; -+ resolved_len = 1; -+ } else if (resolved_len > 1) { -+ /* Strip the last path component. */ -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ -+ /* -+ * If there are any path components left, then -+ * append them to symlink. The result is placed -+ * in `left'. -+ */ -+ if (p != NULL) { -+ if (symlink[slen - 1] != '/') { -+ if (slen + 1 >= sizeof(symlink)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ symlink[slen] = '/'; -+ symlink[slen + 1] = 0; -+ } -+ left_len = strlcat(symlink, left, sizeof(left)); -+ if (left_len >= sizeof(left)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ } -+ left_len = strlcpy(left, symlink, sizeof(left)); -+ } else { -+ if (S_ISDIR(sb.st_mode)) { -+ is_dir = 1; -+ } else { -+ is_dir = 0; -+ } -+ } -+ } -+ -+ /* -+ * Remove trailing slash except when the resolved pathname -+ * is a single "/". -+ */ -+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') -+ resolved[resolved_len - 1] = '\0'; -+ return (resolved); -+} -+#endif -+ - CWD_API void virtual_cwd_startup(void) - { - char cwd[MAXPATHLEN]; -@@ -300,8 +472,11 @@ - - if (path_length == 0) - return (0); -- if (path_length >= MAXPATHLEN) -+ if (path_length >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return (1); -+ } - - #if !defined(TSRM_WIN32) && !defined(NETWARE) - /* cwd_length can be 0 when getcwd() fails. -@@ -313,8 +488,9 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - } else { /* Concat current directory with relative path and then run realpath() on it */ -@@ -323,6 +499,8 @@ - - ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); - if (!tmp) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(ptr, state->cwd, state->cwd_length); -@@ -332,6 +510,8 @@ - ptr += path_length; - *ptr = '\0'; - if (strlen(tmp) >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - free(tmp); - return 1; - } -@@ -340,9 +520,10 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - free(tmp); -- return 1; */ -+ return 1; - } - } - free(tmp); -diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.h ---- php-4.4.2/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:30:33.000000000 +0200 -@@ -128,6 +128,22 @@ - - typedef int (*verify_path_func)(const cwd_state *); - -+#ifndef HAVE_STRLCPY -+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); -+#undef strlcpy -+#define strlcpy php_strlcpy -+#endif -+ -+#ifndef HAVE_STRLCAT -+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); -+#undef strlcat -+#define strlcat php_strlcat -+#endif -+ -+ -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved); -+#endif - CWD_API void virtual_cwd_startup(void); - CWD_API void virtual_cwd_shutdown(void); - CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); -diff -Nura php-4.4.2/Zend/zend_alloc.c hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.c ---- php-4.4.2/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.c 2006-09-05 20:30:33.000000000 +0200 -@@ -56,6 +56,11 @@ - # define END_MAGIC_SIZE 0 - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+# define CANARY_SIZE sizeof(unsigned int) -+#else -+# define CANARY_SIZE 0 -+#endif - - # if MEMORY_LIMIT - # if ZEND_DEBUG -@@ -64,7 +69,15 @@ - #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) - # endif - --#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ -+#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ -+ if (file) { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ -+ } else { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ -+ } \ -+ exit(1); \ -+ } \ -+ AG(allocated_memory) += rs;\ - if (AG(memory_limit)pNext; \ - } else { \ -+ if (p != p->pLast->pNext) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pLast->pNext = p->pNext; \ - } \ - if (p->pNext) { \ -+ if (p != p->pNext->pLast) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pNext->pLast = p->pLast; \ - } - -@@ -111,7 +132,7 @@ - p->pLast = (zend_mem_header *) NULL; - - #define DECLARE_CACHE_VARS() \ -- unsigned int real_size; \ -+ size_t real_size; \ - unsigned int cache_index - - #define REAL_SIZE(size) ((size+7) & ~0x7) -@@ -126,12 +147,22 @@ - - ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -- zend_mem_header *p; -+ zend_mem_header *p = NULL; - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { -+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); -+ exit(1); -+ } -+#endif - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - -+ if (size > INT_MAX || SIZE < size) { -+ goto emalloc_error; -+ } -+ - if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { - p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; - #if ZEND_DEBUG -@@ -147,6 +178,10 @@ - AG(cache_stats)[CACHE_INDEX][1]++; - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->cached = 0; - p->size = size; - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); -@@ -162,9 +197,11 @@ - AG(allocated_memory_peak) = AG(allocated_memory); - } - #endif -- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); - } - -+emalloc_error: -+ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (!p) { -@@ -192,7 +229,10 @@ - # endif - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -- -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } -@@ -219,17 +259,36 @@ - return emalloc_rel(lval + offset); - } - } -- -+ -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); -+#endif - zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset); - return 0; - } - - ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+efree_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); -+ exit(1); -+ } -+ /* to catch double efree()s */ -+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); -+ p->canary = 0; -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring", -@@ -274,6 +333,9 @@ - size_t _size = nmemb * size; - - if (nmemb && (_size/nmemb!=size)) { -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); -+#endif - fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); - #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID - kill(getpid(), SIGSEGV); -@@ -293,6 +355,9 @@ - - ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p; - zend_mem_header *orig; - DECLARE_CACHE_VARS(); -@@ -304,6 +369,16 @@ - - p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+erealloc_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); -+ exit(1); -+ } -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - void *new_p; -@@ -320,6 +395,13 @@ - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - - HANDLE_BLOCK_INTERRUPTIONS(); -+ -+ if (size > INT_MAX || SIZE < size) { -+ REMOVE_POINTER_FROM_LIST(p); -+ p = NULL; -+ goto erealloc_error; -+ } -+ - #if MEMORY_LIMIT - CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); - if (AG(allocated_memory) > AG(allocated_memory_peak)) { -@@ -327,7 +409,8 @@ - } - #endif - REMOVE_POINTER_FROM_LIST(p); -- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); -+erealloc_error: - if (!p) { - if (!allow_failure) { - fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); -@@ -349,6 +432,9 @@ - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - - HANDLE_UNBLOCK_INTERRUPTIONS(); -@@ -423,6 +509,10 @@ - { - AG(head) = NULL; - -+#if HARDENING_PATCH_MM_PROTECT -+ HG(canary_1) = zend_canary(); -+ HG(canary_2) = zend_canary(); -+#endif - #if MEMORY_LIMIT - AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ - AG(allocated_memory) = 0; -diff -Nura php-4.4.2/Zend/zend_alloc.h hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.h ---- php-4.4.2/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_alloc.h 2006-09-05 20:30:33.000000000 +0200 -@@ -32,6 +32,9 @@ - #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL - - typedef struct _zend_mem_header { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary; -+#endif - #if ZEND_DEBUG - long magic; - char *filename; -diff -Nura php-4.4.2/Zend/zend_builtin_functions.c hardening-patch-4.4.2-0.4.15/Zend/zend_builtin_functions.c ---- php-4.4.2/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:30:33.000000000 +0200 -@@ -49,6 +49,9 @@ - static ZEND_FUNCTION(crash); - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+static ZEND_FUNCTION(heap_overflow); -+#endif - static ZEND_FUNCTION(get_included_files); - static ZEND_FUNCTION(is_subclass_of); - static ZEND_FUNCTION(is_a); -@@ -101,6 +104,9 @@ - ZEND_FE(crash, NULL) - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ ZEND_FE(heap_overflow, NULL) -+#endif - ZEND_FE(get_included_files, NULL) - ZEND_FALIAS(get_required_files, get_included_files, NULL) - ZEND_FE(is_subclass_of, NULL) -@@ -805,6 +811,19 @@ - - #endif /* ZEND_DEBUG */ - -+ -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ZEND_FUNCTION(heap_overflow) -+{ -+ char *nowhere = emalloc(10); -+ -+ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); -+ -+ efree(nowhere); -+} -+#endif -+ -+ - /* {{{ proto array get_included_files(void) - Returns an array with the file names that were include_once()'d */ - ZEND_FUNCTION(get_included_files) -diff -Nura php-4.4.2/Zend/zend.c hardening-patch-4.4.2-0.4.15/Zend/zend.c ---- php-4.4.2/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend.c 2006-09-05 20:30:33.000000000 +0200 -@@ -53,6 +53,12 @@ - ZEND_API void (*zend_unblock_interruptions)(void); - ZEND_API void (*zend_ticks_function)(int ticks); - ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); -+#if HARDENING_PATCH -+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - - void (*zend_on_timeout)(int seconds TSRMLS_DC); - -@@ -70,9 +76,391 @@ - return SUCCESS; - } - -+#if HARDENING_PATCH -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; -+ } else { -+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_facility) = LOG_USER; -+ } else { -+ EG(hphp_log_syslog_facility) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_priority) = LOG_ALERT; -+ } else { -+ EG(hphp_log_syslog_priority) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_sapi) -+{ -+ if (!new_value) { -+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; -+ } else { -+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_script) -+{ -+ if (!new_value) { -+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL); -+ } else { -+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) -+{ -+ if (EG(hphp_log_scriptname)) { -+ pefree(EG(hphp_log_scriptname),1); -+ } -+ EG(hphp_log_scriptname) = NULL; -+ if (new_value) { -+ EG(hphp_log_scriptname) = pestrdup(new_value,1); -+ } -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_whitelist_destroy: -+ if (HG(include_whitelist)) { -+ zend_hash_destroy(HG(include_whitelist)); -+ pefree(HG(include_whitelist),1); -+ } -+ HG(include_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_whitelist_destroy; -+ } -+ -+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_blacklist_destroy: -+ if (HG(include_blacklist)) { -+ zend_hash_destroy(HG(include_blacklist)); -+ pefree(HG(include_blacklist),1); -+ } -+ HG(include_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_blacklist_destroy; -+ } -+ -+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_whitelist_destroy: -+ if (HG(eval_whitelist)) { -+ zend_hash_destroy(HG(eval_whitelist)); -+ pefree(HG(eval_whitelist),1); -+ } -+ HG(eval_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_whitelist_destroy; -+ } -+ -+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_blacklist_destroy: -+ if (HG(eval_blacklist)) { -+ zend_hash_destroy(HG(eval_blacklist)); -+ pefree(HG(eval_blacklist), 1); -+ } -+ HG(eval_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_blacklist_destroy; -+ } -+ -+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_whitelist_destroy: -+ if (HG(func_whitelist)) { -+ zend_hash_destroy(HG(func_whitelist)); -+ pefree(HG(func_whitelist),1); -+ } -+ HG(func_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_whitelist_destroy; -+ } -+ -+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_blacklist_destroy: -+ if (HG(func_blacklist)) { -+ zend_hash_destroy(HG(func_blacklist)); -+ pefree(HG(func_blacklist),1); -+ } -+ HG(func_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_blacklist_destroy; -+ } -+ -+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+#endif - - ZEND_INI_BEGIN() - ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) -+#if HARDENING_PATCH -+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) -+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) -+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) -+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) -+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) -+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) -+ 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) -+ -+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) -+ -+ 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) -+ 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) -+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) -+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) -+#endif - ZEND_INI_END() - - -@@ -354,8 +742,12 @@ - zend_init_rsrc_plist(TSRMLS_C); - EG(lambda_count)=0; - EG(user_error_handler) = NULL; -+ EG(in_code_type) = 0; - EG(in_execution) = 0; - EG(current_execute_data) = NULL; -+#if HARDENING_PATCH -+ EG(hphp_log_scriptname) = NULL; -+#endif - } - - -@@ -420,6 +812,14 @@ - extern zend_scanner_globals language_scanner_globals; - #endif - -+ /* Set up Hardening-Patch utility functions first */ -+#if HARDENING_PATCH -+ zend_security_log = utility_functions->security_log_function; -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ zend_is_valid_include = utility_functions->is_valid_include; -+#endif -+ - #ifdef ZTS - ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); - #else -@@ -619,6 +1019,7 @@ - } - CG(unclean_shutdown) = 1; - CG(in_compilation) = EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(current_execute_data) = NULL; - longjmp(EG(bailout), FAILURE); - } -diff -Nura php-4.4.2/Zend/zend_canary.c hardening-patch-4.4.2-0.4.15/Zend/zend_canary.c ---- php-4.4.2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_canary.c 2006-09-05 20:30:33.000000000 +0200 -@@ -0,0 +1,58 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ -+ -+#include "zend.h" -+ -+#include -+#include -+ -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+ZEND_API unsigned int zend_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.2/Zend/zend_compile.c hardening-patch-4.4.2-0.4.15/Zend/zend_compile.c ---- php-4.4.2/Zend/zend_compile.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_compile.c 2006-09-05 20:30:33.000000000 +0200 -@@ -768,6 +768,13 @@ - op_array.function_name = name; - op_array.arg_types = NULL; - op_array.return_reference = return_reference; -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array.created_by_eval = 1; -+ } else { -+ op_array.created_by_eval = 0; -+ } -+#endif - - if (is_method) { - if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { -diff -Nura php-4.4.2/Zend/zend_compile.h hardening-patch-4.4.2-0.4.15/Zend/zend_compile.h ---- php-4.4.2/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_compile.h 2006-09-05 20:30:33.000000000 +0200 -@@ -106,6 +106,9 @@ - char *filename; - - void *reserved[ZEND_MAX_RESERVED_RESOURCES]; -+#if HARDENING_PATCH -+ zend_bool created_by_eval; -+#endif - }; - - -@@ -549,6 +552,7 @@ - #define ZEND_USER_FUNCTION 2 - #define ZEND_OVERLOADED_FUNCTION 3 - #define ZEND_EVAL_CODE 4 -+#define ZEND_SANDBOX_CODE 6 - - #define ZEND_INTERNAL_CLASS 1 - #define ZEND_USER_CLASS 2 -diff -Nura php-4.4.2/Zend/zend_constants.c hardening-patch-4.4.2-0.4.15/Zend/zend_constants.c ---- php-4.4.2/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_constants.c 2006-09-05 20:30:33.000000000 +0200 -@@ -111,6 +111,74 @@ - REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); - - REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); -+ -+ /* error levels */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); -+ /* facility: type of program logging the message */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NEWS -+ /* No LOG_NEWS on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ -+#endif -+#ifdef LOG_UUCP -+ /* No LOG_UUCP on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_CRON -+ /* apparently some systems don't have this one */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_AUTHPRIV -+ /* AIX doesn't have LOG_AUTHPRIV */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); -+#endif -+#if !defined(PHP_WIN32) && !defined(NETWARE) -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); -+#endif -+ /* options */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NOWAIT -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_PERROR -+ /* AIX doesn't have LOG_PERROR */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ -+#endif -+#endif - - /* true/false constants */ - { -diff -Nura php-4.4.2/Zend/zend_errors.h hardening-patch-4.4.2-0.4.15/Zend/zend_errors.h ---- php-4.4.2/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_errors.h 2006-09-05 20:30:33.000000000 +0200 -@@ -36,5 +36,18 @@ - #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) - #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) - -+#if HARDENING_PATCH -+#define S_MEMORY (1<<0L) -+#define S_VARS (1<<1L) -+#define S_FILES (1<<2L) -+#define S_INCLUDE (1<<3L) -+#define S_SQL (1<<4L) -+#define S_EXECUTOR (1<<5L) -+#define S_MAIL (1<<6L) -+#define S_MISC (1<<30L) -+#define S_INTERNAL (1<<29L) -+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) -+#endif -+ - #endif /* ZEND_ERRORS_H */ - -diff -Nura php-4.4.2/Zend/zend_execute_API.c hardening-patch-4.4.2-0.4.15/Zend/zend_execute_API.c ---- php-4.4.2/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:30:33.000000000 +0200 -@@ -142,6 +142,7 @@ - EG(class_table) = CG(class_table); - - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - - zend_ptr_stack_init(&EG(argument_stack)); - -@@ -431,12 +432,14 @@ - zend_execute_data execute_data; - - /* Initialize execute_data */ -+ memset(&execute_data, 0, sizeof(execute_data)); - EX(fbc) = NULL; - EX(object).ptr = NULL; - EX(ce) = NULL; - EX(Ts) = NULL; - EX(op_array) = NULL; - EX(opline) = NULL; -+ EX(execute_depth) = 0; - - *retval_ptr_ptr = NULL; - -@@ -494,6 +497,39 @@ - zval_dtor(&function_name_copy); - return FAILURE; - } -+#if HARDENING_PATCH -+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - zval_dtor(&function_name_copy); - - for (i=0; itype = type; - EG(return_value_ptr_ptr) = &local_retval_ptr; - EG(active_op_array) = new_op_array; - EG(no_extensions)=1; -@@ -673,6 +709,10 @@ - return retval; - } - -+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+{ -+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); -+} - - void execute_new_code(TSRMLS_D) - { -diff -Nura php-4.4.2/Zend/zend_execute.c hardening-patch-4.4.2-0.4.15/Zend/zend_execute.c ---- php-4.4.2/Zend/zend_execute.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_execute.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1042,6 +1042,7 @@ - zend_execute_data execute_data; - - /* Initialize execute_data */ -+ memset(&execute_data, 0, sizeof(execute_data)); - EX(fbc) = NULL; - EX(ce) = NULL; - EX(object).ptr = NULL; -@@ -1053,9 +1054,21 @@ - } - EX(prev_execute_data) = EG(current_execute_data); - EX(original_in_execution)=EG(in_execution); -+ EX(original_in_code_type)=EG(in_code_type); - - EG(current_execute_data) = &execute_data; - -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif -+ - EG(in_execution) = 1; - if (op_array->start_op) { - EX(opline) = op_array->start_op; -@@ -1087,6 +1100,19 @@ - } - } - -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif -+ - while (1) { - #ifdef ZEND_WIN32 - if (EG(timed_out)) { -@@ -1634,6 +1660,36 @@ - if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) { - zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val); - } -+#if HARDENING_PATCH -+ if (active_function_table == EG(function_table)) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+#endif -+ - zval_dtor(&tmp); - EX(fbc) = function; - overloaded_function_call_cont: -@@ -1649,6 +1705,35 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); - zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce)); - EX(object).ptr = NULL; -@@ -1821,6 +1906,7 @@ - efree(EX(Ts)); - } - EG(in_execution) = EX(original_in_execution); -+ EG(in_code_type) = EX(original_in_code_type); - EG(current_execute_data) = EX(prev_execute_data); - return; - } -@@ -2210,7 +2296,12 @@ - int dummy = 1; - zend_file_handle file_handle = {0}; - -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS -+#else - if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS -+#endif - && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { - - file_handle.filename = inc_filename->value.str.val; -@@ -2239,6 +2330,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -2381,7 +2477,7 @@ - if (EX(opline)->extended_value) { - array_ptr_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R); - if (array_ptr_ptr == NULL) { -- MAKE_STD_ZVAL(array_ptr); -+ ALLOC_INIT_ZVAL(array_ptr); - } else { - SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr); - array_ptr = *array_ptr_ptr; -diff -Nura php-4.4.2/Zend/zend_execute_globals.h hardening-patch-4.4.2-0.4.15/Zend/zend_execute_globals.h ---- php-4.4.2/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_execute_globals.h 2006-09-05 20:30:33.000000000 +0200 -@@ -60,6 +60,8 @@ - object_info object; - temp_variable *Ts; - zend_bool original_in_execution; -+ zend_uint original_in_code_type; -+ zend_uint execute_depth; - zend_op_array *op_array; - struct _zend_execute_data *prev_execute_data; - } zend_execute_data; -diff -Nura php-4.4.2/Zend/zend_extensions.c hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.c ---- php-4.4.2/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.c 2006-09-05 20:30:33.000000000 +0200 -@@ -54,23 +54,44 @@ - return FAILURE; - } - -+ /* check if module is compiled against Hardening-Patch */ -+ if (extension_version_info->zend_extension_api_no < 1000000000) { -+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } -+ -+ -+ /* check if module is compiled against correct Hardening-Patch version */ -+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { -+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ extension_version_info->zend_extension_api_no, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } - - /* allow extension to proclaim compatibility with any Zend version */ -- 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)) { -- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { -+ 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)) { -+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is outdated.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO); - DL_UNLOAD(handle); - return FAILURE; -- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { -+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is newer.\n" - "Contact %s at %s for a later version of %s.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO, - new_extension->author, - new_extension->URL, -diff -Nura php-4.4.2/Zend/zend_extensions.h hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.h ---- php-4.4.2/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_extensions.h 2006-09-05 20:30:33.000000000 +0200 -@@ -23,6 +23,9 @@ - - #include "zend_compile.h" - -+/* Create own API version number for Hardening-Patch */ -+ -+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805 - #define ZEND_EXTENSION_API_NO 20050606 - - typedef struct _zend_extension_version_info { -@@ -30,6 +33,7 @@ - char *required_zend_version; - unsigned char thread_safe; - unsigned char debug; -+ int real_zend_extension_api_no; - } zend_extension_version_info; - - -@@ -96,7 +100,7 @@ - - - #define ZEND_EXTENSION() \ -- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } -+ 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 } - - #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 - #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 -diff -Nura php-4.4.2/Zend/zend_globals.h hardening-patch-4.4.2-0.4.15/Zend/zend_globals.h ---- php-4.4.2/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_globals.h 2006-09-05 20:30:33.000000000 +0200 -@@ -163,6 +163,16 @@ - - int error_reporting; - int orig_error_reporting; -+#if HARDENING_PATCH -+ int hphp_log_syslog; -+ int hphp_log_syslog_facility; -+ int hphp_log_syslog_priority; -+ int hphp_log_sapi; -+ int hphp_log_script; -+ char *hphp_log_scriptname; -+ zend_bool hphp_log_use_x_forwarded_for; -+ long hphp_executor_max_depth; -+#endif - int exit_status; - - zend_op_array *active_op_array; -@@ -176,6 +186,7 @@ - int ticks_count; - - zend_bool in_execution; -+ zend_uint in_code_type; - zend_bool bailout_set; - zend_bool full_tables_cleanup; - -diff -Nura php-4.4.2/Zend/zend.h hardening-patch-4.4.2-0.4.15/Zend/zend.h ---- php-4.4.2/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend.h 2006-09-05 20:30:33.000000000 +0200 -@@ -274,9 +274,10 @@ - struct _zval_struct { - /* Variable information */ - zvalue_value value; /* value */ -+ zend_uint refcount; -+ zend_ushort flags; - zend_uchar type; /* active type */ - zend_uchar is_ref; -- zend_ushort refcount; - }; - - -@@ -337,6 +338,12 @@ - void (*ticks_function)(int ticks); - void (*on_timeout)(int seconds TSRMLS_DC); - zend_bool (*open_function)(const char *filename, struct _zend_file_handle *); -+#if HARDENING_PATCH -+ void (*security_log_function)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ int (*is_valid_include)(zval *z); -+#endif - } zend_utility_functions; - - -@@ -468,7 +475,16 @@ - extern ZEND_API void (*zend_ticks_function)(int ticks); - extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); - extern void (*zend_on_timeout)(int seconds TSRMLS_DC); -+#if HARDENING_PATCH -+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+extern ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ZEND_API unsigned int zend_canary(void); -+#endif - - ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3); - -@@ -575,6 +591,11 @@ - - #define ZEND_MAX_RESERVED_RESOURCES 4 - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#include "php_syslog.h" -+#endif -+ - #endif /* ZEND_H */ - - /* -diff -Nura php-4.4.2/Zend/zend_hash.c hardening-patch-4.4.2-0.4.15/Zend/zend_hash.c ---- php-4.4.2/Zend/zend_hash.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_hash.c 2006-09-05 20:30:33.000000000 +0200 -@@ -26,6 +26,17 @@ - # include - #endif - -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int zend_hash_canary = 0x1234567; -+ zend_bool zend_hash_canary_inited = 0; -+#endif -+ -+#define CHECK_HASH_CANARY(hash) \ -+ if (zend_hash_canary != (hash)->canary) { \ -+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ -+ exit(1); \ -+ } -+ - #define HANDLE_NUMERIC(key, length, func) { \ - register char *tmp=key; \ - \ -@@ -175,6 +186,9 @@ - { - uint i = 3; - Bucket **tmp; -+#if HARDENING_PATCH_HASH_PROTECT -+ TSRMLS_FETCH(); -+#endif - - SET_INCONSISTENT(HT_OK); - -@@ -184,6 +198,13 @@ - - ht->nTableSize = 1 << i; - ht->nTableMask = ht->nTableSize - 1; -+#if HARDENING_PATCH_HASH_PROTECT -+ if (zend_hash_canary_inited==0) { -+ zend_hash_canary = zend_canary(); -+ zend_hash_canary_inited = 1; -+ } -+ ht->canary = zend_hash_canary; -+#endif - ht->pDestructor = pDestructor; - ht->pListHead = NULL; - ht->pListTail = NULL; -@@ -259,6 +280,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -327,6 +351,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -402,6 +429,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -450,7 +480,7 @@ - IS_CONSISTENT(ht); - - if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ -- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); -+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); - if (t) { - HANDLE_BLOCK_INTERRUPTIONS(); - ht->arBuckets = t; -@@ -460,6 +490,7 @@ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return SUCCESS; - } -+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); - return FAILURE; - } - return SUCCESS; -@@ -491,15 +522,17 @@ - IS_CONSISTENT(ht); - - if (flag == HASH_DEL_KEY) { -- HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, arKey, nKeyLength, idx, HASH_DEL_INDEX)); -+ HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, NULL, 0, idx, HASH_DEL_INDEX)); - h = zend_inline_hash_func(arKey, nKeyLength); - } - nIndex = h & ht->nTableMask; - - p = ht->arBuckets[nIndex]; - while (p != NULL) { -- if ((p->h == h) && ((p->nKeyLength == 0) || /* Numeric index */ -- ((p->nKeyLength == nKeyLength) && (!memcmp(p->arKey, arKey, nKeyLength))))) { -+ if ((p->h == h) -+ && (p->nKeyLength == nKeyLength) -+ && ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */ -+ || !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */ - HANDLE_BLOCK_INTERRUPTIONS(); - if (p == ht->arBuckets[nIndex]) { - ht->arBuckets[nIndex] = p->pNext; -@@ -524,6 +557,9 @@ - ht->pInternalPointer = p->pListNext; - } - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (!p->pDataPtr) { -@@ -553,6 +589,9 @@ - q = p; - p = p->pListNext; - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(q->pData); - } - if (!q->pDataPtr && q->pData) { -@@ -579,6 +618,9 @@ - q = p; - p = p->pListNext; - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(q->pData); - } - if (!q->pDataPtr && q->pData) { -@@ -608,6 +650,9 @@ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (!p->pDataPtr) { -diff -Nura php-4.4.2/Zend/zend_hash.h hardening-patch-4.4.2-0.4.15/Zend/zend_hash.h ---- php-4.4.2/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_hash.h 2006-09-05 20:30:33.000000000 +0200 -@@ -54,6 +54,9 @@ - } Bucket; - - typedef struct _hashtable { -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int canary; -+#endif - uint nTableSize; - uint nTableMask; - uint nNumOfElements; -diff -Nura php-4.4.2/Zend/zend_ini.c hardening-patch-4.4.2-0.4.15/Zend/zend_ini.c ---- php-4.4.2/Zend/zend_ini.c 2005-09-02 23:09:03.000000000 +0200 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_ini.c 2006-09-07 19:14:18.000000000 +0200 -@@ -256,7 +256,8 @@ - zend_ini_entry *ini_entry; - TSRMLS_FETCH(); - -- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { -+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || -+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifyable & ZEND_INI_USER) == 0)) { - return FAILURE; - } - -diff -Nura php-4.4.2/Zend/zend_ini.h hardening-patch-4.4.2-0.4.15/Zend/zend_ini.h ---- php-4.4.2/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_ini.h 2006-09-05 20:30:33.000000000 +0200 -@@ -174,6 +174,7 @@ - /* Standard message handlers */ - BEGIN_EXTERN_C() - ZEND_API ZEND_INI_MH(OnUpdateBool); -+#define OnUpdateLong OnUpdateInt - ZEND_API ZEND_INI_MH(OnUpdateInt); - ZEND_API ZEND_INI_MH(OnUpdateReal); - ZEND_API ZEND_INI_MH(OnUpdateString); -diff -Nura php-4.4.2/Zend/zend_language_scanner.l hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.l ---- php-4.4.2/Zend/zend_language_scanner.l 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:30:33.000000000 +0200 -@@ -393,6 +393,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-4.4.2/Zend/zend_language_scanner.c hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.c ---- php-4.4.2/Zend/zend_language_scanner.c 2006-01-12 19:24:28.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:30:33.000000000 +0200 -@@ -3036,6 +3036,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-4.4.2/Zend/zend_llist.c hardening-patch-4.4.2-0.4.15/Zend/zend_llist.c ---- php-4.4.2/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_llist.c 2006-09-05 20:30:33.000000000 +0200 -@@ -21,9 +21,49 @@ - #include "zend.h" - #include "zend_llist.h" - #include "zend_qsort.h" -+#include "zend_globals.h" -+ -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int zend_llist_canary_1 = 0x1234567; -+ unsigned int zend_llist_canary_2 = 0x1553425; -+ zend_bool zend_llist_canary_inited = 0; -+#endif -+ -+#define CHECK_LIST_CANARY(list) \ -+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ -+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ -+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+#define CHECK_LISTELEMENT_CANARY(elem, list) \ -+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ -+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ -+ exit(1); \ -+ } -+ - - ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ -+ if (persistent) { -+ if (!zend_llist_canary_inited) { -+ /* do not change order to ensure thread safety */ -+ zend_llist_canary_1 = zend_canary(); -+ zend_llist_canary_2 = zend_canary(); -+ zend_llist_canary_inited = 1; -+ } -+ } else -+ if (!HG(ll_canary_inited)) { -+ HG(canary_3) = zend_canary(); -+ HG(canary_4) = zend_canary(); -+ HG(ll_canary_inited) = 1; -+ } -+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); -+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); -+#endif - l->head = NULL; - l->tail = NULL; - l->count = 0; -@@ -37,6 +77,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->prev = l->tail; - tmp->next = NULL; - if (l->tail) { -@@ -55,6 +100,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->next = l->head; - tmp->prev = NULL; - if (l->head) { -@@ -91,10 +141,20 @@ - zend_llist_element *current=l->head; - zend_llist_element *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (compare(current->data, element)) { - DEL_LLIST_ELEMENT(current, l); -+#if HARDENING_PATCH_LL_PROTECT -+ current->canary = 0; -+#endif - break; - } - current = next; -@@ -106,7 +166,14 @@ - { - zend_llist_element *current=l->head, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (l->dtor) { - l->dtor(current->data); -@@ -131,7 +198,14 @@ - zend_llist_element *old_tail; - void *data; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if ((old_tail = l->tail)) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(old_tail, l) -+#endif - if (l->tail->prev) { - l->tail->prev->next = NULL; - } -@@ -157,9 +231,16 @@ - { - zend_llist_element *ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(src) -+#endif - zend_llist_init(dst, src->size, src->dtor, src->persistent); - ptr = src->head; - while (ptr) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(ptr, src) -+#endif - zend_llist_add_element(dst, ptr->data); - ptr = ptr->next; - } -@@ -170,11 +251,21 @@ - { - zend_llist_element *element, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - element=l->head; - while (element) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - next = element->next; - if (func(element->data)) { - DEL_LLIST_ELEMENT(element, l); -+#if HARDENING_PATCH_LL_PROTECT -+ element->canary = 0; -+#endif - } - element = next; - } -@@ -185,7 +276,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data TSRMLS_CC); - } - } -@@ -197,6 +294,9 @@ - zend_llist_element **elements; - zend_llist_element *element, **ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - if (l->count <= 0) { - return; - } -@@ -206,6 +306,9 @@ - ptr = &elements[0]; - - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - *ptr++ = element; - } - -@@ -228,7 +331,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, arg TSRMLS_CC); - } - } -@@ -239,8 +348,14 @@ - zend_llist_element *element; - va_list args; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - va_start(args, num_args); - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, num_args, args TSRMLS_CC); - } - va_end(args); -@@ -249,6 +364,10 @@ - - ZEND_API int zend_llist_count(zend_llist *l) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - return l->count; - } - -@@ -256,8 +375,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->head; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -269,8 +395,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->tail; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -282,9 +415,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->next; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -@@ -296,9 +439,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->prev; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -diff -Nura php-4.4.2/Zend/zend_llist.h hardening-patch-4.4.2-0.4.15/Zend/zend_llist.h ---- php-4.4.2/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_llist.h 2006-09-05 20:30:33.000000000 +0200 -@@ -24,6 +24,9 @@ - #include - - typedef struct _zend_llist_element { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary, padding; -+#endif - struct _zend_llist_element *next; - struct _zend_llist_element *prev; - char data[1]; /* Needs to always be last in the struct */ -@@ -36,6 +39,9 @@ - typedef void (*llist_apply_func_t)(void * TSRMLS_DC); - - typedef struct _zend_llist { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_h; /* head */ -+#endif - zend_llist_element *head; - zend_llist_element *tail; - size_t size; -@@ -43,6 +49,9 @@ - llist_dtor_func_t dtor; - unsigned char persistent; - zend_llist_element *traverse_ptr; -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_t; /* tail */ -+#endif - } zend_llist; - - typedef zend_llist_element* zend_llist_position; -diff -Nura php-4.4.2/Zend/zend_modules.h hardening-patch-4.4.2-0.4.15/Zend/zend_modules.h ---- php-4.4.2/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_modules.h 2006-09-05 20:30:33.000000000 +0200 -@@ -34,6 +34,7 @@ - ZEND_API extern unsigned char second_arg_force_ref[]; - ZEND_API extern unsigned char third_arg_force_ref[]; - -+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112 - #define ZEND_MODULE_API_NO 20020429 - #ifdef ZTS - #define USING_ZTS 1 -@@ -41,9 +42,9 @@ - #define USING_ZTS 0 - #endif - --#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS -+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS - --#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 -+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO - - #define STANDARD_MODULE_PROPERTIES \ - NULL, NULL, STANDARD_MODULE_PROPERTIES_EX -@@ -75,6 +76,7 @@ - unsigned char type; - void *handle; - int module_number; -+ unsigned int real_zend_api; - }; - - -diff -Nura php-4.4.2/Zend/zend_opcode.c hardening-patch-4.4.2-0.4.15/Zend/zend_opcode.c ---- php-4.4.2/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_opcode.c 2006-09-05 20:30:33.000000000 +0200 -@@ -88,6 +88,9 @@ - op_array->done_pass_two = 0; - - op_array->start_op = NULL; -+#if HARDENING_PATCH -+ op_array->created_by_eval = 0; -+#endif - - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); - } -diff -Nura php-4.4.2/Zend/zend_operators.c hardening-patch-4.4.2-0.4.15/Zend/zend_operators.c ---- php-4.4.2/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_operators.c 2006-09-05 20:30:33.000000000 +0200 -@@ -1604,6 +1604,20 @@ - return (op->value.lval ? 1 : 0); - } - -+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) -+{ -+ register unsigned char *str = (unsigned char*)source; -+ register unsigned char *result = (unsigned char*)dest; -+ register unsigned char *end = str + length; -+ -+ while (str < end) { -+ *result++ = tolower((int)*str++); -+ } -+ *result = *end; -+ -+ return dest; -+} -+ - ZEND_API void zend_str_tolower(char *str, unsigned int length) - { - register char *p=str, *end=p+length; -diff -Nura php-4.4.2/Zend/zend_operators.h hardening-patch-4.4.2-0.4.15/Zend/zend_operators.h ---- php-4.4.2/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.2-0.4.15/Zend/zend_operators.h 2006-09-05 20:30:33.000000000 +0200 -@@ -174,6 +174,14 @@ - #endif - - ZEND_API void zend_str_tolower(char *str, unsigned int length); -+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length); -+ -+static inline char * -+zend_str_tolower_dup(const char *source, unsigned int length) -+{ -+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length); -+} -+ - ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2); - ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3); - ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2); diff --git a/hardening-patch-4.4.3-0.4.15.patch b/hardening-patch-4.4.3-0.4.15.patch deleted file mode 100644 index 017b2a0..0000000 --- a/hardening-patch-4.4.3-0.4.15.patch +++ /dev/null @@ -1,8957 +0,0 @@ -diff -Nura php-4.4.3/Changelog.hphp hardening-patch-4.4.3-0.4.15/Changelog.hphp ---- php-4.4.3/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Changelog.hphp 2006-09-07 19:32:48.000000000 +0200 -@@ -0,0 +1,61 @@ -+Changelog of the Hardening-Patch -+-------------------------------- -+ -+0.4.15 - 07. September 2006 -+ -+ PHP4: -+ [+] Fix for potential DOS in handling of include blacklists -+ -+ PHP4+5: -+ [+] Backported a fix for open_basedir problems with insanse PHP scripts -+ [+] Added a fix for ini_restore() PHP security vulnerability -+ -+0.4.14 - 11. August 2006 -+ -+ PHP4: -+ [+] Remove unecessary call to AC_BROKEN_REALPATH -+ -+ PHP5: -+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant -+ -+ PHP4+5: -+ [+] Added a few PHP security fixes / see changelog.secfix for details -+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits -+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments -+ -+0.4.13 - 07. August 2006 -+ -+ PHP4+5: -+ [+] Added a fix for a compile problem on solaris due to missing strcasestr() -+ -+0.4.12 - 19. July 2006 -+ -+ PHP4: -+ [+] Added fixes from sf4 security patch / see changelog.secfix for details -+ -+ PHP5: -+ [+] Added fixes from sf5 security patch / see changelog.secfix for details -+ -+ PHP4+5: -+ [+] Added anti mail spam feature -+ [+] Speedup of zend_hash canary (clear/destroy) -+ [+] Added a fix for a DOS in the handling of URL blacklists -+ -+0.4.11 - 13. May 2006 -+ -+ PHP5: -+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache -+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 -+ -+ PHP4+5: -+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories -+ -+ -+0.4.10 - 11. May 2006 -+ -+ PHP4: -+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed -+ -+ PHP4+5: -+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir -+ -diff -Nura php-4.4.3/Changelog.secfix hardening-patch-4.4.3-0.4.15/Changelog.secfix ---- php-4.4.3/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Changelog.secfix 2006-09-05 20:30:44.000000000 +0200 -@@ -0,0 +1,17 @@ -+Changelog of PHP 4.4.3 Security Fixes -+ -+Release 2 - 11. August 2006 -+ -+ [+] Added IMAP open_basedir/safe_mode check -+ [+] Added a upstream fix for previous ext/session fixes -+ [+] Added upstream fix to ext/socket -+ [+] Added sscanf() security fix -+ [+] Added fixes for handling of corrupt .gif files to gdlib -+ -+Release 1 - 4. August 2006 -+ -+ [+] Added a fix to disable CURLOPT_FOLLOWLOCATION while in safe_mode()/open_basedir -+ [+] Added a *working* wordwrap() fix -+ [+] Added code to make memory_limit work on 64bit systems -+ [+] Added a fix for an integer overflow in str_repeat() -+ -diff -Nura php-4.4.3/configure hardening-patch-4.4.3-0.4.15/configure ---- php-4.4.3/configure 2006-08-01 09:39:10.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/configure 2006-09-05 20:30:44.000000000 +0200 -@@ -402,6 +402,16 @@ - ac_default_prefix=/usr/local - # Any additions from configure.in: - ac_help="$ac_help -+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." -+ac_help="$ac_help -+ --disable-hardening-patch-ll-protect Disable the Linked List protection." -+ac_help="$ac_help -+ --disable-hardening-patch-inc-protect Disable include/require protection." -+ac_help="$ac_help -+ --disable-hardening-patch-fmt-protect Disable format string protection." -+ac_help="$ac_help -+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." -+ac_help="$ac_help - - SAPI modules: - " -@@ -854,6 +864,8 @@ - ac_help="$ac_help - --disable-tokenizer Disable tokenizer support" - ac_help="$ac_help -+ --disable-varfilter Disable Hardening-Patch's variable filter" -+ac_help="$ac_help - --enable-wddx Enable WDDX support." - ac_help="$ac_help - --disable-xml Disable XML support using bundled expat lib" -@@ -2942,6 +2954,157 @@ - - - -+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. -+if test "${enable_hardening_patch_mm_protect+set}" = set; then -+ enableval="$enable_hardening_patch_mm_protect" -+ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. -+if test "${enable_hardening_patch_ll_protect+set}" = set; then -+ enableval="$enable_hardening_patch_ll_protect" -+ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. -+if test "${enable_hardening_patch_inc_protect+set}" = set; then -+ enableval="$enable_hardening_patch_inc_protect" -+ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. -+if test "${enable_hardening_patch_fmt_protect+set}" = set; then -+ enableval="$enable_hardening_patch_fmt_protect" -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. -+if test "${enable_hardening_patch_hash_protect+set}" = set; then -+ enableval="$enable_hardening_patch_hash_protect" -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+ -+fi -+ -+ -+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 -+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 -+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 -+echo "configure:2733: checking whether to protect include/require statements" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect PHP Format String functions" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 -+ -+ -+cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH 1 -+EOF -+ -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 0 -+EOF -+ -+fi - - - -@@ -16017,6 +16180,62 @@ - fi - - -+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 -+echo "configure:14928: checking whether realpath is broken" >&5 -+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then -+ echo $ac_n "(cached) $ac_c" 1>&6 -+else -+ -+ if test "$cross_compiling" = yes; then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -+then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ echo "configure: failed program was:" >&5 -+ cat conftest.$ac_ext >&5 -+ rm -fr conftest* -+ -+ ac_cv_broken_realpath=yes -+ -+fi -+rm -fr conftest* -+fi -+ -+ -+fi -+ -+echo "$ac_t""$ac_cv_broken_realpath" 1>&6 -+ if test "$ac_cv_broken_realpath" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 1 -+EOF -+ -+ else -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 0 -+EOF -+ -+ fi -+ -+ - echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 - echo "configure:16022: checking for declared timezone" >&5 - if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then -@@ -86718,7 +86937,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - cat >> confdefs.h <&6 -+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 -+# Check whether --enable-varfilter or --disable-varfilter was given. -+if test "${enable_varfilter+set}" = set; then -+ enableval="$enable_varfilter" -+ PHP_VARFILTER=$enableval -+else -+ -+ PHP_VARFILTER=yes -+ -+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then -+ PHP_VARFILTER=$PHP_ENABLE_ALL -+ fi -+ -+fi -+ -+ -+ -+ext_output="yes, shared" -+ext_shared=yes -+case $PHP_VARFILTER in -+shared,*) -+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` -+ ;; -+shared) -+ PHP_VARFILTER=yes -+ ;; -+no) -+ ext_output=no -+ ext_shared=no -+ ;; -+*) -+ ext_output=yes -+ ext_shared=no -+ ;; -+esac -+ -+ -+ -+echo "$ac_t""$ext_output" 1>&6 -+ -+ -+ -+ -+if test "$PHP_VARFILTER" != "no"; then -+ cat >> confdefs.h <<\EOF -+#define HAVE_VARFILTER 1 -+EOF -+ -+ -+ ext_builddir=ext/varfilter -+ ext_srcdir=$abs_srcdir/ext/varfilter -+ -+ ac_extra= -+ -+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then -+ -+ -+ -+ case ext/varfilter in -+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; -+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; -+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; -+ esac -+ -+ -+ -+ b_c_pre=$php_c_pre -+ b_cxx_pre=$php_cxx_pre -+ b_c_meta=$php_c_meta -+ b_cxx_meta=$php_cxx_meta -+ b_c_post=$php_c_post -+ b_cxx_post=$php_cxx_post -+ b_lo=$php_lo -+ -+ -+ old_IFS=$IFS -+ for ac_src in varfilter.c; do -+ -+ IFS=. -+ set $ac_src -+ ac_obj=$1 -+ IFS=$old_IFS -+ -+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" -+ -+ case $ac_src in -+ *.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" ;; -+ *.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" ;; -+ esac -+ -+ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 -@@ -104088,7 +104566,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - streams.c network.c php_open_temporary_file.c php_logos.c \ -- output.c memory_streams.c user_streams.c; do -+ output.c memory_streams.c user_streams.c hardening_patch.c; do - - IFS=. - set $ac_src -@@ -104273,7 +104751,7 @@ - zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ -- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do -+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do - - IFS=. - set $ac_src -diff -Nura php-4.4.3/configure.in hardening-patch-4.4.3-0.4.15/configure.in ---- php-4.4.3/configure.in 2006-07-31 17:04:53.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/configure.in 2006-09-05 20:30:44.000000000 +0200 -@@ -247,7 +247,7 @@ - sinclude(Zend/acinclude.m4) - sinclude(Zend/Zend.m4) - sinclude(TSRM/tsrm.m4) -- -+sinclude(main/hardening_patch.m4) - - - divert(2) -@@ -621,6 +621,7 @@ - AC_FUNC_ALLOCA - dnl PHP_AC_BROKEN_SPRINTF - dnl PHP_AC_BROKEN_SNPRINTF -+dnl PHP_AC_BROKEN_REALPATH - PHP_DECLARED_TIMEZONE - PHP_TIME_R_TYPE - PHP_READDIR_R_TYPE -@@ -1260,7 +1261,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - streams.c network.c php_open_temporary_file.c php_logos.c \ -- output.c memory_streams.c user_streams.c) -+ output.c memory_streams.c user_streams.c hardening_patch.c) - PHP_ADD_SOURCES(/main, internal_functions.c,, sapi) - case $host_alias in - *netware*) -@@ -1281,7 +1282,7 @@ - zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ -- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c) -+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c ) - - if test -r "$abs_srcdir/Zend/zend_objects.c"; then - PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c) -diff -Nura php-4.4.3/ext/curl/curl.c hardening-patch-4.4.3-0.4.15/ext/curl/curl.c ---- php-4.4.3/ext/curl/curl.c 2006-05-21 20:48:50.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/curl/curl.c 2006-09-05 20:30:44.000000000 +0200 -@@ -924,7 +924,6 @@ - case CURLOPT_FTPLISTONLY: - case CURLOPT_FTPAPPEND: - case CURLOPT_NETRC: -- case CURLOPT_FOLLOWLOCATION: - case CURLOPT_PUT: - #if CURLOPT_MUTE != 0 - case CURLOPT_MUTE: -@@ -961,6 +960,16 @@ - convert_to_long_ex(zvalue); - error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); - break; -+ case CURLOPT_FOLLOWLOCATION: -+ convert_to_long_ex(zvalue); -+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { -+ if (Z_LVAL_PP(zvalue) != 0) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set"); -+ RETURN_FALSE; -+ } -+ } -+ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); -+ break; - case CURLOPT_URL: - case CURLOPT_PROXY: - case CURLOPT_USERPWD: -diff -Nura php-4.4.3/ext/curl/curlstreams.c hardening-patch-4.4.3-0.4.15/ext/curl/curlstreams.c ---- php-4.4.3/ext/curl/curlstreams.c 2006-01-01 14:46:50.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/curl/curlstreams.c 2006-09-05 20:30:44.000000000 +0200 -@@ -297,7 +297,11 @@ - curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream); - - /* currently buggy (bug is in curl) */ -- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); -+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { -+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); -+ } else { -+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); -+ } - - curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr); - curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0); -diff -Nura php-4.4.3/ext/fbsql/php_fbsql.c hardening-patch-4.4.3-0.4.15/ext/fbsql/php_fbsql.c ---- php-4.4.3/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:30:44.000000000 +0200 -@@ -1797,8 +1797,24 @@ - } - else if (fbcmdErrorsFound(md)) - { -+#if HARDENING_PATCH -+ char* query_copy; -+ int i; -+#endif - FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); - char* emg = fbcemdAllErrorMessages(emd); -+#if HARDENING_PATCH -+ query_copy=estrdup(query_copy); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ free(emg); -+ fbcemdRelease(emd); -+ result = 0; -+ zend_bailout(); -+ } -+#endif - if (FB_SQL_G(generateWarnings)) - { - if (emg) -diff -Nura php-4.4.3/ext/gd/libgd/gd_gif_in.c hardening-patch-4.4.3-0.4.15/ext/gd/libgd/gd_gif_in.c ---- php-4.4.3/ext/gd/libgd/gd_gif_in.c 2006-05-08 16:04:39.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/gd/libgd/gd_gif_in.c 2006-09-05 20:30:44.000000000 +0200 -@@ -216,6 +216,12 @@ - if (!im) { - return 0; - } -+ -+ if (!im->colorsTotal) { -+ gdImageDestroy(im); -+ return 0; -+ } -+ - /* Check for open colors at the end, so - we can reduce colorsTotal and ultimately - BitsPerPixel */ -@@ -506,6 +512,19 @@ - int v; - int xpos = 0, ypos = 0, pass = 0; - int i; -+ -+ /* -+ ** Initialize the Compression routines -+ */ -+ if (! ReadOK(fd,&c,1)) { -+ return; -+ } -+ -+ if (c > MAX_LWZ_BITS) { -+ return; -+ } -+ -+ - /* Stash the color map into the image */ - for (i=0; (ired[i] = cmap[CM_RED][i]; -@@ -515,12 +534,7 @@ - } - /* Many (perhaps most) of these colors will remain marked open. */ - im->colorsTotal = gdMaxColors; -- /* -- ** Initialize the Compression routines -- */ -- if (! ReadOK(fd,&c,1)) { -- return; -- } -+ - if (LWZReadByte(fd, TRUE, c) < 0) { - return; - } -diff -Nura php-4.4.3/ext/gd/tests/bug38112.gif hardening-patch-4.4.3-0.4.15/ext/gd/tests/bug38112.gif ---- php-4.4.3/ext/gd/tests/bug38112.gif 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/gd/tests/bug38112.gif 2006-09-05 20:30:44.000000000 +0200 -@@ -0,0 +1,140 @@ -+GIF89a}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M -+ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuutt! NETSCAPE2.0!d,}~pnojTIUzv{jTqr^F>M2KGP=5L ,LF^ur~NFj85B4+%ERNf*%K&"ALHe  >&"F!E\Zn>53W"!<43J3$$L&&F&&@MMU~+,Egh= "G+-L<=M -+ CEcKMkSUmhiu"A3};KV6=C%=O*>N.BR,:EKbp6JVq~( #%%@CCvzvXVHtsmnmibR.ڕfyd<4,y{zy2'sfZʮXTQc]Z}mg&{vuuttq]sH6U~F7Jػ|[rEwЫ*4;W(ƺj -+Ȗ֨_x֚hyvVyxc-%Bak(XF(yv aϑ@HZkhڊ'M )Zk[0K\G%y,l [6%F2 >ǾUI?6N>MhغCJ -+JmڶiIeʑ%~!T"2ZU -+禅^@-BAYVY0KTFXLs)rR+0l-BV%UrÜ Jmy@-QYŦm1%ΤOjvr3hm!1`0WDJj%To4Qə%)0 *Ƌ%LTt9sWKș#D(Qѧ_NGPHx#{ -+1He{"˥Z\U+Mf#HPB -+B}1wV$.[zsJ'MN("Os$R'D!EA=#L!`0[S6wL`AxPN* Q+9DŽ"X=R\20Z-ٕ hLRK 8R,QEX:$< -+@p&$ x d\ݵ@HyD5C*sY: -+ auc%l!F!Zr9BH  eP# Q -+!EG}Apk)lĞzZYn,A~*nY( ׌ƨ*1&r\gb*TS%~ZP}DÐhk;`BAkF.g- G!X` DD+8PA\0 -+";_BeI-ൂZ8A6 Mgv͚JG:Rױ` `څ,Ȁ-3bZ5A 7ÈR -+e!0/Jl!@tuACj< P>[[%^:uph ꀄ:`!XY, x/T†{33@46jX`!B0A/h^G) d{c4<J0q+*"ȼZPNaA,7;PHs7x1y 1@XTUnEX"$Q-jJM C@I܀ HD& :d" -+`G*`VgP`CXѰl3_ώ=𙛔f'}K1 F&`GFbL*0ف. @^0d';IPTd0|a˟*R6WpfF&UE_()=pOԻ [KS-Y&KG)$[UB%+Up/*1t5%[¡P ]y^"ZM8uX1Yb}C&mJP W9n2чzjTax9́,8R  Lp -+p"TUf %o,l(kPW$> ;Pp@ -+:>=#^db "Vxq?e+ﶓNCHK؁ -+l"?a @AOK*G:K!ƎƊ'8HB])ƞD?TVp \b1Fᰔ4ӨH7߹"mW~9 E.cM[F/W b׮WƤm335 PssP( TH;cyQr Đ'`1dS(m({frK Me D :  s%x 0' 3cSyp' -+vYao78yd0L zB-I qz=Cy0;9>d=`Fk^0@cƒ9Wpw03 ..@ -+)03f\@@阽 "o9 з l臙 S9gl e+c0S5_G0G9CZ@%P6E9@‖:=lD 03 i3EG0P!d05B#o 919ڐӣP:+WK*_' -+=ß5 &`~S vF= C8 1 sIp#PΖ@p̝X3WA`\=,ࢤT3 -+0l x@@ -+X m 0x茎 -+^qP鸪Epk Y8P0  oXS벎 Hc|i. +l?+\ I@ܐ   lѠ1/=0ݮv@O_n\ݾ@*֖-K -+Ќ g) : \ފ Nm^` h @_RK Z -+Mc5 a ΀ l0x > ? OVG c<^>N` -@`_R Pc@8ofmO?/)@T`r񒰻c^PHM VP{P, c0 -+UiDbb -+ Њ/\mbT]0#U(a0 -+Yij j25_Oߗ?`V{q mysm᮪t1OseXtk~> Q̖ەT;,tؗjzNUHYPIaSsZ*-)6:$NJHP>2Tšd2Z2^Q"XfRrS[p ./4:yd_Z[QP>4HTpwws>ȨNB!s7Q@ ,~G ocC\pC' /%_"RLDvDBK7;13nC}~dkTA  Ê@|3*A2L EA &D;rC2մ!E=a -+7ފSm#HOIC]y3RcorKXO$՚kD +zk#ˀ.ɂ" 7]{tL)[G-w -8E^ۂt@!0#őd ȉ#a"!"$C7 5B fN u&P~ 4 ex|%+փNE["W[(hALv9T0PaG#,?~ r&,Ra$\2љi\,Q3x惆EeVCѶI.CAh$,I%r9lA3)yws8uV`K(Oѭܭ m=Z8ڀ9}1? >)S\zA UV`d`h'57Za| 4_ҧ "blD4]h,PXnfAR"`@؉ ( R.@E4 m8B `m!J}CL np r6]aÞiF(DuB,q8aQrxceO@E`xa yM88(b f\6xE 6AD"r3_N!%(hu:D2I0ґ+4IJZh,@av{8 -+zs-Sqb!Ѕ I,?[:C.`n` @ b@Ϙ6JiJy387X͐t \KS ⴆ+ЇKAPEpP,s{ =eO|^"i;BJ#A9}TchX1qxD$Jno{DK\I2BQ -+?Bf-,6?VS@/B5=V@or -+umD0 %^ vs;DRja kF/vS>ܓ/X5?M+ H#lpH -+Hhwu 3;X+X} 9x!4 $ [uجg7)k08D1-bq@# ~#pacMF=a%9,nWF^|n7._6P0bw/#L!؄z]jj~ԕ_Uz`ЈFCXtI!d,կιǩUXuًȫȣdr*/>ç-Qȫ6AXIRbg *лۭΚʱțyۤsȑ炎ϯ운ΐë›랼ػࢮ柫ֳܐӢȜz;HPҩߟ^hkٟڧԢW^^nqq쮰ɭvzy7D@޹痛خHJ>zilTοȣĘþסϰHp?! OEQ2Zl%*D CII JMD% '>ɳ'Ot+JԪRDV"A|JJU!eC-[֠A4'V V]˶ ʔQLUZ$ -+,%+yռ5+&b!*. #2Ԗk<Bd+է')H]s!zѠ#TT Ÿ \9ViDK/sn ڵ+ z8zdb$ ,,DpJ >Vp:v Tn+M?b׿ gԒL7Ǝ6`2 Q\r, ^rtb+G $ZP3H86hc  hO+&LMp0BG刘XÄsM; g`lӎ)OL)h` }x$g d NCS1,M.#;: qTS©z~&X'|( B1nin&PB ,w\RB3*Ab¶ά`0 A|x!#IrW.fB8D`0 7`> l60 -+R # |ĻRRK-,.@8Ks7HPp hL/C ;|S, \J@^0 =QC&5/1VvD @ќ ? -+=0=G~"Jd[xm 5US! ,7D =| 1C6x(nB|*Mᆧ"!Ik,B+Ov݁Ag08?Km?LfJdL S0_,Ъ>PX -+ĥ'LO~:唑 eBiA,Ε?aKaWO*[(*G-`C8+TP0ZV: q&-,@MY>` 0 ۝$(5gD٪4<0G5!]0Ġ:"08P D>PX)UĀ @{ -+`uXwe`pu !w9Wɶf> Vǀ` -|XFטroi  !"MuP~oƚ5 } OL0&khnk}X -+ JP!D͸" -+@w `|wlوo tls{jmښ5igugLو&GPAř Z5H8v|EH"/,eG  Zz q@ -+` $ -+Pʉ Jn>#RzcPj?Z ` ZVpiC 500}z?i !| Z>==%X1k1 *=YFcT=SE `0((vN mQ;ziPYY+U1v fp0ԝ Н{P 0~ Q5`;|%μʵA ۻ{&ߪ0Xg Fc`NPό>IJR)Іhp@Q-0+sݚ 4f#L&,J -+0 t̆Z@1] [}K} @ -+in`*'` (geWf`0ˌ@g -+ uW͘ P,x- -+ƀWΓ[ˆ -b,i `?{  -+$p ix KA @`Гp݈ɻoSKPѱ=ؙjnDFS/dL$GG@, -+o FO4 -+ ߭4qݩݽ-4M00p -+,k p -+  -+ }0U02ߥ -+ -+Q_P˻Kr@m%fY  P =[Y՗  @ ; VJ@z, xݭ=^ބI,HC -+0 x PJNH*Pt q -+0j>\ڭ u -h *@Ϡ }XQ  -+@ 劮 _^ 6]i~ݞ;`p ,v P  -+R j 0^ h400uR "!`0 ^խuY @ 티 ޾ P߾z@8| -+y -+@5S~ > _nm{ -+n%  훀R H@8 L -+P[Dp'~`EɀV -+%P [ k  -+BLS? ^x! -+dPž_]0O%Udpp & -+jPP& y -+QY -+L0x]- _Qd =h S .> ppS@uk`bQ͏Ⱥyb6,\\ *eR#Y]PR叢:&}4)Dx>TPE- -+!kգ'iɱUp%!e&O -+J.3rϠTɲ̘4 F'OH FlSy@`ҭSh,W,DYDB`9I4FZ8[vK)WiIa Cpbő2m[Yٛg71& yȸE6TPcŴb)1*I^܊\;𞴌pk z FgyXt tl x .aDKJRJi7] Kd?"%21 4o>4@yF:nitx-MDeE1U|/1ы0jizܱBG ,)ďg&n@^|>>J!J`@`R\F9adH X N(>)Er9 "XÏ5@@MW 7Ƌ/@Xj֦HVXT -+f 5>‚qa|e@B -+)ָcK\c pj=E 9(bi|GtcU)=m8cYc>?ذd -+$\>PKreP& 45WL!v(`x?06W,=Qfy -+wB -+aM61 $`.ÎH`H vCjԏ^UjkX%k>f)= 0) X@fo^Jo-(e!ዖM߂{G%lܝayrH<#Lp e#H@EuBqtl/Ekd%]Gs#'>;LЂ(a 8d! w$;x `}R -+L~8 >f?# {8hD#d|%";XCB0~  ą1*l,5P_lYXyr*pz'b$|pEQ -+X@&mX0v` gFIr;F#$y-. -+Qz K(=/yUHMZ(>^s?sE0x84%{D@!KAtXk8 -+H }[)Bb>"G0*tPCE8hQ9xZ(Z# -+~H[Y2x`P?;@5BB*A0kF\2k4̃U}@7C@Z(\!W`x`opGxH:͢)Bp70#_a8CXd dDP;0/C(Gkdl`4 1Ss obX̃kFq?`TȪ8X -+--FILE-- -+ -+--EXPECTF-- -+Warning: imagecreatefromgif() [%s]: '%sbug38112.gif' is not a valid GIF file in %sbug38112.php on line %d -diff -Nura php-4.4.3/ext/imap/php_imap.c hardening-patch-4.4.3-0.4.15/ext/imap/php_imap.c ---- php-4.4.3/ext/imap/php_imap.c 2006-01-05 01:50:19.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/imap/php_imap.c 2006-09-05 20:30:44.000000000 +0200 -@@ -26,7 +26,7 @@ - | PHP 4.0 updates: Zeev Suraski | - +----------------------------------------------------------------------+ - */ --/* $Id: php_imap.c,v 1.142.2.44.2.4 2006/01/05 00:50:19 iliaa Exp $ */ -+/* $Id: php_imap.c,v 1.142.2.44.2.5 2006/08/04 20:32:44 iliaa Exp $ */ - - #define IMAP41 - -@@ -731,6 +731,13 @@ - efree(IMAPG(imap_password)); - } - -+ /* local filename, need to perform open_basedir and safe_mode checks */ -+ if (Z_STRVAL_PP(mailbox)[0] != '{' && -+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || -+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { -+ RETURN_FALSE; -+ } -+ - IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); - IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); - -diff -Nura php-4.4.3/ext/mbstring/mbstring.c hardening-patch-4.4.3-0.4.15/ext/mbstring/mbstring.c ---- php-4.4.3/ext/mbstring/mbstring.c 2006-04-03 15:04:13.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/mbstring/mbstring.c 2006-09-05 20:30:44.000000000 +0200 -@@ -1500,6 +1500,7 @@ - char *strtok_buf = NULL, **val_list; - zval *array_ptr = (zval *) arg; - int n, num, val_len, *len_list; -+ unsigned int new_val_len; - enum mbfl_no_encoding from_encoding; - mbfl_string string, resvar, resval; - mbfl_encoding_detector *identd = NULL; -@@ -1622,8 +1623,14 @@ - val_len = len_list[n]; - } - n++; -- /* add variable to symbol table */ -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ /* we need val to be emalloc()ed */ -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ /* add variable to symbol table */ -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); -+ - if (convd != NULL){ - mbfl_string_clear(&resvar); - mbfl_string_clear(&resval); -diff -Nura php-4.4.3/ext/mysql/php_mysql.c hardening-patch-4.4.3-0.4.15/ext/mysql/php_mysql.c ---- php-4.4.3/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:30:44.000000000 +0200 -@@ -1218,6 +1218,8 @@ - { - php_mysql_conn *mysql; - MYSQL_RES *mysql_result; -+ char *copy_query; -+ int i; - - ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); - -@@ -1268,6 +1270,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #else -@@ -1275,12 +1284,20 @@ - /* check possible error */ - if (MySG(trace_mode)){ - if (mysql_errno(&mysql->conn)){ -- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn)); -+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #endif -+ - if(use_store == MYSQL_USE_RESULT) { - mysql_result=mysql_use_result(&mysql->conn); - } else { -diff -Nura php-4.4.3/ext/pgsql/pgsql.c hardening-patch-4.4.3-0.4.15/ext/pgsql/pgsql.c ---- php-4.4.3/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:30:44.000000000 +0200 -@@ -1001,10 +1001,28 @@ - case PGRES_EMPTY_QUERY: - case PGRES_BAD_RESPONSE: - case PGRES_NONFATAL_ERROR: -- case PGRES_FATAL_ERROR: -- PHP_PQ_ERROR("Query failed: %s", pgsql); -- PQclear(pgsql_result); -- RETURN_FALSE; -+ case PGRES_FATAL_ERROR: -+ { -+#if HARDENING_PATCH -+ int i; -+ char *query_copy; -+#endif -+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); -+ PQclear(pgsql_result); -+#if HARDENING_PATCH -+ query_copy = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ efree(msgbuf); -+ zend_bailout(); -+ } -+#endif -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); -+ efree(msgbuf); -+ RETURN_FALSE; -+ } - break; - case PGRES_COMMAND_OK: /* successful command that did not return rows */ - default: -diff -Nura php-4.4.3/ext/session/mod_files.c hardening-patch-4.4.3-0.4.15/ext/session/mod_files.c ---- php-4.4.3/ext/session/mod_files.c 2006-04-18 01:29:37.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/session/mod_files.c 2006-09-05 20:30:44.000000000 +0200 -@@ -16,7 +16,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: mod_files.c,v 1.83.2.9.2.3 2006/04/17 23:29:37 iliaa Exp $ */ -+/* $Id: mod_files.c,v 1.83.2.9.2.4 2006/08/08 14:57:04 iliaa Exp $ */ - - #include "php.h" - -@@ -368,7 +368,12 @@ - ps_files_close(data); - - if (VCWD_UNLINK(buf) == -1) { -- return FAILURE; -+ /* This is a little safety check for instances when we are dealing with a regenerated session -+ * that was not yet written to disk -+ */ -+ if (!VCWD_ACCESS(buf, F_OK)) { -+ return FAILURE; -+ } - } - } - -@@ -391,6 +396,34 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(files) -+{ -+ char buf[MAXPATHLEN]; -+ int fd; -+ PS_FILES_DATA; -+ -+ if (!ps_files_valid_key(key)) { -+ return FAILURE; -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { -+ return FAILURE; -+ } -+ -+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600); -+ -+ if (fd != -1) { -+ close(fd); -+ return SUCCESS; -+ } -+ -+ return FAILURE; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-4.4.3/ext/session/mod_mm.c hardening-patch-4.4.3-0.4.15/ext/session/mod_mm.c ---- php-4.4.3/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/mod_mm.c 2006-09-05 20:30:44.000000000 +0200 -@@ -425,6 +425,42 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(mm) -+{ -+ PS_MM_DATA; -+ ps_sd *sd; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ } -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ mm_lock(data->mm, MM_LOCK_RD); -+ -+ sd = ps_sd_lookup(data, key, 0); -+ if (sd) { -+ mm_unlock(data->mm); -+ return SUCCESS; -+ } -+ -+ mm_unlock(data->mm); -+ -+ return FAILURE; -+} -+ - #endif - - /* -diff -Nura php-4.4.3/ext/session/mod_user.c hardening-patch-4.4.3-0.4.15/ext/session/mod_user.c ---- php-4.4.3/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/mod_user.c 2006-09-05 20:30:44.000000000 +0200 -@@ -23,7 +23,7 @@ - #include "mod_user.h" - - ps_module ps_mod_user = { -- PS_MOD(user) -+ PS_MOD_SID(user) - }; - - #define SESS_ZVAL_LONG(val, a) \ -@@ -174,6 +174,83 @@ - FINISH; - } - -+PS_CREATE_SID_FUNC(user) -+{ -+ int i; -+ char *val = NULL; -+ zval *retval; -+ ps_user *mdata = PS_GET_MOD_DATA(); -+ -+ if (!mdata) -+ return estrndup("", 0); -+ -+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { -+ return php_session_create_id(mod_data, newlen TSRMLS_CC); -+ } -+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); -+ -+ if (retval) { -+ if (Z_TYPE_P(retval) == IS_STRING) { -+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); -+ } else { -+ val = estrndup("", 0); -+ } -+ zval_ptr_dtor(&retval); -+ } else { -+ val = estrndup("", 0); -+ } -+ -+ return val; -+} -+ -+static int ps_user_valid_key(const char *key TSRMLS_DC) -+{ -+ size_t len; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ ret = FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ ret = FAILURE; -+ -+ return ret; -+} -+ -+PS_VALIDATE_SID_FUNC(user) -+{ -+ zval *args[1]; -+ STDVARS; -+ -+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { -+ return ps_user_valid_key(key TSRMLS_CC); -+ } -+ SESS_ZVAL_STRING(key, args[0]); -+ -+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); -+ -+ if (retval) { -+ convert_to_long(retval); -+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; -+ zval_ptr_dtor(&retval); -+ } -+ -+ return ret; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-4.4.3/ext/session/mod_user.h hardening-patch-4.4.3-0.4.15/ext/session/mod_user.h ---- php-4.4.3/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/mod_user.h 2006-09-05 20:30:44.000000000 +0200 -@@ -22,7 +22,7 @@ - #define MOD_USER_H - - typedef union { -- zval *names[6]; -+ zval *names[8]; - struct { - zval *ps_open; - zval *ps_close; -@@ -30,6 +30,8 @@ - zval *ps_write; - zval *ps_destroy; - zval *ps_gc; -+ zval *ps_create; -+ zval *ps_validate; - } name; - } ps_user; - -diff -Nura php-4.4.3/ext/session/php_session.h hardening-patch-4.4.3-0.4.15/ext/session/php_session.h ---- php-4.4.3/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/php_session.h 2006-09-05 20:30:44.000000000 +0200 -@@ -23,7 +23,7 @@ - - #include "ext/standard/php_var.h" - --#define PHP_SESSION_API 20020330 -+#define PHP_SESSION_API 20051121 - - #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC - #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC -@@ -32,6 +32,7 @@ - #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC - #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC - #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC -+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC - - /* default create id function */ - char *php_session_create_id(PS_CREATE_SID_ARGS); -@@ -45,6 +46,7 @@ - int (*s_destroy)(PS_DESTROY_ARGS); - int (*s_gc)(PS_GC_ARGS); - char *(*s_create_sid)(PS_CREATE_SID_ARGS); -+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); - } ps_module; - - #define PS_GET_MOD_DATA() *mod_data -@@ -57,6 +59,7 @@ - #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) - #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) - #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) -+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) - - #define PS_FUNCS(x) \ - PS_OPEN_FUNC(x); \ -@@ -65,11 +68,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID_FUNC(x) - - #define PS_MOD(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, php_session_create_id -+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x - - /* SID enabled module handler definitions */ - #define PS_FUNCS_SID(x) \ -@@ -79,11 +83,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID(x) - - #define PS_MOD_SID(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, ps_create_sid_##x -+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x - - typedef enum { - php_session_disabled, -@@ -120,6 +125,7 @@ - zend_bool use_only_cookies; - zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ - zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ -+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ - int send_cookie; - int define_sid; - } php_ps_globals; -diff -Nura php-4.4.3/ext/session/session.c hardening-patch-4.4.3-0.4.15/ext/session/session.c ---- php-4.4.3/ext/session/session.c 2006-05-19 00:16:27.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/session/session.c 2006-09-05 20:30:44.000000000 +0200 -@@ -17,7 +17,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: session.c,v 1.336.2.53.2.6 2006/05/18 22:16:27 helly Exp $ */ -+/* $Id: session.c,v 1.336.2.53.2.7 2006/08/01 08:33:13 tony2001 Exp $ */ - - #ifdef HAVE_CONFIG_H - #include "config.h" -@@ -155,6 +155,7 @@ - STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) -+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals) -@@ -643,6 +644,15 @@ - return; - } - -+ /* If there is an ID, use session module to verify it */ -+ if (PS(id)) { -+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ efree(PS(id)); -+ PS(id) = NULL; -+ PS(send_cookie) = 1; -+ } -+ } -+ - /* If there is no ID, use session module to create one */ - if (!PS(id)) - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); -@@ -1262,22 +1272,31 @@ - } - /* }}} */ - --/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) -+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) - Sets user-level functions */ - PHP_FUNCTION(session_set_save_handler) - { -- zval **args[6]; -- int i; -+ zval **args[8]; -+ int i, numargs; - ps_user *mdata; - char *name; - -+ numargs = ZEND_NUM_ARGS(); -+ args[6] = NULL; -+ args[7] = NULL; -+ -+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) -+ WRONG_PARAM_COUNT; - if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) - WRONG_PARAM_COUNT; - - if (PS(session_status) != php_session_none) - RETURN_FALSE; - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ continue; -+ } - if (!zend_is_callable(*args[i], 0, &name)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); - efree(name); -@@ -1290,7 +1309,11 @@ - - mdata = emalloc(sizeof(*mdata)); - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ mdata->names[i] = NULL; -+ continue; -+ } - ZVAL_ADDREF(*args[i]); - mdata->names[i] = *args[i]; - } -@@ -1351,12 +1374,25 @@ - Update the current session id with a newly generated one. */ - PHP_FUNCTION(session_regenerate_id) - { -+ zend_bool del_ses = 0; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) { -+ WRONG_PARAM_COUNT; -+ } -+ - if (SG(headers_sent)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); - RETURN_FALSE; - } -- if (PS(session_status) == php_session_active) { -- if (PS(id)) efree(PS(id)); -+ -+ if (PS(session_status) == php_session_active) { -+ if (PS(id)) { -+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed"); -+ RETURN_FALSE; -+ } -+ efree(PS(id)); -+ } - - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); - -@@ -1405,8 +1441,8 @@ - WRONG_PARAM_COUNT; - - if (ac == 1) { -- convert_to_long_ex(p_cache_expire); -- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); -+ convert_to_string_ex(p_cache_expire); -+ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - } - - RETVAL_LONG(old); -diff -Nura php-4.4.3/ext/session/tests/014.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/014.phpt ---- php-4.4.3/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:30:44.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.bug_compat_42=1 -diff -Nura php-4.4.3/ext/session/tests/015.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/015.phpt ---- php-4.4.3/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:30:44.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - arg_separator.output=& - session.name=PHPSESSID -diff -Nura php-4.4.3/ext/session/tests/018.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/018.phpt ---- php-4.4.3/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:30:44.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - session.name=PHPSESSID -diff -Nura php-4.4.3/ext/session/tests/020.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/020.phpt ---- php-4.4.3/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:30:44.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - arg_separator.output=& -diff -Nura php-4.4.3/ext/session/tests/021.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/021.phpt ---- php-4.4.3/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:30:44.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" -diff -Nura php-4.4.3/ext/session/tests/bug38377.phpt hardening-patch-4.4.3-0.4.15/ext/session/tests/bug38377.phpt ---- php-4.4.3/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:30:44.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+bug #38377 (session_destroy() gives warning after session_regenerate_id()) -+--SKIPIF-- -+ -+--FILE-- -+ -+--EXPECT-- -+Done -diff -Nura php-4.4.3/ext/sockets/sockets.c hardening-patch-4.4.3-0.4.15/ext/sockets/sockets.c ---- php-4.4.3/ext/sockets/sockets.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/sockets/sockets.c 2006-09-05 20:30:44.000000000 +0200 -@@ -19,7 +19,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: sockets.c,v 1.125.2.29.2.3 2006/01/01 13:46:56 sniper Exp $ */ -+/* $Id: sockets.c,v 1.125.2.29.2.6 2006/08/01 12:04:14 tony2001 Exp $ */ - - #ifdef HAVE_CONFIG_H - #include "config.h" -@@ -515,6 +515,7 @@ - int php_sock_array_to_fd_set(zval *sock_array, fd_set *fds, SOCKET *max_fd TSRMLS_DC) { - zval **element; - php_socket *php_sock; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -529,9 +530,10 @@ - if (php_sock->bsd_socket > *max_fd) { - *max_fd = php_sock->bsd_socket; - } -+ num++; - } - -- return 1; -+ return num ? 1 : 0; - } - - int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) { -@@ -539,6 +541,8 @@ - zval **dest_element; - php_socket *php_sock; - HashTable *new_hash; -+ int num = 0; -+ - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - - ALLOC_HASHTABLE(new_hash); -@@ -555,6 +559,7 @@ - zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); - if (dest_element) zval_add_ref(dest_element); - } -+ num++; - } - - /* Destroy old array, add new one */ -@@ -564,7 +569,7 @@ - zend_hash_internal_pointer_reset(new_hash); - Z_ARRVAL_P(sock_array) = new_hash; - -- return 1; -+ return num ? 1 : 0; - } - - -diff -Nura php-4.4.3/ext/standard/array.c hardening-patch-4.4.3-0.4.15/ext/standard/array.c ---- php-4.4.3/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/array.c 2006-09-05 20:30:44.000000000 +0200 -@@ -1162,6 +1162,32 @@ - } - } - } -+ -+ if (var_name[0] == 'H') { -+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_FILES")==0)|| -+ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { -+ return 0; -+ } -+ } else if (var_name[0] == '_') { -+ if ((strcmp(var_name, "_COOKIE")==0)|| -+ (strcmp(var_name, "_ENV")==0)|| -+ (strcmp(var_name, "_FILES")==0)|| -+ (strcmp(var_name, "_GET")==0)|| -+ (strcmp(var_name, "_POST")==0)|| -+ (strcmp(var_name, "_REQUEST")==0)|| -+ (strcmp(var_name, "_SESSION")==0)|| -+ (strcmp(var_name, "_SERVER")==0)) { -+ return 0; -+ } -+ } else if (strcmp(var_name, "GLOBALS")==0) { -+ return 0; -+ } - - return 1; - } -diff -Nura php-4.4.3/ext/standard/basic_functions.c hardening-patch-4.4.3-0.4.15/ext/standard/basic_functions.c ---- php-4.4.3/ext/standard/basic_functions.c 2006-06-29 00:09:09.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:35:02.000000000 +0200 -@@ -107,12 +107,14 @@ - typedef struct _php_shutdown_function_entry { - zval **arguments; - int arg_count; -+ zend_bool created_by_eval; - } php_shutdown_function_entry; - - typedef struct _user_tick_function_entry { - zval **arguments; - int arg_count; - int calling; -+ zend_bool created_by_eval; - } user_tick_function_entry; - - /* some prototypes for local functions */ -@@ -295,6 +297,8 @@ - PHP_FE(get_html_translation_table, NULL) - PHP_FE(sha1, NULL) - PHP_FE(sha1_file, NULL) -+ PHP_FE(sha256, NULL) -+ PHP_FE(sha256_file, NULL) - PHP_NAMED_FE(md5,php_if_md5, NULL) - PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) - PHP_NAMED_FE(crc32,php_if_crc32, NULL) -@@ -676,7 +680,7 @@ - PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) - - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) -- PHP_FE(realpath, NULL) -+ PHP_STATIC_FE("realpath", zif_real_path, NULL) - #endif - - #ifdef HAVE_FNMATCH -@@ -2101,6 +2105,13 @@ - { - zval retval; - char *function_name = NULL; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (shutdown_function_entry->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { - php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); -@@ -2116,6 +2127,9 @@ - if (function_name) { - efree(function_name); - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - return 0; - } - -@@ -2123,6 +2137,13 @@ - { - zval retval; - zval *function = tick_fe->arguments[0]; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (tick_fe->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - /* Prevent reentrant calls to the same user ticks function */ - if (! tick_fe->calling) { -@@ -2154,6 +2175,9 @@ - - tick_fe->calling = 0; - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - } - - static void run_user_tick_functions(int tick_count) -@@ -2222,6 +2246,13 @@ - efree(shutdown_function_entry.arguments); - RETURN_FALSE; - } -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ shutdown_function_entry.created_by_eval = 1; -+ } else { -+ shutdown_function_entry.created_by_eval = 0; -+ } -+#endif - - /* Prevent entering of anything but valid callback (syntax check only!) */ - if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { -@@ -2503,6 +2534,15 @@ - - convert_to_string_ex(varname); - -+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ -+ if (PG(safe_mode)) { -+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || -+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || -+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { -+ RETURN_FALSE; -+ } -+ } -+ - zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); - } - /* }}} */ -@@ -2759,6 +2799,13 @@ - } - - tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ tick_fe.created_by_eval = 1; -+ } else { -+ tick_fe.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { - efree(tick_fe.arguments); -@@ -3057,6 +3104,35 @@ - new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); - } - -+ if (new_key[0] == 'H') { -+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_FILES")==0)|| -+ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (new_key[0] == '_') { -+ if ((strcmp(new_key, "_COOKIE")==0)|| -+ (strcmp(new_key, "_ENV")==0)|| -+ (strcmp(new_key, "_FILES")==0)|| -+ (strcmp(new_key, "_GET")==0)|| -+ (strcmp(new_key, "_POST")==0)|| -+ (strcmp(new_key, "_REQUEST")==0)|| -+ (strcmp(new_key, "_SESSION")==0)|| -+ (strcmp(new_key, "_SERVER")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (strcmp(new_key, "GLOBALS")==0) { -+ efree(new_key); -+ return 0; -+ } -+ - zend_hash_del(&EG(symbol_table), new_key, new_key_len); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); - -diff -Nura php-4.4.3/ext/standard/config.m4 hardening-patch-4.4.3-0.4.15/ext/standard/config.m4 ---- php-4.4.3/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/config.m4 2006-09-05 20:30:45.000000000 +0200 -@@ -203,7 +203,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) - ]) -@@ -419,6 +419,6 @@ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ -- var_unserializer.c ftok.c aggregation.c sha1.c ) -+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ) - - PHP_ADD_MAKEFILE_FRAGMENT -diff -Nura php-4.4.3/ext/standard/crypt_blowfish.c hardening-patch-4.4.3-0.4.15/ext/standard/crypt_blowfish.c ---- php-4.4.3/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,748 @@ -+/* -+ * This code comes from John the Ripper password cracker, with reentrant -+ * and crypt(3) interfaces added, but optimizations specific to password -+ * cracking removed. -+ * -+ * Written by Solar Designer in 1998-2002 and -+ * placed in the public domain. -+ * -+ * There's absolutely no warranty. -+ * -+ * It is my intent that you should be able to use this on your system, -+ * as a part of a software package, or anywhere else to improve security, -+ * ensure compatibility, or for any other purpose. I would appreciate -+ * it if you give credit where it is due and keep your modifications in -+ * the public domain as well, but I don't require that in order to let -+ * you place this code and any modifications you make under a license -+ * of your choice. -+ * -+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) -+ * by Niels Provos , and uses some of his -+ * ideas. The password hashing algorithm was designed by David Mazieres -+ * . -+ * -+ * There's a paper on the algorithm that explains its design decisions: -+ * -+ * http://www.usenix.org/events/usenix99/provos.html -+ * -+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's -+ * Blowfish library (I can't be sure if I would think of something if I -+ * hadn't seen his code). -+ */ -+ -+#include -+ -+#include -+#ifndef __set_errno -+#define __set_errno(val) errno = (val) -+#endif -+ -+#undef __CONST -+#ifdef __GNUC__ -+#define __CONST __const -+#else -+#define __CONST -+#endif -+ -+#ifdef __i386__ -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#elif defined(__alpha__) || defined(__hppa__) -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#else -+#define BF_ASM 0 -+#define BF_SCALE 0 -+#endif -+ -+typedef unsigned int BF_word; -+ -+/* Number of Blowfish rounds, this is also hardcoded into a few places */ -+#define BF_N 16 -+ -+typedef BF_word BF_key[BF_N + 2]; -+ -+typedef struct { -+ BF_word S[4][0x100]; -+ BF_key P; -+} BF_ctx; -+ -+/* -+ * Magic IV for 64 Blowfish encryptions that we do at the end. -+ * The string is "OrpheanBeholderScryDoubt" on big-endian. -+ */ -+static BF_word BF_magic_w[6] = { -+ 0x4F727068, 0x65616E42, 0x65686F6C, -+ 0x64657253, 0x63727944, 0x6F756274 -+}; -+ -+/* -+ * P-box and S-box tables initialized with digits of Pi. -+ */ -+static BF_ctx BF_init_state = { -+ { -+ { -+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, -+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, -+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, -+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, -+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, -+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, -+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, -+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, -+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, -+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, -+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, -+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, -+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, -+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, -+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, -+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, -+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, -+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, -+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, -+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, -+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, -+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, -+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, -+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, -+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, -+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, -+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, -+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, -+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, -+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, -+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, -+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, -+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, -+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, -+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, -+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, -+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, -+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, -+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, -+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, -+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, -+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, -+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, -+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, -+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, -+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, -+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, -+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, -+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, -+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, -+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, -+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, -+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, -+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, -+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, -+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, -+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, -+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, -+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, -+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, -+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, -+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, -+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, -+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a -+ }, { -+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, -+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, -+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, -+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, -+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, -+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, -+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, -+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, -+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, -+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, -+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, -+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, -+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, -+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, -+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, -+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, -+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, -+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, -+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, -+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, -+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, -+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, -+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, -+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, -+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, -+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, -+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, -+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, -+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, -+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, -+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, -+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, -+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, -+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, -+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, -+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, -+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, -+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, -+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, -+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, -+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, -+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, -+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, -+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, -+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, -+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, -+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, -+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, -+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, -+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, -+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, -+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, -+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, -+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, -+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, -+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, -+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, -+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, -+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, -+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, -+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, -+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, -+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, -+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 -+ }, { -+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, -+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, -+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, -+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, -+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, -+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, -+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, -+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, -+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, -+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, -+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, -+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, -+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, -+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, -+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, -+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, -+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, -+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, -+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, -+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, -+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, -+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, -+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, -+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, -+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, -+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, -+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, -+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, -+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, -+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, -+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, -+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, -+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, -+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, -+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, -+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, -+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, -+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, -+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, -+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, -+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, -+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, -+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, -+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, -+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, -+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, -+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, -+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, -+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, -+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, -+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, -+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, -+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, -+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, -+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, -+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, -+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, -+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, -+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, -+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, -+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, -+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, -+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, -+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 -+ }, { -+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, -+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, -+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, -+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, -+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, -+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, -+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, -+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, -+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, -+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, -+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, -+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, -+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, -+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, -+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, -+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, -+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, -+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, -+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, -+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, -+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, -+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, -+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, -+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, -+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, -+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, -+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, -+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, -+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, -+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, -+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, -+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, -+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, -+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, -+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, -+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, -+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, -+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, -+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, -+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, -+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, -+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, -+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, -+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, -+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, -+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, -+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, -+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, -+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, -+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, -+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, -+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, -+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, -+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, -+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, -+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, -+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, -+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, -+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, -+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, -+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, -+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, -+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, -+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 -+ } -+ }, { -+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, -+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, -+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, -+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, -+ 0x9216d5d9, 0x8979fb1b -+ } -+}; -+ -+static unsigned char BF_itoa64[64 + 1] = -+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -+ -+static unsigned char BF_atoi64[0x60] = { -+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, -+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, -+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, -+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, -+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -+}; -+ -+/* -+ * This may be optimized out if built with function inlining and no BF_ASM. -+ */ -+static void clean(void *data, int size) -+{ -+#if BF_ASM -+ extern void _BF_clean(void *data); -+#endif -+ memset(data, 0, size); -+#if BF_ASM -+ _BF_clean(data); -+#endif -+} -+ -+#define BF_safe_atoi64(dst, src) \ -+{ \ -+ tmp = (unsigned char)(src); \ -+ if (tmp == '$') break; \ -+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ -+ tmp = BF_atoi64[tmp]; \ -+ if (tmp > 63) return -1; \ -+ (dst) = tmp; \ -+} -+ -+static int BF_decode(BF_word *dst, __CONST char *src, int size) -+{ -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned char *end = dptr + size; -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned int tmp, c1, c2, c3, c4; -+ -+ do { -+ BF_safe_atoi64(c1, *sptr++); -+ BF_safe_atoi64(c2, *sptr++); -+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c3, *sptr++); -+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c4, *sptr++); -+ *dptr++ = ((c3 & 0x03) << 6) | c4; -+ } while (dptr < end); -+ -+ while (dptr < end) -+ *dptr++ = 0; -+ -+ return 0; -+} -+ -+static void BF_encode(char *dst, __CONST BF_word *src, int size) -+{ -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned char *end = sptr + size; -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned int c1, c2; -+ -+ do { -+ c1 = *sptr++; -+ *dptr++ = BF_itoa64[c1 >> 2]; -+ c1 = (c1 & 0x03) << 4; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 4; -+ *dptr++ = BF_itoa64[c1]; -+ c1 = (c2 & 0x0f) << 2; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 6; -+ *dptr++ = BF_itoa64[c1]; -+ *dptr++ = BF_itoa64[c2 & 0x3f]; -+ } while (sptr < end); -+} -+ -+static void BF_swap(BF_word *x, int count) -+{ -+ static int endianness_check = 1; -+ char *is_little_endian = (char *)&endianness_check; -+ BF_word tmp; -+ -+ if (*is_little_endian) -+ do { -+ tmp = *x; -+ tmp = (tmp << 16) | (tmp >> 16); -+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); -+ } while (--count); -+} -+ -+#if BF_SCALE -+/* Architectures which can shift addresses left by 2 bits with no extra cost */ -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp2 = L >> 8; \ -+ tmp2 &= 0xFF; \ -+ tmp3 = L >> 16; \ -+ tmp3 &= 0xFF; \ -+ tmp4 = L >> 24; \ -+ tmp1 = data.ctx.S[3][tmp1]; \ -+ tmp2 = data.ctx.S[2][tmp2]; \ -+ tmp3 = data.ctx.S[1][tmp3]; \ -+ tmp3 += data.ctx.S[0][tmp4]; \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#else -+/* Architectures with no complicated addressing modes supported */ -+#define BF_INDEX(S, i) \ -+ (*((BF_word *)(((unsigned char *)S) + (i)))) -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp1 <<= 2; \ -+ tmp2 = L >> 6; \ -+ tmp2 &= 0x3FC; \ -+ tmp3 = L >> 14; \ -+ tmp3 &= 0x3FC; \ -+ tmp4 = L >> 22; \ -+ tmp4 &= 0x3FC; \ -+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ -+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ -+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ -+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#endif -+ -+/* -+ * Encrypt one block, BF_N is hardcoded here. -+ */ -+#define BF_ENCRYPT \ -+ L ^= data.ctx.P[0]; \ -+ BF_ROUND(L, R, 0); \ -+ BF_ROUND(R, L, 1); \ -+ BF_ROUND(L, R, 2); \ -+ BF_ROUND(R, L, 3); \ -+ BF_ROUND(L, R, 4); \ -+ BF_ROUND(R, L, 5); \ -+ BF_ROUND(L, R, 6); \ -+ BF_ROUND(R, L, 7); \ -+ BF_ROUND(L, R, 8); \ -+ BF_ROUND(R, L, 9); \ -+ BF_ROUND(L, R, 10); \ -+ BF_ROUND(R, L, 11); \ -+ BF_ROUND(L, R, 12); \ -+ BF_ROUND(R, L, 13); \ -+ BF_ROUND(L, R, 14); \ -+ BF_ROUND(R, L, 15); \ -+ tmp4 = R; \ -+ R = L; \ -+ L = tmp4 ^ data.ctx.P[BF_N + 1]; -+ -+#if BF_ASM -+#define BF_body() \ -+ _BF_body_r(&data.ctx); -+#else -+#define BF_body() \ -+ L = R = 0; \ -+ ptr = data.ctx.P; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.P[BF_N + 2]); \ -+\ -+ ptr = data.ctx.S[0]; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.S[3][0xFF]); -+#endif -+ -+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) -+{ -+ __CONST char *ptr = key; -+ int i, j; -+ BF_word tmp; -+ -+ for (i = 0; i < BF_N + 2; i++) { -+ tmp = 0; -+ for (j = 0; j < 4; j++) { -+ tmp <<= 8; -+ tmp |= *ptr; -+ -+ if (!*ptr) ptr = key; else ptr++; -+ } -+ -+ expanded[i] = tmp; -+ initial[i] = BF_init_state.P[i] ^ tmp; -+ } -+} -+ -+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, -+ char *output, int size) -+{ -+#if BF_ASM -+ extern void _BF_body_r(BF_ctx *ctx); -+#endif -+ struct { -+ BF_ctx ctx; -+ BF_key expanded_key; -+ union { -+ BF_word salt[4]; -+ BF_word output[6]; -+ } binary; -+ } data; -+ BF_word L, R; -+ BF_word tmp1, tmp2, tmp3, tmp4; -+ BF_word *ptr; -+ BF_word count; -+ int i; -+ -+ if (size < 7 + 22 + 31 + 1) { -+ __set_errno(ERANGE); -+ return NULL; -+ } -+ -+ if (setting[0] != '$' || -+ setting[1] != '2' || -+ setting[2] != 'a' || -+ setting[3] != '$' || -+ setting[4] < '0' || setting[4] > '3' || -+ setting[5] < '0' || setting[5] > '9' || -+ setting[6] != '$') { -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); -+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { -+ clean(data.binary.salt, sizeof(data.binary.salt)); -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ BF_swap(data.binary.salt, 4); -+ -+ BF_set_key(key, data.expanded_key, data.ctx.P); -+ -+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); -+ -+ L = R = 0; -+ for (i = 0; i < BF_N + 2; i += 2) { -+ L ^= data.binary.salt[i & 2]; -+ R ^= data.binary.salt[(i & 2) + 1]; -+ BF_ENCRYPT; -+ data.ctx.P[i] = L; -+ data.ctx.P[i + 1] = R; -+ } -+ -+ ptr = data.ctx.S[0]; -+ do { -+ ptr += 4; -+ L ^= data.binary.salt[(BF_N + 2) & 3]; -+ R ^= data.binary.salt[(BF_N + 3) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 4) = L; -+ *(ptr - 3) = R; -+ -+ L ^= data.binary.salt[(BF_N + 4) & 3]; -+ R ^= data.binary.salt[(BF_N + 5) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 2) = L; -+ *(ptr - 1) = R; -+ } while (ptr < &data.ctx.S[3][0xFF]); -+ -+ do { -+ data.ctx.P[0] ^= data.expanded_key[0]; -+ data.ctx.P[1] ^= data.expanded_key[1]; -+ data.ctx.P[2] ^= data.expanded_key[2]; -+ data.ctx.P[3] ^= data.expanded_key[3]; -+ data.ctx.P[4] ^= data.expanded_key[4]; -+ data.ctx.P[5] ^= data.expanded_key[5]; -+ data.ctx.P[6] ^= data.expanded_key[6]; -+ data.ctx.P[7] ^= data.expanded_key[7]; -+ data.ctx.P[8] ^= data.expanded_key[8]; -+ data.ctx.P[9] ^= data.expanded_key[9]; -+ data.ctx.P[10] ^= data.expanded_key[10]; -+ data.ctx.P[11] ^= data.expanded_key[11]; -+ data.ctx.P[12] ^= data.expanded_key[12]; -+ data.ctx.P[13] ^= data.expanded_key[13]; -+ data.ctx.P[14] ^= data.expanded_key[14]; -+ data.ctx.P[15] ^= data.expanded_key[15]; -+ data.ctx.P[16] ^= data.expanded_key[16]; -+ data.ctx.P[17] ^= data.expanded_key[17]; -+ -+ BF_body(); -+ -+ tmp1 = data.binary.salt[0]; -+ tmp2 = data.binary.salt[1]; -+ tmp3 = data.binary.salt[2]; -+ tmp4 = data.binary.salt[3]; -+ data.ctx.P[0] ^= tmp1; -+ data.ctx.P[1] ^= tmp2; -+ data.ctx.P[2] ^= tmp3; -+ data.ctx.P[3] ^= tmp4; -+ data.ctx.P[4] ^= tmp1; -+ data.ctx.P[5] ^= tmp2; -+ data.ctx.P[6] ^= tmp3; -+ data.ctx.P[7] ^= tmp4; -+ data.ctx.P[8] ^= tmp1; -+ data.ctx.P[9] ^= tmp2; -+ data.ctx.P[10] ^= tmp3; -+ data.ctx.P[11] ^= tmp4; -+ data.ctx.P[12] ^= tmp1; -+ data.ctx.P[13] ^= tmp2; -+ data.ctx.P[14] ^= tmp3; -+ data.ctx.P[15] ^= tmp4; -+ data.ctx.P[16] ^= tmp1; -+ data.ctx.P[17] ^= tmp2; -+ -+ BF_body(); -+ } while (--count); -+ -+ for (i = 0; i < 6; i += 2) { -+ L = BF_magic_w[i]; -+ R = BF_magic_w[i + 1]; -+ -+ count = 64; -+ do { -+ BF_ENCRYPT; -+ } while (--count); -+ -+ data.binary.output[i] = L; -+ data.binary.output[i + 1] = R; -+ } -+ -+ memcpy(output, setting, 7 + 22 - 1); -+ output[7 + 22 - 1] = BF_itoa64[(int) -+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; -+ -+/* This has to be bug-compatible with the original implementation, so -+ * only encode 23 of the 24 bytes. :-) */ -+ BF_swap(data.binary.output, 6); -+ BF_encode(&output[7 + 22], data.binary.output, 23); -+ output[7 + 22 + 31] = '\0'; -+ -+/* Overwrite the most obvious sensitive data we have on the stack. Note -+ * that this does not guarantee there's no sensitive data left on the -+ * stack and/or in registers; I'm not aware of portable code that does. */ -+ clean(&data, sizeof(data)); -+ -+ return output; -+} -+ -+char *_crypt_gensalt_blowfish_rn(unsigned long count, -+ __CONST char *input, int size, char *output, int output_size) -+{ -+ if (size < 16 || output_size < 7 + 22 + 1 || -+ (count && (count < 4 || count > 31))) { -+ if (output_size > 0) output[0] = '\0'; -+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); -+ return NULL; -+ } -+ -+ if (!count) count = 5; -+ -+ output[0] = '$'; -+ output[1] = '2'; -+ output[2] = 'a'; -+ output[3] = '$'; -+ output[4] = '0' + count / 10; -+ output[5] = '0' + count % 10; -+ output[6] = '$'; -+ -+ BF_encode(&output[7], (BF_word *)input, 16); -+ output[7 + 22] = '\0'; -+ -+ return output; -+} -diff -Nura php-4.4.3/ext/standard/crypt.c hardening-patch-4.4.3-0.4.15/ext/standard/crypt.c ---- php-4.4.3/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/crypt.c 2006-09-05 20:30:45.000000000 +0200 -@@ -100,6 +100,8 @@ - return SUCCESS; - } - -+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); -+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); - - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -@@ -135,7 +137,14 @@ - - /* The automatic salt generation only covers standard DES and md5-crypt */ - if(!*salt) { --#if PHP_MD5_CRYPT -+#if PHP_BLOWFISH_CRYPT -+ char randat[16]; -+ int i; -+ -+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; -+ -+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); -+#elif PHP_MD5_CRYPT - strcpy(salt, "$1$"); - php_to64(&salt[3], PHP_CRYPT_RAND, 4); - php_to64(&salt[7], PHP_CRYPT_RAND, 4); -@@ -145,8 +154,24 @@ - salt[2] = '\0'; - #endif - } -- -- RETVAL_STRING(crypt(str, salt), 1); -+ -+ if (salt[0] == '$' && -+ salt[1] == '2' && -+ salt[2] == 'a' && -+ salt[3] == '$' && -+ salt[4] >= '0' && salt[4] <= '3' && -+ salt[5] >= '0' && salt[5] <= '9' && -+ salt[6] == '$') { -+ -+ char output[PHP_MAX_SALT_LEN+1]; -+ -+ output[0] = 0; -+ _crypt_blowfish_rn(str, salt, output, sizeof(output)); -+ RETVAL_STRING(output, 1); -+ -+ } else { -+ RETVAL_STRING(crypt(str, salt), 1); -+ } - } - /* }}} */ - #endif -diff -Nura php-4.4.3/ext/standard/dl.c hardening-patch-4.4.3-0.4.15/ext/standard/dl.c ---- php-4.4.3/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/dl.c 2006-09-05 20:30:45.000000000 +0200 -@@ -160,8 +160,35 @@ - RETURN_FALSE; - } - module_entry = get_module(); -+ -+ /* check if Hardening-Patch is installed */ -+ if (module_entry->zend_api < 1000000000) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ -+ /* check if correct Hardening-Patch is installed */ -+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ - if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) -- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { -+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { - /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ - struct pre_4_1_0_module_entry { - char *name; -@@ -195,7 +222,7 @@ - zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; - } else { - name = module_entry->name; -- zend_api = module_entry->zend_api; -+ zend_api = module_entry->real_zend_api; - zend_debug = module_entry->zend_debug; - zts = module_entry->zts; - } -diff -Nura php-4.4.3/ext/standard/file.c hardening-patch-4.4.3-0.4.15/ext/standard/file.c ---- php-4.4.3/ext/standard/file.c 2006-04-14 19:46:59.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/file.c 2006-09-05 20:30:45.000000000 +0200 -@@ -2527,7 +2527,7 @@ - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) - /* {{{ proto string realpath(string path) - Return the resolved path */ --PHP_FUNCTION(realpath) -+PHP_FUNCTION(real_path) - { - zval **path; - char resolved_path_buff[MAXPATHLEN]; -diff -Nura php-4.4.3/ext/standard/file.h hardening-patch-4.4.3-0.4.15/ext/standard/file.h ---- php-4.4.3/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/file.h 2006-09-05 20:30:45.000000000 +0200 -@@ -64,7 +64,7 @@ - PHP_FUNCTION(fd_set); - PHP_FUNCTION(fd_isset); - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) --PHP_FUNCTION(realpath); -+PHP_FUNCTION(real_path); - #endif - #ifdef HAVE_FNMATCH - PHP_FUNCTION(fnmatch); -diff -Nura php-4.4.3/ext/standard/head.c hardening-patch-4.4.3-0.4.15/ext/standard/head.c ---- php-4.4.3/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/head.c 2006-09-05 20:30:45.000000000 +0200 -@@ -44,7 +44,7 @@ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, - &ctr.line_len, &rep, &ctr.response_code) == FAILURE) - return; -- -+ - sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); - } - /* }}} */ -diff -Nura php-4.4.3/ext/standard/mail.c hardening-patch-4.4.3-0.4.15/ext/standard/mail.c ---- php-4.4.3/ext/standard/mail.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/mail.c 2006-09-05 20:30:45.000000000 +0200 -@@ -78,6 +78,25 @@ - } - /* }}} */ - -+/* {{{ hphp_strcasestr */ -+char *hphp_strcasestr(char *haystack, char *needle) -+{ -+ unsigned char *t, *h, *n; -+ -+ h = (unsigned char *) haystack; -+conts: -+ while (*h) { -+ n = (unsigned char *) needle; -+ for (t=h++; *n && *h; t++, n++) { -+ if (toupper(*t) != toupper(*n)) goto conts; -+ } -+ return ((char*)h-1); -+ } -+ -+ return (NULL); -+} -+/* }}} */ -+ - /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) - Send an email message */ - PHP_FUNCTION(mail) -@@ -103,6 +122,44 @@ - return; - } - -+ if (HG(hphp_mailprotect) > 0) { -+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { -+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ /* check for spam attempts with buggy webforms */ -+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (HG(hphp_mailprotect) > 1) { -+ /* search for to, cc or bcc headers */ -+ if (headers_len > 0 && headers != NULL) { -+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { -+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { -+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { -+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ } -+ } -+ } -+ - if (to_len > 0) { - to_r = estrndup(to, to_len); - for (; to_len; to_len--) { -diff -Nura php-4.4.3/ext/standard/php_standard.h hardening-patch-4.4.3-0.4.15/ext/standard/php_standard.h ---- php-4.4.3/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/php_standard.h 2006-09-05 20:30:45.000000000 +0200 -@@ -28,6 +28,7 @@ - #include "php_mail.h" - #include "md5.h" - #include "sha1.h" -+#include "sha256.h" - #include "html.h" - #include "exec.h" - #include "file.h" -diff -Nura php-4.4.3/ext/standard/scanf.c hardening-patch-4.4.3-0.4.15/ext/standard/scanf.c ---- php-4.4.3/ext/standard/scanf.c 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/scanf.c 2006-09-05 20:30:45.000000000 +0200 -@@ -16,7 +16,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: scanf.c,v 1.16.4.9.2.1 2006/01/01 13:46:58 sniper Exp $ */ -+/* $Id: scanf.c,v 1.16.4.9.2.2 2006/08/04 11:59:50 tony2001 Exp $ */ - - /* - scanf.c -- -@@ -732,7 +732,7 @@ - if (*end == '$') { - format = end+1; - ch = format++; -- objIndex = varStart + value; -+ objIndex = varStart + value - 1; - } - } - -@@ -762,8 +762,10 @@ - switch (*ch) { - case 'n': - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -- current = args[objIndex++]; -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { -+ current = args[objIndex++]; - zval_dtor( *current ); - ZVAL_LONG( *current, (long)(string - baseString) ); - } else { -@@ -883,8 +885,10 @@ - } - } - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -- current = args[objIndex++]; -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { -+ current = args[objIndex++]; - zval_dtor( *current ); - ZVAL_STRINGL( *current, string, end-string, 1); - } else { -@@ -922,7 +926,9 @@ - goto done; - } - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - zval_dtor( *current ); - ZVAL_STRINGL( *current, string, end-string, 1); -@@ -1079,8 +1085,10 @@ - value = (int) (*fn)(buf, NULL, base); - if ((flags & SCAN_UNSIGNED) && (value < 0)) { - sprintf(buf, "%u", value); /* INTL: ISO digit */ -- if (numVars) { -- /* change passed value type to string */ -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { -+ /* change passed value type to string */ - current = args[objIndex++]; - convert_to_string( *current ); - ZVAL_STRING( *current, buf, 1 ); -@@ -1088,7 +1096,9 @@ - add_index_string(*return_value, objIndex++, buf, 1); - } - } else { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - convert_to_long( *current ); - Z_LVAL(**current) = value; -@@ -1196,7 +1206,9 @@ - double dvalue; - *end = '\0'; - dvalue = zend_strtod(buf, NULL); -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - convert_to_double( *current ); - Z_DVAL_PP( current ) = dvalue; -diff -Nura php-4.4.3/ext/standard/sha256.c hardening-patch-4.4.3-0.4.15/ext/standard/sha256.c ---- php-4.4.3/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/sha256.c 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,398 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ -+ -+#include -+#include "php.h" -+ -+/* This code is heavily based on the PHP md5/sha1 implementations */ -+ -+#include "sha256.h" -+ -+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ sprintf(sha256str, "%02x", digest[i]); -+ sha256str += 2; -+ } -+ -+ *sha256str = '\0'; -+} -+ -+/* {{{ proto string sha256(string str [, bool raw_output]) -+ Calculate the sha256 hash of a string */ -+PHP_FUNCTION(sha256) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ PHP_SHA256_CTX context; -+ unsigned char digest[32]; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ sha256str[0] = '\0'; -+ PHP_SHA256Init(&context); -+ PHP_SHA256Update(&context, arg, arg_len); -+ PHP_SHA256Final(digest, &context); -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+ -+} -+ -+/* }}} */ -+ -+/* {{{ proto string sha256_file(string filename [, bool raw_output]) -+ Calculate the sha256 hash of given filename */ -+PHP_FUNCTION(sha256_file) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ unsigned char buf[1024]; -+ unsigned char digest[32]; -+ PHP_SHA256_CTX context; -+ int n; -+ FILE *fp; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { -+ RETURN_FALSE; -+ } -+ -+ if (php_check_open_basedir(arg TSRMLS_CC)) { -+ RETURN_FALSE; -+ } -+ -+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); -+ RETURN_FALSE; -+ } -+ -+ PHP_SHA256Init(&context); -+ -+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { -+ PHP_SHA256Update(&context, buf, n); -+ } -+ -+ PHP_SHA256Final(digest, &context); -+ -+ if (ferror(fp)) { -+ fclose(fp); -+ RETURN_FALSE; -+ } -+ -+ fclose(fp); -+ -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+} -+/* }}} */ -+ -+ -+static void SHA256Transform(php_uint32[8], const unsigned char[64]); -+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); -+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); -+ -+static unsigned char PADDING[64] = -+{ -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* F, G, H and I are basic SHA256 functions. -+ */ -+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) -+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) -+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) -+#define I(x, y, z) (((x) & (y)) | ((~x) & z)) -+ -+/* ROTATE_RIGHT rotates x right n bits. -+ */ -+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) -+ -+/* W[i] -+ */ -+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ -+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ -+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) -+ -+/* ROUND function of sha256 -+ */ -+ -+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ -+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ -+ (h) = F((a)) + G((a), (b), (c)) + t1; \ -+ (d) += t1; \ -+ } -+ -+ -+/* {{{ PHP_SHA256Init -+ * SHA256 initialization. Begins an SHA256 operation, writing a new context. -+ */ -+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context) -+{ -+ context->count[0] = context->count[1] = 0; -+ /* Load magic initialization constants. -+ */ -+ context->state[0] = 0x6a09e667; -+ context->state[1] = 0xbb67ae85; -+ context->state[2] = 0x3c6ef372; -+ context->state[3] = 0xa54ff53a; -+ context->state[4] = 0x510e527f; -+ context->state[5] = 0x9b05688c; -+ context->state[6] = 0x1f83d9ab; -+ context->state[7] = 0x5be0cd19; -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Update -+ SHA256 block update operation. Continues an SHA256 message-digest -+ operation, processing another message block, and updating the -+ context. -+ */ -+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, -+ unsigned int inputLen) -+{ -+ unsigned int i, index, partLen; -+ -+ /* Compute number of bytes mod 64 */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); -+ -+ /* Update number of bits */ -+ if ((context->count[0] += ((php_uint32) inputLen << 3)) -+ < ((php_uint32) inputLen << 3)) -+ context->count[1]++; -+ context->count[1] += ((php_uint32) inputLen >> 29); -+ -+ partLen = 64 - index; -+ -+ /* Transform as many times as possible. -+ */ -+ if (inputLen >= partLen) { -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); -+ SHA256Transform(context->state, context->buffer); -+ -+ for (i = partLen; i + 63 < inputLen; i += 64) -+ SHA256Transform(context->state, &input[i]); -+ -+ index = 0; -+ } else -+ i = 0; -+ -+ /* Buffer remaining input */ -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], -+ inputLen - i); -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Final -+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the -+ the message digest and zeroizing the context. -+ */ -+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) -+{ -+ unsigned char bits[8]; -+ unsigned int index, padLen; -+ -+ /* Save number of bits */ -+ bits[7] = context->count[0] & 0xFF; -+ bits[6] = (context->count[0] >> 8) & 0xFF; -+ bits[5] = (context->count[0] >> 16) & 0xFF; -+ bits[4] = (context->count[0] >> 24) & 0xFF; -+ bits[3] = context->count[1] & 0xFF; -+ bits[2] = (context->count[1] >> 8) & 0xFF; -+ bits[1] = (context->count[1] >> 16) & 0xFF; -+ bits[0] = (context->count[1] >> 24) & 0xFF; -+ -+ /* Pad out to 56 mod 64. -+ */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); -+ padLen = (index < 56) ? (56 - index) : (120 - index); -+ PHP_SHA256Update(context, PADDING, padLen); -+ -+ /* Append length (before padding) */ -+ PHP_SHA256Update(context, bits, 8); -+ -+ /* Store state in digest */ -+ SHA256Encode(digest, context->state, 32); -+ -+ /* Zeroize sensitive information. -+ */ -+ memset((unsigned char*) context, 0, sizeof(*context)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Transform -+ * SHA256 basic transformation. Transforms state based on block. -+ */ -+static void SHA256Transform(state, block) -+php_uint32 state[8]; -+const unsigned char block[64]; -+{ -+ php_uint32 a = state[0], b = state[1], c = state[2]; -+ php_uint32 d = state[3], e = state[4], f = state[5]; -+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; -+ -+ SHA256Decode(x, block, 64); -+ -+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) -+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) -+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) -+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) -+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) -+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) -+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) -+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) -+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) -+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) -+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) -+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) -+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) -+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) -+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) -+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) -+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) -+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) -+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) -+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) -+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) -+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) -+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) -+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) -+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) -+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) -+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) -+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) -+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) -+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) -+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) -+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) -+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) -+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) -+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) -+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) -+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) -+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) -+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) -+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) -+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) -+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) -+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) -+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) -+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) -+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) -+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) -+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) -+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) -+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) -+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) -+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) -+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) -+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) -+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) -+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) -+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) -+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) -+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) -+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) -+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) -+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) -+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) -+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) -+ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ state[4] += e; -+ state[5] += f; -+ state[6] += g; -+ state[7] += h; -+ -+ /* Zeroize sensitive information. */ -+ memset((unsigned char*) x, 0, sizeof(x)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Encode -+ Encodes input (php_uint32) into output (unsigned char). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Encode(output, input, len) -+unsigned char *output; -+php_uint32 *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) { -+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); -+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); -+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); -+ output[j + 3] = (unsigned char) (input[i] & 0xff); -+ } -+} -+/* }}} */ -+ -+/* {{{ SHA256Decode -+ Decodes input (unsigned char) into output (php_uint32). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Decode(output, input, len) -+php_uint32 *output; -+const unsigned char *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) -+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | -+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.3/ext/standard/sha256.h hardening-patch-4.4.3-0.4.15/ext/standard/sha256.h ---- php-4.4.3/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/sha256.h 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ -+ -+#ifndef SHA256_H -+#define SHA256_H -+ -+#include "ext/standard/basic_functions.h" -+ -+/* SHA1 context. */ -+typedef struct { -+ php_uint32 state[8]; /* state (ABCD) */ -+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ -+ unsigned char buffer[64]; /* input buffer */ -+} PHP_SHA256_CTX; -+ -+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *); -+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); -+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); -+ -+PHP_FUNCTION(sha256); -+PHP_FUNCTION(sha256_file); -+ -+#endif -diff -Nura php-4.4.3/ext/standard/string.c hardening-patch-4.4.3-0.4.15/ext/standard/string.c ---- php-4.4.3/ext/standard/string.c 2006-05-19 12:20:44.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/string.c 2006-09-05 20:30:45.000000000 +0200 -@@ -628,7 +628,8 @@ - { - const char *text, *breakchar = "\n"; - char *newtext; -- int textlen, breakcharlen = 1, newtextlen, alloced, chk; -+ int textlen, breakcharlen = 1, newtextlen, chk; -+ size_t alloced; - long current = 0, laststart = 0, lastspace = 0; - long linelength = 75; - zend_bool docut = 0; -@@ -3518,7 +3519,7 @@ - zval **input_str; /* Input string */ - zval **mult; /* Multiplier */ - char *result; /* Resulting string */ -- int result_len; /* Length of the resulting string */ -+ size_t result_len; /* Length of the resulting string */ - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { - WRONG_PARAM_COUNT; -@@ -3543,11 +3544,7 @@ - - /* Initialize the result string */ - result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); -- if (result_len < 1) { -- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes"); -- RETURN_FALSE; -- } -- result = (char *)emalloc(result_len + 1); -+ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1); - - /* Heavy optimization for situations where input string is 1 byte long */ - if (Z_STRLEN_PP(input_str) == 1) { -diff -Nura php-4.4.3/ext/standard/syslog.c hardening-patch-4.4.3-0.4.15/ext/standard/syslog.c ---- php-4.4.3/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/syslog.c 2006-09-05 20:30:45.000000000 +0200 -@@ -42,6 +42,8 @@ - */ - PHP_MINIT_FUNCTION(syslog) - { -+ -+#if !HARDENING_PATCH - /* error levels */ - REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ - REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -@@ -97,7 +99,7 @@ - /* AIX doesn't have LOG_PERROR */ - REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ - #endif -- -+#endif - return SUCCESS; - } - /* }}} */ -diff -Nura php-4.4.3/ext/standard/tests/strings/bug38322.phpt hardening-patch-4.4.3-0.4.15/ext/standard/tests/strings/bug38322.phpt ---- php-4.4.3/ext/standard/tests/strings/bug38322.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/standard/tests/strings/bug38322.phpt 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+Bug #38322 (reading past array in sscanf() leads to segfault/arbitary code execution) -+--FILE-- -+ -+--EXPECTF-- -+int(1) -+Done -diff -Nura php-4.4.3/ext/varfilter/config.m4 hardening-patch-4.4.3-0.4.15/ext/varfilter/config.m4 ---- php-4.4.3/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/varfilter/config.m4 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,11 @@ -+dnl -+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+dnl -+ -+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, -+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) -+ -+if test "$PHP_VARFILTER" != "no"; then -+ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) -+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) -+fi -diff -Nura php-4.4.3/ext/varfilter/CREDITS hardening-patch-4.4.3-0.4.15/ext/varfilter/CREDITS ---- php-4.4.3/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,2 @@ -+varfilter -+Stefan Esser -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-4.4.3/ext/varfilter/php_varfilter.h hardening-patch-4.4.3-0.4.15/ext/varfilter/php_varfilter.h ---- php-4.4.3/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,144 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifndef PHP_VARFILTER_H -+#define PHP_VARFILTER_H -+ -+extern zend_module_entry varfilter_module_entry; -+#define phpext_varfilter_ptr &varfilter_module_entry -+ -+#ifdef PHP_WIN32 -+#define PHP_VARFILTER_API __declspec(dllexport) -+#else -+#define PHP_VARFILTER_API -+#endif -+ -+#ifdef ZTS -+#include "TSRM.h" -+#endif -+ -+#include "SAPI.h" -+ -+#include "php_variables.h" -+ -+#ifdef ZEND_ENGINE_2 -+#define HASH_HTTP_GET_VARS 0x2095733f -+#define HASH_HTTP_POST_VARS 0xbfee1265 -+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 -+#define HASH_HTTP_ENV_VARS 0x1fe186a8 -+#define HASH_HTTP_SERVER_VARS 0xc987afd6 -+#define HASH_HTTP_SESSION_VARS 0x7aba0d43 -+#define HASH_HTTP_POST_FILES 0x98eb1ddc -+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec -+#else -+#define HASH_HTTP_GET_VARS 0x8d8645bd -+#define HASH_HTTP_POST_VARS 0x7c699bf3 -+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f -+#define HASH_HTTP_ENV_VARS 0x84da3016 -+#define HASH_HTTP_SERVER_VARS 0x6dbf964e -+#define HASH_HTTP_SESSION_VARS 0x322906f5 -+#define HASH_HTTP_POST_FILES 0xe4e4ce70 -+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e -+#endif -+ -+PHP_MINIT_FUNCTION(varfilter); -+PHP_MSHUTDOWN_FUNCTION(varfilter); -+PHP_RINIT_FUNCTION(varfilter); -+PHP_RSHUTDOWN_FUNCTION(varfilter); -+PHP_MINFO_FUNCTION(varfilter); -+ -+ -+ZEND_BEGIN_MODULE_GLOBALS(varfilter) -+/* request variables */ -+ long max_request_variables; -+ long cur_request_variables; -+ long max_varname_length; -+ long max_totalname_length; -+ long max_value_length; -+ long max_array_depth; -+ long max_array_index_length; -+ zend_bool disallow_nul; -+/* cookie variables */ -+ long max_cookie_vars; -+ long cur_cookie_vars; -+ long max_cookie_name_length; -+ long max_cookie_totalname_length; -+ long max_cookie_value_length; -+ long max_cookie_array_depth; -+ long max_cookie_array_index_length; -+ zend_bool disallow_cookie_nul; -+/* get variables */ -+ long max_get_vars; -+ long cur_get_vars; -+ long max_get_name_length; -+ long max_get_totalname_length; -+ long max_get_value_length; -+ long max_get_array_depth; -+ long max_get_array_index_length; -+ zend_bool disallow_get_nul; -+/* post variables */ -+ long max_post_vars; -+ long cur_post_vars; -+ long max_post_name_length; -+ long max_post_totalname_length; -+ long max_post_value_length; -+ long max_post_array_depth; -+ long max_post_array_index_length; -+ zend_bool disallow_post_nul; -+/* fileupload */ -+ long max_uploads; -+ long cur_uploads; -+ zend_bool disallow_elf_files; -+ char *verification_script; -+ -+ zend_bool no_more_variables; -+ zend_bool no_more_get_variables; -+ zend_bool no_more_post_variables; -+ zend_bool no_more_cookie_variables; -+ zend_bool no_more_uploads; -+ -+ZEND_END_MODULE_GLOBALS(varfilter) -+ -+ -+#ifdef ZTS -+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) -+#else -+#define VARFILTER_G(v) (varfilter_globals.v) -+#endif -+ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); -+SAPI_TREAT_DATA_FUNC(varfilter_treat_data); -+ -+ -+ -+#endif /* PHP_VARFILTER_H */ -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * indent-tabs-mode: t -+ * End: -+ */ -diff -Nura php-4.4.3/ext/varfilter/varfilter.c hardening-patch-4.4.3-0.4.15/ext/varfilter/varfilter.c ---- php-4.4.3/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:50:05.000000000 +0200 -@@ -0,0 +1,915 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "php.h" -+#include "php_ini.h" -+#include "ext/standard/info.h" -+#include "php_varfilter.h" -+#include "hardening_patch.h" -+ -+ZEND_DECLARE_MODULE_GLOBALS(varfilter) -+ -+/* True global resources - no need for thread safety here */ -+static int le_varfilter; -+ -+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; -+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; -+static zend_bool hooked = 0; -+ -+/* {{{ varfilter_module_entry -+ */ -+zend_module_entry varfilter_module_entry = { -+#if ZEND_MODULE_API_NO >= 20010901 -+ STANDARD_MODULE_HEADER, -+#endif -+ "varfilter", -+ NULL, -+ PHP_MINIT(varfilter), -+ PHP_MSHUTDOWN(varfilter), -+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ -+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ -+ PHP_MINFO(varfilter), -+#if ZEND_MODULE_API_NO >= 20010901 -+ "0.4.15", /* Replace with version number for your extension */ -+#endif -+ STANDARD_MODULE_PROPERTIES -+}; -+/* }}} */ -+ -+#ifdef COMPILE_DL_VARFILTER -+ZEND_GET_MODULE(varfilter) -+#endif -+ -+/* {{{ PHP_INI -+ */ -+PHP_INI_BEGIN() -+ /* for backward compatibility */ -+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) -+ -+ -+PHP_INI_END() -+/* }}} */ -+ -+/* {{{ php_varfilter_init_globals -+ */ -+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) -+{ -+ varfilter_globals->max_request_variables = 200; -+ varfilter_globals->max_varname_length = 64; -+ varfilter_globals->max_value_length = 10000; -+ varfilter_globals->max_array_depth = 100; -+ varfilter_globals->max_totalname_length = 256; -+ varfilter_globals->max_array_index_length = 64; -+ varfilter_globals->disallow_nul = 1; -+ -+ varfilter_globals->max_cookie_vars = 100; -+ varfilter_globals->max_cookie_name_length = 64; -+ varfilter_globals->max_cookie_totalname_length = 256; -+ varfilter_globals->max_cookie_value_length = 10000; -+ varfilter_globals->max_cookie_array_depth = 100; -+ varfilter_globals->max_cookie_array_index_length = 64; -+ varfilter_globals->disallow_cookie_nul = 1; -+ -+ varfilter_globals->max_get_vars = 100; -+ varfilter_globals->max_get_name_length = 64; -+ varfilter_globals->max_get_totalname_length = 256; -+ varfilter_globals->max_get_value_length = 512; -+ varfilter_globals->max_get_array_depth = 50; -+ varfilter_globals->max_get_array_index_length = 64; -+ varfilter_globals->disallow_get_nul = 1; -+ -+ varfilter_globals->max_post_vars = 200; -+ varfilter_globals->max_post_name_length = 64; -+ varfilter_globals->max_post_totalname_length = 256; -+ varfilter_globals->max_post_value_length = 65000; -+ varfilter_globals->max_post_array_depth = 100; -+ varfilter_globals->max_post_array_index_length = 64; -+ varfilter_globals->disallow_post_nul = 1; -+ -+ varfilter_globals->max_uploads = 25; -+ varfilter_globals->disallow_elf_files = 1; -+ varfilter_globals->verification_script = NULL; -+ -+ varfilter_globals->no_more_variables = 0; -+ varfilter_globals->no_more_get_variables = 0; -+ varfilter_globals->no_more_post_variables = 0; -+ varfilter_globals->no_more_cookie_variables = 0; -+ varfilter_globals->no_more_uploads = 0; -+ -+ varfilter_globals->cur_request_variables = 0; -+ varfilter_globals->cur_get_vars = 0; -+ varfilter_globals->cur_post_vars = 0; -+ varfilter_globals->cur_cookie_vars = 0; -+ -+ varfilter_globals->cur_uploads = 0; -+ -+} -+/* }}} */ -+ -+ -+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) -+{ -+ HashTable *svars; -+ int retval, failure=0; -+ -+ orig_register_server_variables(track_vars_array TSRMLS_CC); -+ -+ svars = Z_ARRVAL_P(track_vars_array); -+ -+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ -+ if (failure) { -+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); -+ } -+} -+ -+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) -+{ -+ int retval = SAPI_HEADER_ADD, i; -+ char *tmp; -+ -+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { -+ -+ tmp = sapi_header->header; -+ for (i=0; iheader_len; i++, tmp++) { -+ if (tmp[0] == 0) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); -+ sapi_header->header_len = i; -+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); -+ sapi_header->header_len = i; -+ tmp[0] = 0; -+ } -+ } -+ } -+ -+ if (orig_header_handler) { -+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); -+ } -+ -+ return retval; -+} -+ -+/* {{{ PHP_MINIT_FUNCTION -+ */ -+PHP_MINIT_FUNCTION(varfilter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); -+ REGISTER_INI_ENTRIES(); -+ -+ if (!hooked) { -+ void *temp; -+ hooked = 1; -+ -+ temp = (void *)sapi_module.register_server_variables; -+ if (temp != varfilter_register_server_variables) { -+ orig_register_server_variables = temp; -+ } -+ temp = (void *)sapi_module.header_handler; -+ if (temp != varfilter_header_handler) { -+ orig_header_handler = temp; -+ } -+ } -+ -+ sapi_register_input_filter(varfilter_input_filter); -+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); -+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); -+ sapi_register_upload_content_filter(varfilter_upload_content_filter); -+ sapi_register_post_upload_filter(varfilter_post_upload_filter); -+ -+ sapi_module.header_handler = varfilter_header_handler; -+ sapi_module.register_server_variables = varfilter_register_server_variables; -+ -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MSHUTDOWN_FUNCTION -+ */ -+PHP_MSHUTDOWN_FUNCTION(varfilter) -+{ -+ UNREGISTER_INI_ENTRIES(); -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request start */ -+/* {{{ PHP_RINIT_FUNCTION -+ */ -+PHP_RINIT_FUNCTION(varfilter) -+{ -+ VARFILTER_G(cur_request_variables) = 0; -+ VARFILTER_G(cur_get_vars) = 0; -+ VARFILTER_G(cur_post_vars) = 0; -+ VARFILTER_G(cur_cookie_vars) = 0; -+ -+ VARFILTER_G(cur_uploads) = 0; -+ -+ VARFILTER_G(no_more_variables) = 0; -+ VARFILTER_G(no_more_get_variables) = 0; -+ VARFILTER_G(no_more_post_variables) = 0; -+ VARFILTER_G(no_more_cookie_variables) = 0; -+ VARFILTER_G(no_more_uploads) = 0; -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request end */ -+/* {{{ PHP_RSHUTDOWN_FUNCTION -+ */ -+PHP_RSHUTDOWN_FUNCTION(varfilter) -+{ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MINFO_FUNCTION -+ */ -+PHP_MINFO_FUNCTION(varfilter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); -+ php_info_print_table_end(); -+ -+ DISPLAY_INI_ENTRIES(); -+} -+/* }}} */ -+ -+/* {{{ normalize_varname -+ */ -+static void normalize_varname(char *varname) -+{ -+ char *s=varname, *index=NULL, *indexend=NULL, *p; -+ -+ /* overjump leading space */ -+ while (*s == ' ') { -+ s++; -+ } -+ -+ /* and remove it */ -+ if (s != varname) { -+ memmove(varname, s, strlen(s)+1); -+ } -+ -+ for (p=varname; *p && *p != '['; p++) { -+ switch(*p) { -+ case ' ': -+ case '.': -+ *p='_'; -+ break; -+ } -+ } -+ -+ /* find index */ -+ index = strchr(varname, '['); -+ if (index) { -+ index++; -+ s=index; -+ } else { -+ return; -+ } -+ -+ /* done? */ -+ while (index) { -+ -+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { -+ index++; -+ } -+ indexend = strchr(index, ']'); -+ indexend = indexend ? indexend + 1 : index + strlen(index); -+ -+ if (s != index) { -+ memmove(s, index, strlen(index)+1); -+ s += indexend-index; -+ } else { -+ s = indexend; -+ } -+ -+ if (*s == '[') { -+ s++; -+ index = s; -+ } else { -+ index = NULL; -+ } -+ } -+ *s++='\0'; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC -+ */ -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) -+{ -+ char *index, *prev_index = NULL, *var; -+ unsigned int var_len, total_len, depth = 0; -+ -+ var = estrdup(varname); -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); -+ -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; -+ break; -+ } -+ -+ efree(var); -+ return SUCCESS; -+protected_varname2: -+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); -+return_failure: -+ efree(var); -+ return FAILURE; -+} -+/* }}} */ -+ -+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC -+ */ -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) -+{ -+ /* Drop if no more variables flag is set */ -+ if (VARFILTER_G(no_more_uploads)) { -+ return FAILURE; -+ } -+ /* Drop this fileupload if the limit is reached */ -+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { -+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); -+ VARFILTER_G(no_more_uploads) = 1; -+ return FAILURE; -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC -+ */ -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) -+{ -+ -+ if (VARFILTER_G(disallow_elf_files)) { -+ -+ if (offset == 0 && buffer_len > 10) { -+ -+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { -+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); -+ return FAILURE; -+ } -+ } -+ -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC -+ */ -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) -+{ -+ int retval = SUCCESS; -+ -+ if (VARFILTER_G(verification_script)) { -+ char cmd[8192]; -+ FILE *in; -+ int first=1; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); -+ return FAILURE; -+ } -+ -+ retval = FAILURE; -+ -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ if (first) { -+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; -+ first = 0; -+ } -+ } -+ pclose(in); -+ } -+ -+ if (retval != SUCCESS) { -+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); -+ return FAILURE; -+ } -+ -+ VARFILTER_G(cur_uploads)++; -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_INPUT_FILTER_FUNC -+ */ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) -+{ -+ char *index, *prev_index = NULL; -+ unsigned int var_len, total_len, depth = 0; -+ -+ /* Drop this variable if the limit was reached */ -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(no_more_get_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(no_more_post_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(no_more_cookie_variables)) { -+ return 0; -+ } -+ break; -+ default: /* we do not want to protect parse_str() and friends */ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ return 1; -+ } -+ if (VARFILTER_G(no_more_variables)) { -+ return 0; -+ } -+ -+ /* Drop this variable if the limit is now reached */ -+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { -+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_variables) = 1; -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { -+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_get_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { -+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_cookie_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { -+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_post_variables) = 1; -+ return 0; -+ } -+ break; -+ } -+ -+ -+ /* Drop this variable if it exceeds the value length limit */ -+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { -+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { -+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { -+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { -+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { -+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { -+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Check if variable value is truncated by a \0 */ -+ -+ if (val && *val && val_len != strlen(*val)) { -+ -+ if (VARFILTER_G(disallow_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(disallow_get_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(disallow_cookie_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(disallow_post_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ } -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname; -+ break; -+ } -+ -+ /* Okay let PHP register this variable */ -+ VARFILTER_G(cur_request_variables)++; -+ switch (arg) { -+ case PARSE_GET: -+ VARFILTER_G(cur_get_vars)++; -+ break; -+ case PARSE_COOKIE: -+ VARFILTER_G(cur_cookie_vars)++; -+ break; -+ case PARSE_POST: -+ VARFILTER_G(cur_post_vars)++; -+ break; -+ } -+ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ -+ return 1; -+protected_varname: -+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); -+ return 0; -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: noet sw=4 ts=4 fdm=marker -+ * vim<600: noet sw=4 ts=4 -+ */ -+ -+ -diff -Nura php-4.4.3/main/fopen_wrappers.c hardening-patch-4.4.3-0.4.15/main/fopen_wrappers.c ---- php-4.4.3/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:34.000000000 +0200 -@@ -106,7 +106,10 @@ - } - - /* Resolve the real path into resolved_name */ -- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { -+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { -+ return -2; -+ } -+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { - /* Handler for basedirs that end with a / */ - resolved_basedir_len = strlen(resolved_basedir); - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { -@@ -116,14 +119,20 @@ - } - } - -+ resolved_name_len = strlen(resolved_name); - if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { -- resolved_name_len = strlen(resolved_name); - if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { - resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; - resolved_name[++resolved_name_len] = '\0'; - } - } - -+ if (resolved_name_len == resolved_basedir_len - 1) { -+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { -+ resolved_basedir_len--; -+ } -+ } -+ - /* Check the path */ - #ifdef PHP_WIN32 - if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { -@@ -137,7 +146,7 @@ - } - } else { - /* Unable to resolve the real path, return -1 */ -- return -1; -+ return -3; - } - } - /* }}} */ -@@ -156,22 +165,44 @@ - char *pathbuf; - char *ptr; - char *end; -+ char path_copy[MAXPATHLEN]; -+ int path_len; -+ -+ /* Special case path ends with a trailing slash */ -+ path_len = strlen(path); -+ if (path_len >= MAXPATHLEN) { -+ errno = EPERM; /* we deny permission to open it */ -+ return -1; -+ } -+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { -+ memcpy(path_copy, path, path_len+1); -+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; -+ path_copy[path_len] = '\0'; -+ path = (const char *)&path_copy; -+ } - - pathbuf = estrdup(PG(open_basedir)); - - ptr = pathbuf; - - while (ptr && *ptr) { -+ int res; - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - -- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { -+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); -+ if (res == 0) { - efree(pathbuf); - return 0; - } -+ if (res == -2) { -+ efree(pathbuf); -+ errno = EPERM; -+ return -1; -+ } - - ptr = end; - } -diff -Nura php-4.4.3/main/hardened_globals.h hardening-patch-4.4.3-0.4.15/main/hardened_globals.h ---- php-4.4.3/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/hardened_globals.h 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,64 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENED_GLOBALS_H -+#define HARDENED_GLOBALS_H -+ -+typedef struct _hardened_globals hardened_globals_struct; -+ -+#ifdef ZTS -+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) -+extern int hardened_globals_id; -+#else -+# define HG(v) (hardened_globals.v) -+extern struct _hardened_globals hardened_globals; -+#endif -+ -+ -+struct _hardened_globals { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_1; -+ unsigned int canary_2; -+#endif -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_3; -+ unsigned int canary_4; -+ unsigned int ll_canary_inited; -+#endif -+ zend_bool hphp_sql_bailout_on_error; -+ zend_bool hphp_multiheader; -+ unsigned long hphp_mailprotect; -+ long hard_memory_limit; -+ HashTable *eval_whitelist; -+ HashTable *eval_blacklist; -+ HashTable *func_whitelist; -+ HashTable *func_blacklist; -+ HashTable *include_whitelist; -+ HashTable *include_blacklist; -+ unsigned int dummy; -+}; -+ -+ -+#endif /* HARDENED_GLOBALS_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-4.4.3/main/hardening_patch.c hardening-patch-4.4.3-0.4.15/main/hardening_patch.c ---- php-4.4.3/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/hardening_patch.c 2006-09-07 18:48:07.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ -+ -+#include "php.h" -+ -+#include -+#include -+ -+#if HAVE_UNISTD_H -+#include -+#endif -+#include "SAPI.h" -+#include "php_globals.h" -+ -+#if HARDENING_PATCH -+ -+#ifdef HAVE_SYS_SOCKET_H -+#include -+#endif -+ -+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) -+#undef AF_UNIX -+#endif -+ -+#if defined(AF_UNIX) -+#include -+#endif -+ -+#define SYSLOG_PATH "/dev/log" -+ -+#include "snprintf.h" -+ -+#include "hardening_patch.h" -+ -+#ifdef ZTS -+#include "hardened_globals.h" -+int hardened_globals_id; -+#else -+struct _hardened_globals hardened_globals; -+#endif -+ -+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) -+{ -+ memset(hardened_globals, 0, sizeof(*hardened_globals)); -+} -+ -+ -+PHPAPI void hardened_startup() -+{ -+#ifdef ZTS -+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); -+#else -+ hardened_globals_ctor(&hardened_globals TSRMLS_CC); -+#endif -+} -+ -+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) -+{ -+ HG(canary_1) = php_canary(); -+ HG(canary_2) = php_canary(); -+} -+ -+char *loglevel2string(int loglevel) -+{ -+ switch (loglevel) { -+ case S_FILES: -+ return "FILES"; -+ case S_INCLUDE: -+ return "INCLUDE"; -+ case S_MEMORY: -+ return "MEMORY"; -+ case S_MISC: -+ return "MISC"; -+ case S_SQL: -+ return "SQL"; -+ case S_EXECUTOR: -+ return "EXECUTOR"; -+ case S_VARS: -+ return "VARS"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+PHPAPI void php_security_log(int loglevel, char *fmt, ...) -+{ -+#if defined(AF_UNIX) -+ int s, r, i=0; -+ struct sockaddr_un saun; -+ char buf[4096+64]; -+ char error[4096+100]; -+ char *ip_address; -+ char *fname; -+ int lineno; -+ va_list ap; -+ TSRMLS_FETCH(); -+ -+ if (EG(hphp_log_use_x_forwarded_for)) { -+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "X-FORWARDED-FOR not set"; -+ } -+ } else { -+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "REMOTE_ADDR not set"; -+ } -+ } -+ -+ -+ va_start(ap, fmt); -+ ap_php_vsnprintf(error, sizeof(error), fmt, ap); -+ va_end(ap); -+ while (error[i]) { -+ if (error[i] < 32) error[i] = '.'; -+ i++; -+ } -+ -+ if (zend_is_executing(TSRMLS_C)) { -+ lineno = zend_get_executed_lineno(TSRMLS_C); -+ fname = zend_get_executed_filename(TSRMLS_C); -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); -+ } else { -+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); -+ if (fname==NULL) { -+ fname = "unknown"; -+ } -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); -+ } -+ -+ /* Syslog-Logging disabled? */ -+ if ((EG(hphp_log_syslog) & loglevel)==0) { -+ goto log_sapi; -+ } -+ -+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); -+ -+ s = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ s = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ goto log_sapi; -+ } -+ } -+ send(s, error, strlen(error), 0); -+ -+ close(s); -+ -+log_sapi: -+ /* SAPI Logging activated? */ -+ if ((EG(hphp_log_sapi) & loglevel)!=0) { -+ sapi_module.log_message(buf); -+ } -+ -+log_script: -+ /* script logging activaed? */ -+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { -+ char cmd[8192], *cmdpos, *bufpos; -+ FILE *in; -+ int space; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); -+ space = sizeof(cmd) - strlen(cmd); -+ cmdpos = cmd + strlen(cmd); -+ bufpos = buf; -+ if (space <= 1) return; -+ while (space > 2 && *bufpos) { -+ if (*bufpos == '\'') { -+ if (space<=5) break; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\\'; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\''; -+ bufpos++; -+ space-=4; -+ } else { -+ *cmdpos++ = *bufpos++; -+ space--; -+ } -+ } -+ *cmdpos++ = '\''; -+ *cmdpos = 0; -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); -+ return; -+ } -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ } -+ pclose(in); -+ } -+ -+#endif -+} -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+PHPAPI unsigned int php_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+ -+PHPAPI int php_is_valid_include(zval *z) -+{ -+ char *filename; -+ int len, i; -+ TSRMLS_FETCH(); -+ -+ /* must be of type string */ -+ if (z->type != IS_STRING || z->value.str.val == NULL) { -+ return (0); -+ } -+ -+ /* short cut */ -+ filename = z->value.str.val; -+ len = z->value.str.len; -+ -+ /* 1. must be shorter than MAXPATHLEN */ -+ if (len > MAXPATHLEN) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 2. must not be cutted */ -+ if (len != strlen(filename)) { -+ char *fname = estrndup(filename, len); -+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ -+ if (strstr(filename, "://")) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ -+ /* no black or whitelist then disallow all */ -+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* whitelist is stronger than blacklist */ -+ if (HG(include_whitelist)) { -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ zend_bool isOk = 0; -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_whitelist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ isOk = 1; -+ break; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_whitelist)); -+ } while (1); -+ -+ /* not found in whitelist */ -+ if (!isOk) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); -+ efree(fname); -+ return 0; -+ } -+ -+ s = h + 3; -+ } while (1); -+ } else { -+ /* okay then handle the blacklist */ -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_blacklist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); -+ efree(fname); -+ return 0; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_blacklist)); -+ } while (1); -+ -+ s = h + 3; -+ } while (1); -+ } -+ -+ efree(fname); -+ } -+ -+ /* 4. must not be an uploaded file */ -+ if (SG(rfc1867_uploaded_files)) { -+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { -+ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); -+ return (0); -+ } -+ } -+ -+ /* passed all tests */ -+ return (1); -+} -+ -+#endif -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.3/main/hardening_patch.h hardening-patch-4.4.3-0.4.15/main/hardening_patch.h ---- php-4.4.3/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/hardening_patch.h 2006-09-07 18:50:14.000000000 +0200 -@@ -0,0 +1,46 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENING_PATCH_H -+#define HARDENING_PATCH_H -+ -+#include "zend.h" -+ -+#if HARDENING_PATCH -+PHPAPI void php_security_log(int loglevel, char *fmt, ...); -+PHPAPI void hardened_startup(); -+#define HARDENING_PATCH_VERSION "0.4.15" -+ -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+PHPAPI unsigned int php_canary(); -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+PHPAPI int php_is_valid_include(zval *z); -+#endif -+ -+#endif /* HARDENING_PATCH_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-4.4.3/main/hardening_patch.m4 hardening-patch-4.4.3-0.4.15/main/hardening_patch.m4 ---- php-4.4.3/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/hardening_patch.m4 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,95 @@ -+dnl -+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ -+dnl -+dnl This file contains Hardening Patch for PHP specific autoconf functions. -+dnl -+ -+AC_ARG_ENABLE(hardening-patch-mm-protect, -+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-ll-protect, -+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-inc-protect, -+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-fmt-protect, -+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-hash-protect, -+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+]) -+ -+AC_MSG_CHECKING(whether to protect the Zend Memory Manager) -+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the Zend Linked Lists) -+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect include/require statements) -+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect PHP Format String functions) -+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) -+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) -+ -+ -+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) -+fi -+ -diff -Nura php-4.4.3/main/main.c hardening-patch-4.4.3-0.4.15/main/main.c ---- php-4.4.3/main/main.c 2006-05-19 00:36:14.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/main/main.c 2006-09-05 20:30:45.000000000 +0200 -@@ -92,6 +92,10 @@ - PHPAPI int core_globals_id; - #endif - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#endif -+ - #define ERROR_BUF_LEN 1024 - - typedef struct { -@@ -142,17 +146,39 @@ - */ - static PHP_INI_MH(OnChangeMemoryLimit) - { -+#if HARDENING_PATCH -+ long hard_memory_limit = 1<<30; -+ -+ if (stage == ZEND_INI_STAGE_RUNTIME) { -+ if (HG(hard_memory_limit) == 0) { -+ HG(hard_memory_limit) = PG(memory_limit); -+ } -+ hard_memory_limit = HG(hard_memory_limit); -+ } else { -+ HG(hard_memory_limit) = 0; -+ } -+#endif - if (new_value) { - PG(memory_limit) = zend_atoi(new_value, new_value_length); -+#if HARDENING_PATCH -+ if (PG(memory_limit) > hard_memory_limit) { -+ PG(memory_limit) = hard_memory_limit; -+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); -+ return FAILURE; -+ } -+#endif - } else { -+#if HARDENING_PATCH -+ PG(memory_limit) = hard_memory_limit; -+#else - PG(memory_limit) = 1<<30; /* effectively, no limit */ -+#endif - } - return zend_set_memory_limit(PG(memory_limit)); - } - /* }}} */ - #endif - -- - /* {{{ php_disable_functions - */ - static void php_disable_functions(TSRMLS_D) -@@ -1008,6 +1034,9 @@ - - zend_try { - shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); -+#if HARDENING_PATCH -+ hardened_clear_mm_canaries(TSRMLS_C); -+#endif - } zend_end_try(); - - zend_try { -@@ -1098,6 +1127,10 @@ - tsrm_ls = ts_resource(0); - #endif - -+#if HARDENING_PATCH -+ hardened_startup(); -+#endif -+ - sapi_initialize_empty_request(TSRMLS_C); - sapi_activate(TSRMLS_C); - -@@ -1109,6 +1142,12 @@ - - php_output_startup(); - -+#if HARDENING_PATCH_INC_PROTECT -+ zuf.is_valid_include = php_is_valid_include; -+#endif -+#if HARDENING_PATCH -+ zuf.security_log_function = php_security_log; -+#endif - zuf.error_function = php_error_cb; - zuf.printf_function = php_printf; - zuf.write_function = php_body_write_wrapper; -@@ -1210,6 +1249,10 @@ - REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS); - 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); - REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); -+#endif - REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); -@@ -1317,7 +1360,7 @@ - */ - static inline void php_register_server_variables(TSRMLS_D) - { -- zval *array_ptr=NULL; -+ zval *array_ptr=NULL, *vptr; - - ALLOC_ZVAL(array_ptr); - array_init(array_ptr); -diff -Nura php-4.4.3/main/php_config.h.in hardening-patch-4.4.3-0.4.15/main/php_config.h.in ---- php-4.4.3/main/php_config.h.in 2006-08-01 09:39:13.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/main/php_config.h.in 2006-09-05 20:30:45.000000000 +0200 -@@ -1,4 +1,4 @@ --/* main/php_config.h.in. Generated automatically from configure.in by autoheader. */ -+/* main/php_config.h.in. Generated automatically from configure.in by autoheader 2.13. */ - /* Leave this file alone */ - #define ZEND_API - #define ZEND_DLEXPORT -@@ -865,6 +865,39 @@ - /* Enabling BIND8 compatibility for Panther */ - #undef BIND_8_COMPAT - -+/* Hardening-Patch */ -+#undef HARDENING_PATCH -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ - /* Whether you have AOLserver */ - #undef HAVE_AOLSERVER - -@@ -1148,6 +1181,12 @@ - /* Define if you have the getaddrinfo function */ - #undef HAVE_GETADDRINFO - -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ - /* Whether system headers declare timezone */ - #undef HAVE_DECLARED_TIMEZONE - -diff -Nura php-4.4.3/main/php_content_types.c hardening-patch-4.4.3-0.4.15/main/php_content_types.c ---- php-4.4.3/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/php_content_types.c 2006-09-05 20:30:45.000000000 +0200 -@@ -77,6 +77,7 @@ - sapi_register_post_entries(php_post_entries); - sapi_register_default_post_reader(php_default_post_reader); - sapi_register_treat_data(php_default_treat_data); -+ sapi_register_input_filter(php_default_input_filter); - return SUCCESS; - } - /* }}} */ -diff -Nura php-4.4.3/main/php.h hardening-patch-4.4.3-0.4.15/main/php.h ---- php-4.4.3/main/php.h 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/php.h 2006-09-05 20:30:45.000000000 +0200 -@@ -35,11 +35,19 @@ - #include "zend_qsort.h" - #include "php_compat.h" - -+ - #include "zend_API.h" - - #undef sprintf - #define sprintf php_sprintf - -+#if HARDENING_PATCH -+#if HAVE_REALPATH -+#undef realpath -+#define realpath php_realpath -+#endif -+#endif -+ - /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ - #undef PHP_DEBUG - #define PHP_DEBUG ZEND_DEBUG -@@ -409,6 +417,10 @@ - #endif - #endif /* !XtOffsetOf */ - -+#if HARDENING_PATCH -+#include "hardening_patch.h" -+#endif -+ - #endif - - /* -diff -Nura php-4.4.3/main/php_variables.c hardening-patch-4.4.3-0.4.15/main/php_variables.c ---- php-4.4.3/main/php_variables.c 2006-02-13 13:19:10.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/php_variables.c 2006-09-05 20:30:45.000000000 +0200 -@@ -238,17 +238,28 @@ - while (var) { - val = strchr(var, '='); - if (val) { /* have a value */ -- int val_len; -+ unsigned int val_len, new_val_len; - - *val++ = '\0'; - php_url_decode(var, strlen(var)); - val_len = php_url_decode(val, strlen(val)); -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } - var = php_strtok_r(NULL, "&", &strtok_buf); - } - } - -+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) -+{ -+ /* TODO: check .ini setting here and apply user-defined input filter */ -+ *new_val_len = val_len; -+ return 1; -+} -+ - SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) - { - char *res = NULL, *var, *val, *separator=NULL; -@@ -326,15 +337,26 @@ - while (var) { - val = strchr(var, '='); - if (val) { /* have a value */ -- int val_len; -+ unsigned int val_len, new_val_len; - - *val++ = '\0'; - php_url_decode(var, strlen(var)); - val_len = php_url_decode(val, strlen(val)); -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } else { -+ unsigned int val_len, new_val_len; -+ - php_url_decode(var, strlen(var)); -- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC); -+ val_len = 0; -+ val = estrndup("", 0); -+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } - var = php_strtok_r(NULL, separator, &strtok_buf); - } -diff -Nura php-4.4.3/main/php_version.h hardening-patch-4.4.3-0.4.15/main/php_version.h ---- php-4.4.3/main/php_version.h 2006-07-31 17:04:54.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/main/php_version.h 2006-09-05 20:30:45.000000000 +0200 -@@ -2,6 +2,6 @@ - /* edit configure.in to change version number */ - #define PHP_MAJOR_VERSION 4 - #define PHP_MINOR_VERSION 4 --#define PHP_RELEASE_VERSION 3 --#define PHP_EXTRA_VERSION "" --#define PHP_VERSION "4.4.3" -+#define PHP_RELEASE_VERSION 4 -+#define PHP_EXTRA_VERSION "-dev" -+#define PHP_VERSION "4.4.4-dev" -diff -Nura php-4.4.3/main/rfc1867.c hardening-patch-4.4.3-0.4.15/main/rfc1867.c ---- php-4.4.3/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/rfc1867.c 2006-09-05 20:30:45.000000000 +0200 -@@ -128,6 +128,8 @@ - #define UPLOAD_ERROR_D 4 /* No file uploaded */ - #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ - #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ -+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */ -+ - - void php_rfc1867_register_constants(TSRMLS_D) - { -@@ -138,6 +140,7 @@ - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); - } - - static void normalize_protected_variable(char *varname TSRMLS_DC) -@@ -849,6 +852,7 @@ - char buff[FILLUNIT]; - char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; - int blen=0, wlen=0; -+ unsigned long offset; - - zend_llist_clean(&header); - -@@ -897,21 +901,24 @@ - if (!filename && param) { - - char *value = multipart_buffer_read_body(mbuff TSRMLS_CC); -+ unsigned int new_val_len; /* Dummy variable */ - - if (!value) { - value = estrdup(""); - } - -+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) { - #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) -- if (php_mb_encoding_translation(TSRMLS_C)) { -- php_mb_gpc_stack_variable(param, value, &val_list, &len_list, -- &num_vars, &num_vars_max TSRMLS_CC); -- } else { -- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -- } -+ if (php_mb_encoding_translation(TSRMLS_C)) { -+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list, -+ &num_vars, &num_vars_max TSRMLS_CC); -+ } else { -+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -+ } - #else -- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); - #endif -+ } - if (!strcasecmp(param, "MAX_FILE_SIZE")) { - max_file_size = atol(value); - } -@@ -963,7 +970,11 @@ - tmp++; - } - } -- -+ -+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { -+ skip_upload = 1; -+ } -+ - total_bytes = cancel_upload = 0; - - if (!skip_upload) { -@@ -987,6 +998,11 @@ - cancel_upload = UPLOAD_ERROR_D; - } - -+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ -+ offset = 0; - end = 0; - while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) - { -@@ -997,6 +1013,11 @@ - sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); - cancel_upload = UPLOAD_ERROR_B; - } else if (blen > 0) { -+ -+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - wlen = write(fd, buff, blen); - - if (wlen < blen) { -@@ -1004,6 +1025,7 @@ - cancel_upload = UPLOAD_ERROR_F; - } else { - total_bytes += wlen; -+ offset += wlen; - } - } - } -@@ -1025,6 +1047,10 @@ - } - #endif - -+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - if (cancel_upload) { - if (temp_filename) { - if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ -diff -Nura php-4.4.3/main/SAPI.c hardening-patch-4.4.3-0.4.15/main/SAPI.c ---- php-4.4.3/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/SAPI.c 2006-09-05 20:30:45.000000000 +0200 -@@ -854,6 +854,37 @@ - return SUCCESS; - } - -+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)) -+{ -+ sapi_module.input_filter = input_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) -+{ -+ sapi_module.upload_varname_filter = upload_varname_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) -+{ -+ sapi_module.pre_upload_filter = pre_upload_filter; -+ return SUCCESS; -+} -+ -+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)) -+{ -+ sapi_module.upload_content_filter = upload_content_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) -+{ -+ sapi_module.post_upload_filter = post_upload_filter; -+ return SUCCESS; -+} -+ -+ - - SAPI_API int sapi_flush(TSRMLS_D) - { -diff -Nura php-4.4.3/main/SAPI.h hardening-patch-4.4.3-0.4.15/main/SAPI.h ---- php-4.4.3/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/SAPI.h 2006-09-05 20:30:45.000000000 +0200 -@@ -101,9 +101,10 @@ - char *current_user; - int current_user_length; - -- /* this is necessary for CLI module */ -- int argc; -- char **argv; -+ /* this is necessary for CLI module */ -+ int argc; -+ char **argv; -+ - } sapi_request_info; - - -@@ -177,6 +178,10 @@ - SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); - SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); - SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); - - SAPI_API int sapi_flush(TSRMLS_D); - SAPI_API struct stat *sapi_get_stat(TSRMLS_D); -@@ -238,8 +243,16 @@ - int (*get_target_uid)(uid_t * TSRMLS_DC); - int (*get_target_gid)(gid_t * TSRMLS_DC); - -+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); -+ -+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); -+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); -+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); -+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); -+ - void (*ini_defaults)(HashTable *configuration_hash); - int phpinfo_as_text; -+ - }; - - -@@ -262,16 +275,27 @@ - - #define SAPI_DEFAULT_MIMETYPE "text/html" - #define SAPI_DEFAULT_CHARSET "" -+ -+#if HARDENING_PATCH -+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" -+#else - #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION -+#endif - - #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) - #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) - - #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) -+#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) -+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) -+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) -+#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) -+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) - - SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); - SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); - SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); -+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter); - - #define STANDARD_SAPI_MODULE_PROPERTIES - -diff -Nura php-4.4.3/main/snprintf.c hardening-patch-4.4.3-0.4.15/main/snprintf.c ---- php-4.4.3/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/snprintf.c 2006-09-05 20:30:45.000000000 +0200 -@@ -1014,7 +1014,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = cc; -+#endif - break; - - /* -diff -Nura php-4.4.3/main/spprintf.c hardening-patch-4.4.3-0.4.15/main/spprintf.c ---- php-4.4.3/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/main/spprintf.c 2006-09-05 20:30:45.000000000 +0200 -@@ -630,7 +630,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = xbuf->len; -+#endif - break; - - /* -diff -Nura php-4.4.3/php.ini-dist hardening-patch-4.4.3-0.4.15/php.ini-dist ---- php-4.4.3/php.ini-dist 2005-12-30 18:19:43.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/php.ini-dist 2006-09-05 20:30:45.000000000 +0200 -@@ -1114,6 +1114,209 @@ - ;exif.decode_jis_motorola = JIS - ;exif.decode_jis_intel = JIS - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-4.4.3/php.ini-recommended hardening-patch-4.4.3-0.4.15/php.ini-recommended ---- php-4.4.3/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/php.ini-recommended 2006-09-05 20:30:45.000000000 +0200 -@@ -1112,6 +1112,209 @@ - ;exif.decode_jis_motorola = JIS - ;exif.decode_jis_intel = JIS - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-4.4.3/README.input_filter hardening-patch-4.4.3-0.4.15/README.input_filter ---- php-4.4.3/README.input_filter 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/README.input_filter 2006-09-05 20:30:45.000000000 +0200 -@@ -0,0 +1,193 @@ -+Input Filter Support ported from PHP 5 -+-------------------------------------- -+ -+XSS (Cross Site Scripting) hacks are becoming more and more prevalent, -+and can be quite difficult to prevent. Whenever you accept user data -+and somehow display this data back to users, you are likely vulnerable -+to XSS hacks. -+ -+The Input Filter support in PHP 5 is aimed at providing the framework -+through which a company-wide or site-wide security policy can be -+enforced. It is implemented as a SAPI hook and is called from the -+treat_data and post handler functions. To implement your own security -+policy you will need to write a standard PHP extension. -+ -+A simple implementation might look like the following. This stores the -+original raw user data and adds a my_get_raw() function while the normal -+$_POST, $_GET and $_COOKIE arrays are only populated with stripped -+data. In this simple example all I am doing is calling strip_tags() on -+the data. If register_globals is turned on, the default globals that -+are created will be stripped ($foo) while a $RAW_foo is created with the -+original user input. -+ -+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) -+ zval *post_array; -+ zval *get_array; -+ zval *cookie_array; -+ZEND_END_MODULE_GLOBALS(my_input_filter) -+ -+#ifdef ZTS -+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v) -+#else -+#define IF_G(v) (my_input_filter_globals.v) -+#endif -+ -+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter) -+ -+function_entry my_input_filter_functions[] = { -+ PHP_FE(my_get_raw, NULL) -+ {NULL, NULL, NULL} -+}; -+ -+zend_module_entry my_input_filter_module_entry = { -+ STANDARD_MODULE_HEADER, -+ "my_input_filter", -+ my_input_filter_functions, -+ PHP_MINIT(my_input_filter), -+ PHP_MSHUTDOWN(my_input_filter), -+ NULL, -+ PHP_RSHUTDOWN(my_input_filter), -+ PHP_MINFO(my_input_filter), -+ "0.1", -+ STANDARD_MODULE_PROPERTIES -+}; -+ -+PHP_MINIT_FUNCTION(my_input_filter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL); -+ -+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); -+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); -+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); -+ -+ sapi_register_input_filter(my_sapi_input_filter); -+ return SUCCESS; -+} -+ -+PHP_RSHUTDOWN_FUNCTION(my_input_filter) -+{ -+ if(IF_G(get_array)) { -+ zval_ptr_dtor(&IF_G(get_array)); -+ IF_G(get_array) = NULL; -+ } -+ if(IF_G(post_array)) { -+ zval_ptr_dtor(&IF_G(post_array)); -+ IF_G(post_array) = NULL; -+ } -+ if(IF_G(cookie_array)) { -+ zval_ptr_dtor(&IF_G(cookie_array)); -+ IF_G(cookie_array) = NULL; -+ } -+ return SUCCESS; -+} -+ -+PHP_MINFO_FUNCTION(my_input_filter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); -+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $"); -+ php_info_print_table_end(); -+} -+ -+/* The filter handler. If you return 1 from it, then PHP also registers the -+ * (modified) variable. Returning 0 prevents PHP from registering the variable; -+ * you can use this if your filter already registers the variable under a -+ * different name, or if you just don't want the variable registered at all. */ -+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter) -+{ -+ zval new_var; -+ zval *array_ptr = NULL; -+ char *raw_var; -+ int var_len; -+ -+ assert(*val != NULL); -+ -+ switch(arg) { -+ case PARSE_GET: -+ if(!IF_G(get_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(get_array) = array_ptr; -+ break; -+ case PARSE_POST: -+ if(!IF_G(post_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(post_array) = array_ptr; -+ break; -+ case PARSE_COOKIE: -+ if(!IF_G(cookie_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(cookie_array) = array_ptr; -+ break; -+ } -+ Z_STRLEN(new_var) = val_len; -+ Z_STRVAL(new_var) = estrndup(*val, val_len); -+ Z_TYPE(new_var) = IS_STRING; -+ -+ var_len = strlen(var); -+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ -+ strcpy(raw_var, "RAW_"); -+ strlcat(raw_var,var,var_len+5); -+ -+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC); -+ -+ php_strip_tags(*val, val_len, NULL, NULL, 0); -+ -+ *new_val_len = strlen(*val); -+ return 1; -+} -+ -+PHP_FUNCTION(my_get_raw) -+{ -+ long arg; -+ char *var; -+ int var_len; -+ zval **tmp; -+ zval *array_ptr = NULL; -+ HashTable *hash_ptr; -+ char *raw_var; -+ -+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) { -+ return; -+ } -+ -+ switch(arg) { -+ case PARSE_GET: -+ array_ptr = IF_G(get_array); -+ break; -+ case PARSE_POST: -+ array_ptr = IF_G(post_array); -+ break; -+ case PARSE_COOKIE: -+ array_ptr = IF_G(post_array); -+ break; -+ } -+ -+ if(!array_ptr) RETURN_FALSE; -+ -+ /* -+ * I'm changing the variable name here because when running with register_globals on, -+ * the variable will end up in the global symbol table -+ */ -+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ -+ strcpy(raw_var, "RAW_"); -+ strlcat(raw_var,var,var_len+5); -+ hash_ptr = HASH_OF(array_ptr); -+ -+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) { -+ *return_value = **tmp; -+ zval_copy_ctor(return_value); -+ } else { -+ RETVAL_FALSE; -+ } -+ efree(raw_var); -+} -+ -diff -Nura php-4.4.3/run-tests.php hardening-patch-4.4.3-0.4.15/run-tests.php ---- php-4.4.3/run-tests.php 2006-01-18 18:59:41.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/run-tests.php 2006-09-05 20:30:45.000000000 +0200 -@@ -152,6 +152,10 @@ - 'error_reporting=2047', - 'display_errors=1', - 'log_errors=0', -+ 'hphp.executor.include.whitelist=cookietest', -+ 'hphp.log.syslog=0', -+ 'hphp.log.sapi=0', -+ 'hphp.log.script=0', - 'html_errors=0', - 'track_errors=1', - 'report_memleaks=1', -diff -Nura php-4.4.3/sapi/apache/mod_php4.c hardening-patch-4.4.3-0.4.15/sapi/apache/mod_php4.c ---- php-4.4.3/sapi/apache/mod_php4.c 2006-05-13 23:42:14.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/sapi/apache/mod_php4.c 2006-09-05 20:30:45.000000000 +0200 -@@ -451,7 +451,7 @@ - sapi_apache_get_fd, - sapi_apache_force_http_10, - sapi_apache_get_target_uid, -- sapi_apache_get_target_gid -+ sapi_apache_get_target_gid, - }; - /* }}} */ - -@@ -897,7 +897,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component("PHP/" PHP_VERSION); -+#endif - } - } - #endif -diff -Nura php-4.4.3/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.3-0.4.15/sapi/apache2filter/sapi_apache2.c ---- php-4.4.3/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:30:45.000000000 +0200 -@@ -562,7 +562,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-4.4.3/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.3-0.4.15/sapi/apache2handler/sapi_apache2.c ---- php-4.4.3/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:30:45.000000000 +0200 -@@ -340,7 +340,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-4.4.3/sapi/cgi/cgi_main.c hardening-patch-4.4.3-0.4.15/sapi/cgi/cgi_main.c ---- php-4.4.3/sapi/cgi/cgi_main.c 2006-02-22 16:11:53.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:30:46.000000000 +0200 -@@ -1435,11 +1435,19 @@ - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - } -+#if HARDENING_PATCH -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif -+#else - #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #endif -+#endif - php_end_ob_buffers(1 TSRMLS_CC); - exit(0); - break; -diff -Nura php-4.4.3/sapi/cli/php_cli.c hardening-patch-4.4.3-0.4.15/sapi/cli/php_cli.c ---- php-4.4.3/sapi/cli/php_cli.c 2006-05-18 22:33:46.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:30:46.000000000 +0200 -@@ -656,11 +656,19 @@ - if (php_request_startup(TSRMLS_C)==FAILURE) { - goto err; - } -+#if HARDENING_PATCH -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif -+#else - #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #endif -+#endif - php_end_ob_buffers(1 TSRMLS_CC); - exit_status=0; - goto out; -diff -Nura php-4.4.3/tests/lang/bug35239.phpt hardening-patch-4.4.3-0.4.15/tests/lang/bug35239.phpt ---- php-4.4.3/tests/lang/bug35239.phpt 2006-05-19 13:17:53.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/tests/lang/bug35239.phpt 2006-09-05 20:30:46.000000000 +0200 -@@ -10,16 +10,16 @@ - $a->x0->y0 = 'b'; - var_dump($a); - $a->x0->y1 = "ok\n"; --echo $a->x0; -+var_dump($a->x0); - ?> - --EXPECT-- --object(stdClass)#1 (1) { -+object(stdClass)(1) { - ["x0"]=> -- &object(stdClass)#2 (3) { -+ &object(stdClass)(3) { - ["y0"]=> - string(1) "b" - ["y1"]=> -- &object(stdClass)#2 (3) { -+ &object(stdClass)(3) { - ["y0"]=> - string(1) "b" - ["y1"]=> -@@ -28,7 +28,7 @@ - *RECURSION* - } - ["y2"]=> -- &object(stdClass)#2 (3) { -+ &object(stdClass)(3) { - ["y0"]=> - string(1) "b" - ["y1"]=> -@@ -38,4 +38,4 @@ - } - } - } --ok -+string(2) "ok" -diff -Nura php-4.4.3/TSRM/TSRM.h hardening-patch-4.4.3-0.4.15/TSRM/TSRM.h ---- php-4.4.3/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/TSRM/TSRM.h 2006-09-05 20:30:46.000000000 +0200 -@@ -33,6 +33,13 @@ - # define TSRM_API - #endif - -+#if HARDENING_PATCH -+# if HAVE_REALPATH -+# undef realpath -+# define realpath php_realpath -+# endif -+#endif -+ - /* Only compile multi-threading functions if we're in ZTS mode */ - #ifdef ZTS - -@@ -84,6 +91,7 @@ - - #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts - -+ - #ifdef __cplusplus - extern "C" { - #endif -diff -Nura php-4.4.3/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.c ---- php-4.4.3/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:30:46.000000000 +0200 -@@ -179,6 +179,178 @@ - return p; - } - -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved) -+{ -+ struct stat sb; -+ char *p, *q, *s; -+ size_t left_len, resolved_len; -+ unsigned symlinks; -+ int serrno, slen; -+ int is_dir = 1; -+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; -+ -+ serrno = errno; -+ symlinks = 0; -+ if (path[0] == '/') { -+ resolved[0] = '/'; -+ resolved[1] = '\0'; -+ if (path[1] == '\0') -+ return (resolved); -+ resolved_len = 1; -+ left_len = strlcpy(left, path + 1, sizeof(left)); -+ } else { -+ if (getcwd(resolved, PATH_MAX) == NULL) { -+ strlcpy(resolved, ".", PATH_MAX); -+ return (NULL); -+ } -+ resolved_len = strlen(resolved); -+ left_len = strlcpy(left, path, sizeof(left)); -+ } -+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ -+ /* -+ * Iterate over path components in `left'. -+ */ -+ while (left_len != 0) { -+ /* -+ * Extract the next path component and adjust `left' -+ * and its length. -+ */ -+ p = strchr(left, '/'); -+ s = p ? p : left + left_len; -+ if (s - left >= sizeof(next_token)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ memcpy(next_token, left, s - left); -+ next_token[s - left] = '\0'; -+ left_len -= s - left; -+ if (p != NULL) -+ memmove(left, s + 1, left_len + 1); -+ if (resolved[resolved_len - 1] != '/') { -+ if (resolved_len + 1 >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ resolved[resolved_len++] = '/'; -+ resolved[resolved_len] = '\0'; -+ } -+ if (next_token[0] == '\0') -+ continue; -+ else if (strcmp(next_token, ".") == 0) -+ continue; -+ else if (strcmp(next_token, "..") == 0) { -+ /* -+ * Strip the last path component except when we have -+ * single "/" -+ */ -+ if (!is_dir) { -+ errno = ENOENT; -+ return (NULL); -+ } -+ if (resolved_len > 1) { -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ continue; -+ } -+ -+ /* -+ * Append the next path component and lstat() it. If -+ * lstat() fails we still can return successfully if -+ * there are no more path components left. -+ */ -+ resolved_len = strlcat(resolved, next_token, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ if (lstat(resolved, &sb) != 0) { -+ if (errno == ENOENT) { -+ if (p == NULL) { -+ errno = serrno; -+ return (resolved); -+ } else -+ /* dirty hack to support a vanilla PHP feature */ -+ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { -+ resolved_len = strlcat(resolved, "/", PATH_MAX); -+ resolved_len = strlcat(resolved, left, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ errno = serrno; -+ return (resolved); -+ } -+ } -+ return (NULL); -+ } -+ if (S_ISLNK(sb.st_mode)) { -+ if (symlinks++ > MAXSYMLINKS) { -+ errno = ELOOP; -+ return (NULL); -+ } -+ slen = readlink(resolved, symlink, sizeof(symlink) - 1); -+ if (slen < 0) -+ return (NULL); -+ symlink[slen] = '\0'; -+ if (symlink[0] == '/') { -+ resolved[1] = 0; -+ resolved_len = 1; -+ } else if (resolved_len > 1) { -+ /* Strip the last path component. */ -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ -+ /* -+ * If there are any path components left, then -+ * append them to symlink. The result is placed -+ * in `left'. -+ */ -+ if (p != NULL) { -+ if (symlink[slen - 1] != '/') { -+ if (slen + 1 >= sizeof(symlink)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ symlink[slen] = '/'; -+ symlink[slen + 1] = 0; -+ } -+ left_len = strlcat(symlink, left, sizeof(left)); -+ if (left_len >= sizeof(left)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ } -+ left_len = strlcpy(left, symlink, sizeof(left)); -+ } else { -+ if (S_ISDIR(sb.st_mode)) { -+ is_dir = 1; -+ } else { -+ is_dir = 0; -+ } -+ } -+ } -+ -+ /* -+ * Remove trailing slash except when the resolved pathname -+ * is a single "/". -+ */ -+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') -+ resolved[resolved_len - 1] = '\0'; -+ return (resolved); -+} -+#endif -+ - CWD_API void virtual_cwd_startup(void) - { - char cwd[MAXPATHLEN]; -@@ -300,8 +472,11 @@ - - if (path_length == 0) - return (0); -- if (path_length >= MAXPATHLEN) -+ if (path_length >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return (1); -+ } - - #if !defined(TSRM_WIN32) && !defined(NETWARE) - /* cwd_length can be 0 when getcwd() fails. -@@ -313,8 +488,9 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - } else { /* Concat current directory with relative path and then run realpath() on it */ -@@ -323,6 +499,8 @@ - - ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); - if (!tmp) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(ptr, state->cwd, state->cwd_length); -@@ -332,6 +510,8 @@ - ptr += path_length; - *ptr = '\0'; - if (strlen(tmp) >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - free(tmp); - return 1; - } -@@ -340,9 +520,10 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - free(tmp); -- return 1; */ -+ return 1; - } - } - free(tmp); -diff -Nura php-4.4.3/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.h ---- php-4.4.3/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:30:46.000000000 +0200 -@@ -128,6 +128,22 @@ - - typedef int (*verify_path_func)(const cwd_state *); - -+#ifndef HAVE_STRLCPY -+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); -+#undef strlcpy -+#define strlcpy php_strlcpy -+#endif -+ -+#ifndef HAVE_STRLCAT -+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); -+#undef strlcat -+#define strlcat php_strlcat -+#endif -+ -+ -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved); -+#endif - CWD_API void virtual_cwd_startup(void); - CWD_API void virtual_cwd_shutdown(void); - CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); -diff -Nura php-4.4.3/Zend/zend_alloc.c hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.c ---- php-4.4.3/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.c 2006-09-05 20:30:46.000000000 +0200 -@@ -56,6 +56,11 @@ - # define END_MAGIC_SIZE 0 - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+# define CANARY_SIZE sizeof(unsigned int) -+#else -+# define CANARY_SIZE 0 -+#endif - - # if MEMORY_LIMIT - # if ZEND_DEBUG -@@ -64,7 +69,15 @@ - #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) - # endif - --#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ -+#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ -+ if (file) { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ -+ } else { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ -+ } \ -+ exit(1); \ -+ } \ -+ AG(allocated_memory) += rs;\ - if (AG(memory_limit)pNext; \ - } else { \ -+ if (p != p->pLast->pNext) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pLast->pNext = p->pNext; \ - } \ - if (p->pNext) { \ -+ if (p != p->pNext->pLast) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pNext->pLast = p->pLast; \ - } - -@@ -111,7 +132,7 @@ - p->pLast = (zend_mem_header *) NULL; - - #define DECLARE_CACHE_VARS() \ -- unsigned int real_size; \ -+ size_t real_size; \ - unsigned int cache_index - - #define REAL_SIZE(size) ((size+7) & ~0x7) -@@ -126,12 +147,22 @@ - - ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -- zend_mem_header *p; -+ zend_mem_header *p = NULL; - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { -+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); -+ exit(1); -+ } -+#endif - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - -+ if (size > INT_MAX || SIZE < size) { -+ goto emalloc_error; -+ } -+ - if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { - p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; - #if ZEND_DEBUG -@@ -147,6 +178,10 @@ - AG(cache_stats)[CACHE_INDEX][1]++; - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->cached = 0; - p->size = size; - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); -@@ -162,9 +197,11 @@ - AG(allocated_memory_peak) = AG(allocated_memory); - } - #endif -- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); - } - -+emalloc_error: -+ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (!p) { -@@ -192,7 +229,10 @@ - # endif - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -- -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } -@@ -219,17 +259,36 @@ - return emalloc_rel(lval + offset); - } - } -- -+ -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); -+#endif - zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset); - return 0; - } - - ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+efree_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); -+ exit(1); -+ } -+ /* to catch double efree()s */ -+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); -+ p->canary = 0; -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring", -@@ -274,6 +333,9 @@ - size_t _size = nmemb * size; - - if (nmemb && (_size/nmemb!=size)) { -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); -+#endif - fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); - #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID - kill(getpid(), SIGSEGV); -@@ -293,6 +355,9 @@ - - ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p; - zend_mem_header *orig; - DECLARE_CACHE_VARS(); -@@ -304,6 +369,16 @@ - - p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+erealloc_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); -+ exit(1); -+ } -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - void *new_p; -@@ -320,6 +395,13 @@ - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - - HANDLE_BLOCK_INTERRUPTIONS(); -+ -+ if (size > INT_MAX || SIZE < size) { -+ REMOVE_POINTER_FROM_LIST(p); -+ p = NULL; -+ goto erealloc_error; -+ } -+ - #if MEMORY_LIMIT - CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); - if (AG(allocated_memory) > AG(allocated_memory_peak)) { -@@ -327,7 +409,8 @@ - } - #endif - REMOVE_POINTER_FROM_LIST(p); -- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); -+erealloc_error: - if (!p) { - if (!allow_failure) { - fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); -@@ -349,6 +432,9 @@ - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - - HANDLE_UNBLOCK_INTERRUPTIONS(); -@@ -423,6 +509,10 @@ - { - AG(head) = NULL; - -+#if HARDENING_PATCH_MM_PROTECT -+ HG(canary_1) = zend_canary(); -+ HG(canary_2) = zend_canary(); -+#endif - #if MEMORY_LIMIT - AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ - AG(allocated_memory) = 0; -diff -Nura php-4.4.3/Zend/zend_alloc.h hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.h ---- php-4.4.3/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_alloc.h 2006-09-05 20:30:46.000000000 +0200 -@@ -32,6 +32,9 @@ - #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL - - typedef struct _zend_mem_header { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary; -+#endif - #if ZEND_DEBUG - long magic; - char *filename; -diff -Nura php-4.4.3/Zend/zend_builtin_functions.c hardening-patch-4.4.3-0.4.15/Zend/zend_builtin_functions.c ---- php-4.4.3/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:30:46.000000000 +0200 -@@ -49,6 +49,9 @@ - static ZEND_FUNCTION(crash); - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+static ZEND_FUNCTION(heap_overflow); -+#endif - static ZEND_FUNCTION(get_included_files); - static ZEND_FUNCTION(is_subclass_of); - static ZEND_FUNCTION(is_a); -@@ -101,6 +104,9 @@ - ZEND_FE(crash, NULL) - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ ZEND_FE(heap_overflow, NULL) -+#endif - ZEND_FE(get_included_files, NULL) - ZEND_FALIAS(get_required_files, get_included_files, NULL) - ZEND_FE(is_subclass_of, NULL) -@@ -805,6 +811,19 @@ - - #endif /* ZEND_DEBUG */ - -+ -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ZEND_FUNCTION(heap_overflow) -+{ -+ char *nowhere = emalloc(10); -+ -+ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); -+ -+ efree(nowhere); -+} -+#endif -+ -+ - /* {{{ proto array get_included_files(void) - Returns an array with the file names that were include_once()'d */ - ZEND_FUNCTION(get_included_files) -diff -Nura php-4.4.3/Zend/zend.c hardening-patch-4.4.3-0.4.15/Zend/zend.c ---- php-4.4.3/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend.c 2006-09-05 20:30:46.000000000 +0200 -@@ -53,6 +53,12 @@ - ZEND_API void (*zend_unblock_interruptions)(void); - ZEND_API void (*zend_ticks_function)(int ticks); - ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); -+#if HARDENING_PATCH -+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - - void (*zend_on_timeout)(int seconds TSRMLS_DC); - -@@ -70,9 +76,391 @@ - return SUCCESS; - } - -+#if HARDENING_PATCH -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; -+ } else { -+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_facility) = LOG_USER; -+ } else { -+ EG(hphp_log_syslog_facility) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_priority) = LOG_ALERT; -+ } else { -+ EG(hphp_log_syslog_priority) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_sapi) -+{ -+ if (!new_value) { -+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; -+ } else { -+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_script) -+{ -+ if (!new_value) { -+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL); -+ } else { -+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) -+{ -+ if (EG(hphp_log_scriptname)) { -+ pefree(EG(hphp_log_scriptname),1); -+ } -+ EG(hphp_log_scriptname) = NULL; -+ if (new_value) { -+ EG(hphp_log_scriptname) = pestrdup(new_value,1); -+ } -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_whitelist_destroy: -+ if (HG(include_whitelist)) { -+ zend_hash_destroy(HG(include_whitelist)); -+ pefree(HG(include_whitelist),1); -+ } -+ HG(include_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_whitelist_destroy; -+ } -+ -+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_blacklist_destroy: -+ if (HG(include_blacklist)) { -+ zend_hash_destroy(HG(include_blacklist)); -+ pefree(HG(include_blacklist),1); -+ } -+ HG(include_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_blacklist_destroy; -+ } -+ -+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_whitelist_destroy: -+ if (HG(eval_whitelist)) { -+ zend_hash_destroy(HG(eval_whitelist)); -+ pefree(HG(eval_whitelist),1); -+ } -+ HG(eval_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_whitelist_destroy; -+ } -+ -+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_blacklist_destroy: -+ if (HG(eval_blacklist)) { -+ zend_hash_destroy(HG(eval_blacklist)); -+ pefree(HG(eval_blacklist), 1); -+ } -+ HG(eval_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_blacklist_destroy; -+ } -+ -+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_whitelist_destroy: -+ if (HG(func_whitelist)) { -+ zend_hash_destroy(HG(func_whitelist)); -+ pefree(HG(func_whitelist),1); -+ } -+ HG(func_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_whitelist_destroy; -+ } -+ -+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_blacklist_destroy: -+ if (HG(func_blacklist)) { -+ zend_hash_destroy(HG(func_blacklist)); -+ pefree(HG(func_blacklist),1); -+ } -+ HG(func_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_blacklist_destroy; -+ } -+ -+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+#endif - - ZEND_INI_BEGIN() - ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) -+#if HARDENING_PATCH -+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) -+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) -+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) -+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) -+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) -+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) -+ 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) -+ -+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) -+ -+ 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) -+ 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) -+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) -+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) -+#endif - ZEND_INI_END() - - -@@ -354,8 +742,12 @@ - zend_init_rsrc_plist(TSRMLS_C); - EG(lambda_count)=0; - EG(user_error_handler) = NULL; -+ EG(in_code_type) = 0; - EG(in_execution) = 0; - EG(current_execute_data) = NULL; -+#if HARDENING_PATCH -+ EG(hphp_log_scriptname) = NULL; -+#endif - } - - -@@ -420,6 +812,14 @@ - extern zend_scanner_globals language_scanner_globals; - #endif - -+ /* Set up Hardening-Patch utility functions first */ -+#if HARDENING_PATCH -+ zend_security_log = utility_functions->security_log_function; -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ zend_is_valid_include = utility_functions->is_valid_include; -+#endif -+ - #ifdef ZTS - ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); - #else -@@ -619,6 +1019,7 @@ - } - CG(unclean_shutdown) = 1; - CG(in_compilation) = EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(current_execute_data) = NULL; - longjmp(EG(bailout), FAILURE); - } -diff -Nura php-4.4.3/Zend/zend_canary.c hardening-patch-4.4.3-0.4.15/Zend/zend_canary.c ---- php-4.4.3/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_canary.c 2006-09-05 20:30:46.000000000 +0200 -@@ -0,0 +1,58 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ -+ -+#include "zend.h" -+ -+#include -+#include -+ -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+ZEND_API unsigned int zend_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.3/Zend/zend_compile.c hardening-patch-4.4.3-0.4.15/Zend/zend_compile.c ---- php-4.4.3/Zend/zend_compile.c 2006-02-23 19:07:16.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_compile.c 2006-09-05 20:30:46.000000000 +0200 -@@ -768,6 +768,13 @@ - op_array.function_name = name; - op_array.arg_types = NULL; - op_array.return_reference = return_reference; -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array.created_by_eval = 1; -+ } else { -+ op_array.created_by_eval = 0; -+ } -+#endif - - if (is_method) { - if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { -diff -Nura php-4.4.3/Zend/zend_compile.h hardening-patch-4.4.3-0.4.15/Zend/zend_compile.h ---- php-4.4.3/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_compile.h 2006-09-05 20:30:46.000000000 +0200 -@@ -106,6 +106,9 @@ - char *filename; - - void *reserved[ZEND_MAX_RESERVED_RESOURCES]; -+#if HARDENING_PATCH -+ zend_bool created_by_eval; -+#endif - }; - - -@@ -549,6 +552,7 @@ - #define ZEND_USER_FUNCTION 2 - #define ZEND_OVERLOADED_FUNCTION 3 - #define ZEND_EVAL_CODE 4 -+#define ZEND_SANDBOX_CODE 6 - - #define ZEND_INTERNAL_CLASS 1 - #define ZEND_USER_CLASS 2 -diff -Nura php-4.4.3/Zend/zend_constants.c hardening-patch-4.4.3-0.4.15/Zend/zend_constants.c ---- php-4.4.3/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_constants.c 2006-09-05 20:30:46.000000000 +0200 -@@ -111,6 +111,74 @@ - REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); - - REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); -+ -+ /* error levels */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); -+ /* facility: type of program logging the message */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NEWS -+ /* No LOG_NEWS on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ -+#endif -+#ifdef LOG_UUCP -+ /* No LOG_UUCP on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_CRON -+ /* apparently some systems don't have this one */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_AUTHPRIV -+ /* AIX doesn't have LOG_AUTHPRIV */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); -+#endif -+#if !defined(PHP_WIN32) && !defined(NETWARE) -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); -+#endif -+ /* options */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NOWAIT -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_PERROR -+ /* AIX doesn't have LOG_PERROR */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ -+#endif -+#endif - - /* true/false constants */ - { -diff -Nura php-4.4.3/Zend/zend_errors.h hardening-patch-4.4.3-0.4.15/Zend/zend_errors.h ---- php-4.4.3/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_errors.h 2006-09-05 20:30:46.000000000 +0200 -@@ -36,5 +36,18 @@ - #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) - #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) - -+#if HARDENING_PATCH -+#define S_MEMORY (1<<0L) -+#define S_VARS (1<<1L) -+#define S_FILES (1<<2L) -+#define S_INCLUDE (1<<3L) -+#define S_SQL (1<<4L) -+#define S_EXECUTOR (1<<5L) -+#define S_MAIL (1<<6L) -+#define S_MISC (1<<30L) -+#define S_INTERNAL (1<<29L) -+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) -+#endif -+ - #endif /* ZEND_ERRORS_H */ - -diff -Nura php-4.4.3/Zend/zend_execute_API.c hardening-patch-4.4.3-0.4.15/Zend/zend_execute_API.c ---- php-4.4.3/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:30:46.000000000 +0200 -@@ -142,6 +142,7 @@ - EG(class_table) = CG(class_table); - - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - - zend_ptr_stack_init(&EG(argument_stack)); - -@@ -431,12 +432,14 @@ - zend_execute_data execute_data; - - /* Initialize execute_data */ -+ memset(&execute_data, 0, sizeof(execute_data)); - EX(fbc) = NULL; - EX(object).ptr = NULL; - EX(ce) = NULL; - EX(Ts) = NULL; - EX(op_array) = NULL; - EX(opline) = NULL; -+ EX(execute_depth) = 0; - - *retval_ptr_ptr = NULL; - -@@ -494,6 +497,39 @@ - zval_dtor(&function_name_copy); - return FAILURE; - } -+#if HARDENING_PATCH -+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - zval_dtor(&function_name_copy); - - for (i=0; itype = type; - EG(return_value_ptr_ptr) = &local_retval_ptr; - EG(active_op_array) = new_op_array; - EG(no_extensions)=1; -@@ -673,6 +709,10 @@ - return retval; - } - -+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+{ -+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); -+} - - void execute_new_code(TSRMLS_D) - { -diff -Nura php-4.4.3/Zend/zend_execute.c hardening-patch-4.4.3-0.4.15/Zend/zend_execute.c ---- php-4.4.3/Zend/zend_execute.c 2006-04-13 08:16:42.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_execute.c 2006-09-05 20:30:46.000000000 +0200 -@@ -1042,6 +1042,7 @@ - zend_execute_data execute_data; - - /* Initialize execute_data */ -+ memset(&execute_data, 0, sizeof(execute_data)); - EX(fbc) = NULL; - EX(ce) = NULL; - EX(object).ptr = NULL; -@@ -1053,9 +1054,21 @@ - } - EX(prev_execute_data) = EG(current_execute_data); - EX(original_in_execution)=EG(in_execution); -+ EX(original_in_code_type)=EG(in_code_type); - - EG(current_execute_data) = &execute_data; - -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif -+ - EG(in_execution) = 1; - if (op_array->start_op) { - EX(opline) = op_array->start_op; -@@ -1087,6 +1100,19 @@ - } - } - -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif -+ - while (1) { - #ifdef ZEND_WIN32 - if (EG(timed_out)) { -@@ -1634,6 +1660,36 @@ - if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) { - zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val); - } -+#if HARDENING_PATCH -+ if (active_function_table == EG(function_table)) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+#endif -+ - zval_dtor(&tmp); - EX(fbc) = function; - overloaded_function_call_cont: -@@ -1649,6 +1705,35 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); - zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce)); - EX(object).ptr = NULL; -@@ -1821,6 +1906,7 @@ - efree(EX(Ts)); - } - EG(in_execution) = EX(original_in_execution); -+ EG(in_code_type) = EX(original_in_code_type); - EG(current_execute_data) = EX(prev_execute_data); - return; - } -@@ -2210,7 +2296,12 @@ - int dummy = 1; - zend_file_handle file_handle = {0}; - -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS -+#else - if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS -+#endif - && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { - - file_handle.filename = inc_filename->value.str.val; -@@ -2239,6 +2330,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -2381,7 +2477,7 @@ - if (EX(opline)->extended_value) { - array_ptr_ptr = get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R); - if (array_ptr_ptr == NULL) { -- MAKE_STD_ZVAL(array_ptr); -+ ALLOC_INIT_ZVAL(array_ptr); - } else { - SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr); - array_ptr = *array_ptr_ptr; -diff -Nura php-4.4.3/Zend/zend_execute_globals.h hardening-patch-4.4.3-0.4.15/Zend/zend_execute_globals.h ---- php-4.4.3/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_execute_globals.h 2006-09-05 20:30:46.000000000 +0200 -@@ -60,6 +60,8 @@ - object_info object; - temp_variable *Ts; - zend_bool original_in_execution; -+ zend_uint original_in_code_type; -+ zend_uint execute_depth; - zend_op_array *op_array; - struct _zend_execute_data *prev_execute_data; - } zend_execute_data; -diff -Nura php-4.4.3/Zend/zend_extensions.c hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.c ---- php-4.4.3/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.c 2006-09-05 20:30:46.000000000 +0200 -@@ -54,23 +54,44 @@ - return FAILURE; - } - -+ /* check if module is compiled against Hardening-Patch */ -+ if (extension_version_info->zend_extension_api_no < 1000000000) { -+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } -+ -+ -+ /* check if module is compiled against correct Hardening-Patch version */ -+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { -+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ extension_version_info->zend_extension_api_no, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } - - /* allow extension to proclaim compatibility with any Zend version */ -- 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)) { -- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { -+ 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)) { -+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is outdated.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO); - DL_UNLOAD(handle); - return FAILURE; -- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { -+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is newer.\n" - "Contact %s at %s for a later version of %s.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO, - new_extension->author, - new_extension->URL, -diff -Nura php-4.4.3/Zend/zend_extensions.h hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.h ---- php-4.4.3/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_extensions.h 2006-09-05 20:30:46.000000000 +0200 -@@ -23,6 +23,9 @@ - - #include "zend_compile.h" - -+/* Create own API version number for Hardening-Patch */ -+ -+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805 - #define ZEND_EXTENSION_API_NO 20050606 - - typedef struct _zend_extension_version_info { -@@ -30,6 +33,7 @@ - char *required_zend_version; - unsigned char thread_safe; - unsigned char debug; -+ int real_zend_extension_api_no; - } zend_extension_version_info; - - -@@ -96,7 +100,7 @@ - - - #define ZEND_EXTENSION() \ -- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } -+ 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 } - - #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 - #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 -diff -Nura php-4.4.3/Zend/zend_globals.h hardening-patch-4.4.3-0.4.15/Zend/zend_globals.h ---- php-4.4.3/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_globals.h 2006-09-05 20:30:46.000000000 +0200 -@@ -163,6 +163,16 @@ - - int error_reporting; - int orig_error_reporting; -+#if HARDENING_PATCH -+ int hphp_log_syslog; -+ int hphp_log_syslog_facility; -+ int hphp_log_syslog_priority; -+ int hphp_log_sapi; -+ int hphp_log_script; -+ char *hphp_log_scriptname; -+ zend_bool hphp_log_use_x_forwarded_for; -+ long hphp_executor_max_depth; -+#endif - int exit_status; - - zend_op_array *active_op_array; -@@ -176,6 +186,7 @@ - int ticks_count; - - zend_bool in_execution; -+ zend_uint in_code_type; - zend_bool bailout_set; - zend_bool full_tables_cleanup; - -diff -Nura php-4.4.3/Zend/zend.h hardening-patch-4.4.3-0.4.15/Zend/zend.h ---- php-4.4.3/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend.h 2006-09-05 20:30:46.000000000 +0200 -@@ -274,9 +274,10 @@ - struct _zval_struct { - /* Variable information */ - zvalue_value value; /* value */ -+ zend_uint refcount; -+ zend_ushort flags; - zend_uchar type; /* active type */ - zend_uchar is_ref; -- zend_ushort refcount; - }; - - -@@ -337,6 +338,12 @@ - void (*ticks_function)(int ticks); - void (*on_timeout)(int seconds TSRMLS_DC); - zend_bool (*open_function)(const char *filename, struct _zend_file_handle *); -+#if HARDENING_PATCH -+ void (*security_log_function)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ int (*is_valid_include)(zval *z); -+#endif - } zend_utility_functions; - - -@@ -468,7 +475,16 @@ - extern ZEND_API void (*zend_ticks_function)(int ticks); - extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); - extern void (*zend_on_timeout)(int seconds TSRMLS_DC); -+#if HARDENING_PATCH -+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+extern ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ZEND_API unsigned int zend_canary(void); -+#endif - - ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3); - -@@ -575,6 +591,11 @@ - - #define ZEND_MAX_RESERVED_RESOURCES 4 - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#include "php_syslog.h" -+#endif -+ - #endif /* ZEND_H */ - - /* -diff -Nura php-4.4.3/Zend/zend_hash.c hardening-patch-4.4.3-0.4.15/Zend/zend_hash.c ---- php-4.4.3/Zend/zend_hash.c 2006-02-01 10:11:55.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_hash.c 2006-09-05 20:30:46.000000000 +0200 -@@ -26,6 +26,17 @@ - # include - #endif - -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int zend_hash_canary = 0x1234567; -+ zend_bool zend_hash_canary_inited = 0; -+#endif -+ -+#define CHECK_HASH_CANARY(hash) \ -+ if (zend_hash_canary != (hash)->canary) { \ -+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ -+ exit(1); \ -+ } -+ - #define HANDLE_NUMERIC(key, length, func) { \ - register char *tmp=key; \ - \ -@@ -175,6 +186,9 @@ - { - uint i = 3; - Bucket **tmp; -+#if HARDENING_PATCH_HASH_PROTECT -+ TSRMLS_FETCH(); -+#endif - - SET_INCONSISTENT(HT_OK); - -@@ -184,6 +198,13 @@ - - ht->nTableSize = 1 << i; - ht->nTableMask = ht->nTableSize - 1; -+#if HARDENING_PATCH_HASH_PROTECT -+ if (zend_hash_canary_inited==0) { -+ zend_hash_canary = zend_canary(); -+ zend_hash_canary_inited = 1; -+ } -+ ht->canary = zend_hash_canary; -+#endif - ht->pDestructor = pDestructor; - ht->pListHead = NULL; - ht->pListTail = NULL; -@@ -259,6 +280,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -327,6 +351,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -402,6 +429,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -450,7 +480,7 @@ - IS_CONSISTENT(ht); - - if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ -- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); -+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); - if (t) { - HANDLE_BLOCK_INTERRUPTIONS(); - ht->arBuckets = t; -@@ -460,6 +490,7 @@ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return SUCCESS; - } -+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); - return FAILURE; - } - return SUCCESS; -@@ -526,6 +557,9 @@ - ht->pInternalPointer = p->pListNext; - } - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (!p->pDataPtr) { -@@ -555,6 +589,9 @@ - q = p; - p = p->pListNext; - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(q->pData); - } - if (!q->pDataPtr && q->pData) { -@@ -581,6 +618,9 @@ - q = p; - p = p->pListNext; - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(q->pData); - } - if (!q->pDataPtr && q->pData) { -@@ -610,6 +650,9 @@ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (!p->pDataPtr) { -diff -Nura php-4.4.3/Zend/zend_hash.h hardening-patch-4.4.3-0.4.15/Zend/zend_hash.h ---- php-4.4.3/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_hash.h 2006-09-05 20:30:46.000000000 +0200 -@@ -54,6 +54,9 @@ - } Bucket; - - typedef struct _hashtable { -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int canary; -+#endif - uint nTableSize; - uint nTableMask; - uint nNumOfElements; -diff -Nura php-4.4.3/Zend/zend_ini.c hardening-patch-4.4.3-0.4.15/Zend/zend_ini.c ---- php-4.4.3/Zend/zend_ini.c 2005-09-02 23:09:03.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:56.000000000 +0200 -@@ -256,7 +256,8 @@ - zend_ini_entry *ini_entry; - TSRMLS_FETCH(); - -- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { -+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || -+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifyable & ZEND_INI_USER) == 0)) { - return FAILURE; - } - -diff -Nura php-4.4.3/Zend/zend_ini.h hardening-patch-4.4.3-0.4.15/Zend/zend_ini.h ---- php-4.4.3/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_ini.h 2006-09-05 20:30:46.000000000 +0200 -@@ -174,6 +174,7 @@ - /* Standard message handlers */ - BEGIN_EXTERN_C() - ZEND_API ZEND_INI_MH(OnUpdateBool); -+#define OnUpdateLong OnUpdateInt - ZEND_API ZEND_INI_MH(OnUpdateInt); - ZEND_API ZEND_INI_MH(OnUpdateReal); - ZEND_API ZEND_INI_MH(OnUpdateString); -diff -Nura php-4.4.3/Zend/zend_language_scanner.l hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.l ---- php-4.4.3/Zend/zend_language_scanner.l 2006-04-13 15:52:24.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:30:46.000000000 +0200 -@@ -393,6 +393,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-4.4.3/Zend/zend_language_scanner.c hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.c ---- php-4.4.3/Zend/zend_language_scanner.c 2006-08-01 09:39:14.000000000 +0200 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:30:46.000000000 +0200 -@@ -3036,6 +3036,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-4.4.3/Zend/zend_llist.c hardening-patch-4.4.3-0.4.15/Zend/zend_llist.c ---- php-4.4.3/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_llist.c 2006-09-05 20:30:46.000000000 +0200 -@@ -21,9 +21,49 @@ - #include "zend.h" - #include "zend_llist.h" - #include "zend_qsort.h" -+#include "zend_globals.h" -+ -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int zend_llist_canary_1 = 0x1234567; -+ unsigned int zend_llist_canary_2 = 0x1553425; -+ zend_bool zend_llist_canary_inited = 0; -+#endif -+ -+#define CHECK_LIST_CANARY(list) \ -+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ -+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ -+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+#define CHECK_LISTELEMENT_CANARY(elem, list) \ -+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ -+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ -+ exit(1); \ -+ } -+ - - ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ -+ if (persistent) { -+ if (!zend_llist_canary_inited) { -+ /* do not change order to ensure thread safety */ -+ zend_llist_canary_1 = zend_canary(); -+ zend_llist_canary_2 = zend_canary(); -+ zend_llist_canary_inited = 1; -+ } -+ } else -+ if (!HG(ll_canary_inited)) { -+ HG(canary_3) = zend_canary(); -+ HG(canary_4) = zend_canary(); -+ HG(ll_canary_inited) = 1; -+ } -+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); -+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); -+#endif - l->head = NULL; - l->tail = NULL; - l->count = 0; -@@ -37,6 +77,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->prev = l->tail; - tmp->next = NULL; - if (l->tail) { -@@ -55,6 +100,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->next = l->head; - tmp->prev = NULL; - if (l->head) { -@@ -91,10 +141,20 @@ - zend_llist_element *current=l->head; - zend_llist_element *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (compare(current->data, element)) { - DEL_LLIST_ELEMENT(current, l); -+#if HARDENING_PATCH_LL_PROTECT -+ current->canary = 0; -+#endif - break; - } - current = next; -@@ -106,7 +166,14 @@ - { - zend_llist_element *current=l->head, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (l->dtor) { - l->dtor(current->data); -@@ -131,7 +198,14 @@ - zend_llist_element *old_tail; - void *data; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if ((old_tail = l->tail)) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(old_tail, l) -+#endif - if (l->tail->prev) { - l->tail->prev->next = NULL; - } -@@ -157,9 +231,16 @@ - { - zend_llist_element *ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(src) -+#endif - zend_llist_init(dst, src->size, src->dtor, src->persistent); - ptr = src->head; - while (ptr) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(ptr, src) -+#endif - zend_llist_add_element(dst, ptr->data); - ptr = ptr->next; - } -@@ -170,11 +251,21 @@ - { - zend_llist_element *element, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - element=l->head; - while (element) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - next = element->next; - if (func(element->data)) { - DEL_LLIST_ELEMENT(element, l); -+#if HARDENING_PATCH_LL_PROTECT -+ element->canary = 0; -+#endif - } - element = next; - } -@@ -185,7 +276,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data TSRMLS_CC); - } - } -@@ -197,6 +294,9 @@ - zend_llist_element **elements; - zend_llist_element *element, **ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - if (l->count <= 0) { - return; - } -@@ -206,6 +306,9 @@ - ptr = &elements[0]; - - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - *ptr++ = element; - } - -@@ -228,7 +331,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, arg TSRMLS_CC); - } - } -@@ -239,8 +348,14 @@ - zend_llist_element *element; - va_list args; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - va_start(args, num_args); - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, num_args, args TSRMLS_CC); - } - va_end(args); -@@ -249,6 +364,10 @@ - - ZEND_API int zend_llist_count(zend_llist *l) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - return l->count; - } - -@@ -256,8 +375,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->head; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -269,8 +395,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->tail; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -282,9 +415,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->next; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -@@ -296,9 +439,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->prev; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -diff -Nura php-4.4.3/Zend/zend_llist.h hardening-patch-4.4.3-0.4.15/Zend/zend_llist.h ---- php-4.4.3/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_llist.h 2006-09-05 20:30:46.000000000 +0200 -@@ -24,6 +24,9 @@ - #include - - typedef struct _zend_llist_element { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary, padding; -+#endif - struct _zend_llist_element *next; - struct _zend_llist_element *prev; - char data[1]; /* Needs to always be last in the struct */ -@@ -36,6 +39,9 @@ - typedef void (*llist_apply_func_t)(void * TSRMLS_DC); - - typedef struct _zend_llist { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_h; /* head */ -+#endif - zend_llist_element *head; - zend_llist_element *tail; - size_t size; -@@ -43,6 +49,9 @@ - llist_dtor_func_t dtor; - unsigned char persistent; - zend_llist_element *traverse_ptr; -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_t; /* tail */ -+#endif - } zend_llist; - - typedef zend_llist_element* zend_llist_position; -diff -Nura php-4.4.3/Zend/zend_modules.h hardening-patch-4.4.3-0.4.15/Zend/zend_modules.h ---- php-4.4.3/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_modules.h 2006-09-05 20:30:46.000000000 +0200 -@@ -34,6 +34,7 @@ - ZEND_API extern unsigned char second_arg_force_ref[]; - ZEND_API extern unsigned char third_arg_force_ref[]; - -+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112 - #define ZEND_MODULE_API_NO 20020429 - #ifdef ZTS - #define USING_ZTS 1 -@@ -41,9 +42,9 @@ - #define USING_ZTS 0 - #endif - --#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS -+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS - --#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 -+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO - - #define STANDARD_MODULE_PROPERTIES \ - NULL, NULL, STANDARD_MODULE_PROPERTIES_EX -@@ -75,6 +76,7 @@ - unsigned char type; - void *handle; - int module_number; -+ unsigned int real_zend_api; - }; - - -diff -Nura php-4.4.3/Zend/zend_opcode.c hardening-patch-4.4.3-0.4.15/Zend/zend_opcode.c ---- php-4.4.3/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_opcode.c 2006-09-05 20:30:46.000000000 +0200 -@@ -88,6 +88,9 @@ - op_array->done_pass_two = 0; - - op_array->start_op = NULL; -+#if HARDENING_PATCH -+ op_array->created_by_eval = 0; -+#endif - - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); - } -diff -Nura php-4.4.3/Zend/zend_operators.c hardening-patch-4.4.3-0.4.15/Zend/zend_operators.c ---- php-4.4.3/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_operators.c 2006-09-05 20:30:46.000000000 +0200 -@@ -1604,6 +1604,20 @@ - return (op->value.lval ? 1 : 0); - } - -+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) -+{ -+ register unsigned char *str = (unsigned char*)source; -+ register unsigned char *result = (unsigned char*)dest; -+ register unsigned char *end = str + length; -+ -+ while (str < end) { -+ *result++ = tolower((int)*str++); -+ } -+ *result = *end; -+ -+ return dest; -+} -+ - ZEND_API void zend_str_tolower(char *str, unsigned int length) - { - register char *p=str, *end=p+length; -diff -Nura php-4.4.3/Zend/zend_operators.h hardening-patch-4.4.3-0.4.15/Zend/zend_operators.h ---- php-4.4.3/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.3-0.4.15/Zend/zend_operators.h 2006-09-05 20:30:46.000000000 +0200 -@@ -174,6 +174,14 @@ - #endif - - ZEND_API void zend_str_tolower(char *str, unsigned int length); -+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length); -+ -+static inline char * -+zend_str_tolower_dup(const char *source, unsigned int length) -+{ -+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length); -+} -+ - ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2); - ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3); - ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2); diff --git a/hardening-patch-4.4.4-0.4.15.patch b/hardening-patch-4.4.4-0.4.15.patch deleted file mode 100644 index c0208f6..0000000 --- a/hardening-patch-4.4.4-0.4.15.patch +++ /dev/null @@ -1,8300 +0,0 @@ -diff -Nura php-4.4.4/Changelog.hphp hardening-patch-4.4.4-0.4.15/Changelog.hphp ---- php-4.4.4/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Changelog.hphp 2006-09-07 19:32:38.000000000 +0200 -@@ -0,0 +1,61 @@ -+Changelog of the Hardening-Patch -+-------------------------------- -+ -+0.4.15 - 07. September 2006 -+ -+ PHP4: -+ [+] Fix for potential DOS in handling of include blacklists -+ -+ PHP4+5: -+ [+] Backported a fix for open_basedir problems with insanse PHP scripts -+ [+] Added a fix for ini_restore() PHP security vulnerability -+ -+0.4.14 - 11. August 2006 -+ -+ PHP4: -+ [+] Remove unecessary call to AC_BROKEN_REALPATH -+ -+ PHP5: -+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant -+ -+ PHP4+5: -+ [+] Added a few PHP security fixes / see changelog.secfix for details -+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits -+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments -+ -+0.4.13 - 07. August 2006 -+ -+ PHP4+5: -+ [+] Added a fix for a compile problem on solaris due to missing strcasestr() -+ -+0.4.12 - 19. July 2006 -+ -+ PHP4: -+ [+] Added fixes from sf4 security patch / see changelog.secfix for details -+ -+ PHP5: -+ [+] Added fixes from sf5 security patch / see changelog.secfix for details -+ -+ PHP4+5: -+ [+] Added anti mail spam feature -+ [+] Speedup of zend_hash canary (clear/destroy) -+ [+] Added a fix for a DOS in the handling of URL blacklists -+ -+0.4.11 - 13. May 2006 -+ -+ PHP5: -+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache -+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 -+ -+ PHP4+5: -+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories -+ -+ -+0.4.10 - 11. May 2006 -+ -+ PHP4: -+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed -+ -+ PHP4+5: -+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir -+ -diff -Nura php-4.4.4/Changelog.secfix hardening-patch-4.4.4-0.4.15/Changelog.secfix ---- php-4.4.4/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Changelog.secfix 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,17 @@ -+Changelog of PHP 4.4.3 Security Fixes -+ -+Release 2 - 11. August 2006 -+ -+ [+] Added IMAP open_basedir/safe_mode check -+ [+] Added a upstream fix for previous ext/session fixes -+ [+] Added upstream fix to ext/socket -+ [+] Added sscanf() security fix -+ [+] Added fixes for handling of corrupt .gif files to gdlib -+ -+Release 1 - 4. August 2006 -+ -+ [+] Added a fix to disable CURLOPT_FOLLOWLOCATION while in safe_mode()/open_basedir -+ [+] Added a *working* wordwrap() fix -+ [+] Added code to make memory_limit work on 64bit systems -+ [+] Added a fix for an integer overflow in str_repeat() -+ -diff -Nura php-4.4.4/configure hardening-patch-4.4.4-0.4.15/configure ---- php-4.4.4/configure 2006-08-15 14:01:18.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/configure 2006-09-05 20:30:51.000000000 +0200 -@@ -402,6 +402,16 @@ - ac_default_prefix=/usr/local - # Any additions from configure.in: - ac_help="$ac_help -+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." -+ac_help="$ac_help -+ --disable-hardening-patch-ll-protect Disable the Linked List protection." -+ac_help="$ac_help -+ --disable-hardening-patch-inc-protect Disable include/require protection." -+ac_help="$ac_help -+ --disable-hardening-patch-fmt-protect Disable format string protection." -+ac_help="$ac_help -+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." -+ac_help="$ac_help - - SAPI modules: - " -@@ -854,6 +864,8 @@ - ac_help="$ac_help - --disable-tokenizer Disable tokenizer support" - ac_help="$ac_help -+ --disable-varfilter Disable Hardening-Patch's variable filter" -+ac_help="$ac_help - --enable-wddx Enable WDDX support." - ac_help="$ac_help - --disable-xml Disable XML support using bundled expat lib" -@@ -2942,6 +2954,157 @@ - - - -+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. -+if test "${enable_hardening_patch_mm_protect+set}" = set; then -+ enableval="$enable_hardening_patch_mm_protect" -+ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. -+if test "${enable_hardening_patch_ll_protect+set}" = set; then -+ enableval="$enable_hardening_patch_ll_protect" -+ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. -+if test "${enable_hardening_patch_inc_protect+set}" = set; then -+ enableval="$enable_hardening_patch_inc_protect" -+ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. -+if test "${enable_hardening_patch_fmt_protect+set}" = set; then -+ enableval="$enable_hardening_patch_fmt_protect" -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. -+if test "${enable_hardening_patch_hash_protect+set}" = set; then -+ enableval="$enable_hardening_patch_hash_protect" -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+ -+fi -+ -+ -+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 -+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 -+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 -+echo "configure:2733: checking whether to protect include/require statements" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect PHP Format String functions" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 -+ -+ -+cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH 1 -+EOF -+ -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 0 -+EOF -+ -+fi - - - -@@ -16017,6 +16180,62 @@ - fi - - -+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 -+echo "configure:14928: checking whether realpath is broken" >&5 -+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then -+ echo $ac_n "(cached) $ac_c" 1>&6 -+else -+ -+ if test "$cross_compiling" = yes; then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -+then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ echo "configure: failed program was:" >&5 -+ cat conftest.$ac_ext >&5 -+ rm -fr conftest* -+ -+ ac_cv_broken_realpath=yes -+ -+fi -+rm -fr conftest* -+fi -+ -+ -+fi -+ -+echo "$ac_t""$ac_cv_broken_realpath" 1>&6 -+ if test "$ac_cv_broken_realpath" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 1 -+EOF -+ -+ else -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 0 -+EOF -+ -+ fi -+ -+ - echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 - echo "configure:16022: checking for declared timezone" >&5 - if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then -@@ -86718,7 +86937,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - cat >> confdefs.h <&6 -+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 -+# Check whether --enable-varfilter or --disable-varfilter was given. -+if test "${enable_varfilter+set}" = set; then -+ enableval="$enable_varfilter" -+ PHP_VARFILTER=$enableval -+else -+ -+ PHP_VARFILTER=yes -+ -+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then -+ PHP_VARFILTER=$PHP_ENABLE_ALL -+ fi -+ -+fi -+ -+ -+ -+ext_output="yes, shared" -+ext_shared=yes -+case $PHP_VARFILTER in -+shared,*) -+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` -+ ;; -+shared) -+ PHP_VARFILTER=yes -+ ;; -+no) -+ ext_output=no -+ ext_shared=no -+ ;; -+*) -+ ext_output=yes -+ ext_shared=no -+ ;; -+esac -+ -+ -+ -+echo "$ac_t""$ext_output" 1>&6 -+ -+ -+ -+ -+if test "$PHP_VARFILTER" != "no"; then -+ cat >> confdefs.h <<\EOF -+#define HAVE_VARFILTER 1 -+EOF -+ -+ -+ ext_builddir=ext/varfilter -+ ext_srcdir=$abs_srcdir/ext/varfilter -+ -+ ac_extra= -+ -+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then -+ -+ -+ -+ case ext/varfilter in -+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; -+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; -+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; -+ esac -+ -+ -+ -+ b_c_pre=$php_c_pre -+ b_cxx_pre=$php_cxx_pre -+ b_c_meta=$php_c_meta -+ b_cxx_meta=$php_cxx_meta -+ b_c_post=$php_c_post -+ b_cxx_post=$php_cxx_post -+ b_lo=$php_lo -+ -+ -+ old_IFS=$IFS -+ for ac_src in varfilter.c; do -+ -+ IFS=. -+ set $ac_src -+ ac_obj=$1 -+ IFS=$old_IFS -+ -+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" -+ -+ case $ac_src in -+ *.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" ;; -+ *.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" ;; -+ esac -+ -+ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 -@@ -104088,7 +104566,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - streams.c network.c php_open_temporary_file.c php_logos.c \ -- output.c memory_streams.c user_streams.c; do -+ output.c memory_streams.c user_streams.c hardening_patch.c; do - - IFS=. - set $ac_src -@@ -104273,7 +104751,7 @@ - zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ -- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do -+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do - - IFS=. - set $ac_src -diff -Nura php-4.4.4/configure.in hardening-patch-4.4.4-0.4.15/configure.in ---- php-4.4.4/configure.in 2006-08-15 14:22:14.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/configure.in 2006-09-05 20:30:51.000000000 +0200 -@@ -247,7 +247,7 @@ - sinclude(Zend/acinclude.m4) - sinclude(Zend/Zend.m4) - sinclude(TSRM/tsrm.m4) -- -+sinclude(main/hardening_patch.m4) - - - divert(2) -@@ -621,6 +621,7 @@ - AC_FUNC_ALLOCA - dnl PHP_AC_BROKEN_SPRINTF - dnl PHP_AC_BROKEN_SNPRINTF -+dnl PHP_AC_BROKEN_REALPATH - PHP_DECLARED_TIMEZONE - PHP_TIME_R_TYPE - PHP_READDIR_R_TYPE -@@ -1260,7 +1261,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - streams.c network.c php_open_temporary_file.c php_logos.c \ -- output.c memory_streams.c user_streams.c) -+ output.c memory_streams.c user_streams.c hardening_patch.c) - PHP_ADD_SOURCES(/main, internal_functions.c,, sapi) - case $host_alias in - *netware*) -@@ -1281,7 +1282,7 @@ - zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ -- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c) -+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c ) - - if test -r "$abs_srcdir/Zend/zend_objects.c"; then - PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c) -diff -Nura php-4.4.4/ext/fbsql/php_fbsql.c hardening-patch-4.4.4-0.4.15/ext/fbsql/php_fbsql.c ---- php-4.4.4/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1797,8 +1797,24 @@ - } - else if (fbcmdErrorsFound(md)) - { -+#if HARDENING_PATCH -+ char* query_copy; -+ int i; -+#endif - FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); - char* emg = fbcemdAllErrorMessages(emd); -+#if HARDENING_PATCH -+ query_copy=estrdup(query_copy); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ free(emg); -+ fbcemdRelease(emd); -+ result = 0; -+ zend_bailout(); -+ } -+#endif - if (FB_SQL_G(generateWarnings)) - { - if (emg) -diff -Nura php-4.4.4/ext/imap/php_imap.c hardening-patch-4.4.4-0.4.15/ext/imap/php_imap.c ---- php-4.4.4/ext/imap/php_imap.c 2006-08-11 17:07:00.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/ext/imap/php_imap.c 2006-09-05 20:30:51.000000000 +0200 -@@ -738,6 +738,13 @@ - RETURN_FALSE; - } - -+ /* local filename, need to perform open_basedir and safe_mode checks */ -+ if (Z_STRVAL_PP(mailbox)[0] != '{' && -+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || -+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { -+ RETURN_FALSE; -+ } -+ - IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); - IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); - -diff -Nura php-4.4.4/ext/mbstring/mbstring.c hardening-patch-4.4.4-0.4.15/ext/mbstring/mbstring.c ---- php-4.4.4/ext/mbstring/mbstring.c 2006-04-03 15:04:13.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/ext/mbstring/mbstring.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1500,6 +1500,7 @@ - char *strtok_buf = NULL, **val_list; - zval *array_ptr = (zval *) arg; - int n, num, val_len, *len_list; -+ unsigned int new_val_len; - enum mbfl_no_encoding from_encoding; - mbfl_string string, resvar, resval; - mbfl_encoding_detector *identd = NULL; -@@ -1622,8 +1623,14 @@ - val_len = len_list[n]; - } - n++; -- /* add variable to symbol table */ -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ /* we need val to be emalloc()ed */ -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ /* add variable to symbol table */ -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); -+ - if (convd != NULL){ - mbfl_string_clear(&resvar); - mbfl_string_clear(&resval); -diff -Nura php-4.4.4/ext/mysql/php_mysql.c hardening-patch-4.4.4-0.4.15/ext/mysql/php_mysql.c ---- php-4.4.4/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1218,6 +1218,8 @@ - { - php_mysql_conn *mysql; - MYSQL_RES *mysql_result; -+ char *copy_query; -+ int i; - - ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); - -@@ -1268,6 +1270,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #else -@@ -1275,12 +1284,20 @@ - /* check possible error */ - if (MySG(trace_mode)){ - if (mysql_errno(&mysql->conn)){ -- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn)); -+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #endif -+ - if(use_store == MYSQL_USE_RESULT) { - mysql_result=mysql_use_result(&mysql->conn); - } else { -diff -Nura php-4.4.4/ext/pgsql/pgsql.c hardening-patch-4.4.4-0.4.15/ext/pgsql/pgsql.c ---- php-4.4.4/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1001,10 +1001,28 @@ - case PGRES_EMPTY_QUERY: - case PGRES_BAD_RESPONSE: - case PGRES_NONFATAL_ERROR: -- case PGRES_FATAL_ERROR: -- PHP_PQ_ERROR("Query failed: %s", pgsql); -- PQclear(pgsql_result); -- RETURN_FALSE; -+ case PGRES_FATAL_ERROR: -+ { -+#if HARDENING_PATCH -+ int i; -+ char *query_copy; -+#endif -+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); -+ PQclear(pgsql_result); -+#if HARDENING_PATCH -+ query_copy = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ efree(msgbuf); -+ zend_bailout(); -+ } -+#endif -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); -+ efree(msgbuf); -+ RETURN_FALSE; -+ } - break; - case PGRES_COMMAND_OK: /* successful command that did not return rows */ - default: -diff -Nura php-4.4.4/ext/session/mod_files.c hardening-patch-4.4.4-0.4.15/ext/session/mod_files.c ---- php-4.4.4/ext/session/mod_files.c 2006-08-11 17:04:28.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_files.c 2006-09-05 20:30:51.000000000 +0200 -@@ -397,6 +397,34 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(files) -+{ -+ char buf[MAXPATHLEN]; -+ int fd; -+ PS_FILES_DATA; -+ -+ if (!ps_files_valid_key(key)) { -+ return FAILURE; -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { -+ return FAILURE; -+ } -+ -+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600); -+ -+ if (fd != -1) { -+ close(fd); -+ return SUCCESS; -+ } -+ -+ return FAILURE; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-4.4.4/ext/session/mod_mm.c hardening-patch-4.4.4-0.4.15/ext/session/mod_mm.c ---- php-4.4.4/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_mm.c 2006-09-05 20:30:51.000000000 +0200 -@@ -425,6 +425,42 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(mm) -+{ -+ PS_MM_DATA; -+ ps_sd *sd; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ } -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ mm_lock(data->mm, MM_LOCK_RD); -+ -+ sd = ps_sd_lookup(data, key, 0); -+ if (sd) { -+ mm_unlock(data->mm); -+ return SUCCESS; -+ } -+ -+ mm_unlock(data->mm); -+ -+ return FAILURE; -+} -+ - #endif - - /* -diff -Nura php-4.4.4/ext/session/mod_user.c hardening-patch-4.4.4-0.4.15/ext/session/mod_user.c ---- php-4.4.4/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_user.c 2006-09-05 20:30:51.000000000 +0200 -@@ -23,7 +23,7 @@ - #include "mod_user.h" - - ps_module ps_mod_user = { -- PS_MOD(user) -+ PS_MOD_SID(user) - }; - - #define SESS_ZVAL_LONG(val, a) \ -@@ -174,6 +174,83 @@ - FINISH; - } - -+PS_CREATE_SID_FUNC(user) -+{ -+ int i; -+ char *val = NULL; -+ zval *retval; -+ ps_user *mdata = PS_GET_MOD_DATA(); -+ -+ if (!mdata) -+ return estrndup("", 0); -+ -+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { -+ return php_session_create_id(mod_data, newlen TSRMLS_CC); -+ } -+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); -+ -+ if (retval) { -+ if (Z_TYPE_P(retval) == IS_STRING) { -+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); -+ } else { -+ val = estrndup("", 0); -+ } -+ zval_ptr_dtor(&retval); -+ } else { -+ val = estrndup("", 0); -+ } -+ -+ return val; -+} -+ -+static int ps_user_valid_key(const char *key TSRMLS_DC) -+{ -+ size_t len; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ ret = FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ ret = FAILURE; -+ -+ return ret; -+} -+ -+PS_VALIDATE_SID_FUNC(user) -+{ -+ zval *args[1]; -+ STDVARS; -+ -+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { -+ return ps_user_valid_key(key TSRMLS_CC); -+ } -+ SESS_ZVAL_STRING(key, args[0]); -+ -+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); -+ -+ if (retval) { -+ convert_to_long(retval); -+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; -+ zval_ptr_dtor(&retval); -+ } -+ -+ return ret; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-4.4.4/ext/session/mod_user.h hardening-patch-4.4.4-0.4.15/ext/session/mod_user.h ---- php-4.4.4/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_user.h 2006-09-05 20:30:51.000000000 +0200 -@@ -22,7 +22,7 @@ - #define MOD_USER_H - - typedef union { -- zval *names[6]; -+ zval *names[8]; - struct { - zval *ps_open; - zval *ps_close; -@@ -30,6 +30,8 @@ - zval *ps_write; - zval *ps_destroy; - zval *ps_gc; -+ zval *ps_create; -+ zval *ps_validate; - } name; - } ps_user; - -diff -Nura php-4.4.4/ext/session/php_session.h hardening-patch-4.4.4-0.4.15/ext/session/php_session.h ---- php-4.4.4/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/php_session.h 2006-09-05 20:30:51.000000000 +0200 -@@ -23,7 +23,7 @@ - - #include "ext/standard/php_var.h" - --#define PHP_SESSION_API 20020330 -+#define PHP_SESSION_API 20051121 - - #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC - #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC -@@ -32,6 +32,7 @@ - #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC - #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC - #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC -+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC - - /* default create id function */ - char *php_session_create_id(PS_CREATE_SID_ARGS); -@@ -45,6 +46,7 @@ - int (*s_destroy)(PS_DESTROY_ARGS); - int (*s_gc)(PS_GC_ARGS); - char *(*s_create_sid)(PS_CREATE_SID_ARGS); -+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); - } ps_module; - - #define PS_GET_MOD_DATA() *mod_data -@@ -57,6 +59,7 @@ - #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) - #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) - #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) -+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) - - #define PS_FUNCS(x) \ - PS_OPEN_FUNC(x); \ -@@ -65,11 +68,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID_FUNC(x) - - #define PS_MOD(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, php_session_create_id -+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x - - /* SID enabled module handler definitions */ - #define PS_FUNCS_SID(x) \ -@@ -79,11 +83,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID(x) - - #define PS_MOD_SID(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, ps_create_sid_##x -+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x - - typedef enum { - php_session_disabled, -@@ -120,6 +125,7 @@ - zend_bool use_only_cookies; - zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ - zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ -+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ - int send_cookie; - int define_sid; - } php_ps_globals; -diff -Nura php-4.4.4/ext/session/session.c hardening-patch-4.4.4-0.4.15/ext/session/session.c ---- php-4.4.4/ext/session/session.c 2006-08-01 10:33:13.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/ext/session/session.c 2006-09-05 20:30:51.000000000 +0200 -@@ -155,6 +155,7 @@ - STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) -+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals) -@@ -643,6 +644,15 @@ - return; - } - -+ /* If there is an ID, use session module to verify it */ -+ if (PS(id)) { -+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ efree(PS(id)); -+ PS(id) = NULL; -+ PS(send_cookie) = 1; -+ } -+ } -+ - /* If there is no ID, use session module to create one */ - if (!PS(id)) - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); -@@ -1266,18 +1276,25 @@ - Sets user-level functions */ - PHP_FUNCTION(session_set_save_handler) - { -- zval **args[6]; -- int i; -+ zval **args[8]; -+ int i, numargs; - ps_user *mdata; - char *name; - -- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) -+ numargs = ZEND_NUM_ARGS(); -+ args[6] = NULL; -+ args[7] = NULL; -+ -+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) - WRONG_PARAM_COUNT; - - if (PS(session_status) != php_session_none) - RETURN_FALSE; - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ continue; -+ } - if (!zend_is_callable(*args[i], 0, &name)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); - efree(name); -@@ -1290,7 +1307,11 @@ - - mdata = emalloc(sizeof(*mdata)); - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ mdata->names[i] = NULL; -+ continue; -+ } - ZVAL_ADDREF(*args[i]); - mdata->names[i] = *args[i]; - } -@@ -1351,12 +1372,24 @@ - Update the current session id with a newly generated one. */ - PHP_FUNCTION(session_regenerate_id) - { -+ zend_bool del_ses = 0; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) { -+ WRONG_PARAM_COUNT; -+ } -+ - if (SG(headers_sent)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); - RETURN_FALSE; - } - if (PS(session_status) == php_session_active) { -- if (PS(id)) efree(PS(id)); -+ if (PS(id)) { -+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed"); -+ RETURN_FALSE; -+ } -+ efree(PS(id)); -+ } - - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); - -diff -Nura php-4.4.4/ext/session/tests/014.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/014.phpt ---- php-4.4.4/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:30:51.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.bug_compat_42=1 -diff -Nura php-4.4.4/ext/session/tests/015.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/015.phpt ---- php-4.4.4/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:30:51.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - arg_separator.output=& - session.name=PHPSESSID -diff -Nura php-4.4.4/ext/session/tests/018.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/018.phpt ---- php-4.4.4/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:30:51.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - session.name=PHPSESSID -diff -Nura php-4.4.4/ext/session/tests/020.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/020.phpt ---- php-4.4.4/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:30:51.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - arg_separator.output=& -diff -Nura php-4.4.4/ext/session/tests/021.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/021.phpt ---- php-4.4.4/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:30:51.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" -diff -Nura php-4.4.4/ext/standard/array.c hardening-patch-4.4.4-0.4.15/ext/standard/array.c ---- php-4.4.4/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/array.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1162,6 +1162,32 @@ - } - } - } -+ -+ if (var_name[0] == 'H') { -+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_FILES")==0)|| -+ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { -+ return 0; -+ } -+ } else if (var_name[0] == '_') { -+ if ((strcmp(var_name, "_COOKIE")==0)|| -+ (strcmp(var_name, "_ENV")==0)|| -+ (strcmp(var_name, "_FILES")==0)|| -+ (strcmp(var_name, "_GET")==0)|| -+ (strcmp(var_name, "_POST")==0)|| -+ (strcmp(var_name, "_REQUEST")==0)|| -+ (strcmp(var_name, "_SESSION")==0)|| -+ (strcmp(var_name, "_SERVER")==0)) { -+ return 0; -+ } -+ } else if (strcmp(var_name, "GLOBALS")==0) { -+ return 0; -+ } - - return 1; - } -diff -Nura php-4.4.4/ext/standard/basic_functions.c hardening-patch-4.4.4-0.4.15/ext/standard/basic_functions.c ---- php-4.4.4/ext/standard/basic_functions.c 2006-06-29 00:09:09.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:34:48.000000000 +0200 -@@ -107,12 +107,14 @@ - typedef struct _php_shutdown_function_entry { - zval **arguments; - int arg_count; -+ zend_bool created_by_eval; - } php_shutdown_function_entry; - - typedef struct _user_tick_function_entry { - zval **arguments; - int arg_count; - int calling; -+ zend_bool created_by_eval; - } user_tick_function_entry; - - /* some prototypes for local functions */ -@@ -295,6 +297,8 @@ - PHP_FE(get_html_translation_table, NULL) - PHP_FE(sha1, NULL) - PHP_FE(sha1_file, NULL) -+ PHP_FE(sha256, NULL) -+ PHP_FE(sha256_file, NULL) - PHP_NAMED_FE(md5,php_if_md5, NULL) - PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) - PHP_NAMED_FE(crc32,php_if_crc32, NULL) -@@ -676,7 +680,7 @@ - PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) - - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) -- PHP_FE(realpath, NULL) -+ PHP_STATIC_FE("realpath", zif_real_path, NULL) - #endif - - #ifdef HAVE_FNMATCH -@@ -2101,6 +2105,13 @@ - { - zval retval; - char *function_name = NULL; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (shutdown_function_entry->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { - php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); -@@ -2116,6 +2127,9 @@ - if (function_name) { - efree(function_name); - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - return 0; - } - -@@ -2123,6 +2137,13 @@ - { - zval retval; - zval *function = tick_fe->arguments[0]; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (tick_fe->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - /* Prevent reentrant calls to the same user ticks function */ - if (! tick_fe->calling) { -@@ -2154,6 +2175,9 @@ - - tick_fe->calling = 0; - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - } - - static void run_user_tick_functions(int tick_count) -@@ -2222,6 +2246,13 @@ - efree(shutdown_function_entry.arguments); - RETURN_FALSE; - } -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ shutdown_function_entry.created_by_eval = 1; -+ } else { -+ shutdown_function_entry.created_by_eval = 0; -+ } -+#endif - - /* Prevent entering of anything but valid callback (syntax check only!) */ - if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { -@@ -2503,6 +2534,15 @@ - - convert_to_string_ex(varname); - -+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ -+ if (PG(safe_mode)) { -+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || -+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || -+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { -+ RETURN_FALSE; -+ } -+ } -+ - zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); - } - /* }}} */ -@@ -2759,6 +2799,13 @@ - } - - tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ tick_fe.created_by_eval = 1; -+ } else { -+ tick_fe.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { - efree(tick_fe.arguments); -@@ -3057,6 +3104,35 @@ - new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); - } - -+ if (new_key[0] == 'H') { -+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_FILES")==0)|| -+ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (new_key[0] == '_') { -+ if ((strcmp(new_key, "_COOKIE")==0)|| -+ (strcmp(new_key, "_ENV")==0)|| -+ (strcmp(new_key, "_FILES")==0)|| -+ (strcmp(new_key, "_GET")==0)|| -+ (strcmp(new_key, "_POST")==0)|| -+ (strcmp(new_key, "_REQUEST")==0)|| -+ (strcmp(new_key, "_SESSION")==0)|| -+ (strcmp(new_key, "_SERVER")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (strcmp(new_key, "GLOBALS")==0) { -+ efree(new_key); -+ return 0; -+ } -+ - zend_hash_del(&EG(symbol_table), new_key, new_key_len); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); - -diff -Nura php-4.4.4/ext/standard/config.m4 hardening-patch-4.4.4-0.4.15/ext/standard/config.m4 ---- php-4.4.4/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/config.m4 2006-09-05 20:30:51.000000000 +0200 -@@ -203,7 +203,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) - ]) -@@ -419,6 +419,6 @@ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ -- var_unserializer.c ftok.c aggregation.c sha1.c ) -+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ) - - PHP_ADD_MAKEFILE_FRAGMENT -diff -Nura php-4.4.4/ext/standard/crypt_blowfish.c hardening-patch-4.4.4-0.4.15/ext/standard/crypt_blowfish.c ---- php-4.4.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,748 @@ -+/* -+ * This code comes from John the Ripper password cracker, with reentrant -+ * and crypt(3) interfaces added, but optimizations specific to password -+ * cracking removed. -+ * -+ * Written by Solar Designer in 1998-2002 and -+ * placed in the public domain. -+ * -+ * There's absolutely no warranty. -+ * -+ * It is my intent that you should be able to use this on your system, -+ * as a part of a software package, or anywhere else to improve security, -+ * ensure compatibility, or for any other purpose. I would appreciate -+ * it if you give credit where it is due and keep your modifications in -+ * the public domain as well, but I don't require that in order to let -+ * you place this code and any modifications you make under a license -+ * of your choice. -+ * -+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) -+ * by Niels Provos , and uses some of his -+ * ideas. The password hashing algorithm was designed by David Mazieres -+ * . -+ * -+ * There's a paper on the algorithm that explains its design decisions: -+ * -+ * http://www.usenix.org/events/usenix99/provos.html -+ * -+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's -+ * Blowfish library (I can't be sure if I would think of something if I -+ * hadn't seen his code). -+ */ -+ -+#include -+ -+#include -+#ifndef __set_errno -+#define __set_errno(val) errno = (val) -+#endif -+ -+#undef __CONST -+#ifdef __GNUC__ -+#define __CONST __const -+#else -+#define __CONST -+#endif -+ -+#ifdef __i386__ -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#elif defined(__alpha__) || defined(__hppa__) -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#else -+#define BF_ASM 0 -+#define BF_SCALE 0 -+#endif -+ -+typedef unsigned int BF_word; -+ -+/* Number of Blowfish rounds, this is also hardcoded into a few places */ -+#define BF_N 16 -+ -+typedef BF_word BF_key[BF_N + 2]; -+ -+typedef struct { -+ BF_word S[4][0x100]; -+ BF_key P; -+} BF_ctx; -+ -+/* -+ * Magic IV for 64 Blowfish encryptions that we do at the end. -+ * The string is "OrpheanBeholderScryDoubt" on big-endian. -+ */ -+static BF_word BF_magic_w[6] = { -+ 0x4F727068, 0x65616E42, 0x65686F6C, -+ 0x64657253, 0x63727944, 0x6F756274 -+}; -+ -+/* -+ * P-box and S-box tables initialized with digits of Pi. -+ */ -+static BF_ctx BF_init_state = { -+ { -+ { -+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, -+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, -+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, -+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, -+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, -+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, -+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, -+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, -+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, -+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, -+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, -+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, -+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, -+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, -+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, -+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, -+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, -+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, -+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, -+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, -+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, -+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, -+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, -+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, -+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, -+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, -+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, -+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, -+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, -+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, -+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, -+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, -+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, -+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, -+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, -+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, -+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, -+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, -+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, -+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, -+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, -+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, -+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, -+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, -+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, -+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, -+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, -+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, -+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, -+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, -+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, -+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, -+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, -+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, -+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, -+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, -+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, -+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, -+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, -+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, -+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, -+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, -+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, -+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a -+ }, { -+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, -+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, -+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, -+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, -+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, -+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, -+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, -+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, -+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, -+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, -+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, -+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, -+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, -+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, -+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, -+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, -+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, -+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, -+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, -+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, -+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, -+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, -+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, -+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, -+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, -+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, -+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, -+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, -+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, -+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, -+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, -+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, -+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, -+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, -+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, -+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, -+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, -+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, -+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, -+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, -+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, -+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, -+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, -+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, -+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, -+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, -+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, -+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, -+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, -+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, -+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, -+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, -+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, -+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, -+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, -+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, -+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, -+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, -+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, -+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, -+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, -+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, -+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, -+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 -+ }, { -+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, -+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, -+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, -+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, -+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, -+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, -+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, -+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, -+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, -+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, -+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, -+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, -+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, -+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, -+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, -+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, -+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, -+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, -+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, -+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, -+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, -+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, -+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, -+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, -+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, -+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, -+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, -+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, -+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, -+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, -+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, -+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, -+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, -+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, -+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, -+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, -+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, -+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, -+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, -+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, -+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, -+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, -+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, -+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, -+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, -+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, -+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, -+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, -+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, -+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, -+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, -+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, -+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, -+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, -+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, -+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, -+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, -+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, -+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, -+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, -+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, -+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, -+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, -+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 -+ }, { -+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, -+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, -+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, -+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, -+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, -+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, -+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, -+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, -+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, -+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, -+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, -+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, -+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, -+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, -+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, -+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, -+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, -+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, -+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, -+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, -+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, -+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, -+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, -+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, -+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, -+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, -+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, -+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, -+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, -+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, -+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, -+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, -+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, -+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, -+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, -+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, -+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, -+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, -+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, -+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, -+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, -+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, -+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, -+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, -+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, -+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, -+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, -+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, -+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, -+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, -+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, -+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, -+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, -+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, -+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, -+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, -+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, -+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, -+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, -+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, -+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, -+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, -+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, -+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 -+ } -+ }, { -+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, -+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, -+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, -+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, -+ 0x9216d5d9, 0x8979fb1b -+ } -+}; -+ -+static unsigned char BF_itoa64[64 + 1] = -+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -+ -+static unsigned char BF_atoi64[0x60] = { -+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, -+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, -+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, -+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, -+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -+}; -+ -+/* -+ * This may be optimized out if built with function inlining and no BF_ASM. -+ */ -+static void clean(void *data, int size) -+{ -+#if BF_ASM -+ extern void _BF_clean(void *data); -+#endif -+ memset(data, 0, size); -+#if BF_ASM -+ _BF_clean(data); -+#endif -+} -+ -+#define BF_safe_atoi64(dst, src) \ -+{ \ -+ tmp = (unsigned char)(src); \ -+ if (tmp == '$') break; \ -+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ -+ tmp = BF_atoi64[tmp]; \ -+ if (tmp > 63) return -1; \ -+ (dst) = tmp; \ -+} -+ -+static int BF_decode(BF_word *dst, __CONST char *src, int size) -+{ -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned char *end = dptr + size; -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned int tmp, c1, c2, c3, c4; -+ -+ do { -+ BF_safe_atoi64(c1, *sptr++); -+ BF_safe_atoi64(c2, *sptr++); -+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c3, *sptr++); -+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c4, *sptr++); -+ *dptr++ = ((c3 & 0x03) << 6) | c4; -+ } while (dptr < end); -+ -+ while (dptr < end) -+ *dptr++ = 0; -+ -+ return 0; -+} -+ -+static void BF_encode(char *dst, __CONST BF_word *src, int size) -+{ -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned char *end = sptr + size; -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned int c1, c2; -+ -+ do { -+ c1 = *sptr++; -+ *dptr++ = BF_itoa64[c1 >> 2]; -+ c1 = (c1 & 0x03) << 4; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 4; -+ *dptr++ = BF_itoa64[c1]; -+ c1 = (c2 & 0x0f) << 2; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 6; -+ *dptr++ = BF_itoa64[c1]; -+ *dptr++ = BF_itoa64[c2 & 0x3f]; -+ } while (sptr < end); -+} -+ -+static void BF_swap(BF_word *x, int count) -+{ -+ static int endianness_check = 1; -+ char *is_little_endian = (char *)&endianness_check; -+ BF_word tmp; -+ -+ if (*is_little_endian) -+ do { -+ tmp = *x; -+ tmp = (tmp << 16) | (tmp >> 16); -+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); -+ } while (--count); -+} -+ -+#if BF_SCALE -+/* Architectures which can shift addresses left by 2 bits with no extra cost */ -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp2 = L >> 8; \ -+ tmp2 &= 0xFF; \ -+ tmp3 = L >> 16; \ -+ tmp3 &= 0xFF; \ -+ tmp4 = L >> 24; \ -+ tmp1 = data.ctx.S[3][tmp1]; \ -+ tmp2 = data.ctx.S[2][tmp2]; \ -+ tmp3 = data.ctx.S[1][tmp3]; \ -+ tmp3 += data.ctx.S[0][tmp4]; \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#else -+/* Architectures with no complicated addressing modes supported */ -+#define BF_INDEX(S, i) \ -+ (*((BF_word *)(((unsigned char *)S) + (i)))) -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp1 <<= 2; \ -+ tmp2 = L >> 6; \ -+ tmp2 &= 0x3FC; \ -+ tmp3 = L >> 14; \ -+ tmp3 &= 0x3FC; \ -+ tmp4 = L >> 22; \ -+ tmp4 &= 0x3FC; \ -+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ -+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ -+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ -+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#endif -+ -+/* -+ * Encrypt one block, BF_N is hardcoded here. -+ */ -+#define BF_ENCRYPT \ -+ L ^= data.ctx.P[0]; \ -+ BF_ROUND(L, R, 0); \ -+ BF_ROUND(R, L, 1); \ -+ BF_ROUND(L, R, 2); \ -+ BF_ROUND(R, L, 3); \ -+ BF_ROUND(L, R, 4); \ -+ BF_ROUND(R, L, 5); \ -+ BF_ROUND(L, R, 6); \ -+ BF_ROUND(R, L, 7); \ -+ BF_ROUND(L, R, 8); \ -+ BF_ROUND(R, L, 9); \ -+ BF_ROUND(L, R, 10); \ -+ BF_ROUND(R, L, 11); \ -+ BF_ROUND(L, R, 12); \ -+ BF_ROUND(R, L, 13); \ -+ BF_ROUND(L, R, 14); \ -+ BF_ROUND(R, L, 15); \ -+ tmp4 = R; \ -+ R = L; \ -+ L = tmp4 ^ data.ctx.P[BF_N + 1]; -+ -+#if BF_ASM -+#define BF_body() \ -+ _BF_body_r(&data.ctx); -+#else -+#define BF_body() \ -+ L = R = 0; \ -+ ptr = data.ctx.P; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.P[BF_N + 2]); \ -+\ -+ ptr = data.ctx.S[0]; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.S[3][0xFF]); -+#endif -+ -+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) -+{ -+ __CONST char *ptr = key; -+ int i, j; -+ BF_word tmp; -+ -+ for (i = 0; i < BF_N + 2; i++) { -+ tmp = 0; -+ for (j = 0; j < 4; j++) { -+ tmp <<= 8; -+ tmp |= *ptr; -+ -+ if (!*ptr) ptr = key; else ptr++; -+ } -+ -+ expanded[i] = tmp; -+ initial[i] = BF_init_state.P[i] ^ tmp; -+ } -+} -+ -+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, -+ char *output, int size) -+{ -+#if BF_ASM -+ extern void _BF_body_r(BF_ctx *ctx); -+#endif -+ struct { -+ BF_ctx ctx; -+ BF_key expanded_key; -+ union { -+ BF_word salt[4]; -+ BF_word output[6]; -+ } binary; -+ } data; -+ BF_word L, R; -+ BF_word tmp1, tmp2, tmp3, tmp4; -+ BF_word *ptr; -+ BF_word count; -+ int i; -+ -+ if (size < 7 + 22 + 31 + 1) { -+ __set_errno(ERANGE); -+ return NULL; -+ } -+ -+ if (setting[0] != '$' || -+ setting[1] != '2' || -+ setting[2] != 'a' || -+ setting[3] != '$' || -+ setting[4] < '0' || setting[4] > '3' || -+ setting[5] < '0' || setting[5] > '9' || -+ setting[6] != '$') { -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); -+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { -+ clean(data.binary.salt, sizeof(data.binary.salt)); -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ BF_swap(data.binary.salt, 4); -+ -+ BF_set_key(key, data.expanded_key, data.ctx.P); -+ -+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); -+ -+ L = R = 0; -+ for (i = 0; i < BF_N + 2; i += 2) { -+ L ^= data.binary.salt[i & 2]; -+ R ^= data.binary.salt[(i & 2) + 1]; -+ BF_ENCRYPT; -+ data.ctx.P[i] = L; -+ data.ctx.P[i + 1] = R; -+ } -+ -+ ptr = data.ctx.S[0]; -+ do { -+ ptr += 4; -+ L ^= data.binary.salt[(BF_N + 2) & 3]; -+ R ^= data.binary.salt[(BF_N + 3) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 4) = L; -+ *(ptr - 3) = R; -+ -+ L ^= data.binary.salt[(BF_N + 4) & 3]; -+ R ^= data.binary.salt[(BF_N + 5) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 2) = L; -+ *(ptr - 1) = R; -+ } while (ptr < &data.ctx.S[3][0xFF]); -+ -+ do { -+ data.ctx.P[0] ^= data.expanded_key[0]; -+ data.ctx.P[1] ^= data.expanded_key[1]; -+ data.ctx.P[2] ^= data.expanded_key[2]; -+ data.ctx.P[3] ^= data.expanded_key[3]; -+ data.ctx.P[4] ^= data.expanded_key[4]; -+ data.ctx.P[5] ^= data.expanded_key[5]; -+ data.ctx.P[6] ^= data.expanded_key[6]; -+ data.ctx.P[7] ^= data.expanded_key[7]; -+ data.ctx.P[8] ^= data.expanded_key[8]; -+ data.ctx.P[9] ^= data.expanded_key[9]; -+ data.ctx.P[10] ^= data.expanded_key[10]; -+ data.ctx.P[11] ^= data.expanded_key[11]; -+ data.ctx.P[12] ^= data.expanded_key[12]; -+ data.ctx.P[13] ^= data.expanded_key[13]; -+ data.ctx.P[14] ^= data.expanded_key[14]; -+ data.ctx.P[15] ^= data.expanded_key[15]; -+ data.ctx.P[16] ^= data.expanded_key[16]; -+ data.ctx.P[17] ^= data.expanded_key[17]; -+ -+ BF_body(); -+ -+ tmp1 = data.binary.salt[0]; -+ tmp2 = data.binary.salt[1]; -+ tmp3 = data.binary.salt[2]; -+ tmp4 = data.binary.salt[3]; -+ data.ctx.P[0] ^= tmp1; -+ data.ctx.P[1] ^= tmp2; -+ data.ctx.P[2] ^= tmp3; -+ data.ctx.P[3] ^= tmp4; -+ data.ctx.P[4] ^= tmp1; -+ data.ctx.P[5] ^= tmp2; -+ data.ctx.P[6] ^= tmp3; -+ data.ctx.P[7] ^= tmp4; -+ data.ctx.P[8] ^= tmp1; -+ data.ctx.P[9] ^= tmp2; -+ data.ctx.P[10] ^= tmp3; -+ data.ctx.P[11] ^= tmp4; -+ data.ctx.P[12] ^= tmp1; -+ data.ctx.P[13] ^= tmp2; -+ data.ctx.P[14] ^= tmp3; -+ data.ctx.P[15] ^= tmp4; -+ data.ctx.P[16] ^= tmp1; -+ data.ctx.P[17] ^= tmp2; -+ -+ BF_body(); -+ } while (--count); -+ -+ for (i = 0; i < 6; i += 2) { -+ L = BF_magic_w[i]; -+ R = BF_magic_w[i + 1]; -+ -+ count = 64; -+ do { -+ BF_ENCRYPT; -+ } while (--count); -+ -+ data.binary.output[i] = L; -+ data.binary.output[i + 1] = R; -+ } -+ -+ memcpy(output, setting, 7 + 22 - 1); -+ output[7 + 22 - 1] = BF_itoa64[(int) -+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; -+ -+/* This has to be bug-compatible with the original implementation, so -+ * only encode 23 of the 24 bytes. :-) */ -+ BF_swap(data.binary.output, 6); -+ BF_encode(&output[7 + 22], data.binary.output, 23); -+ output[7 + 22 + 31] = '\0'; -+ -+/* Overwrite the most obvious sensitive data we have on the stack. Note -+ * that this does not guarantee there's no sensitive data left on the -+ * stack and/or in registers; I'm not aware of portable code that does. */ -+ clean(&data, sizeof(data)); -+ -+ return output; -+} -+ -+char *_crypt_gensalt_blowfish_rn(unsigned long count, -+ __CONST char *input, int size, char *output, int output_size) -+{ -+ if (size < 16 || output_size < 7 + 22 + 1 || -+ (count && (count < 4 || count > 31))) { -+ if (output_size > 0) output[0] = '\0'; -+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); -+ return NULL; -+ } -+ -+ if (!count) count = 5; -+ -+ output[0] = '$'; -+ output[1] = '2'; -+ output[2] = 'a'; -+ output[3] = '$'; -+ output[4] = '0' + count / 10; -+ output[5] = '0' + count % 10; -+ output[6] = '$'; -+ -+ BF_encode(&output[7], (BF_word *)input, 16); -+ output[7 + 22] = '\0'; -+ -+ return output; -+} -diff -Nura php-4.4.4/ext/standard/crypt.c hardening-patch-4.4.4-0.4.15/ext/standard/crypt.c ---- php-4.4.4/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/crypt.c 2006-09-05 20:30:51.000000000 +0200 -@@ -100,6 +100,8 @@ - return SUCCESS; - } - -+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); -+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); - - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -@@ -135,7 +137,14 @@ - - /* The automatic salt generation only covers standard DES and md5-crypt */ - if(!*salt) { --#if PHP_MD5_CRYPT -+#if PHP_BLOWFISH_CRYPT -+ char randat[16]; -+ int i; -+ -+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; -+ -+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); -+#elif PHP_MD5_CRYPT - strcpy(salt, "$1$"); - php_to64(&salt[3], PHP_CRYPT_RAND, 4); - php_to64(&salt[7], PHP_CRYPT_RAND, 4); -@@ -145,8 +154,24 @@ - salt[2] = '\0'; - #endif - } -- -- RETVAL_STRING(crypt(str, salt), 1); -+ -+ if (salt[0] == '$' && -+ salt[1] == '2' && -+ salt[2] == 'a' && -+ salt[3] == '$' && -+ salt[4] >= '0' && salt[4] <= '3' && -+ salt[5] >= '0' && salt[5] <= '9' && -+ salt[6] == '$') { -+ -+ char output[PHP_MAX_SALT_LEN+1]; -+ -+ output[0] = 0; -+ _crypt_blowfish_rn(str, salt, output, sizeof(output)); -+ RETVAL_STRING(output, 1); -+ -+ } else { -+ RETVAL_STRING(crypt(str, salt), 1); -+ } - } - /* }}} */ - #endif -diff -Nura php-4.4.4/ext/standard/dl.c hardening-patch-4.4.4-0.4.15/ext/standard/dl.c ---- php-4.4.4/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/dl.c 2006-09-05 20:30:51.000000000 +0200 -@@ -160,8 +160,35 @@ - RETURN_FALSE; - } - module_entry = get_module(); -+ -+ /* check if Hardening-Patch is installed */ -+ if (module_entry->zend_api < 1000000000) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ -+ /* check if correct Hardening-Patch is installed */ -+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ - if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) -- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { -+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { - /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ - struct pre_4_1_0_module_entry { - char *name; -@@ -195,7 +222,7 @@ - zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; - } else { - name = module_entry->name; -- zend_api = module_entry->zend_api; -+ zend_api = module_entry->real_zend_api; - zend_debug = module_entry->zend_debug; - zts = module_entry->zts; - } -diff -Nura php-4.4.4/ext/standard/file.c hardening-patch-4.4.4-0.4.15/ext/standard/file.c ---- php-4.4.4/ext/standard/file.c 2006-04-14 19:46:59.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/file.c 2006-09-05 20:30:51.000000000 +0200 -@@ -2527,7 +2527,7 @@ - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) - /* {{{ proto string realpath(string path) - Return the resolved path */ --PHP_FUNCTION(realpath) -+PHP_FUNCTION(real_path) - { - zval **path; - char resolved_path_buff[MAXPATHLEN]; -diff -Nura php-4.4.4/ext/standard/file.h hardening-patch-4.4.4-0.4.15/ext/standard/file.h ---- php-4.4.4/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/file.h 2006-09-05 20:30:51.000000000 +0200 -@@ -64,7 +64,7 @@ - PHP_FUNCTION(fd_set); - PHP_FUNCTION(fd_isset); - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) --PHP_FUNCTION(realpath); -+PHP_FUNCTION(real_path); - #endif - #ifdef HAVE_FNMATCH - PHP_FUNCTION(fnmatch); -diff -Nura php-4.4.4/ext/standard/head.c hardening-patch-4.4.4-0.4.15/ext/standard/head.c ---- php-4.4.4/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/head.c 2006-09-05 20:30:51.000000000 +0200 -@@ -44,7 +44,7 @@ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, - &ctr.line_len, &rep, &ctr.response_code) == FAILURE) - return; -- -+ - sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); - } - /* }}} */ -diff -Nura php-4.4.4/ext/standard/mail.c hardening-patch-4.4.4-0.4.15/ext/standard/mail.c ---- php-4.4.4/ext/standard/mail.c 2006-01-01 14:46:57.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/mail.c 2006-09-05 20:30:51.000000000 +0200 -@@ -78,6 +78,25 @@ - } - /* }}} */ - -+/* {{{ hphp_strcasestr */ -+char *hphp_strcasestr(char *haystack, char *needle) -+{ -+ unsigned char *t, *h, *n; -+ -+ h = (unsigned char *) haystack; -+conts: -+ while (*h) { -+ n = (unsigned char *) needle; -+ for (t=h++; *n && *h; t++, n++) { -+ if (toupper(*t) != toupper(*n)) goto conts; -+ } -+ return ((char*)h-1); -+ } -+ -+ return (NULL); -+} -+/* }}} */ -+ - /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) - Send an email message */ - PHP_FUNCTION(mail) -@@ -103,6 +122,44 @@ - return; - } - -+ if (HG(hphp_mailprotect) > 0) { -+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { -+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ /* check for spam attempts with buggy webforms */ -+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (HG(hphp_mailprotect) > 1) { -+ /* search for to, cc or bcc headers */ -+ if (headers_len > 0 && headers != NULL) { -+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { -+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { -+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { -+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ } -+ } -+ } -+ - if (to_len > 0) { - to_r = estrndup(to, to_len); - for (; to_len; to_len--) { -diff -Nura php-4.4.4/ext/standard/php_standard.h hardening-patch-4.4.4-0.4.15/ext/standard/php_standard.h ---- php-4.4.4/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/php_standard.h 2006-09-05 20:30:51.000000000 +0200 -@@ -28,6 +28,7 @@ - #include "php_mail.h" - #include "md5.h" - #include "sha1.h" -+#include "sha256.h" - #include "html.h" - #include "exec.h" - #include "file.h" -diff -Nura php-4.4.4/ext/standard/sha256.c hardening-patch-4.4.4-0.4.15/ext/standard/sha256.c ---- php-4.4.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/sha256.c 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,398 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ -+ -+#include -+#include "php.h" -+ -+/* This code is heavily based on the PHP md5/sha1 implementations */ -+ -+#include "sha256.h" -+ -+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ sprintf(sha256str, "%02x", digest[i]); -+ sha256str += 2; -+ } -+ -+ *sha256str = '\0'; -+} -+ -+/* {{{ proto string sha256(string str [, bool raw_output]) -+ Calculate the sha256 hash of a string */ -+PHP_FUNCTION(sha256) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ PHP_SHA256_CTX context; -+ unsigned char digest[32]; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ sha256str[0] = '\0'; -+ PHP_SHA256Init(&context); -+ PHP_SHA256Update(&context, arg, arg_len); -+ PHP_SHA256Final(digest, &context); -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+ -+} -+ -+/* }}} */ -+ -+/* {{{ proto string sha256_file(string filename [, bool raw_output]) -+ Calculate the sha256 hash of given filename */ -+PHP_FUNCTION(sha256_file) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ unsigned char buf[1024]; -+ unsigned char digest[32]; -+ PHP_SHA256_CTX context; -+ int n; -+ FILE *fp; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { -+ RETURN_FALSE; -+ } -+ -+ if (php_check_open_basedir(arg TSRMLS_CC)) { -+ RETURN_FALSE; -+ } -+ -+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file"); -+ RETURN_FALSE; -+ } -+ -+ PHP_SHA256Init(&context); -+ -+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) { -+ PHP_SHA256Update(&context, buf, n); -+ } -+ -+ PHP_SHA256Final(digest, &context); -+ -+ if (ferror(fp)) { -+ fclose(fp); -+ RETURN_FALSE; -+ } -+ -+ fclose(fp); -+ -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+} -+/* }}} */ -+ -+ -+static void SHA256Transform(php_uint32[8], const unsigned char[64]); -+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); -+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); -+ -+static unsigned char PADDING[64] = -+{ -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* F, G, H and I are basic SHA256 functions. -+ */ -+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) -+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) -+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) -+#define I(x, y, z) (((x) & (y)) | ((~x) & z)) -+ -+/* ROTATE_RIGHT rotates x right n bits. -+ */ -+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) -+ -+/* W[i] -+ */ -+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ -+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ -+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) -+ -+/* ROUND function of sha256 -+ */ -+ -+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ -+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ -+ (h) = F((a)) + G((a), (b), (c)) + t1; \ -+ (d) += t1; \ -+ } -+ -+ -+/* {{{ PHP_SHA256Init -+ * SHA256 initialization. Begins an SHA256 operation, writing a new context. -+ */ -+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context) -+{ -+ context->count[0] = context->count[1] = 0; -+ /* Load magic initialization constants. -+ */ -+ context->state[0] = 0x6a09e667; -+ context->state[1] = 0xbb67ae85; -+ context->state[2] = 0x3c6ef372; -+ context->state[3] = 0xa54ff53a; -+ context->state[4] = 0x510e527f; -+ context->state[5] = 0x9b05688c; -+ context->state[6] = 0x1f83d9ab; -+ context->state[7] = 0x5be0cd19; -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Update -+ SHA256 block update operation. Continues an SHA256 message-digest -+ operation, processing another message block, and updating the -+ context. -+ */ -+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, -+ unsigned int inputLen) -+{ -+ unsigned int i, index, partLen; -+ -+ /* Compute number of bytes mod 64 */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); -+ -+ /* Update number of bits */ -+ if ((context->count[0] += ((php_uint32) inputLen << 3)) -+ < ((php_uint32) inputLen << 3)) -+ context->count[1]++; -+ context->count[1] += ((php_uint32) inputLen >> 29); -+ -+ partLen = 64 - index; -+ -+ /* Transform as many times as possible. -+ */ -+ if (inputLen >= partLen) { -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); -+ SHA256Transform(context->state, context->buffer); -+ -+ for (i = partLen; i + 63 < inputLen; i += 64) -+ SHA256Transform(context->state, &input[i]); -+ -+ index = 0; -+ } else -+ i = 0; -+ -+ /* Buffer remaining input */ -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], -+ inputLen - i); -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Final -+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the -+ the message digest and zeroizing the context. -+ */ -+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) -+{ -+ unsigned char bits[8]; -+ unsigned int index, padLen; -+ -+ /* Save number of bits */ -+ bits[7] = context->count[0] & 0xFF; -+ bits[6] = (context->count[0] >> 8) & 0xFF; -+ bits[5] = (context->count[0] >> 16) & 0xFF; -+ bits[4] = (context->count[0] >> 24) & 0xFF; -+ bits[3] = context->count[1] & 0xFF; -+ bits[2] = (context->count[1] >> 8) & 0xFF; -+ bits[1] = (context->count[1] >> 16) & 0xFF; -+ bits[0] = (context->count[1] >> 24) & 0xFF; -+ -+ /* Pad out to 56 mod 64. -+ */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); -+ padLen = (index < 56) ? (56 - index) : (120 - index); -+ PHP_SHA256Update(context, PADDING, padLen); -+ -+ /* Append length (before padding) */ -+ PHP_SHA256Update(context, bits, 8); -+ -+ /* Store state in digest */ -+ SHA256Encode(digest, context->state, 32); -+ -+ /* Zeroize sensitive information. -+ */ -+ memset((unsigned char*) context, 0, sizeof(*context)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Transform -+ * SHA256 basic transformation. Transforms state based on block. -+ */ -+static void SHA256Transform(state, block) -+php_uint32 state[8]; -+const unsigned char block[64]; -+{ -+ php_uint32 a = state[0], b = state[1], c = state[2]; -+ php_uint32 d = state[3], e = state[4], f = state[5]; -+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; -+ -+ SHA256Decode(x, block, 64); -+ -+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) -+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) -+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) -+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) -+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) -+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) -+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) -+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) -+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) -+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) -+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) -+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) -+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) -+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) -+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) -+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) -+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) -+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) -+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) -+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) -+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) -+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) -+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) -+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) -+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) -+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) -+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) -+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) -+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) -+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) -+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) -+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) -+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) -+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) -+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) -+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) -+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) -+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) -+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) -+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) -+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) -+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) -+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) -+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) -+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) -+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) -+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) -+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) -+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) -+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) -+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) -+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) -+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) -+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) -+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) -+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) -+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) -+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) -+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) -+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) -+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) -+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) -+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) -+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) -+ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ state[4] += e; -+ state[5] += f; -+ state[6] += g; -+ state[7] += h; -+ -+ /* Zeroize sensitive information. */ -+ memset((unsigned char*) x, 0, sizeof(x)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Encode -+ Encodes input (php_uint32) into output (unsigned char). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Encode(output, input, len) -+unsigned char *output; -+php_uint32 *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) { -+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); -+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); -+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); -+ output[j + 3] = (unsigned char) (input[i] & 0xff); -+ } -+} -+/* }}} */ -+ -+/* {{{ SHA256Decode -+ Decodes input (unsigned char) into output (php_uint32). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Decode(output, input, len) -+php_uint32 *output; -+const unsigned char *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) -+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | -+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.4/ext/standard/sha256.h hardening-patch-4.4.4-0.4.15/ext/standard/sha256.h ---- php-4.4.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/sha256.h 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ -+ -+#ifndef SHA256_H -+#define SHA256_H -+ -+#include "ext/standard/basic_functions.h" -+ -+/* SHA1 context. */ -+typedef struct { -+ php_uint32 state[8]; /* state (ABCD) */ -+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ -+ unsigned char buffer[64]; /* input buffer */ -+} PHP_SHA256_CTX; -+ -+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *); -+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); -+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); -+ -+PHP_FUNCTION(sha256); -+PHP_FUNCTION(sha256_file); -+ -+#endif -diff -Nura php-4.4.4/ext/standard/syslog.c hardening-patch-4.4.4-0.4.15/ext/standard/syslog.c ---- php-4.4.4/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/standard/syslog.c 2006-09-05 20:30:51.000000000 +0200 -@@ -42,6 +42,8 @@ - */ - PHP_MINIT_FUNCTION(syslog) - { -+ -+#if !HARDENING_PATCH - /* error levels */ - REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ - REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -@@ -97,7 +99,7 @@ - /* AIX doesn't have LOG_PERROR */ - REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ - #endif -- -+#endif - return SUCCESS; - } - /* }}} */ -diff -Nura php-4.4.4/ext/varfilter/config.m4 hardening-patch-4.4.4-0.4.15/ext/varfilter/config.m4 ---- php-4.4.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/config.m4 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,11 @@ -+dnl -+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+dnl -+ -+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, -+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) -+ -+if test "$PHP_VARFILTER" != "no"; then -+ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) -+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) -+fi -diff -Nura php-4.4.4/ext/varfilter/CREDITS hardening-patch-4.4.4-0.4.15/ext/varfilter/CREDITS ---- php-4.4.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,2 @@ -+varfilter -+Stefan Esser -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-4.4.4/ext/varfilter/php_varfilter.h hardening-patch-4.4.4-0.4.15/ext/varfilter/php_varfilter.h ---- php-4.4.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,144 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifndef PHP_VARFILTER_H -+#define PHP_VARFILTER_H -+ -+extern zend_module_entry varfilter_module_entry; -+#define phpext_varfilter_ptr &varfilter_module_entry -+ -+#ifdef PHP_WIN32 -+#define PHP_VARFILTER_API __declspec(dllexport) -+#else -+#define PHP_VARFILTER_API -+#endif -+ -+#ifdef ZTS -+#include "TSRM.h" -+#endif -+ -+#include "SAPI.h" -+ -+#include "php_variables.h" -+ -+#ifdef ZEND_ENGINE_2 -+#define HASH_HTTP_GET_VARS 0x2095733f -+#define HASH_HTTP_POST_VARS 0xbfee1265 -+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 -+#define HASH_HTTP_ENV_VARS 0x1fe186a8 -+#define HASH_HTTP_SERVER_VARS 0xc987afd6 -+#define HASH_HTTP_SESSION_VARS 0x7aba0d43 -+#define HASH_HTTP_POST_FILES 0x98eb1ddc -+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec -+#else -+#define HASH_HTTP_GET_VARS 0x8d8645bd -+#define HASH_HTTP_POST_VARS 0x7c699bf3 -+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f -+#define HASH_HTTP_ENV_VARS 0x84da3016 -+#define HASH_HTTP_SERVER_VARS 0x6dbf964e -+#define HASH_HTTP_SESSION_VARS 0x322906f5 -+#define HASH_HTTP_POST_FILES 0xe4e4ce70 -+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e -+#endif -+ -+PHP_MINIT_FUNCTION(varfilter); -+PHP_MSHUTDOWN_FUNCTION(varfilter); -+PHP_RINIT_FUNCTION(varfilter); -+PHP_RSHUTDOWN_FUNCTION(varfilter); -+PHP_MINFO_FUNCTION(varfilter); -+ -+ -+ZEND_BEGIN_MODULE_GLOBALS(varfilter) -+/* request variables */ -+ long max_request_variables; -+ long cur_request_variables; -+ long max_varname_length; -+ long max_totalname_length; -+ long max_value_length; -+ long max_array_depth; -+ long max_array_index_length; -+ zend_bool disallow_nul; -+/* cookie variables */ -+ long max_cookie_vars; -+ long cur_cookie_vars; -+ long max_cookie_name_length; -+ long max_cookie_totalname_length; -+ long max_cookie_value_length; -+ long max_cookie_array_depth; -+ long max_cookie_array_index_length; -+ zend_bool disallow_cookie_nul; -+/* get variables */ -+ long max_get_vars; -+ long cur_get_vars; -+ long max_get_name_length; -+ long max_get_totalname_length; -+ long max_get_value_length; -+ long max_get_array_depth; -+ long max_get_array_index_length; -+ zend_bool disallow_get_nul; -+/* post variables */ -+ long max_post_vars; -+ long cur_post_vars; -+ long max_post_name_length; -+ long max_post_totalname_length; -+ long max_post_value_length; -+ long max_post_array_depth; -+ long max_post_array_index_length; -+ zend_bool disallow_post_nul; -+/* fileupload */ -+ long max_uploads; -+ long cur_uploads; -+ zend_bool disallow_elf_files; -+ char *verification_script; -+ -+ zend_bool no_more_variables; -+ zend_bool no_more_get_variables; -+ zend_bool no_more_post_variables; -+ zend_bool no_more_cookie_variables; -+ zend_bool no_more_uploads; -+ -+ZEND_END_MODULE_GLOBALS(varfilter) -+ -+ -+#ifdef ZTS -+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) -+#else -+#define VARFILTER_G(v) (varfilter_globals.v) -+#endif -+ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); -+SAPI_TREAT_DATA_FUNC(varfilter_treat_data); -+ -+ -+ -+#endif /* PHP_VARFILTER_H */ -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * indent-tabs-mode: t -+ * End: -+ */ -diff -Nura php-4.4.4/ext/varfilter/varfilter.c hardening-patch-4.4.4-0.4.15/ext/varfilter/varfilter.c ---- php-4.4.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:51:18.000000000 +0200 -@@ -0,0 +1,915 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "php.h" -+#include "php_ini.h" -+#include "ext/standard/info.h" -+#include "php_varfilter.h" -+#include "hardening_patch.h" -+ -+ZEND_DECLARE_MODULE_GLOBALS(varfilter) -+ -+/* True global resources - no need for thread safety here */ -+static int le_varfilter; -+ -+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; -+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; -+static zend_bool hooked = 0; -+ -+/* {{{ varfilter_module_entry -+ */ -+zend_module_entry varfilter_module_entry = { -+#if ZEND_MODULE_API_NO >= 20010901 -+ STANDARD_MODULE_HEADER, -+#endif -+ "varfilter", -+ NULL, -+ PHP_MINIT(varfilter), -+ PHP_MSHUTDOWN(varfilter), -+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ -+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ -+ PHP_MINFO(varfilter), -+#if ZEND_MODULE_API_NO >= 20010901 -+ "0.4.15", /* Replace with version number for your extension */ -+#endif -+ STANDARD_MODULE_PROPERTIES -+}; -+/* }}} */ -+ -+#ifdef COMPILE_DL_VARFILTER -+ZEND_GET_MODULE(varfilter) -+#endif -+ -+/* {{{ PHP_INI -+ */ -+PHP_INI_BEGIN() -+ /* for backward compatibility */ -+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) -+ -+ -+PHP_INI_END() -+/* }}} */ -+ -+/* {{{ php_varfilter_init_globals -+ */ -+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) -+{ -+ varfilter_globals->max_request_variables = 200; -+ varfilter_globals->max_varname_length = 64; -+ varfilter_globals->max_value_length = 10000; -+ varfilter_globals->max_array_depth = 100; -+ varfilter_globals->max_totalname_length = 256; -+ varfilter_globals->max_array_index_length = 64; -+ varfilter_globals->disallow_nul = 1; -+ -+ varfilter_globals->max_cookie_vars = 100; -+ varfilter_globals->max_cookie_name_length = 64; -+ varfilter_globals->max_cookie_totalname_length = 256; -+ varfilter_globals->max_cookie_value_length = 10000; -+ varfilter_globals->max_cookie_array_depth = 100; -+ varfilter_globals->max_cookie_array_index_length = 64; -+ varfilter_globals->disallow_cookie_nul = 1; -+ -+ varfilter_globals->max_get_vars = 100; -+ varfilter_globals->max_get_name_length = 64; -+ varfilter_globals->max_get_totalname_length = 256; -+ varfilter_globals->max_get_value_length = 512; -+ varfilter_globals->max_get_array_depth = 50; -+ varfilter_globals->max_get_array_index_length = 64; -+ varfilter_globals->disallow_get_nul = 1; -+ -+ varfilter_globals->max_post_vars = 200; -+ varfilter_globals->max_post_name_length = 64; -+ varfilter_globals->max_post_totalname_length = 256; -+ varfilter_globals->max_post_value_length = 65000; -+ varfilter_globals->max_post_array_depth = 100; -+ varfilter_globals->max_post_array_index_length = 64; -+ varfilter_globals->disallow_post_nul = 1; -+ -+ varfilter_globals->max_uploads = 25; -+ varfilter_globals->disallow_elf_files = 1; -+ varfilter_globals->verification_script = NULL; -+ -+ varfilter_globals->no_more_variables = 0; -+ varfilter_globals->no_more_get_variables = 0; -+ varfilter_globals->no_more_post_variables = 0; -+ varfilter_globals->no_more_cookie_variables = 0; -+ varfilter_globals->no_more_uploads = 0; -+ -+ varfilter_globals->cur_request_variables = 0; -+ varfilter_globals->cur_get_vars = 0; -+ varfilter_globals->cur_post_vars = 0; -+ varfilter_globals->cur_cookie_vars = 0; -+ -+ varfilter_globals->cur_uploads = 0; -+ -+} -+/* }}} */ -+ -+ -+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) -+{ -+ HashTable *svars; -+ int retval, failure=0; -+ -+ orig_register_server_variables(track_vars_array TSRMLS_CC); -+ -+ svars = Z_ARRVAL_P(track_vars_array); -+ -+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ -+ if (failure) { -+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); -+ } -+} -+ -+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) -+{ -+ int retval = SAPI_HEADER_ADD, i; -+ char *tmp; -+ -+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { -+ -+ tmp = sapi_header->header; -+ for (i=0; iheader_len; i++, tmp++) { -+ if (tmp[0] == 0) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); -+ sapi_header->header_len = i; -+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); -+ sapi_header->header_len = i; -+ tmp[0] = 0; -+ } -+ } -+ } -+ -+ if (orig_header_handler) { -+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); -+ } -+ -+ return retval; -+} -+ -+/* {{{ PHP_MINIT_FUNCTION -+ */ -+PHP_MINIT_FUNCTION(varfilter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); -+ REGISTER_INI_ENTRIES(); -+ -+ if (!hooked) { -+ void *temp; -+ hooked = 1; -+ -+ temp = (void *)sapi_module.register_server_variables; -+ if (temp != varfilter_register_server_variables) { -+ orig_register_server_variables = temp; -+ } -+ temp = (void *)sapi_module.header_handler; -+ if (temp != varfilter_header_handler) { -+ orig_header_handler = temp; -+ } -+ } -+ -+ sapi_register_input_filter(varfilter_input_filter); -+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); -+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); -+ sapi_register_upload_content_filter(varfilter_upload_content_filter); -+ sapi_register_post_upload_filter(varfilter_post_upload_filter); -+ -+ sapi_module.header_handler = varfilter_header_handler; -+ sapi_module.register_server_variables = varfilter_register_server_variables; -+ -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MSHUTDOWN_FUNCTION -+ */ -+PHP_MSHUTDOWN_FUNCTION(varfilter) -+{ -+ UNREGISTER_INI_ENTRIES(); -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request start */ -+/* {{{ PHP_RINIT_FUNCTION -+ */ -+PHP_RINIT_FUNCTION(varfilter) -+{ -+ VARFILTER_G(cur_request_variables) = 0; -+ VARFILTER_G(cur_get_vars) = 0; -+ VARFILTER_G(cur_post_vars) = 0; -+ VARFILTER_G(cur_cookie_vars) = 0; -+ -+ VARFILTER_G(cur_uploads) = 0; -+ -+ VARFILTER_G(no_more_variables) = 0; -+ VARFILTER_G(no_more_get_variables) = 0; -+ VARFILTER_G(no_more_post_variables) = 0; -+ VARFILTER_G(no_more_cookie_variables) = 0; -+ VARFILTER_G(no_more_uploads) = 0; -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request end */ -+/* {{{ PHP_RSHUTDOWN_FUNCTION -+ */ -+PHP_RSHUTDOWN_FUNCTION(varfilter) -+{ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MINFO_FUNCTION -+ */ -+PHP_MINFO_FUNCTION(varfilter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); -+ php_info_print_table_end(); -+ -+ DISPLAY_INI_ENTRIES(); -+} -+/* }}} */ -+ -+/* {{{ normalize_varname -+ */ -+static void normalize_varname(char *varname) -+{ -+ char *s=varname, *index=NULL, *indexend=NULL, *p; -+ -+ /* overjump leading space */ -+ while (*s == ' ') { -+ s++; -+ } -+ -+ /* and remove it */ -+ if (s != varname) { -+ memmove(varname, s, strlen(s)+1); -+ } -+ -+ for (p=varname; *p && *p != '['; p++) { -+ switch(*p) { -+ case ' ': -+ case '.': -+ *p='_'; -+ break; -+ } -+ } -+ -+ /* find index */ -+ index = strchr(varname, '['); -+ if (index) { -+ index++; -+ s=index; -+ } else { -+ return; -+ } -+ -+ /* done? */ -+ while (index) { -+ -+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { -+ index++; -+ } -+ indexend = strchr(index, ']'); -+ indexend = indexend ? indexend + 1 : index + strlen(index); -+ -+ if (s != index) { -+ memmove(s, index, strlen(index)+1); -+ s += indexend-index; -+ } else { -+ s = indexend; -+ } -+ -+ if (*s == '[') { -+ s++; -+ index = s; -+ } else { -+ index = NULL; -+ } -+ } -+ *s++='\0'; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC -+ */ -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) -+{ -+ char *index, *prev_index = NULL, *var; -+ unsigned int var_len, total_len, depth = 0; -+ -+ var = estrdup(varname); -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); -+ -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; -+ break; -+ } -+ -+ efree(var); -+ return SUCCESS; -+protected_varname2: -+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); -+return_failure: -+ efree(var); -+ return FAILURE; -+} -+/* }}} */ -+ -+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC -+ */ -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) -+{ -+ /* Drop if no more variables flag is set */ -+ if (VARFILTER_G(no_more_uploads)) { -+ return FAILURE; -+ } -+ /* Drop this fileupload if the limit is reached */ -+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { -+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); -+ VARFILTER_G(no_more_uploads) = 1; -+ return FAILURE; -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC -+ */ -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) -+{ -+ -+ if (VARFILTER_G(disallow_elf_files)) { -+ -+ if (offset == 0 && buffer_len > 10) { -+ -+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { -+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); -+ return FAILURE; -+ } -+ } -+ -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC -+ */ -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) -+{ -+ int retval = SUCCESS; -+ -+ if (VARFILTER_G(verification_script)) { -+ char cmd[8192]; -+ FILE *in; -+ int first=1; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); -+ return FAILURE; -+ } -+ -+ retval = FAILURE; -+ -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ if (first) { -+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; -+ first = 0; -+ } -+ } -+ pclose(in); -+ } -+ -+ if (retval != SUCCESS) { -+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); -+ return FAILURE; -+ } -+ -+ VARFILTER_G(cur_uploads)++; -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_INPUT_FILTER_FUNC -+ */ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) -+{ -+ char *index, *prev_index = NULL; -+ unsigned int var_len, total_len, depth = 0; -+ -+ /* Drop this variable if the limit was reached */ -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(no_more_get_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(no_more_post_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(no_more_cookie_variables)) { -+ return 0; -+ } -+ break; -+ default: /* we do not want to protect parse_str() and friends */ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ return 1; -+ } -+ if (VARFILTER_G(no_more_variables)) { -+ return 0; -+ } -+ -+ /* Drop this variable if the limit is now reached */ -+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { -+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_variables) = 1; -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { -+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_get_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { -+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_cookie_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { -+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_post_variables) = 1; -+ return 0; -+ } -+ break; -+ } -+ -+ -+ /* Drop this variable if it exceeds the value length limit */ -+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { -+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { -+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { -+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { -+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { -+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { -+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Check if variable value is truncated by a \0 */ -+ -+ if (val && *val && val_len != strlen(*val)) { -+ -+ if (VARFILTER_G(disallow_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(disallow_get_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(disallow_cookie_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(disallow_post_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ } -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname; -+ break; -+ } -+ -+ /* Okay let PHP register this variable */ -+ VARFILTER_G(cur_request_variables)++; -+ switch (arg) { -+ case PARSE_GET: -+ VARFILTER_G(cur_get_vars)++; -+ break; -+ case PARSE_COOKIE: -+ VARFILTER_G(cur_cookie_vars)++; -+ break; -+ case PARSE_POST: -+ VARFILTER_G(cur_post_vars)++; -+ break; -+ } -+ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ -+ return 1; -+protected_varname: -+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); -+ return 0; -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: noet sw=4 ts=4 fdm=marker -+ * vim<600: noet sw=4 ts=4 -+ */ -+ -+ -diff -Nura php-4.4.4/main/fopen_wrappers.c hardening-patch-4.4.4-0.4.15/main/fopen_wrappers.c ---- php-4.4.4/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:45.000000000 +0200 -@@ -106,7 +106,10 @@ - } - - /* Resolve the real path into resolved_name */ -- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { -+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { -+ return -2; -+ } -+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { - /* Handler for basedirs that end with a / */ - resolved_basedir_len = strlen(resolved_basedir); - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { -@@ -116,14 +119,20 @@ - } - } - -+ resolved_name_len = strlen(resolved_name); - if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { -- resolved_name_len = strlen(resolved_name); - if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { - resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; - resolved_name[++resolved_name_len] = '\0'; - } - } - -+ if (resolved_name_len == resolved_basedir_len - 1) { -+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { -+ resolved_basedir_len--; -+ } -+ } -+ - /* Check the path */ - #ifdef PHP_WIN32 - if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { -@@ -137,7 +146,7 @@ - } - } else { - /* Unable to resolve the real path, return -1 */ -- return -1; -+ return -3; - } - } - /* }}} */ -@@ -156,22 +165,44 @@ - char *pathbuf; - char *ptr; - char *end; -+ char path_copy[MAXPATHLEN]; -+ int path_len; -+ -+ /* Special case path ends with a trailing slash */ -+ path_len = strlen(path); -+ if (path_len >= MAXPATHLEN) { -+ errno = EPERM; /* we deny permission to open it */ -+ return -1; -+ } -+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { -+ memcpy(path_copy, path, path_len+1); -+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; -+ path_copy[path_len] = '\0'; -+ path = (const char *)&path_copy; -+ } - - pathbuf = estrdup(PG(open_basedir)); - - ptr = pathbuf; - - while (ptr && *ptr) { -+ int res; - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - -- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { -+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); -+ if (res == 0) { - efree(pathbuf); - return 0; - } -+ if (res == -2) { -+ efree(pathbuf); -+ errno = EPERM; -+ return -1; -+ } - - ptr = end; - } -diff -Nura php-4.4.4/main/hardened_globals.h hardening-patch-4.4.4-0.4.15/main/hardened_globals.h ---- php-4.4.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/hardened_globals.h 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,64 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENED_GLOBALS_H -+#define HARDENED_GLOBALS_H -+ -+typedef struct _hardened_globals hardened_globals_struct; -+ -+#ifdef ZTS -+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) -+extern int hardened_globals_id; -+#else -+# define HG(v) (hardened_globals.v) -+extern struct _hardened_globals hardened_globals; -+#endif -+ -+ -+struct _hardened_globals { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_1; -+ unsigned int canary_2; -+#endif -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_3; -+ unsigned int canary_4; -+ unsigned int ll_canary_inited; -+#endif -+ zend_bool hphp_sql_bailout_on_error; -+ zend_bool hphp_multiheader; -+ unsigned long hphp_mailprotect; -+ long hard_memory_limit; -+ HashTable *eval_whitelist; -+ HashTable *eval_blacklist; -+ HashTable *func_whitelist; -+ HashTable *func_blacklist; -+ HashTable *include_whitelist; -+ HashTable *include_blacklist; -+ unsigned int dummy; -+}; -+ -+ -+#endif /* HARDENED_GLOBALS_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-4.4.4/main/hardening_patch.c hardening-patch-4.4.4-0.4.15/main/hardening_patch.c ---- php-4.4.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.c 2006-09-07 18:47:49.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ -+ -+#include "php.h" -+ -+#include -+#include -+ -+#if HAVE_UNISTD_H -+#include -+#endif -+#include "SAPI.h" -+#include "php_globals.h" -+ -+#if HARDENING_PATCH -+ -+#ifdef HAVE_SYS_SOCKET_H -+#include -+#endif -+ -+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) -+#undef AF_UNIX -+#endif -+ -+#if defined(AF_UNIX) -+#include -+#endif -+ -+#define SYSLOG_PATH "/dev/log" -+ -+#include "snprintf.h" -+ -+#include "hardening_patch.h" -+ -+#ifdef ZTS -+#include "hardened_globals.h" -+int hardened_globals_id; -+#else -+struct _hardened_globals hardened_globals; -+#endif -+ -+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) -+{ -+ memset(hardened_globals, 0, sizeof(*hardened_globals)); -+} -+ -+ -+PHPAPI void hardened_startup() -+{ -+#ifdef ZTS -+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); -+#else -+ hardened_globals_ctor(&hardened_globals TSRMLS_CC); -+#endif -+} -+ -+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) -+{ -+ HG(canary_1) = php_canary(); -+ HG(canary_2) = php_canary(); -+} -+ -+char *loglevel2string(int loglevel) -+{ -+ switch (loglevel) { -+ case S_FILES: -+ return "FILES"; -+ case S_INCLUDE: -+ return "INCLUDE"; -+ case S_MEMORY: -+ return "MEMORY"; -+ case S_MISC: -+ return "MISC"; -+ case S_SQL: -+ return "SQL"; -+ case S_EXECUTOR: -+ return "EXECUTOR"; -+ case S_VARS: -+ return "VARS"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+PHPAPI void php_security_log(int loglevel, char *fmt, ...) -+{ -+#if defined(AF_UNIX) -+ int s, r, i=0; -+ struct sockaddr_un saun; -+ char buf[4096+64]; -+ char error[4096+100]; -+ char *ip_address; -+ char *fname; -+ int lineno; -+ va_list ap; -+ TSRMLS_FETCH(); -+ -+ if (EG(hphp_log_use_x_forwarded_for)) { -+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "X-FORWARDED-FOR not set"; -+ } -+ } else { -+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "REMOTE_ADDR not set"; -+ } -+ } -+ -+ -+ va_start(ap, fmt); -+ ap_php_vsnprintf(error, sizeof(error), fmt, ap); -+ va_end(ap); -+ while (error[i]) { -+ if (error[i] < 32) error[i] = '.'; -+ i++; -+ } -+ -+ if (zend_is_executing(TSRMLS_C)) { -+ lineno = zend_get_executed_lineno(TSRMLS_C); -+ fname = zend_get_executed_filename(TSRMLS_C); -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); -+ } else { -+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); -+ if (fname==NULL) { -+ fname = "unknown"; -+ } -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); -+ } -+ -+ /* Syslog-Logging disabled? */ -+ if ((EG(hphp_log_syslog) & loglevel)==0) { -+ goto log_sapi; -+ } -+ -+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); -+ -+ s = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ s = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ goto log_sapi; -+ } -+ } -+ send(s, error, strlen(error), 0); -+ -+ close(s); -+ -+log_sapi: -+ /* SAPI Logging activated? */ -+ if ((EG(hphp_log_sapi) & loglevel)!=0) { -+ sapi_module.log_message(buf); -+ } -+ -+log_script: -+ /* script logging activaed? */ -+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { -+ char cmd[8192], *cmdpos, *bufpos; -+ FILE *in; -+ int space; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); -+ space = sizeof(cmd) - strlen(cmd); -+ cmdpos = cmd + strlen(cmd); -+ bufpos = buf; -+ if (space <= 1) return; -+ while (space > 2 && *bufpos) { -+ if (*bufpos == '\'') { -+ if (space<=5) break; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\\'; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\''; -+ bufpos++; -+ space-=4; -+ } else { -+ *cmdpos++ = *bufpos++; -+ space--; -+ } -+ } -+ *cmdpos++ = '\''; -+ *cmdpos = 0; -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); -+ return; -+ } -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ } -+ pclose(in); -+ } -+ -+#endif -+} -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+PHPAPI unsigned int php_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+ -+PHPAPI int php_is_valid_include(zval *z) -+{ -+ char *filename; -+ int len, i; -+ TSRMLS_FETCH(); -+ -+ /* must be of type string */ -+ if (z->type != IS_STRING || z->value.str.val == NULL) { -+ return (0); -+ } -+ -+ /* short cut */ -+ filename = z->value.str.val; -+ len = z->value.str.len; -+ -+ /* 1. must be shorter than MAXPATHLEN */ -+ if (len > MAXPATHLEN) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 2. must not be cutted */ -+ if (len != strlen(filename)) { -+ char *fname = estrndup(filename, len); -+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ -+ if (strstr(filename, "://")) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ -+ /* no black or whitelist then disallow all */ -+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* whitelist is stronger than blacklist */ -+ if (HG(include_whitelist)) { -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ zend_bool isOk = 0; -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_whitelist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ isOk = 1; -+ break; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_whitelist)); -+ } while (1); -+ -+ /* not found in whitelist */ -+ if (!isOk) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); -+ efree(fname); -+ return 0; -+ } -+ -+ s = h + 3; -+ } while (1); -+ } else { -+ /* okay then handle the blacklist */ -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_blacklist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); -+ efree(fname); -+ return 0; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_blacklist)); -+ } while (1); -+ -+ s = h + 3; -+ } while (1); -+ } -+ -+ efree(fname); -+ } -+ -+ /* 4. must not be an uploaded file */ -+ if (SG(rfc1867_uploaded_files)) { -+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { -+ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); -+ return (0); -+ } -+ } -+ -+ /* passed all tests */ -+ return (1); -+} -+ -+#endif -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.4/main/hardening_patch.h hardening-patch-4.4.4-0.4.15/main/hardening_patch.h ---- php-4.4.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.h 2006-09-07 18:51:06.000000000 +0200 -@@ -0,0 +1,46 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENING_PATCH_H -+#define HARDENING_PATCH_H -+ -+#include "zend.h" -+ -+#if HARDENING_PATCH -+PHPAPI void php_security_log(int loglevel, char *fmt, ...); -+PHPAPI void hardened_startup(); -+#define HARDENING_PATCH_VERSION "0.4.15" -+ -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+PHPAPI unsigned int php_canary(); -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+PHPAPI int php_is_valid_include(zval *z); -+#endif -+ -+#endif /* HARDENING_PATCH_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-4.4.4/main/hardening_patch.m4 hardening-patch-4.4.4-0.4.15/main/hardening_patch.m4 ---- php-4.4.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.m4 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,95 @@ -+dnl -+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ -+dnl -+dnl This file contains Hardening Patch for PHP specific autoconf functions. -+dnl -+ -+AC_ARG_ENABLE(hardening-patch-mm-protect, -+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-ll-protect, -+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-inc-protect, -+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-fmt-protect, -+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-hash-protect, -+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+]) -+ -+AC_MSG_CHECKING(whether to protect the Zend Memory Manager) -+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the Zend Linked Lists) -+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect include/require statements) -+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect PHP Format String functions) -+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) -+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) -+ -+ -+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) -+fi -+ -diff -Nura php-4.4.4/main/main.c hardening-patch-4.4.4-0.4.15/main/main.c ---- php-4.4.4/main/main.c 2006-05-19 00:36:14.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/main/main.c 2006-09-05 20:30:51.000000000 +0200 -@@ -92,6 +92,10 @@ - PHPAPI int core_globals_id; - #endif - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#endif -+ - #define ERROR_BUF_LEN 1024 - - typedef struct { -@@ -142,17 +146,39 @@ - */ - static PHP_INI_MH(OnChangeMemoryLimit) - { -+#if HARDENING_PATCH -+ long hard_memory_limit = 1<<30; -+ -+ if (stage == ZEND_INI_STAGE_RUNTIME) { -+ if (HG(hard_memory_limit) == 0) { -+ HG(hard_memory_limit) = PG(memory_limit); -+ } -+ hard_memory_limit = HG(hard_memory_limit); -+ } else { -+ HG(hard_memory_limit) = 0; -+ } -+#endif - if (new_value) { - PG(memory_limit) = zend_atoi(new_value, new_value_length); -+#if HARDENING_PATCH -+ if (PG(memory_limit) > hard_memory_limit) { -+ PG(memory_limit) = hard_memory_limit; -+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); -+ return FAILURE; -+ } -+#endif - } else { -+#if HARDENING_PATCH -+ PG(memory_limit) = hard_memory_limit; -+#else - PG(memory_limit) = 1<<30; /* effectively, no limit */ -+#endif - } - return zend_set_memory_limit(PG(memory_limit)); - } - /* }}} */ - #endif - -- - /* {{{ php_disable_functions - */ - static void php_disable_functions(TSRMLS_D) -@@ -1008,6 +1034,9 @@ - - zend_try { - shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); -+#if HARDENING_PATCH -+ hardened_clear_mm_canaries(TSRMLS_C); -+#endif - } zend_end_try(); - - zend_try { -@@ -1098,6 +1127,10 @@ - tsrm_ls = ts_resource(0); - #endif - -+#if HARDENING_PATCH -+ hardened_startup(); -+#endif -+ - sapi_initialize_empty_request(TSRMLS_C); - sapi_activate(TSRMLS_C); - -@@ -1109,6 +1142,12 @@ - - php_output_startup(); - -+#if HARDENING_PATCH_INC_PROTECT -+ zuf.is_valid_include = php_is_valid_include; -+#endif -+#if HARDENING_PATCH -+ zuf.security_log_function = php_security_log; -+#endif - zuf.error_function = php_error_cb; - zuf.printf_function = php_printf; - zuf.write_function = php_body_write_wrapper; -@@ -1210,6 +1249,10 @@ - REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS); - 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); - REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); -+#endif - REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); -@@ -1317,7 +1360,7 @@ - */ - static inline void php_register_server_variables(TSRMLS_D) - { -- zval *array_ptr=NULL; -+ zval *array_ptr=NULL, *vptr; - - ALLOC_ZVAL(array_ptr); - array_init(array_ptr); -diff -Nura php-4.4.4/main/php_config.h.in hardening-patch-4.4.4-0.4.15/main/php_config.h.in ---- php-4.4.4/main/php_config.h.in 2006-08-15 14:01:21.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/main/php_config.h.in 2006-09-05 20:30:51.000000000 +0200 -@@ -1,4 +1,4 @@ --/* main/php_config.h.in. Generated automatically from configure.in by autoheader. */ -+/* main/php_config.h.in. Generated automatically from configure.in by autoheader 2.13. */ - /* Leave this file alone */ - #define ZEND_API - #define ZEND_DLEXPORT -@@ -865,6 +865,39 @@ - /* Enabling BIND8 compatibility for Panther */ - #undef BIND_8_COMPAT - -+/* Hardening-Patch */ -+#undef HARDENING_PATCH -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ - /* Whether you have AOLserver */ - #undef HAVE_AOLSERVER - -@@ -1148,6 +1181,12 @@ - /* Define if you have the getaddrinfo function */ - #undef HAVE_GETADDRINFO - -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ - /* Whether system headers declare timezone */ - #undef HAVE_DECLARED_TIMEZONE - -diff -Nura php-4.4.4/main/php_content_types.c hardening-patch-4.4.4-0.4.15/main/php_content_types.c ---- php-4.4.4/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/php_content_types.c 2006-09-05 20:30:51.000000000 +0200 -@@ -77,6 +77,7 @@ - sapi_register_post_entries(php_post_entries); - sapi_register_default_post_reader(php_default_post_reader); - sapi_register_treat_data(php_default_treat_data); -+ sapi_register_input_filter(php_default_input_filter); - return SUCCESS; - } - /* }}} */ -diff -Nura php-4.4.4/main/php.h hardening-patch-4.4.4-0.4.15/main/php.h ---- php-4.4.4/main/php.h 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/php.h 2006-09-05 20:30:51.000000000 +0200 -@@ -35,11 +35,19 @@ - #include "zend_qsort.h" - #include "php_compat.h" - -+ - #include "zend_API.h" - - #undef sprintf - #define sprintf php_sprintf - -+#if HARDENING_PATCH -+#if HAVE_REALPATH -+#undef realpath -+#define realpath php_realpath -+#endif -+#endif -+ - /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ - #undef PHP_DEBUG - #define PHP_DEBUG ZEND_DEBUG -@@ -409,6 +417,10 @@ - #endif - #endif /* !XtOffsetOf */ - -+#if HARDENING_PATCH -+#include "hardening_patch.h" -+#endif -+ - #endif - - /* -diff -Nura php-4.4.4/main/php_variables.c hardening-patch-4.4.4-0.4.15/main/php_variables.c ---- php-4.4.4/main/php_variables.c 2006-02-13 13:19:10.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/php_variables.c 2006-09-05 20:30:51.000000000 +0200 -@@ -238,17 +238,28 @@ - while (var) { - val = strchr(var, '='); - if (val) { /* have a value */ -- int val_len; -+ unsigned int val_len, new_val_len; - - *val++ = '\0'; - php_url_decode(var, strlen(var)); - val_len = php_url_decode(val, strlen(val)); -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } - var = php_strtok_r(NULL, "&", &strtok_buf); - } - } - -+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter) -+{ -+ /* TODO: check .ini setting here and apply user-defined input filter */ -+ *new_val_len = val_len; -+ return 1; -+} -+ - SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) - { - char *res = NULL, *var, *val, *separator=NULL; -@@ -326,15 +337,26 @@ - while (var) { - val = strchr(var, '='); - if (val) { /* have a value */ -- int val_len; -+ unsigned int val_len, new_val_len; - - *val++ = '\0'; - php_url_decode(var, strlen(var)); - val_len = php_url_decode(val, strlen(val)); -- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC); -+ val = estrndup(val, val_len); -+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } else { -+ unsigned int val_len, new_val_len; -+ - php_url_decode(var, strlen(var)); -- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC); -+ val_len = 0; -+ val = estrndup("", 0); -+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { -+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); -+ } -+ efree(val); - } - var = php_strtok_r(NULL, separator, &strtok_buf); - } -diff -Nura php-4.4.4/main/rfc1867.c hardening-patch-4.4.4-0.4.15/main/rfc1867.c ---- php-4.4.4/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/rfc1867.c 2006-09-05 20:30:51.000000000 +0200 -@@ -128,6 +128,8 @@ - #define UPLOAD_ERROR_D 4 /* No file uploaded */ - #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ - #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ -+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */ -+ - - void php_rfc1867_register_constants(TSRMLS_D) - { -@@ -138,6 +140,7 @@ - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); - } - - static void normalize_protected_variable(char *varname TSRMLS_DC) -@@ -849,6 +852,7 @@ - char buff[FILLUNIT]; - char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; - int blen=0, wlen=0; -+ unsigned long offset; - - zend_llist_clean(&header); - -@@ -897,21 +901,24 @@ - if (!filename && param) { - - char *value = multipart_buffer_read_body(mbuff TSRMLS_CC); -+ unsigned int new_val_len; /* Dummy variable */ - - if (!value) { - value = estrdup(""); - } - -+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) { - #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) -- if (php_mb_encoding_translation(TSRMLS_C)) { -- php_mb_gpc_stack_variable(param, value, &val_list, &len_list, -- &num_vars, &num_vars_max TSRMLS_CC); -- } else { -- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -- } -+ if (php_mb_encoding_translation(TSRMLS_C)) { -+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list, -+ &num_vars, &num_vars_max TSRMLS_CC); -+ } else { -+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -+ } - #else -- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); -+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); - #endif -+ } - if (!strcasecmp(param, "MAX_FILE_SIZE")) { - max_file_size = atol(value); - } -@@ -963,7 +970,11 @@ - tmp++; - } - } -- -+ -+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { -+ skip_upload = 1; -+ } -+ - total_bytes = cancel_upload = 0; - - if (!skip_upload) { -@@ -987,6 +998,11 @@ - cancel_upload = UPLOAD_ERROR_D; - } - -+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ -+ offset = 0; - end = 0; - while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) - { -@@ -997,6 +1013,11 @@ - sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); - cancel_upload = UPLOAD_ERROR_B; - } else if (blen > 0) { -+ -+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - wlen = write(fd, buff, blen); - - if (wlen < blen) { -@@ -1004,6 +1025,7 @@ - cancel_upload = UPLOAD_ERROR_F; - } else { - total_bytes += wlen; -+ offset += wlen; - } - } - } -@@ -1025,6 +1047,10 @@ - } - #endif - -+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - if (cancel_upload) { - if (temp_filename) { - if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ -diff -Nura php-4.4.4/main/SAPI.c hardening-patch-4.4.4-0.4.15/main/SAPI.c ---- php-4.4.4/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/SAPI.c 2006-09-05 20:30:51.000000000 +0200 -@@ -854,6 +854,37 @@ - return SUCCESS; - } - -+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)) -+{ -+ sapi_module.input_filter = input_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) -+{ -+ sapi_module.upload_varname_filter = upload_varname_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) -+{ -+ sapi_module.pre_upload_filter = pre_upload_filter; -+ return SUCCESS; -+} -+ -+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)) -+{ -+ sapi_module.upload_content_filter = upload_content_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) -+{ -+ sapi_module.post_upload_filter = post_upload_filter; -+ return SUCCESS; -+} -+ -+ - - SAPI_API int sapi_flush(TSRMLS_D) - { -diff -Nura php-4.4.4/main/SAPI.h hardening-patch-4.4.4-0.4.15/main/SAPI.h ---- php-4.4.4/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/SAPI.h 2006-09-05 20:30:51.000000000 +0200 -@@ -101,9 +101,10 @@ - char *current_user; - int current_user_length; - -- /* this is necessary for CLI module */ -- int argc; -- char **argv; -+ /* this is necessary for CLI module */ -+ int argc; -+ char **argv; -+ - } sapi_request_info; - - -@@ -177,6 +178,10 @@ - SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); - SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)); - SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); - - SAPI_API int sapi_flush(TSRMLS_D); - SAPI_API struct stat *sapi_get_stat(TSRMLS_D); -@@ -238,8 +243,16 @@ - int (*get_target_uid)(uid_t * TSRMLS_DC); - int (*get_target_gid)(gid_t * TSRMLS_DC); - -+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); -+ -+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); -+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); -+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); -+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); -+ - void (*ini_defaults)(HashTable *configuration_hash); - int phpinfo_as_text; -+ - }; - - -@@ -262,16 +275,27 @@ - - #define SAPI_DEFAULT_MIMETYPE "text/html" - #define SAPI_DEFAULT_CHARSET "" -+ -+#if HARDENING_PATCH -+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" -+#else - #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION -+#endif - - #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) - #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) - - #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) -+#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) -+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) -+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) -+#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) -+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) - - SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); - SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); - SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data); -+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter); - - #define STANDARD_SAPI_MODULE_PROPERTIES - -diff -Nura php-4.4.4/main/snprintf.c hardening-patch-4.4.4-0.4.15/main/snprintf.c ---- php-4.4.4/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/snprintf.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1014,7 +1014,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = cc; -+#endif - break; - - /* -diff -Nura php-4.4.4/main/spprintf.c hardening-patch-4.4.4-0.4.15/main/spprintf.c ---- php-4.4.4/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/main/spprintf.c 2006-09-05 20:30:51.000000000 +0200 -@@ -630,7 +630,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = xbuf->len; -+#endif - break; - - /* -diff -Nura php-4.4.4/php.ini-dist hardening-patch-4.4.4-0.4.15/php.ini-dist ---- php-4.4.4/php.ini-dist 2005-12-30 18:19:43.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/php.ini-dist 2006-09-05 20:30:51.000000000 +0200 -@@ -1114,6 +1114,209 @@ - ;exif.decode_jis_motorola = JIS - ;exif.decode_jis_intel = JIS - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-4.4.4/php.ini-recommended hardening-patch-4.4.4-0.4.15/php.ini-recommended ---- php-4.4.4/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/php.ini-recommended 2006-09-05 20:30:51.000000000 +0200 -@@ -1112,6 +1112,209 @@ - ;exif.decode_jis_motorola = JIS - ;exif.decode_jis_intel = JIS - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-4.4.4/README.input_filter hardening-patch-4.4.4-0.4.15/README.input_filter ---- php-4.4.4/README.input_filter 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/README.input_filter 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,193 @@ -+Input Filter Support ported from PHP 5 -+-------------------------------------- -+ -+XSS (Cross Site Scripting) hacks are becoming more and more prevalent, -+and can be quite difficult to prevent. Whenever you accept user data -+and somehow display this data back to users, you are likely vulnerable -+to XSS hacks. -+ -+The Input Filter support in PHP 5 is aimed at providing the framework -+through which a company-wide or site-wide security policy can be -+enforced. It is implemented as a SAPI hook and is called from the -+treat_data and post handler functions. To implement your own security -+policy you will need to write a standard PHP extension. -+ -+A simple implementation might look like the following. This stores the -+original raw user data and adds a my_get_raw() function while the normal -+$_POST, $_GET and $_COOKIE arrays are only populated with stripped -+data. In this simple example all I am doing is calling strip_tags() on -+the data. If register_globals is turned on, the default globals that -+are created will be stripped ($foo) while a $RAW_foo is created with the -+original user input. -+ -+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter) -+ zval *post_array; -+ zval *get_array; -+ zval *cookie_array; -+ZEND_END_MODULE_GLOBALS(my_input_filter) -+ -+#ifdef ZTS -+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v) -+#else -+#define IF_G(v) (my_input_filter_globals.v) -+#endif -+ -+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter) -+ -+function_entry my_input_filter_functions[] = { -+ PHP_FE(my_get_raw, NULL) -+ {NULL, NULL, NULL} -+}; -+ -+zend_module_entry my_input_filter_module_entry = { -+ STANDARD_MODULE_HEADER, -+ "my_input_filter", -+ my_input_filter_functions, -+ PHP_MINIT(my_input_filter), -+ PHP_MSHUTDOWN(my_input_filter), -+ NULL, -+ PHP_RSHUTDOWN(my_input_filter), -+ PHP_MINFO(my_input_filter), -+ "0.1", -+ STANDARD_MODULE_PROPERTIES -+}; -+ -+PHP_MINIT_FUNCTION(my_input_filter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL); -+ -+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT); -+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT); -+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT); -+ -+ sapi_register_input_filter(my_sapi_input_filter); -+ return SUCCESS; -+} -+ -+PHP_RSHUTDOWN_FUNCTION(my_input_filter) -+{ -+ if(IF_G(get_array)) { -+ zval_ptr_dtor(&IF_G(get_array)); -+ IF_G(get_array) = NULL; -+ } -+ if(IF_G(post_array)) { -+ zval_ptr_dtor(&IF_G(post_array)); -+ IF_G(post_array) = NULL; -+ } -+ if(IF_G(cookie_array)) { -+ zval_ptr_dtor(&IF_G(cookie_array)); -+ IF_G(cookie_array) = NULL; -+ } -+ return SUCCESS; -+} -+ -+PHP_MINFO_FUNCTION(my_input_filter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); -+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $"); -+ php_info_print_table_end(); -+} -+ -+/* The filter handler. If you return 1 from it, then PHP also registers the -+ * (modified) variable. Returning 0 prevents PHP from registering the variable; -+ * you can use this if your filter already registers the variable under a -+ * different name, or if you just don't want the variable registered at all. */ -+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter) -+{ -+ zval new_var; -+ zval *array_ptr = NULL; -+ char *raw_var; -+ int var_len; -+ -+ assert(*val != NULL); -+ -+ switch(arg) { -+ case PARSE_GET: -+ if(!IF_G(get_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(get_array) = array_ptr; -+ break; -+ case PARSE_POST: -+ if(!IF_G(post_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(post_array) = array_ptr; -+ break; -+ case PARSE_COOKIE: -+ if(!IF_G(cookie_array)) { -+ ALLOC_ZVAL(array_ptr); -+ array_init(array_ptr); -+ INIT_PZVAL(array_ptr); -+ } -+ IF_G(cookie_array) = array_ptr; -+ break; -+ } -+ Z_STRLEN(new_var) = val_len; -+ Z_STRVAL(new_var) = estrndup(*val, val_len); -+ Z_TYPE(new_var) = IS_STRING; -+ -+ var_len = strlen(var); -+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ -+ strcpy(raw_var, "RAW_"); -+ strlcat(raw_var,var,var_len+5); -+ -+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC); -+ -+ php_strip_tags(*val, val_len, NULL, NULL, 0); -+ -+ *new_val_len = strlen(*val); -+ return 1; -+} -+ -+PHP_FUNCTION(my_get_raw) -+{ -+ long arg; -+ char *var; -+ int var_len; -+ zval **tmp; -+ zval *array_ptr = NULL; -+ HashTable *hash_ptr; -+ char *raw_var; -+ -+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) { -+ return; -+ } -+ -+ switch(arg) { -+ case PARSE_GET: -+ array_ptr = IF_G(get_array); -+ break; -+ case PARSE_POST: -+ array_ptr = IF_G(post_array); -+ break; -+ case PARSE_COOKIE: -+ array_ptr = IF_G(post_array); -+ break; -+ } -+ -+ if(!array_ptr) RETURN_FALSE; -+ -+ /* -+ * I'm changing the variable name here because when running with register_globals on, -+ * the variable will end up in the global symbol table -+ */ -+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */ -+ strcpy(raw_var, "RAW_"); -+ strlcat(raw_var,var,var_len+5); -+ hash_ptr = HASH_OF(array_ptr); -+ -+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) { -+ *return_value = **tmp; -+ zval_copy_ctor(return_value); -+ } else { -+ RETVAL_FALSE; -+ } -+ efree(raw_var); -+} -+ -diff -Nura php-4.4.4/run-tests.php hardening-patch-4.4.4-0.4.15/run-tests.php ---- php-4.4.4/run-tests.php 2006-01-18 18:59:41.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/run-tests.php 2006-09-05 20:30:51.000000000 +0200 -@@ -152,6 +152,10 @@ - 'error_reporting=2047', - 'display_errors=1', - 'log_errors=0', -+ 'hphp.executor.include.whitelist=cookietest', -+ 'hphp.log.syslog=0', -+ 'hphp.log.sapi=0', -+ 'hphp.log.script=0', - 'html_errors=0', - 'track_errors=1', - 'report_memleaks=1', -diff -Nura php-4.4.4/sapi/apache/mod_php4.c hardening-patch-4.4.4-0.4.15/sapi/apache/mod_php4.c ---- php-4.4.4/sapi/apache/mod_php4.c 2006-05-13 23:42:14.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/sapi/apache/mod_php4.c 2006-09-05 20:30:51.000000000 +0200 -@@ -451,7 +451,7 @@ - sapi_apache_get_fd, - sapi_apache_force_http_10, - sapi_apache_get_target_uid, -- sapi_apache_get_target_gid -+ sapi_apache_get_target_gid, - }; - /* }}} */ - -@@ -897,7 +897,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component("PHP/" PHP_VERSION); -+#endif - } - } - #endif -diff -Nura php-4.4.4/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.4-0.4.15/sapi/apache2filter/sapi_apache2.c ---- php-4.4.4/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:30:51.000000000 +0200 -@@ -562,7 +562,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-4.4.4/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.4-0.4.15/sapi/apache2handler/sapi_apache2.c ---- php-4.4.4/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:30:51.000000000 +0200 -@@ -340,7 +340,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-4.4.4/sapi/cgi/cgi_main.c hardening-patch-4.4.4-0.4.15/sapi/cgi/cgi_main.c ---- php-4.4.4/sapi/cgi/cgi_main.c 2006-02-22 16:11:53.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1435,11 +1435,19 @@ - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - } -+#if HARDENING_PATCH -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif -+#else - #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #endif -+#endif - php_end_ob_buffers(1 TSRMLS_CC); - exit(0); - break; -diff -Nura php-4.4.4/sapi/cli/php_cli.c hardening-patch-4.4.4-0.4.15/sapi/cli/php_cli.c ---- php-4.4.4/sapi/cli/php_cli.c 2006-05-18 22:33:46.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:30:51.000000000 +0200 -@@ -656,11 +656,19 @@ - if (php_request_startup(TSRMLS_C)==FAILURE) { - goto err; - } -+#if HARDENING_PATCH -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif -+#else - #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); - #endif -+#endif - php_end_ob_buffers(1 TSRMLS_CC); - exit_status=0; - goto out; -diff -Nura php-4.4.4/TSRM/TSRM.h hardening-patch-4.4.4-0.4.15/TSRM/TSRM.h ---- php-4.4.4/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/TSRM/TSRM.h 2006-09-05 20:30:51.000000000 +0200 -@@ -33,6 +33,13 @@ - # define TSRM_API - #endif - -+#if HARDENING_PATCH -+# if HAVE_REALPATH -+# undef realpath -+# define realpath php_realpath -+# endif -+#endif -+ - /* Only compile multi-threading functions if we're in ZTS mode */ - #ifdef ZTS - -@@ -84,6 +91,7 @@ - - #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts - -+ - #ifdef __cplusplus - extern "C" { - #endif -diff -Nura php-4.4.4/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.c ---- php-4.4.4/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:30:51.000000000 +0200 -@@ -179,6 +179,178 @@ - return p; - } - -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved) -+{ -+ struct stat sb; -+ char *p, *q, *s; -+ size_t left_len, resolved_len; -+ unsigned symlinks; -+ int serrno, slen; -+ int is_dir = 1; -+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; -+ -+ serrno = errno; -+ symlinks = 0; -+ if (path[0] == '/') { -+ resolved[0] = '/'; -+ resolved[1] = '\0'; -+ if (path[1] == '\0') -+ return (resolved); -+ resolved_len = 1; -+ left_len = strlcpy(left, path + 1, sizeof(left)); -+ } else { -+ if (getcwd(resolved, PATH_MAX) == NULL) { -+ strlcpy(resolved, ".", PATH_MAX); -+ return (NULL); -+ } -+ resolved_len = strlen(resolved); -+ left_len = strlcpy(left, path, sizeof(left)); -+ } -+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ -+ /* -+ * Iterate over path components in `left'. -+ */ -+ while (left_len != 0) { -+ /* -+ * Extract the next path component and adjust `left' -+ * and its length. -+ */ -+ p = strchr(left, '/'); -+ s = p ? p : left + left_len; -+ if (s - left >= sizeof(next_token)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ memcpy(next_token, left, s - left); -+ next_token[s - left] = '\0'; -+ left_len -= s - left; -+ if (p != NULL) -+ memmove(left, s + 1, left_len + 1); -+ if (resolved[resolved_len - 1] != '/') { -+ if (resolved_len + 1 >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ resolved[resolved_len++] = '/'; -+ resolved[resolved_len] = '\0'; -+ } -+ if (next_token[0] == '\0') -+ continue; -+ else if (strcmp(next_token, ".") == 0) -+ continue; -+ else if (strcmp(next_token, "..") == 0) { -+ /* -+ * Strip the last path component except when we have -+ * single "/" -+ */ -+ if (!is_dir) { -+ errno = ENOENT; -+ return (NULL); -+ } -+ if (resolved_len > 1) { -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ continue; -+ } -+ -+ /* -+ * Append the next path component and lstat() it. If -+ * lstat() fails we still can return successfully if -+ * there are no more path components left. -+ */ -+ resolved_len = strlcat(resolved, next_token, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ if (lstat(resolved, &sb) != 0) { -+ if (errno == ENOENT) { -+ if (p == NULL) { -+ errno = serrno; -+ return (resolved); -+ } else -+ /* dirty hack to support a vanilla PHP feature */ -+ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { -+ resolved_len = strlcat(resolved, "/", PATH_MAX); -+ resolved_len = strlcat(resolved, left, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ errno = serrno; -+ return (resolved); -+ } -+ } -+ return (NULL); -+ } -+ if (S_ISLNK(sb.st_mode)) { -+ if (symlinks++ > MAXSYMLINKS) { -+ errno = ELOOP; -+ return (NULL); -+ } -+ slen = readlink(resolved, symlink, sizeof(symlink) - 1); -+ if (slen < 0) -+ return (NULL); -+ symlink[slen] = '\0'; -+ if (symlink[0] == '/') { -+ resolved[1] = 0; -+ resolved_len = 1; -+ } else if (resolved_len > 1) { -+ /* Strip the last path component. */ -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ -+ /* -+ * If there are any path components left, then -+ * append them to symlink. The result is placed -+ * in `left'. -+ */ -+ if (p != NULL) { -+ if (symlink[slen - 1] != '/') { -+ if (slen + 1 >= sizeof(symlink)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ symlink[slen] = '/'; -+ symlink[slen + 1] = 0; -+ } -+ left_len = strlcat(symlink, left, sizeof(left)); -+ if (left_len >= sizeof(left)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ } -+ left_len = strlcpy(left, symlink, sizeof(left)); -+ } else { -+ if (S_ISDIR(sb.st_mode)) { -+ is_dir = 1; -+ } else { -+ is_dir = 0; -+ } -+ } -+ } -+ -+ /* -+ * Remove trailing slash except when the resolved pathname -+ * is a single "/". -+ */ -+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') -+ resolved[resolved_len - 1] = '\0'; -+ return (resolved); -+} -+#endif -+ - CWD_API void virtual_cwd_startup(void) - { - char cwd[MAXPATHLEN]; -@@ -300,8 +472,11 @@ - - if (path_length == 0) - return (0); -- if (path_length >= MAXPATHLEN) -+ if (path_length >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return (1); -+ } - - #if !defined(TSRM_WIN32) && !defined(NETWARE) - /* cwd_length can be 0 when getcwd() fails. -@@ -313,8 +488,9 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - } else { /* Concat current directory with relative path and then run realpath() on it */ -@@ -323,6 +499,8 @@ - - ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); - if (!tmp) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(ptr, state->cwd, state->cwd_length); -@@ -332,6 +510,8 @@ - ptr += path_length; - *ptr = '\0'; - if (strlen(tmp) >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - free(tmp); - return 1; - } -@@ -340,9 +520,10 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - free(tmp); -- return 1; */ -+ return 1; - } - } - free(tmp); -diff -Nura php-4.4.4/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.h ---- php-4.4.4/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:30:51.000000000 +0200 -@@ -128,6 +128,22 @@ - - typedef int (*verify_path_func)(const cwd_state *); - -+#ifndef HAVE_STRLCPY -+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); -+#undef strlcpy -+#define strlcpy php_strlcpy -+#endif -+ -+#ifndef HAVE_STRLCAT -+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); -+#undef strlcat -+#define strlcat php_strlcat -+#endif -+ -+ -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved); -+#endif - CWD_API void virtual_cwd_startup(void); - CWD_API void virtual_cwd_shutdown(void); - CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); -diff -Nura php-4.4.4/Zend/zend_alloc.c hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.c ---- php-4.4.4/Zend/zend_alloc.c 2006-08-10 19:27:12.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.c 2006-09-05 20:30:51.000000000 +0200 -@@ -56,6 +56,11 @@ - # define END_MAGIC_SIZE 0 - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+# define CANARY_SIZE sizeof(unsigned int) -+#else -+# define CANARY_SIZE 0 -+#endif - - # if MEMORY_LIMIT - # if ZEND_DEBUG -@@ -104,9 +109,17 @@ - if (p==AG(head)) { \ - AG(head) = p->pNext; \ - } else { \ -+ if (p != p->pLast->pNext) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pLast->pNext = p->pNext; \ - } \ - if (p->pNext) { \ -+ if (p != p->pNext->pLast) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pNext->pLast = p->pLast; \ - } - -@@ -138,6 +151,12 @@ - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { -+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); -+ exit(1); -+ } -+#endif - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - - if (size > INT_MAX || SIZE < size) { -@@ -159,6 +178,10 @@ - AG(cache_stats)[CACHE_INDEX][1]++; - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->cached = 0; - p->size = size; - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); -@@ -174,7 +197,7 @@ - AG(allocated_memory_peak) = AG(allocated_memory); - } - #endif -- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); - } - - emalloc_error: -@@ -206,7 +229,10 @@ - # endif - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -- -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } -@@ -233,17 +259,36 @@ - return emalloc_rel(lval + offset); - } - } -- -+ -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); -+#endif - zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset); - return 0; - } - - ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+efree_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); -+ exit(1); -+ } -+ /* to catch double efree()s */ -+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); -+ p->canary = 0; -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring", -@@ -288,6 +333,9 @@ - size_t _size = nmemb * size; - - if (nmemb && (_size/nmemb!=size)) { -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); -+#endif - fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); - #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID - kill(getpid(), SIGSEGV); -@@ -307,6 +355,9 @@ - - ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p; - zend_mem_header *orig; - DECLARE_CACHE_VARS(); -@@ -318,6 +369,16 @@ - - p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+erealloc_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); -+ exit(1); -+ } -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - void *new_p; -@@ -348,7 +409,7 @@ - } - #endif - REMOVE_POINTER_FROM_LIST(p); -- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); - erealloc_error: - if (!p) { - if (!allow_failure) { -@@ -371,6 +432,9 @@ - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - - HANDLE_UNBLOCK_INTERRUPTIONS(); -@@ -445,6 +509,10 @@ - { - AG(head) = NULL; - -+#if HARDENING_PATCH_MM_PROTECT -+ HG(canary_1) = zend_canary(); -+ HG(canary_2) = zend_canary(); -+#endif - #if MEMORY_LIMIT - AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ - AG(allocated_memory) = 0; -diff -Nura php-4.4.4/Zend/zend_alloc.h hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.h ---- php-4.4.4/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.h 2006-09-05 20:30:51.000000000 +0200 -@@ -32,6 +32,9 @@ - #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL - - typedef struct _zend_mem_header { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary; -+#endif - #if ZEND_DEBUG - long magic; - char *filename; -diff -Nura php-4.4.4/Zend/zend_builtin_functions.c hardening-patch-4.4.4-0.4.15/Zend/zend_builtin_functions.c ---- php-4.4.4/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:30:51.000000000 +0200 -@@ -49,6 +49,9 @@ - static ZEND_FUNCTION(crash); - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+static ZEND_FUNCTION(heap_overflow); -+#endif - static ZEND_FUNCTION(get_included_files); - static ZEND_FUNCTION(is_subclass_of); - static ZEND_FUNCTION(is_a); -@@ -101,6 +104,9 @@ - ZEND_FE(crash, NULL) - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ ZEND_FE(heap_overflow, NULL) -+#endif - ZEND_FE(get_included_files, NULL) - ZEND_FALIAS(get_required_files, get_included_files, NULL) - ZEND_FE(is_subclass_of, NULL) -@@ -805,6 +811,19 @@ - - #endif /* ZEND_DEBUG */ - -+ -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ZEND_FUNCTION(heap_overflow) -+{ -+ char *nowhere = emalloc(10); -+ -+ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); -+ -+ efree(nowhere); -+} -+#endif -+ -+ - /* {{{ proto array get_included_files(void) - Returns an array with the file names that were include_once()'d */ - ZEND_FUNCTION(get_included_files) -diff -Nura php-4.4.4/Zend/zend.c hardening-patch-4.4.4-0.4.15/Zend/zend.c ---- php-4.4.4/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend.c 2006-09-05 20:30:51.000000000 +0200 -@@ -53,6 +53,12 @@ - ZEND_API void (*zend_unblock_interruptions)(void); - ZEND_API void (*zend_ticks_function)(int ticks); - ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); -+#if HARDENING_PATCH -+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - - void (*zend_on_timeout)(int seconds TSRMLS_DC); - -@@ -70,9 +76,391 @@ - return SUCCESS; - } - -+#if HARDENING_PATCH -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; -+ } else { -+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_facility) = LOG_USER; -+ } else { -+ EG(hphp_log_syslog_facility) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_priority) = LOG_ALERT; -+ } else { -+ EG(hphp_log_syslog_priority) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_sapi) -+{ -+ if (!new_value) { -+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; -+ } else { -+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_script) -+{ -+ if (!new_value) { -+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL); -+ } else { -+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) -+{ -+ if (EG(hphp_log_scriptname)) { -+ pefree(EG(hphp_log_scriptname),1); -+ } -+ EG(hphp_log_scriptname) = NULL; -+ if (new_value) { -+ EG(hphp_log_scriptname) = pestrdup(new_value,1); -+ } -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_whitelist_destroy: -+ if (HG(include_whitelist)) { -+ zend_hash_destroy(HG(include_whitelist)); -+ pefree(HG(include_whitelist),1); -+ } -+ HG(include_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_whitelist_destroy; -+ } -+ -+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_blacklist_destroy: -+ if (HG(include_blacklist)) { -+ zend_hash_destroy(HG(include_blacklist)); -+ pefree(HG(include_blacklist),1); -+ } -+ HG(include_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_blacklist_destroy; -+ } -+ -+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_whitelist_destroy: -+ if (HG(eval_whitelist)) { -+ zend_hash_destroy(HG(eval_whitelist)); -+ pefree(HG(eval_whitelist),1); -+ } -+ HG(eval_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_whitelist_destroy; -+ } -+ -+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_blacklist_destroy: -+ if (HG(eval_blacklist)) { -+ zend_hash_destroy(HG(eval_blacklist)); -+ pefree(HG(eval_blacklist), 1); -+ } -+ HG(eval_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_blacklist_destroy; -+ } -+ -+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_whitelist_destroy: -+ if (HG(func_whitelist)) { -+ zend_hash_destroy(HG(func_whitelist)); -+ pefree(HG(func_whitelist),1); -+ } -+ HG(func_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_whitelist_destroy; -+ } -+ -+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_blacklist_destroy: -+ if (HG(func_blacklist)) { -+ zend_hash_destroy(HG(func_blacklist)); -+ pefree(HG(func_blacklist),1); -+ } -+ HG(func_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_blacklist_destroy; -+ } -+ -+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+#endif - - ZEND_INI_BEGIN() - ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) -+#if HARDENING_PATCH -+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) -+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) -+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) -+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) -+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) -+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) -+ 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) -+ -+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) -+ -+ 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) -+ 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) -+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) -+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) -+#endif - ZEND_INI_END() - - -@@ -354,8 +742,12 @@ - zend_init_rsrc_plist(TSRMLS_C); - EG(lambda_count)=0; - EG(user_error_handler) = NULL; -+ EG(in_code_type) = 0; - EG(in_execution) = 0; - EG(current_execute_data) = NULL; -+#if HARDENING_PATCH -+ EG(hphp_log_scriptname) = NULL; -+#endif - } - - -@@ -420,6 +812,14 @@ - extern zend_scanner_globals language_scanner_globals; - #endif - -+ /* Set up Hardening-Patch utility functions first */ -+#if HARDENING_PATCH -+ zend_security_log = utility_functions->security_log_function; -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ zend_is_valid_include = utility_functions->is_valid_include; -+#endif -+ - #ifdef ZTS - ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); - #else -@@ -619,6 +1019,7 @@ - } - CG(unclean_shutdown) = 1; - CG(in_compilation) = EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(current_execute_data) = NULL; - longjmp(EG(bailout), FAILURE); - } -diff -Nura php-4.4.4/Zend/zend_canary.c hardening-patch-4.4.4-0.4.15/Zend/zend_canary.c ---- php-4.4.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_canary.c 2006-09-05 20:30:51.000000000 +0200 -@@ -0,0 +1,58 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ -+ -+#include "zend.h" -+ -+#include -+#include -+ -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+ZEND_API unsigned int zend_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-4.4.4/Zend/zend_compile.c hardening-patch-4.4.4-0.4.15/Zend/zend_compile.c ---- php-4.4.4/Zend/zend_compile.c 2006-02-23 19:07:16.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_compile.c 2006-09-05 20:30:51.000000000 +0200 -@@ -768,6 +768,13 @@ - op_array.function_name = name; - op_array.arg_types = NULL; - op_array.return_reference = return_reference; -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array.created_by_eval = 1; -+ } else { -+ op_array.created_by_eval = 0; -+ } -+#endif - - if (is_method) { - if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { -diff -Nura php-4.4.4/Zend/zend_compile.h hardening-patch-4.4.4-0.4.15/Zend/zend_compile.h ---- php-4.4.4/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_compile.h 2006-09-05 20:30:51.000000000 +0200 -@@ -106,6 +106,9 @@ - char *filename; - - void *reserved[ZEND_MAX_RESERVED_RESOURCES]; -+#if HARDENING_PATCH -+ zend_bool created_by_eval; -+#endif - }; - - -@@ -549,6 +552,7 @@ - #define ZEND_USER_FUNCTION 2 - #define ZEND_OVERLOADED_FUNCTION 3 - #define ZEND_EVAL_CODE 4 -+#define ZEND_SANDBOX_CODE 6 - - #define ZEND_INTERNAL_CLASS 1 - #define ZEND_USER_CLASS 2 -diff -Nura php-4.4.4/Zend/zend_constants.c hardening-patch-4.4.4-0.4.15/Zend/zend_constants.c ---- php-4.4.4/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_constants.c 2006-09-05 20:30:51.000000000 +0200 -@@ -111,6 +111,74 @@ - REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); - - REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); -+ -+ /* error levels */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); -+ /* facility: type of program logging the message */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NEWS -+ /* No LOG_NEWS on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ -+#endif -+#ifdef LOG_UUCP -+ /* No LOG_UUCP on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_CRON -+ /* apparently some systems don't have this one */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_AUTHPRIV -+ /* AIX doesn't have LOG_AUTHPRIV */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); -+#endif -+#if !defined(PHP_WIN32) && !defined(NETWARE) -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); -+#endif -+ /* options */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NOWAIT -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_PERROR -+ /* AIX doesn't have LOG_PERROR */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ -+#endif -+#endif - - /* true/false constants */ - { -diff -Nura php-4.4.4/Zend/zend_errors.h hardening-patch-4.4.4-0.4.15/Zend/zend_errors.h ---- php-4.4.4/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_errors.h 2006-09-05 20:30:51.000000000 +0200 -@@ -36,5 +36,18 @@ - #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) - #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) - -+#if HARDENING_PATCH -+#define S_MEMORY (1<<0L) -+#define S_VARS (1<<1L) -+#define S_FILES (1<<2L) -+#define S_INCLUDE (1<<3L) -+#define S_SQL (1<<4L) -+#define S_EXECUTOR (1<<5L) -+#define S_MAIL (1<<6L) -+#define S_MISC (1<<30L) -+#define S_INTERNAL (1<<29L) -+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) -+#endif -+ - #endif /* ZEND_ERRORS_H */ - -diff -Nura php-4.4.4/Zend/zend_execute_API.c hardening-patch-4.4.4-0.4.15/Zend/zend_execute_API.c ---- php-4.4.4/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:30:51.000000000 +0200 -@@ -142,6 +142,7 @@ - EG(class_table) = CG(class_table); - - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - - zend_ptr_stack_init(&EG(argument_stack)); - -@@ -431,12 +432,14 @@ - zend_execute_data execute_data; - - /* Initialize execute_data */ -+ memset(&execute_data, 0, sizeof(execute_data)); - EX(fbc) = NULL; - EX(object).ptr = NULL; - EX(ce) = NULL; - EX(Ts) = NULL; - EX(op_array) = NULL; - EX(opline) = NULL; -+ EX(execute_depth) = 0; - - *retval_ptr_ptr = NULL; - -@@ -494,6 +497,39 @@ - zval_dtor(&function_name_copy); - return FAILURE; - } -+#if HARDENING_PATCH -+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val); -+ zval_dtor(&function_name_copy); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - zval_dtor(&function_name_copy); - - for (i=0; itype = type; - EG(return_value_ptr_ptr) = &local_retval_ptr; - EG(active_op_array) = new_op_array; - EG(no_extensions)=1; -@@ -673,6 +709,10 @@ - return retval; - } - -+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+{ -+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); -+} - - void execute_new_code(TSRMLS_D) - { -diff -Nura php-4.4.4/Zend/zend_execute.c hardening-patch-4.4.4-0.4.15/Zend/zend_execute.c ---- php-4.4.4/Zend/zend_execute.c 2006-08-11 15:04:14.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1042,6 +1042,7 @@ - zend_execute_data execute_data; - - /* Initialize execute_data */ -+ memset(&execute_data, 0, sizeof(execute_data)); - EX(fbc) = NULL; - EX(ce) = NULL; - EX(object).ptr = NULL; -@@ -1053,9 +1054,21 @@ - } - EX(prev_execute_data) = EG(current_execute_data); - EX(original_in_execution)=EG(in_execution); -+ EX(original_in_code_type)=EG(in_code_type); - - EG(current_execute_data) = &execute_data; - -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif -+ - EG(in_execution) = 1; - if (op_array->start_op) { - EX(opline) = op_array->start_op; -@@ -1087,6 +1100,19 @@ - } - } - -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif -+ - while (1) { - #ifdef ZEND_WIN32 - if (EG(timed_out)) { -@@ -1634,6 +1660,36 @@ - if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) { - zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val); - } -+#if HARDENING_PATCH -+ if (active_function_table == EG(function_table)) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+#endif -+ - zval_dtor(&tmp); - EX(fbc) = function; - overloaded_function_call_cont: -@@ -1649,6 +1705,35 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); - zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce)); - EX(object).ptr = NULL; -@@ -1821,6 +1906,7 @@ - efree(EX(Ts)); - } - EG(in_execution) = EX(original_in_execution); -+ EG(in_code_type) = EX(original_in_code_type); - EG(current_execute_data) = EX(prev_execute_data); - return; - } -@@ -2210,7 +2296,12 @@ - int dummy = 1; - zend_file_handle file_handle = {0}; - -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS -+#else - if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS -+#endif - && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { - - file_handle.filename = inc_filename->value.str.val; -@@ -2239,6 +2330,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -diff -Nura php-4.4.4/Zend/zend_execute_globals.h hardening-patch-4.4.4-0.4.15/Zend/zend_execute_globals.h ---- php-4.4.4/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute_globals.h 2006-09-05 20:30:51.000000000 +0200 -@@ -60,6 +60,8 @@ - object_info object; - temp_variable *Ts; - zend_bool original_in_execution; -+ zend_uint original_in_code_type; -+ zend_uint execute_depth; - zend_op_array *op_array; - struct _zend_execute_data *prev_execute_data; - } zend_execute_data; -diff -Nura php-4.4.4/Zend/zend_extensions.c hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.c ---- php-4.4.4/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.c 2006-09-05 20:30:51.000000000 +0200 -@@ -54,23 +54,44 @@ - return FAILURE; - } - -+ /* check if module is compiled against Hardening-Patch */ -+ if (extension_version_info->zend_extension_api_no < 1000000000) { -+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } -+ -+ -+ /* check if module is compiled against correct Hardening-Patch version */ -+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { -+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ extension_version_info->zend_extension_api_no, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } - - /* allow extension to proclaim compatibility with any Zend version */ -- 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)) { -- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { -+ 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)) { -+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is outdated.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO); - DL_UNLOAD(handle); - return FAILURE; -- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { -+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is newer.\n" - "Contact %s at %s for a later version of %s.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO, - new_extension->author, - new_extension->URL, -diff -Nura php-4.4.4/Zend/zend_extensions.h hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.h ---- php-4.4.4/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.h 2006-09-05 20:30:51.000000000 +0200 -@@ -23,6 +23,9 @@ - - #include "zend_compile.h" - -+/* Create own API version number for Hardening-Patch */ -+ -+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805 - #define ZEND_EXTENSION_API_NO 20050606 - - typedef struct _zend_extension_version_info { -@@ -30,6 +33,7 @@ - char *required_zend_version; - unsigned char thread_safe; - unsigned char debug; -+ int real_zend_extension_api_no; - } zend_extension_version_info; - - -@@ -96,7 +100,7 @@ - - - #define ZEND_EXTENSION() \ -- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } -+ 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 } - - #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 - #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 -diff -Nura php-4.4.4/Zend/zend_globals.h hardening-patch-4.4.4-0.4.15/Zend/zend_globals.h ---- php-4.4.4/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_globals.h 2006-09-05 20:30:51.000000000 +0200 -@@ -163,6 +163,16 @@ - - int error_reporting; - int orig_error_reporting; -+#if HARDENING_PATCH -+ int hphp_log_syslog; -+ int hphp_log_syslog_facility; -+ int hphp_log_syslog_priority; -+ int hphp_log_sapi; -+ int hphp_log_script; -+ char *hphp_log_scriptname; -+ zend_bool hphp_log_use_x_forwarded_for; -+ long hphp_executor_max_depth; -+#endif - int exit_status; - - zend_op_array *active_op_array; -@@ -176,6 +186,7 @@ - int ticks_count; - - zend_bool in_execution; -+ zend_uint in_code_type; - zend_bool bailout_set; - zend_bool full_tables_cleanup; - -diff -Nura php-4.4.4/Zend/zend.h hardening-patch-4.4.4-0.4.15/Zend/zend.h ---- php-4.4.4/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend.h 2006-09-05 20:30:51.000000000 +0200 -@@ -274,9 +274,10 @@ - struct _zval_struct { - /* Variable information */ - zvalue_value value; /* value */ -+ zend_uint refcount; -+ zend_ushort flags; - zend_uchar type; /* active type */ - zend_uchar is_ref; -- zend_ushort refcount; - }; - - -@@ -337,6 +338,12 @@ - void (*ticks_function)(int ticks); - void (*on_timeout)(int seconds TSRMLS_DC); - zend_bool (*open_function)(const char *filename, struct _zend_file_handle *); -+#if HARDENING_PATCH -+ void (*security_log_function)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ int (*is_valid_include)(zval *z); -+#endif - } zend_utility_functions; - - -@@ -468,7 +475,16 @@ - extern ZEND_API void (*zend_ticks_function)(int ticks); - extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); - extern void (*zend_on_timeout)(int seconds TSRMLS_DC); -+#if HARDENING_PATCH -+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+extern ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ZEND_API unsigned int zend_canary(void); -+#endif - - ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3); - -@@ -575,6 +591,11 @@ - - #define ZEND_MAX_RESERVED_RESOURCES 4 - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#include "php_syslog.h" -+#endif -+ - #endif /* ZEND_H */ - - /* -diff -Nura php-4.4.4/Zend/zend_hash.c hardening-patch-4.4.4-0.4.15/Zend/zend_hash.c ---- php-4.4.4/Zend/zend_hash.c 2006-02-01 10:11:55.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_hash.c 2006-09-05 20:30:51.000000000 +0200 -@@ -26,6 +26,17 @@ - # include - #endif - -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int zend_hash_canary = 0x1234567; -+ zend_bool zend_hash_canary_inited = 0; -+#endif -+ -+#define CHECK_HASH_CANARY(hash) \ -+ if (zend_hash_canary != (hash)->canary) { \ -+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ -+ exit(1); \ -+ } -+ - #define HANDLE_NUMERIC(key, length, func) { \ - register char *tmp=key; \ - \ -@@ -175,6 +186,9 @@ - { - uint i = 3; - Bucket **tmp; -+#if HARDENING_PATCH_HASH_PROTECT -+ TSRMLS_FETCH(); -+#endif - - SET_INCONSISTENT(HT_OK); - -@@ -184,6 +198,13 @@ - - ht->nTableSize = 1 << i; - ht->nTableMask = ht->nTableSize - 1; -+#if HARDENING_PATCH_HASH_PROTECT -+ if (zend_hash_canary_inited==0) { -+ zend_hash_canary = zend_canary(); -+ zend_hash_canary_inited = 1; -+ } -+ ht->canary = zend_hash_canary; -+#endif - ht->pDestructor = pDestructor; - ht->pListHead = NULL; - ht->pListTail = NULL; -@@ -259,6 +280,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -327,6 +351,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -402,6 +429,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -450,7 +480,7 @@ - IS_CONSISTENT(ht); - - if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ -- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); -+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); - if (t) { - HANDLE_BLOCK_INTERRUPTIONS(); - ht->arBuckets = t; -@@ -460,6 +490,7 @@ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return SUCCESS; - } -+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); - return FAILURE; - } - return SUCCESS; -@@ -526,6 +557,9 @@ - ht->pInternalPointer = p->pListNext; - } - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (!p->pDataPtr) { -@@ -555,6 +589,9 @@ - q = p; - p = p->pListNext; - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(q->pData); - } - if (!q->pDataPtr && q->pData) { -@@ -581,6 +618,9 @@ - q = p; - p = p->pListNext; - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(q->pData); - } - if (!q->pDataPtr && q->pData) { -@@ -610,6 +650,9 @@ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (!p->pDataPtr) { -diff -Nura php-4.4.4/Zend/zend_hash.h hardening-patch-4.4.4-0.4.15/Zend/zend_hash.h ---- php-4.4.4/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_hash.h 2006-09-05 20:30:51.000000000 +0200 -@@ -54,6 +54,9 @@ - } Bucket; - - typedef struct _hashtable { -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int canary; -+#endif - uint nTableSize; - uint nTableMask; - uint nNumOfElements; -diff -Nura php-4.4.4/Zend/zend_ini.c hardening-patch-4.4.4-0.4.15/Zend/zend_ini.c ---- php-4.4.4/Zend/zend_ini.c 2005-09-02 23:09:03.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:37.000000000 +0200 -@@ -256,7 +256,8 @@ - zend_ini_entry *ini_entry; - TSRMLS_FETCH(); - -- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { -+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || -+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifyable & ZEND_INI_USER) == 0)) { - return FAILURE; - } - -diff -Nura php-4.4.4/Zend/zend_ini.h hardening-patch-4.4.4-0.4.15/Zend/zend_ini.h ---- php-4.4.4/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_ini.h 2006-09-05 20:30:51.000000000 +0200 -@@ -174,6 +174,7 @@ - /* Standard message handlers */ - BEGIN_EXTERN_C() - ZEND_API ZEND_INI_MH(OnUpdateBool); -+#define OnUpdateLong OnUpdateInt - ZEND_API ZEND_INI_MH(OnUpdateInt); - ZEND_API ZEND_INI_MH(OnUpdateReal); - ZEND_API ZEND_INI_MH(OnUpdateString); -diff -Nura php-4.4.4/Zend/zend_language_scanner.l hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.l ---- php-4.4.4/Zend/zend_language_scanner.l 2006-04-13 15:52:24.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:30:51.000000000 +0200 -@@ -393,6 +393,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-4.4.4/Zend/zend_language_scanner.c hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.c ---- php-4.4.4/Zend/zend_language_scanner.c 2006-08-15 14:01:21.000000000 +0200 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:30:51.000000000 +0200 -@@ -3036,6 +3036,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-4.4.4/Zend/zend_llist.c hardening-patch-4.4.4-0.4.15/Zend/zend_llist.c ---- php-4.4.4/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_llist.c 2006-09-05 20:30:51.000000000 +0200 -@@ -21,9 +21,49 @@ - #include "zend.h" - #include "zend_llist.h" - #include "zend_qsort.h" -+#include "zend_globals.h" -+ -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int zend_llist_canary_1 = 0x1234567; -+ unsigned int zend_llist_canary_2 = 0x1553425; -+ zend_bool zend_llist_canary_inited = 0; -+#endif -+ -+#define CHECK_LIST_CANARY(list) \ -+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ -+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ -+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+#define CHECK_LISTELEMENT_CANARY(elem, list) \ -+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ -+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ -+ exit(1); \ -+ } -+ - - ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ -+ if (persistent) { -+ if (!zend_llist_canary_inited) { -+ /* do not change order to ensure thread safety */ -+ zend_llist_canary_1 = zend_canary(); -+ zend_llist_canary_2 = zend_canary(); -+ zend_llist_canary_inited = 1; -+ } -+ } else -+ if (!HG(ll_canary_inited)) { -+ HG(canary_3) = zend_canary(); -+ HG(canary_4) = zend_canary(); -+ HG(ll_canary_inited) = 1; -+ } -+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); -+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); -+#endif - l->head = NULL; - l->tail = NULL; - l->count = 0; -@@ -37,6 +77,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->prev = l->tail; - tmp->next = NULL; - if (l->tail) { -@@ -55,6 +100,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->next = l->head; - tmp->prev = NULL; - if (l->head) { -@@ -91,10 +141,20 @@ - zend_llist_element *current=l->head; - zend_llist_element *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (compare(current->data, element)) { - DEL_LLIST_ELEMENT(current, l); -+#if HARDENING_PATCH_LL_PROTECT -+ current->canary = 0; -+#endif - break; - } - current = next; -@@ -106,7 +166,14 @@ - { - zend_llist_element *current=l->head, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (l->dtor) { - l->dtor(current->data); -@@ -131,7 +198,14 @@ - zend_llist_element *old_tail; - void *data; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if ((old_tail = l->tail)) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(old_tail, l) -+#endif - if (l->tail->prev) { - l->tail->prev->next = NULL; - } -@@ -157,9 +231,16 @@ - { - zend_llist_element *ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(src) -+#endif - zend_llist_init(dst, src->size, src->dtor, src->persistent); - ptr = src->head; - while (ptr) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(ptr, src) -+#endif - zend_llist_add_element(dst, ptr->data); - ptr = ptr->next; - } -@@ -170,11 +251,21 @@ - { - zend_llist_element *element, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - element=l->head; - while (element) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - next = element->next; - if (func(element->data)) { - DEL_LLIST_ELEMENT(element, l); -+#if HARDENING_PATCH_LL_PROTECT -+ element->canary = 0; -+#endif - } - element = next; - } -@@ -185,7 +276,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data TSRMLS_CC); - } - } -@@ -197,6 +294,9 @@ - zend_llist_element **elements; - zend_llist_element *element, **ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - if (l->count <= 0) { - return; - } -@@ -206,6 +306,9 @@ - ptr = &elements[0]; - - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - *ptr++ = element; - } - -@@ -228,7 +331,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, arg TSRMLS_CC); - } - } -@@ -239,8 +348,14 @@ - zend_llist_element *element; - va_list args; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - va_start(args, num_args); - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, num_args, args TSRMLS_CC); - } - va_end(args); -@@ -249,6 +364,10 @@ - - ZEND_API int zend_llist_count(zend_llist *l) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - return l->count; - } - -@@ -256,8 +375,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->head; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -269,8 +395,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->tail; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -282,9 +415,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->next; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -@@ -296,9 +439,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->prev; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -diff -Nura php-4.4.4/Zend/zend_llist.h hardening-patch-4.4.4-0.4.15/Zend/zend_llist.h ---- php-4.4.4/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_llist.h 2006-09-05 20:30:51.000000000 +0200 -@@ -24,6 +24,9 @@ - #include - - typedef struct _zend_llist_element { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary, padding; -+#endif - struct _zend_llist_element *next; - struct _zend_llist_element *prev; - char data[1]; /* Needs to always be last in the struct */ -@@ -36,6 +39,9 @@ - typedef void (*llist_apply_func_t)(void * TSRMLS_DC); - - typedef struct _zend_llist { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_h; /* head */ -+#endif - zend_llist_element *head; - zend_llist_element *tail; - size_t size; -@@ -43,6 +49,9 @@ - llist_dtor_func_t dtor; - unsigned char persistent; - zend_llist_element *traverse_ptr; -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_t; /* tail */ -+#endif - } zend_llist; - - typedef zend_llist_element* zend_llist_position; -diff -Nura php-4.4.4/Zend/zend_modules.h hardening-patch-4.4.4-0.4.15/Zend/zend_modules.h ---- php-4.4.4/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_modules.h 2006-09-05 20:30:51.000000000 +0200 -@@ -34,6 +34,7 @@ - ZEND_API extern unsigned char second_arg_force_ref[]; - ZEND_API extern unsigned char third_arg_force_ref[]; - -+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112 - #define ZEND_MODULE_API_NO 20020429 - #ifdef ZTS - #define USING_ZTS 1 -@@ -41,9 +42,9 @@ - #define USING_ZTS 0 - #endif - --#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS -+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS - --#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 -+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO - - #define STANDARD_MODULE_PROPERTIES \ - NULL, NULL, STANDARD_MODULE_PROPERTIES_EX -@@ -75,6 +76,7 @@ - unsigned char type; - void *handle; - int module_number; -+ unsigned int real_zend_api; - }; - - -diff -Nura php-4.4.4/Zend/zend_opcode.c hardening-patch-4.4.4-0.4.15/Zend/zend_opcode.c ---- php-4.4.4/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_opcode.c 2006-09-05 20:30:51.000000000 +0200 -@@ -88,6 +88,9 @@ - op_array->done_pass_two = 0; - - op_array->start_op = NULL; -+#if HARDENING_PATCH -+ op_array->created_by_eval = 0; -+#endif - - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); - } -diff -Nura php-4.4.4/Zend/zend_operators.c hardening-patch-4.4.4-0.4.15/Zend/zend_operators.c ---- php-4.4.4/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_operators.c 2006-09-05 20:30:51.000000000 +0200 -@@ -1604,6 +1604,20 @@ - return (op->value.lval ? 1 : 0); - } - -+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) -+{ -+ register unsigned char *str = (unsigned char*)source; -+ register unsigned char *result = (unsigned char*)dest; -+ register unsigned char *end = str + length; -+ -+ while (str < end) { -+ *result++ = tolower((int)*str++); -+ } -+ *result = *end; -+ -+ return dest; -+} -+ - ZEND_API void zend_str_tolower(char *str, unsigned int length) - { - register char *p=str, *end=p+length; -diff -Nura php-4.4.4/Zend/zend_operators.h hardening-patch-4.4.4-0.4.15/Zend/zend_operators.h ---- php-4.4.4/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100 -+++ hardening-patch-4.4.4-0.4.15/Zend/zend_operators.h 2006-09-05 20:30:51.000000000 +0200 -@@ -174,6 +174,14 @@ - #endif - - ZEND_API void zend_str_tolower(char *str, unsigned int length); -+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length); -+ -+static inline char * -+zend_str_tolower_dup(const char *source, unsigned int length) -+{ -+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length); -+} -+ - ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2); - ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3); - ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2); diff --git a/hardening-patch-5.1.4-0.4.15.patch b/hardening-patch-5.1.4-0.4.15.patch deleted file mode 100644 index 6b2eba0..0000000 --- a/hardening-patch-5.1.4-0.4.15.patch +++ /dev/null @@ -1,9802 +0,0 @@ -diff -Nura php-5.1.4/Changelog.hphp hardening-patch-5.1.4-0.4.15/Changelog.hphp ---- php-5.1.4/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Changelog.hphp 2006-09-07 19:32:29.000000000 +0200 -@@ -0,0 +1,61 @@ -+Changelog of the Hardening-Patch -+-------------------------------- -+ -+0.4.15 - 07. September 2006 -+ -+ PHP4: -+ [+] Fix for potential DOS in handling of include blacklists -+ -+ PHP4+5: -+ [+] Backported a fix for open_basedir problems with insanse PHP scripts -+ [+] Added a fix for ini_restore() PHP security vulnerability -+ -+0.4.14 - 11. August 2006 -+ -+ PHP4: -+ [+] Remove unecessary call to AC_BROKEN_REALPATH -+ -+ PHP5: -+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant -+ -+ PHP4+5: -+ [+] Added a few PHP security fixes / see changelog.secfix for details -+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits -+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments -+ -+0.4.13 - 07. August 2006 -+ -+ PHP4+5: -+ [+] Added a fix for a compile problem on solaris due to missing strcasestr() -+ -+0.4.12 - 19. July 2006 -+ -+ PHP4: -+ [+] Added fixes from sf4 security patch / see changelog.secfix for details -+ -+ PHP5: -+ [+] Added fixes from sf5 security patch / see changelog.secfix for details -+ -+ PHP4+5: -+ [+] Added anti mail spam feature -+ [+] Speedup of zend_hash canary (clear/destroy) -+ [+] Added a fix for a DOS in the handling of URL blacklists -+ -+0.4.11 - 13. May 2006 -+ -+ PHP5: -+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache -+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 -+ -+ PHP4+5: -+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories -+ -+ -+0.4.10 - 11. May 2006 -+ -+ PHP4: -+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed -+ -+ PHP4+5: -+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir -+ -diff -Nura php-5.1.4/Changelog.secfix hardening-patch-5.1.4-0.4.15/Changelog.secfix ---- php-5.1.4/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Changelog.secfix 2006-09-05 20:31:02.000000000 +0200 -@@ -0,0 +1,40 @@ -+Changelog of PHP 5.1.4 Security Fixes -+ -+Release 6 - 11. August 2006 -+ -+ [+] Added IMAP open_basedir/safe_mode check -+ [+] Added a fix for previous ext/session fixes -+ [+] Added upstream fix to ext/socket -+ [+] Added sscanf() security fix -+ [+] Added fixes for handling of corrupt .gif files to gdlib -+ -+Release 5 - 13. July 2006 -+ -+ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode -+ -+Release 4 - 13. July 2006 -+ -+ [+] Added a recursive array printing fix to the phpinfo() XSS fix -+ [+] Added a fix for stat() on non existing files in safe_mode -+ -+Release 3 - 07. July 2006 -+ -+ [+] Added a fix for an integer overflow in str_repeat() -+ [+] Added a *working* wordwrap() fix -+ [+] Added code to make memory_limit work on 64bit systems -+ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability -+ [+] Added a fix for overlong tempfilename -+ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl -+ [+] Added a high characters fix to ext/wddx -+ -+Release 2 - 16. May 2006 -+ -+ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP -+ tarball got updated -+ -+Release 1 - 13. May 2006 -+ -+ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball -+ and is downloaded when make install is called (usually as root -> security risk) -+ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache -+ -diff -Nura php-5.1.4/configure hardening-patch-5.1.4-0.4.15/configure ---- php-5.1.4/configure 2006-05-12 16:41:10.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/configure 2006-09-05 20:31:02.000000000 +0200 -@@ -942,6 +942,16 @@ - ac_help="$ac_help - --with-libdir=NAME Look for libraries in .../NAME rather than .../lib" - ac_help="$ac_help -+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." -+ac_help="$ac_help -+ --disable-hardening-patch-ll-protect Disable the Linked List protection." -+ac_help="$ac_help -+ --disable-hardening-patch-inc-protect Disable include/require protection." -+ac_help="$ac_help -+ --disable-hardening-patch-fmt-protect Disable format string protection." -+ac_help="$ac_help -+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." -+ac_help="$ac_help - - SAPI modules: - " -@@ -1410,6 +1420,8 @@ - ac_help="$ac_help - --enable-wddx Enable WDDX support" - ac_help="$ac_help -+ --disable-varfilter Disable Hardening-Patch's variable filter" -+ac_help="$ac_help - --disable-xml Disable XML support" - ac_help="$ac_help - --with-libxml-dir=DIR XML: libxml2 install prefix" -@@ -3618,6 +3630,157 @@ - - - -+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. -+if test "${enable_hardening_patch_mm_protect+set}" = set; then -+ enableval="$enable_hardening_patch_mm_protect" -+ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. -+if test "${enable_hardening_patch_ll_protect+set}" = set; then -+ enableval="$enable_hardening_patch_ll_protect" -+ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. -+if test "${enable_hardening_patch_inc_protect+set}" = set; then -+ enableval="$enable_hardening_patch_inc_protect" -+ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. -+if test "${enable_hardening_patch_fmt_protect+set}" = set; then -+ enableval="$enable_hardening_patch_fmt_protect" -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. -+if test "${enable_hardening_patch_hash_protect+set}" = set; then -+ enableval="$enable_hardening_patch_hash_protect" -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+ -+fi -+ -+ -+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 -+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 -+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 -+echo "configure:2733: checking whether to protect include/require statements" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect PHP Format String functions" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 -+ -+ -+cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH 1 -+EOF -+ -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 0 -+EOF -+ -+fi - - - -@@ -18607,6 +18770,62 @@ - fi - - -+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 -+echo "configure:14928: checking whether realpath is broken" >&5 -+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then -+ echo $ac_n "(cached) $ac_c" 1>&6 -+else -+ -+ if test "$cross_compiling" = yes; then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -+then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ echo "configure: failed program was:" >&5 -+ cat conftest.$ac_ext >&5 -+ rm -fr conftest* -+ -+ ac_cv_broken_realpath=yes -+ -+fi -+rm -fr conftest* -+fi -+ -+ -+fi -+ -+echo "$ac_t""$ac_cv_broken_realpath" 1>&6 -+ if test "$ac_cv_broken_realpath" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 1 -+EOF -+ -+ else -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 0 -+EOF -+ -+ fi -+ -+ - echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 - echo "configure:18612: checking for declared timezone" >&5 - if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then -@@ -89422,7 +89641,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - cat >> confdefs.h <&6 -+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 -+# Check whether --enable-varfilter or --disable-varfilter was given. -+if test "${enable_varfilter+set}" = set; then -+ enableval="$enable_varfilter" -+ PHP_VARFILTER=$enableval -+else -+ -+ PHP_VARFILTER=yes -+ -+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then -+ PHP_VARFILTER=$PHP_ENABLE_ALL -+ fi -+ -+fi -+ -+ -+ -+ext_output="yes, shared" -+ext_shared=yes -+case $PHP_VARFILTER in -+shared,*) -+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` -+ ;; -+shared) -+ PHP_VARFILTER=yes -+ ;; -+no) -+ ext_output=no -+ ext_shared=no -+ ;; -+*) -+ ext_output=yes -+ ext_shared=no -+ ;; -+esac -+ -+ -+ -+echo "$ac_t""$ext_output" 1>&6 -+ -+ -+ -+ -+if test "$PHP_VARFILTER" != "no"; then -+ cat >> confdefs.h <<\EOF -+#define HAVE_VARFILTER 1 -+EOF -+ -+ -+ ext_builddir=ext/varfilter -+ ext_srcdir=$abs_srcdir/ext/varfilter -+ -+ ac_extra= -+ -+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then -+ -+ -+ -+ case ext/varfilter in -+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; -+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; -+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; -+ esac -+ -+ -+ -+ b_c_pre=$php_c_pre -+ b_cxx_pre=$php_cxx_pre -+ b_c_meta=$php_c_meta -+ b_cxx_meta=$php_cxx_meta -+ b_c_post=$php_c_post -+ b_cxx_post=$php_cxx_post -+ b_lo=$php_lo -+ -+ -+ old_IFS=$IFS -+ for ac_src in varfilter.c; do -+ -+ IFS=. -+ set $ac_src -+ ac_obj=$1 -+ IFS=$old_IFS -+ -+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" -+ -+ case $ac_src in -+ *.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" ;; -+ *.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" ;; -+ esac -+ -+ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 -@@ -112351,7 +112829,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_logos.c \ -- output.c ; do -+ output.c hardening_patch.c ; do - - IFS=. - set $ac_src -@@ -112596,7 +113074,7 @@ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ - zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ -- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do -+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do - - IFS=. - set $ac_src -diff -Nura php-5.1.4/configure.in hardening-patch-5.1.4-0.4.15/configure.in ---- php-5.1.4/configure.in 2006-05-04 01:30:02.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/configure.in 2006-09-05 20:31:02.000000000 +0200 -@@ -209,7 +209,7 @@ - - sinclude(Zend/Zend.m4) - sinclude(TSRM/tsrm.m4) -- -+sinclude(main/hardening_patch.m4) - - divert(2) - -@@ -1275,7 +1275,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_logos.c \ -- output.c ) -+ output.c hardening_patch.c ) - - PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ - plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c) -@@ -1302,7 +1302,7 @@ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ - zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ -- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c) -+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c ) - - if test -r "$abs_srcdir/Zend/zend_objects.c"; then - PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \ -diff -Nura php-5.1.4/ext/curl/interface.c hardening-patch-5.1.4-0.4.15/ext/curl/interface.c ---- php-5.1.4/ext/curl/interface.c 2006-04-13 13:26:10.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/curl/interface.c 2006-09-05 20:31:02.000000000 +0200 -@@ -167,6 +167,11 @@ - RETURN_FALSE; \ - } \ - \ -+ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ -+ RETURN_FALSE; \ -+ } \ -+ \ - if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ - (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ - ) { \ -@@ -1065,7 +1070,6 @@ - case CURLOPT_FTPLISTONLY: - case CURLOPT_FTPAPPEND: - case CURLOPT_NETRC: -- case CURLOPT_FOLLOWLOCATION: - case CURLOPT_PUT: - #if CURLOPT_MUTE != 0 - case CURLOPT_MUTE: -@@ -1116,6 +1120,16 @@ - convert_to_long_ex(zvalue); - error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); - break; -+ case CURLOPT_FOLLOWLOCATION: -+ convert_to_long_ex(zvalue); -+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { -+ if (Z_LVAL_PP(zvalue) != 0) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set"); -+ RETURN_FALSE; -+ } -+ } -+ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); -+ break; - case CURLOPT_URL: - case CURLOPT_PROXY: - case CURLOPT_USERPWD: -diff -Nura php-5.1.4/ext/curl/streams.c hardening-patch-5.1.4-0.4.15/ext/curl/streams.c ---- php-5.1.4/ext/curl/streams.c 2006-01-01 13:50:01.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/curl/streams.c 2006-09-05 20:31:02.000000000 +0200 -@@ -289,7 +289,11 @@ - curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream); - - /* currently buggy (bug is in curl) */ -- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); -+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) { -+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0); -+ } else { -+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1); -+ } - - curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr); - curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0); -diff -Nura php-5.1.4/ext/fbsql/php_fbsql.c hardening-patch-5.1.4-0.4.15/ext/fbsql/php_fbsql.c ---- php-5.1.4/ext/fbsql/php_fbsql.c 2006-01-01 13:50:06.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:31:02.000000000 +0200 -@@ -1925,8 +1925,24 @@ - } - else if (fbcmdErrorsFound(md)) - { -+#if HARDENING_PATCH -+ char* query_copy; -+ int i; -+#endif - FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); - char* emg = fbcemdAllErrorMessages(emd); -+#if HARDENING_PATCH -+ query_copy=estrdup(query_copy); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ free(emg); -+ fbcemdRelease(emd); -+ result = 0; -+ zend_bailout(); -+ } -+#endif - if (FB_SQL_G(generateWarnings)) - { - if (emg) -diff -Nura php-5.1.4/ext/gd/libgd/gd.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd.c ---- php-5.1.4/ext/gd/libgd/gd.c 2005-09-30 22:48:05.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd.c 2006-09-05 20:31:02.000000000 +0200 -@@ -2161,7 +2161,7 @@ - for (x = 0; (x < w); x++) { - int c = gdImageGetPixel (src, srcX + x, srcY + y); - if (c != src->transparent) { -- gdImageSetPixel (dst, dstX + x, dstY + y, gdTrueColor(src->red[c], src->green[c], src->blue[c])); -+ gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c])); - } - } - } -diff -Nura php-5.1.4/ext/gd/libgd/gd_gd2.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gd2.c ---- php-5.1.4/ext/gd/libgd/gd_gd2.c 2005-08-18 14:54:43.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gd2.c 2006-09-05 20:31:02.000000000 +0200 -@@ -430,6 +430,10 @@ - - gdImagePtr im; - -+ if (w<1 || h <1) { -+ return 0; -+ } -+ - /* The next few lines are basically copied from gd2CreateFromFile - * we change the file size, so don't want to use the code directly. - * but we do need to know the file size. -diff -Nura php-5.1.4/ext/gd/libgd/gd_gif_in.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_in.c ---- php-5.1.4/ext/gd/libgd/gd_gif_in.c 2005-09-24 16:39:16.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_in.c 2006-09-05 20:31:02.000000000 +0200 -@@ -44,7 +44,7 @@ - #define LOCALCOLORMAP 0x80 - #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) - --#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0) -+#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0) - - #define LM_to_uint(a,b) (((b)<<8)|(a)) - -@@ -147,6 +147,9 @@ - Background = buf[5]; - AspectRatio = buf[6]; - -+ imw = LM_to_uint(buf[0],buf[1]); -+ imh = LM_to_uint(buf[2],buf[3]); -+ - if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ - if (ReadColorMap(fd, BitPixel, ColorMap)) { - return 0; -@@ -182,14 +185,13 @@ - - bitPixel = 1<<((buf[8]&0x07)+1); - -- imw = LM_to_uint(buf[4],buf[5]); -- imh = LM_to_uint(buf[6],buf[7]); -- if (!(im = gdImageCreate(imw, imh))) { -- return 0; -- } -+ if (!(im = gdImageCreate(imw, imh))) { -+ return 0; -+ } -+ - im->interlace = BitSet(buf[8], INTERLACE); - if (! useGlobalColormap) { -- if (ReadColorMap(fd, bitPixel, localColorMap)) { -+ if (ReadColorMap(fd, bitPixel, localColorMap)) { - return 0; - } - ReadImage(im, fd, imw, imh, localColorMap, -@@ -212,6 +214,10 @@ - if (!im) { - return 0; - } -+ if (!im->colorsTotal) { -+ gdImageDestroy(im); -+ return 0; -+ } - /* Check for open colors at the end, so - we can reduce colorsTotal and ultimately - BitsPerPixel */ -@@ -502,6 +508,18 @@ - int v; - int xpos = 0, ypos = 0, pass = 0; - int i; -+ -+ /* -+ ** Initialize the Compression routines -+ */ -+ if (! ReadOK(fd,&c,1)) { -+ return; -+ } -+ -+ if (c > MAX_LWZ_BITS) { -+ return; -+ } -+ - /* Stash the color map into the image */ - for (i=0; (ired[i] = cmap[CM_RED][i]; -@@ -511,12 +529,7 @@ - } - /* Many (perhaps most) of these colors will remain marked open. */ - im->colorsTotal = gdMaxColors; -- /* -- ** Initialize the Compression routines -- */ -- if (! ReadOK(fd,&c,1)) { -- return; -- } -+ - if (LWZReadByte(fd, TRUE, c) < 0) { - return; - } -diff -Nura php-5.1.4/ext/gd/libgd/gd_gif_out.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_out.c ---- php-5.1.4/ext/gd/libgd/gd_gif_out.c 2006-03-13 22:56:38.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_out.c 2006-09-05 20:31:02.000000000 +0200 -@@ -265,9 +265,11 @@ - int InitCodeSize; - int i; - GifCtx ctx; -+ -+ memset(&ctx, 0, sizeof(ctx)); - ctx.Interlace = GInterlace; - ctx.in_count = 1; -- memset(&ctx, 0, sizeof(ctx)); -+ - ColorMapSize = 1 << BitsPerPixel; - - RWidth = ctx.Width = GWidth; -diff -Nura php-5.1.4/ext/gd/tests/bug37346.gif hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.gif ---- php-5.1.4/ext/gd/tests/bug37346.gif 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.gif 2006-09-05 20:31:02.000000000 +0200 -@@ -0,0 +1,4 @@ -+GIF89a -+< -+ -+, Ҷ˵˲ -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-5.1.4/ext/gd/tests/bug37346.phpt hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.phpt ---- php-5.1.4/ext/gd/tests/bug37346.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.phpt 2006-09-05 20:31:02.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+Bug #37346 (gdimagecreatefromgif, bad colormap) -+--SKIPIF-- -+ -+--FILE-- -+ -+--EXPECTF-- -+Warning: imagecreatefromgif(): '%sbug37346.gif' is not a valid GIF file in %sbug37346.php on line %d -diff -Nura php-5.1.4/ext/gd/tests/bug37360.gif hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.gif ---- php-5.1.4/ext/gd/tests/bug37360.gif 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.gif 2006-09-05 20:31:02.000000000 +0200 -@@ -0,0 +1,469 @@ -+GIF89aK+wױ⾱c BsȼԾǼ䒐j2ȴħ¹ȭOIsŦ*ƶï;k-fݺ޲ڛવ󘞳0սӲXixQվtڷ0Æʼõ˽ֵƳĝ˳$Qx,\ƹ4-42󶹾$m✆~%}ѹa9˰ȷϯش2ƹ|Ƹ25Є=1=HCןz]߬Έ54/ᒧ?6ջ! NETSCAPE2.1! , H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ -+JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ nÈN̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ2j("x00(xLc:Ԓ`}>@C& ;e X4,]*:N$)$ H ,2 Kh a1i<Hr14"07wưR# iަZsŀ֢3\do!kJ?H#fqnĬ<4re0m5 -+]:޲'(O"#``ahؑii oSD1G|2^$f` fP )$+P>0"eHHe2瑀&$@ p~B5!U@ -+0A W_3l TQ$ ``.P~`Q Ƞ(!4id){`!3?0 -+!t!6(؀@`&E1S(z0Q)dЉg, A >,lE%D @cV8R& 6q A0XCB,lPB0y|kPRC8`Nx?`H PAaJPY'iԹR#PB:␋fP >c0 -Be ,8W E+d0lE(;$ -+Hl?Xc'BE0HY(X5@3pO H -+H.ـFH]^0DiH 2JUjUA.ѱ1Kg@* -+ڊ? @Tb~xM7 I8A &Qa CA0HG@gZ0@qT L)p&mpZ6ax 2&bY6@8.DUzY(ߨ0aA N PЁa-ʔJ a&@8`p y\LHP -+#t鐀17B@9%yS 4]!&bAx)@DBm*; gۀ5=I*g ! r -+@Xf X# Bq$4 h3`f-ٶ5հ 7h1vP p -+8f n3N@:`.R LC;P5O`N&G:% 3F8֙6Lr'`AbL_dzU$׾6[f{HCwfo mg@G9Q -+k d8$nr8k- kfHx -D@k)" -+3ii Ѐj؉=P P f~2( Y"0-p TВ `qȖډIu- ) !zy@S -+i @oЃް~IJ uT -+V- p@0Zv|pT0p' Tؑ` |eXS{ 4w@i2܀0n\װ k Ay1 QUD T` 1Q T>Xei.iGxtAop Qw S~Ot*z` -+逕EpP`o0s8 -+R`} I߰x`q։ Z gm{wP  UP -+YhPI. {r @ -+)Ug6* YqV4UjfK0R J @P Er0 a#.h؟#AV .py@@ LZp >I}H a -+ @@@NwwJ(G,Pn~Nj0 -+Q m -+LX@D@ 5`}z XM  ˖G 0,4qZ@Qf>h)@L `@g{ -+ W&@ˈ0 7 \xB .@<H mJf0`ooSC Mpf;uʤp,y -+ О|~xhƌp=i -+̌O q@t֢ L:-Pg ZpHQ cA6J 7B B^|m0pJs+iPDpu  J0?dlcq-骵LP -+0u6mP݀Po H 少Q Tpfu`̠P<`rПTͅg4 LypX]n>0 ql)0AgKЅ9vp~No -+Pi=O mM!U`lh}P+/<〒@qk ~zoGP -+ԪꃞpsQEl`Z:ȝ}KfV[{·=0P i`YW h-k)s* .ٓkȸ.@.p b dJ L"]UXr3 zmr7[L@Yk|m^x@ :g0y0*]0>_p-C?F FGv.6L MKLpm~VPX pY\A9CoE?'Pے`x }~{\M` - -+`%` ՛  7btπ\ymUkMJM߲Nhg`-} n-ʝ $< virKxRA &IIQLW_ -+4cBE!EvIR8cٲ%AFΤYM9uOA~LR48C7g6d{B+9"Ba۴0b7BFHQ_y,+]IK_&\pE2FqBen4,-a7 -+hװ:@,DMԄdVc1UfXusa'N,T堲 ,Ki܁`$Mݻ$+Et'좢F8%7")R0){ocp@ 4"#xg98a(Xʅ5l;rX -+X 8[H}HO(b=".ܜ!-¹@$Trɜ $RA*0^Ă"VYG!$q`ʒpMD6(DD -8*NIFut8"n(gـ, yA) -+RDV 1z 1" Gab뭀:Zl`qX&2]Ԩ6঑ $Tp:Zm @br+$wC!qf# y4j`b ?m+G łcggTrƅ tA\` -+˰*x5y]Tc;` 1xa $KBYRA  k5qiLaz* 7h-W@y W3|V)qFG۞q޸`) -+$l;GL r=H fθۆ !#y&6j"%x -+J馱<~xaA:(\FʯNsxWm p"fVC mr廁< #`P(QXJ7.6g48N<-xԧ: PC H5` @`i$ A@}ÜBY l $,4U3A- EMq4`d xǐr=B):NР%Hpk"1&h$<4\P(V PrT h><3 - pk(-ե̚DHx\fc@'$-P<`l~+{P9`zcn" \Naײӻ`nԃmTgИ SZF0ӗ`ǕB:q xaCNo؂ޕK)>7X3;jԦ@l[`H̟!ْ&@6gj#v=]NC+)qtFnrc=}2_ZäjpQ{cSyH"N-*@'HvG QN@%`|ы`/y/) 5,>[,q$b77^ GKpo4F+p<5;k tI\WZ -+?* [ָi/l0()_\:7 -+ł@H?l?zwB?yY؁p:-83NH"? .p@KPK$WaXh70 @;z#`. "[ P&V.gP -7hB 4g؁ -+K.q N@I ):X-yl -+X & =h#39;Ba -+#(GÂ&ɣ(XDF @ {l*x3D(Eqp< Z{iC +h:ul( '`ҝ+˧ ( HR. !ig58qr* (. -+,{g0 -+t-U &h9MRfHsМ $i(PDITNP0`9 >Vr+| HT$F1{X PCl ˄U$E2?B.0|-Խ#8"hJbP(Ι)X3U3(PVn4 4 "rHQɷwTW]h<[- 0`ʩ#x*VMOis(+epЉENTG#w@H ڀ֓eL+L9 *6Y(NҝUО518IL6 o0xըo85_6P0+, @X) F/l#=3`]hR("|mFR9\x91 -+x̛AY \F,(]]PV!6hɦ)S*30؝"B65peL!@٢$o \^g;eyFȝ `_l8P]2]?8T'*`k&MJ^m]]Z ~`w^ l|饊j@Tf<;E ]Xpۨn=d&=>a%^Z(#51w)1h=Rɡ"\“hq-;ĨXJ`ec,"i% d5؞(c\`-/Xk1-M -+XQ I>S5µ^|taeQ/;Va^0P#F; [,(Z6:t;]!T7"i>"vuWBbR"#PJ_]hY$E> Hj8aa8ţpȃA؀jh..Sx㷸 8`eW^s5Tk+8; -+f@1T1kÄ^L+_o-%sc6.:S*P pU"konnղ> hm*0`l*쌃ˍ;/;(#`j/L &!d<#~z=S@䞞C` vqfVx#*en#  -+ă["Wn'P Xݖ7)mf ҽRP+l!Ѐ nB Z6,>!6ws5l 9os:aЖ@= $/th;tD?g۽pG=t50%tntN{uWG} WTf7V?WW8ėZf`\]g`^cd0ČJo]0vj8hlmgxɼpd7X<`s?w6/pwlRzHc,Eplx/x?xOx_xox ! , H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ -+JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ>K̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(=3(x:ࡃ+KL3RP8p(Ň޵ܰ;3&d&RlP򢆏>PI$A7*=sCK,dڈ 0N>PS<<#?<(P& 'fs&N-!s`D\OJ^d -+Ϣ6}#>QGKc,,ejL@*MBA03$#& (vDrJ Ϙ#3 mZd  <r3$L7L !QȢ$SP͔K`)tj@Mm^t!'IBkt B$u-KD -+XL kDq 4 В Y77@:%8@#7nj/pm/B\J -+31` ݼmӏZIDV+ P2BHL1Vq$? -+;ÌU TNr`е@sS@  -+FPy$J&_Bd9F TBް@R.8X# -#riW @ '0XHFFQQˠTԨJĴ8<[D$эRh!f0m@vh &^xFe=!*Hc2P3b#A5 vUWР'ZNrTURrqC9]̕s4Ak jUS`wZ !X0 4[ˈI4zH@> 6EX>"` -+>TM. -+\,OQJX=V 1039N 7Åhi uN`m`BiFwSaP%0m;=X'(߅> 9dzbrƾAFc\pִp7@nР)N' 5%@ {G%Psw&pp0|0qW/7Iw 5yp97%}p?62PF2?@ok0Syn#ZSjBU p62 [ /pv`v  zpEբ>5 q  ,2 ="h# Z *opjk_ΰC?Q~u7PTWX@0-Yg{C=@ `& |"303=^1-u9@u(RTPkmD,QF6C9@\oLy? -+vN0 ? -+Y v { H Y &P Iq*pQ@ݤ(nJ oDcxVnUCDwW -+GB19JP-N+ -+3f`_0* Y(h0w"P% t("P^`jX=jp)D)@߰V9e4'@NJhty4<DP)@Dp T0 #P*h@ 0wl Pe8s(I(qRmd=cyx(ntKp !߰uB8p<%eN4 'H\tT}> \`@ hvl1ղ& @@($00KdL)ZӛްOsmnqsV&Rney.4`W 0 `G)0"`_pk2 hpdp6(p@2vxTpR -+Q@@߀D(B@zj4d'Rk~Eޔh)Z -+d  ,phoARZ -+( 8y7W)@y=&O(}ť/1DP EB0@Ry9ɣR G7.ped @( I* p" ]0 :38xcU,*HpgNHМVV7tgdWV ?.Z[1c*s@NJf.`LyN0v`i -+ceGM L^+{giPuHuHBL@"hf"i!tRKsڴRcRpV'LN?C P9Y;vGvG`g[ScP-Ёs.]*OJTt7Z9^6V`/ ؛Gg5G -+p㨰c@C@x I`{*Pp0{֐P|O( -+ֆup4E 3z{xݠc%3K N8eFx3Czd#R~L -+T^^p8w`k * Pl8,@VnʤB@hɫzxԩ {j#RZN.G &s3o -+kyz }yF;R s*15 P,p7f3gzrVRA` z4tx sjL!|9Qؤ.CsRpz-oyЭx4Јjtΐ -+  .js0j `0?{3P MuC01th8~ 3zlDkn؁9R,e58J.~kx?p)XB'PVpv@@lʯְ@A -+} BR u9PwTd/ QcoIhVÜч ea n[/yَo Gw`j?vJ` ϐUp^@l \ -u2Hƻ,CXp}wkLз2$!Q,nGd@8CXq[TnXDnLp*) vHJcČ4[zxݐn ϰ6һӧ@j_M5;[baiv 0% P` iDZ`Jcu8J*nk=vR.7fsJlSܹsj`Jy04`2 -+FD6npOWFUmp} 'ТQLc `@L3A8cvm/Lolg vqIst@1Tiny ߀4P| -+P]úPt6@@G⺽,pXl~*ZV&'ԋ6gUQV"#@qP -+PϰqUPh3pN} fukpGڥ$(@xn5PוIZg4 I<͍hקNs,u40C $3dmC E`@00f.R&4vu5"U6nȨ_WE5{y8?pˁ1o@p*/~VJ[Z4@CTRy~}=ۦ!p\SvhIZ~hG'm4LP :Gdg.F  ].p #[4~YTлi-RH -+?RUV,kBSvD10Pi=Z@P!VU_;T"nFn&tI'n pv¥(D(@?:4G VLh#@]H-hfh -+hp.j٢A醊@p(G`(C=x -+B(Rg8uW^{o!nh$6p" s &(s y @PPE\ |Bn01!,`x -+ Ҹ8ܜdɨA!N./op *SM7H= gwj-1 -+hb۳Wc yƊ$+@W=kimk I\a꩟, * % (x f*7 -+ |UڨH4րggF$ Z1˝¡eS9l{fC}C`ALF+\-nr1*@d2D[$%!UU 48<+ Tyg`P -+ %ot* z& 8Ƀm`X!*Z0p]e$ -+0 -+B3pnt@qc`a"'D6VA9`BQ8Gʴ;m#0iBH1t@ 4!"&t HA74pm@P@  -+ -+e5o*ߨCܬ⏲s8P\`EQH ndMYBRs`(h9K``A !&oa -+(`Ӗ$# * (0]ꀁA -+0j=hq8\Bd*XB˻G !(#4'H@p&wZgGXfH-ᐈ3iNkC*g B4 Ѓ -+Հ? ` -+ 0eD|f-H8hIO\@݃v)QHܰYnݤiM4B rJ|h@K -+3@ -+D\L -+=.<XgyЂ* 0lƩj rq3%5XM|ÚK h,&P&(뮪DHRba'fD9 poT*3r@֪8 aB}3"u3x#2lqijgHpcTeID& ]b٧j -+(QNYiU^$E#CT!9t", @A ('ݕ)0!d@񆗸V]h_X.@l"g D) -+<ވBX;bJ"yZh7NA*A7*|-HMxUTS39&$g*0JAr{%p"  4W lLPUƣ!ܼ'"n36p g܁=ZN -+j3:D4/k s")?A Tyh$+xWy7R >=u*Tb&9=܄}ŌoH@@"PkULQS ALm^/ @co<8[a>} 03P @n?ۍR}(3"pƣX= G Auz  'Vao:!>$`i). -+Zu>%AS&b@E\1`! {O1 -+Q&%$utכ&`H` -+|Ɛ?C`pQ< -+HYl0mǾϐ3BJqtc 3H:4n~>B*{AwYD -+|D5{ﵗHTC XA+Db O "`ƚSx[!XT=mCH+[ %H?S9 -+Kz/;0 ϪK<ʀPJ"H -+f(CoCx6؀ -+Bx -+* Hqr'. -+cu$I8g8;P;BX> )C p595ZQ.ȁe=87KY*`pb(hrŀCQ8!* X P5{5 ꛙ ,GdXϲx0%)8DTIړ -+ii9DYB -+^7P]LF|3&Pac\  03'a -+(GHg(50R`HG + &3  1Rm1Y#0ȃn#HXP$KFTzW*Hz1Đ<MmIm iSM'9FuCӂsXͳP!h3ΐIQaH[ -+!( ў2D\UDSR*ȃC3ܥZfh(X:1@G`t-'`0PP(.,ޙA53.L:[(M+Ї,m HS( Yl_o2m.^ ,AǪ4pT2gpt \gʐ8i. MH(R"-ġa;=f -+3pN2v".HU8õFC"(%(#bm@fڅNpS74UoեD[hK߆oVc]PpFbdW@('@& Ʋ-[gV+5eaHnqm0>N;IP~7xr!Icpæbx&p;u&+q&-r1Vg4kƠbѦ_胰sm<^_ц]HʡրRE*(p .c027i7xn!NC=pH쉞`b PuVoU&-*Cg辠Su` vƞ_fG*sy_ 8j_˖-hlO?P(nzxiE~Jw9􇆎oW.ZohȝeKŽgXv˅VA JCx($~wWtog[OV&˸c .daBSz abX!2M(d;>&:zV(80l"I=߻Oo8xw~FANP4 :^gȁȊ{c8H?(Ũoo{_o8thȉ.>P>] y/Pq -+N?9O)6CyI9ȷ}|(j1NdG?/m`vG?t~ e&Wh7؀':Lgab}KF8o -+ -+2l!Ĉ'Rhg89Ɛ"G,i$ʔ*Ia,@ 8&Μ⬛:-j(RP9LIRC7g).<+ذHAh*1IJ5zHK7,Lzk.ޅb HI0+<.IJ#,n-8U@G L7Gtä[fG.P( Na6Eܺ)"^~m3g\3o^EgEȱ0#y^=&. yr;H'~b]()~ -+Ч@4ۀSݓm;48ax1@haSA#4!}Sh]GH8cs"fXl2Av_ -+f y7ǒQf_`.h"eJ-AW\Y2 Q IR/50&lPr,VEԠ k,`sGZTy brp)DB*Fei!G`:+G++uxt|*,͊t -+J,JdJ5&( Lڪ" Ey&@{(Ԁq@{0];P0&0Ŵ -+ LX `I!j -+JP"`¨"l)J/\g:uF;2%XڰQygeg"',,5-Rԙ"[w}9SWR/h>*Ep07dmv߅_ %fEnψ!Dzk-M m>zlGrX*MG6:a݉  &%;9|^h2?}[}|kV2qEۋ)? e)RǙ -+0fD*H9{-1NȟG.M -+8p$ψC/x CZ{R*rC<:%2N|"()RV"-r^"(1f<#Ө5n|#(9ұv#=~# )A<$"! , H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ -+JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKguew߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ ~!(_f] >B/` f (FCaUd(]$·A`,Hd7U|!G#8# B ژ0xhA3D,԰e -+N ]B0@Dr5A`1  -+4@3$;DU$D)8HpE8)01HANG@d$=#~҂}@ 9l bAEtM -+ `˄QE#fI_t@] D4&X -+DB8^ ~,aC "xDIHܵ3)tD -+\P-G||p=cD .!$,]H0D80"-:ރE -+X0 WYtLt͕TSJk@ -+bT]XH 1)B;gD8)4$tEAvC`0[8'9=W0 q{耇{ A7|CG0 Bw7BoPyopP2AҒnH0727g # 8Pߗ!~ c:T0îH),3i V .`.,U -+:@@@0@.q %, 'U`OG5cϋX#nET`RƍFLlu`mJXX -+se Z`©(H8xl[؂!F@ԪaĊoW(* ̀( 2TB3xȴalZ@oZfĺmZBWS" H9t ~jj`(@ -+Џ. @/,\庑 -+,@ E@@j Қa%4qQ#  >J  IHRX}.tT8жP4"T_ fܥ{`pV`M_D-k7y ‹dh5*`$n=A@G5 8vA*#B)zrr:#-uQB q ga98IP3DV[)6"Iఈ `#^M`6@Ÿ u-(DAРWX4 -+ZK%'HB2YG4,P2#P -+tOL(BIڄU csmgpu7޻XRJsFrl{ W$^ ܃& H]֔o pWIi~:qXj4sy1͉d>+   R8qpEN!caQ͡FfAQ{aB3BނԈ>W,oν:'敂W -+$|S:sa5A:8O |:&ڗņFqrP ֙ skZ:Kg[b`1a.5xrA"+7F6yDm-ac"O}@ -+\P/Yчy ݀lK paJaH,s"H#,uycͲ)@,V -+0u}$P}3PG3Q"5p c~ ZF:0p DppA +BkzlBTR=Zk@Vt%p/TzXx U\*B:U 0-Y7 ~.GLUX~@_q7pv74 RV1YFT/4kmZ nZ &  R}P6}i1Q6z-XߦʷGt3wSaUAQ,ݰ& Zv35{Cv^_ -+ -+ P$epBe k4 e( nS0m &QH'a`< nqyP_#4wZUU&bsVp 0G|eK?* HPZoYLQtȉF]4p!% T6t\Uo Y4%gqlP# Om$ -+`2pl03ie050 0R0PO=li(Q"qU0sG80Z@vև.ɔ+Dp'jpwa$ w E++_|sR/ -+ # ]0 >eM > `c -+P3P :C&7I5pV PKGF7̠w)v'K;/Soji&1Es@R.L04 ? `@  -+`0# _" l`  S=@#!:DPzr/J4@ ]~E3MzekT4Dp6iCB"-XTa@AŔrexJYH!) ~b9 k EȺExR*5Ы0`p -+ Pś%W`0+ +r%Lw;t)@~@.PS -+Q@ SxcW -+\`{0Dj']1X?X0Gp.Lua4RWdT2 [ '`v P,ؐf c l ߷O$ T85@KPx""vJX? יđb`bBQKxQZUX`A9UT0zR -+p=dT- @ngπ @ _`30T $*h{r Upbߦ8Q@Ɲܾ F V^'+B^3WQ:Ps2Qb] Z -+s =0PfͰ0=@ =E![ 쀆{u d6m1ȳX8ZZ ,˸(Qpgw0{9 _Ϡԅ\1 ;`6g kP"/N%Е0 F{P-=0x{r 5jF;㨃?pyuPy`4G8T@)[.UK* `  #0S``ϰUp?)Le$>,@sv!WL@};{e -+G" dG[ZN n^Z> 0dL󽰕Pl @"t tS  ;`!K._|A\%?.b(D޳b bPAG5vT1 =@+  -+ 8@ -+I Č=L"ŋh%` g)Ud'NPT[ 4̛dR*ox3JpI)=,)jYiծe[q IF:@ɭoTпNR =s7s1>A*4h;6l @p&k$TqbQ S35 QBj֞4K1B!I+m\3ܔ˲haŠtH.S,Saf`KgkF.㺔`Bc -+h-Ha"L{q"atQA0!^ǚ0y@*i~gN( loBg8dHpAÞC8zL5[ @K6Ϥ"3S"žFGD@tg@y80lFo A1g2c@9 -+(lBqV 懈ͣ%(@ - -+jIbt -+HA,)  x  "@H@B rʁ:y87B^|"Q(`\Aq‚zK7$N:j @$qbTX]ck(8"`hnb{r!&i놑08oC?k) @$:HyF(\ l$ -+VJ! -+,(E:_=䃬ib$14M NV0QA )g -+TH:xq&B)Њ+[n(6i@9$%lU`w=hn9!pC E$" a80ȯg(9QA)38\pC8o \@x$37doTYNx@@Ē&؀aW aJ0 8 vCLT H4a8AK90d4lbul< \ -+(I̼7܃ÜLJ@ I -+{A((љp"2U̥ Q +~) 45?Ѐ) C@kق:&M`QDxЂ oK@\1 4"sm ɬ(~A97H̫QN&<-i0!SޠZ [ 1aT9!RPky﵃&8ԻYAFh9#1 (F\ 5&(#`@  Ϲ pF:ukB uyF9]F -+UXnjQ[3'DPi@YF̡0\#I3dprph!XYnχ|<l 9w -+H+ B@ޕ-0DPaYQldnR+vh8$5c88P&haJA6??- ^@C"/P -+[|`sFsÎ^x'!-rh Ǯξr =X 8.{E hLaun@ ρA{(SP|.)޻<0C'l ys&:@o  -+KolfYD ?C*@޺E؀ɪE>J!79ѓ$aFD7 ʡ>@ӣ?]K>^{1P  ]x=;t:Ѐ@6;!AB[*:9kp)<7X5:(`/s,X@@%@4 @N{*XCdR~ -+yĕKh 7rۄ+tn(.5S5s5Cj]|("J OŲѷJ*{  mQƕ3Km `A,S5= -+<< ),+%P@(7F q/(#C%~5291  x%Nl[u$3 XGy)Plh0AU {0!Jy(wਔ:> ( d\Qq؆'5"脏CӂC^|Gh8P10!IP M䕔(K:<7@PSp Y̵E`M(<xl0ɬlSH6>rp[9g}Z N@C885T<l3+Ѐ`hD'@E%_S9-ė@H͕1!.l70ȪL*ġH&LCZP{.pDÄ"ЀbY@<9$oX!뼇L,(PZӂ( @(x0Pz}τ?+p&PE?Є8-R:(ʴ| YֱTD`z@8?*Ӱ_@sD]T`KXNPUI$ʌ8ФpX%(SyDQP@Hń;\C(yO9+::Ђwb:д΋T|y؂nDfSyܼ:IE?N-bUAyXZBҔH?F -+`x 4edo2`[7/]J8,]D'GسPp_ м{Xp(A(h ͍ ZXVC@٥u_XAO'h=Օ 7 ڐQ/8gm^I`7s V] "`&^<T0 M!X^ GNc!Y`f17'5=j_1#+??@yDD D(}`[@%SXI"p܀5h|M@+L,H,|"~a}H55\TX9c8]D=} E-rՍc$ -+x 6XuVIǭ 0gh8Uc>N ZСpw8ݠI[C`4I%h5T3GF] OV8'J$(Y"Rf+؀mE 7Shd-]^N{p -+g.P5I`εWuL%qe4fZ0d`(Uv%@YET@1{^ E~ ddMh~hՁ&RA&X$9Tx 4 K^ jTJJ鞼68]d68t}!Eir @{ hoViH .^0P`3F: =qLkH-j+ЇMe\sp UI,,$^~)Ul Jb@0C'` x|f*#l),6bGDrX} -+Xf` 틨 8R7a5'f .xD`؇NCF-o[n*Vȥj'苘GXaΈ"Cݿ[#m\%x_ ~v2mA11 EX ӽ W256`H8g-UT˲1OhK{Pc po~I f-ސPN]K lqy(f.FT+LoԮqB 5(^r%r -+r,/O4Æ S䮃M>>X570&mR>bTvo8 7gF85o@U+s-".rq+t,IRktp3> S_1.WY(pRp`F"'c/ -+F&'{(c/N;4gtZރ8owQӄyP w_p}+X~fO+RB]PH -+(tuUA8``qÌХxz ,u))@vSq~p;u݋wCPƊt'%UYG| σ(X)(M1Pw8FzR805oR\.(`()0Ѵ0098 7 K(0s؀0 63f_@y;:5W8e&|PX)aI%@05+d 0D➄P[E"8f5!={Gwe WM.Li(BPķ -+2l!Ĉ'Rh"ƅ*0,#Ȑ"G,idF(h"lyր˜ )'> `',l7U4j*֬Z+H3Q̙B, 9"ࠠB -+80ּzKpd0BlKwUXEE -++SWLТ>x4Ԫ)b !'<@,AOT&L`Zm8ʭ~vRPj+[tDK[JCǓ/o4_Fw2L_]0N -+uk9` YC BeuF"7!Z8QD 1eQp)"y|hc\"=(?'h1h("Ww*'֏QJ9U}xSb ـ6HeyE -+}dP[""@E`&h'sQ E !*:!RŢZZ)d@ `ɥzfW* v1&9*bK肘Yy1ڟ?jA 4D,A:le1Z{q}Rd6b;.Uݮ)EpP.j IpIϜВ& 0u~,L0C Ūv(|%"̑-1c< ؠd=@1IN,eIVčJ[)$KAR^=6zء.1$ " -+d=jiB|o97ߡF`-6k7 +%>y@x)0eŞn <3̒e0. ܺ bKK[3D*?@^8ȔD%' @BLp8"߰z`bX~E|D|!*(r!XWK F,C؅ D0+fok,"4Qa@uG(2-'{A0> UH!sE -+`I%$b2ID`Q&2E> m,  Gl0*e&Q3؀2WLY o1IVERQ.A/UmcK,PX"q Y%>'iD` P~2T˅ -+O5R4_ ZDp9hs–J(E%bdL}S@5IfY5wQj7T 2.!ԩvJfCBqq1X3uqҲܐVYЀc\$5:CY+ӯ{FI>o`j9k>]H -+.a|VJLHfR -+`!vz <` md2}.t+Rֽ.vr.x+񒷼=/zӫ}/|+ҷ/~/lހ! ,K H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ -+JѣH* (KJJuf*$!Yկ` -+ٳoq1M۷pa>cϬoh߿!TKZ+^p…C̸e-Ck١ˠCmafhVFكpڬ B>#-hN< -+uk?P?BTkтGk8ʟ_ڨ1G@m=2 (=7v =H3U<83]$hBP$QE~F dwhiE7Th R"70~ Y|MwSJo^l ݀-zrY C QV;wp#_} K50rf`M"lQC_V -+ڀgaD3g<,pF)'@|ֵnP}9΅0A&`$ -+0A2hD0BX؀C` sF H@   h((5H1(X(0"~v9-`~ppAEp&#֠FЂ+D.Aby? -+70#$X M1Q6) uE*IG XɃ Q#6p]Fk SE4myE #@ 0 &~F@7+>D6҂AZ\X1Yc P,yX -+`h8ChX(o &`4VԢĂOc`waƻPt'PI%E87 -+^,T4Y>c@TRSo#&@Qf_pA@~EWY9s٥ -+ݠxȹ  Vb -+npb Q *kZT`ٖBW6hB7`lୁ@`-lzxYSIT04HMI;+` AįT0P Zs f3BX[#+3܃8.{[ " -+uR"m8̲@6&V{`lIhoW{#D JkOd_ f Rڲf%B^P` iXR)hPef݁%) m.вr u@op\o0"c"6!T;QCc[Aí7fBeB@3R`!8ՋAqx*\i2X8@,V 4^vO=a QC(\a!DM]Qq1,h^Qmgr⽺ЀWBA$(@jW$7 8Py{['5Рg89&uyuk4#`z}ЬZp?ΈRPa4XCM(rh\0ޣx@EF x]5^Z  h3ր/v#smbRDA CKܝ8L -+=)&A֝0ba (,2'm--'F3(1 ha0HA7b9K_kD 1D@e! {w'Qu]gJ'} +WB5q * -+U`Ey LpwZw4J(<GmfSʥn``kQS10.@-H#?4qpU@Mpw -+(XP+蹠 K݀#߷yiv )asXV:ٜ5JGq@V >2Pv{1(ĥtQXq Yl˕ B@3OxDK\*֗z baZ9 T ~1Lc Zp>+bq@YfTeFfPp^/{ dʫŠP6WŤ ՘YPi+d$'ڭAzWFC1TO4%Kߠj%)@;y溣pa Rh ~T}0p- 5+?k)x 0# @;p 0 #0 P -+YQّEivL1+@gP\xX@0kj P#0 -+F GRc X Zp6  ]"D$ $  -+28ap]Z('W#w%8aA2.@/0K8Ϋ [=[ 9K@GTTU -+&KrCɄ£oRgdfm }a c{eP  ohQ;p -+X-wtRƮukdPF> c ˛{ @ =`,!F.I0̪" [i2)]CUL$[zsq95@:4X)qXvZS -+ #v,| e${TqJwoP |Q.rR"v -+ :˗ -+І1Qy`F,w@mu.jeH:@ -S=7XfLP?-:wh|rz  ;/ XS>$ м =% @@y] -+(pJGp5q} wƷ1)˟04!BfrP9 ٙ =0L ]@䭀)No}7m -+@MҋF<` xu8fXS &ԃ0Cސj -+P  ߆ -+!d#u&Nj  oB# e  R[ -+``([p;~\D - NNP*=nR0 e[p `|_Xfn;痐  pГ^ p *a*1Q}x`ՇNor?p r| ?0R際 es p@&G8-:uZ|tT!ֱ.A`d88N> }w> hkKI` >`054/tQL,Kq2S# KN3ՠ -+~ ? R ِPkYj@Q} -+DVGSH@/N 0$K2@Ae; #[0.UIeKw{7#,#XKH(oO57qV  -+#@ @ 2p p˶eP c ԋ0XZMX< _XP\. 33   G -+_P n;~ Y0_= AjoqbwG9 Ҡ -+ -+ f  -+IFoʮ1@L.3J0&==G %̤I"qK1eΌ #&TH} OA%ZQI.eڴh -+dค]_ k4,@@iو +"K K -+A@&=D_2mbF*otcȑ%O>4@kT񪀀1dˮfl oy0[`g& hxCѥO^:g\ -+Ǽ:Ҩ +4eǰ8%6W)R="# 3耓Fs & -+(RD Ĩ :CC̟$T1NkJ0Jb8ࢸz0ÜH?+"8)H4`)@C- -+K!o ED24L3 )\ #Cf1OTi(BvQM>0*䐡ᡤԀ! l28,2ISM9% o8Ѣ64SUuUVzs Z!B(Bzh0/!/6 .%8Z[pERh  CT("`FVtQ\jAN(ZkIu -+h#q+`F4&^j@H,6.A4QC ^x I)ῸAEcvz7 -+%q;9!Һje|FLb_ zj!MRc(`ۅR;F8(2(hiw(r9x T4 ;dՈ⎞¿(g R0F,sv 7Xc -(o -+|x ƙF0-DJV YfU2D -+e12 }`Kmrヘo6S,xPd N0#Jp<"8 0@ -+8`% '(phc4P$ #@"W{UPtP=чc ad \@0@ )P7C0qUR8R O^@`(dG: 3 (Y_8 _c#Io\A ,`4Xd z 7sAD8T -+{d/}!' #0X@!;W"X3P(`R)ES+6 dg;2< \r,3"kDF6&R.&( *DT7SP -+*htxt(p& "h ?h .d)\:S:P6Xa \Tk4 (M l 0 jWjN,8j9(Z P;\M@,{P:qt (Y`HYLSS( -+)-Tp&G xE WԢV.D6yJ`@8SAd8*a` 4$9:02ӝ.&v ז b0'n}0GX6"MoS{N;` -+kVfz_y[ϙ ViqAExpg8mǮ\? pll@qf1j! *fl?ӨT]$ -+i[|!N34߸k(6% -+ v"4"Y?e$Zbp]j`LĶ {sRsZoHukhh7R ϛ7*6 zm$ "C(X(F9}~C 7̀@ bx0PD?']#u%hׅuIp70B!ؠ -+Pk] V7 B<[#0^Z'al+ @W0I '9-Q -+l -+d+hA 8P킫% 5q -+'p#q+JƇQ('BWDϭ>CTz"^6`&7ڠ% 3 WQ >Hfg@آ -+#\ }~G 2`u<ƾ TL4b؂Fx?!@ +Xo\0ahhN9` 4):!; g~Ӻ=eu FtLTG~'xЂ -+V6@Kw_2&5ȸ8脏x;?\S?R`mԸ@h@4*Є.X:4}>C(AOs,a@f 4x|H01x@BЃ$*X `_8@8={g>Ȁ1B8*8>Zp.8DpAj_xl:L@CH„*7.1`ALK'1XH\ƀ>x$`[5xL0"}.*x9Xg7dEe\ -+L8 ' ?87 *@F02'6?IXFt<.0pBQs2d=G(4HG -+S!(++XH`:Sx(ȟ -+KH&ڀAҀP|ɏsn[bD< J2pw0A${o1$+Є3AL:.ʗl=rAp KL$smsADLT(?Sˌ4tX`[l?DpA>1g`L&ۮ6d;#Sh1L+J D-()td;7K;"H\FO4E%"(m _'ǎ1rD(e -+hLnSNL&Db'pKgA\EXl2;ɤ$dώ0H5Bٹ{O#tD}OC<#6`D,8D5 |%6N 8;+0> gjȔ݌Py1K_ CX7L%*y C@IDLAΑ ELY L=PPS<8{]!`nX[35­>5^i:PCgX(/35 CBϑTAhF%40QH8Ҏ3s( XPMȘ[SܐtRNa%A=hv*J|THE(8 -+P/@(d5dV`Tf .x<`5DW/AE -+nUSFHJ"A->UKEDQ8`+й(+Μ33؅hN#hC)9YYm>L({=X( 2L?d WUMZCG3` 0Y1( X1`%[ˑSvs h#@><R=S [( ~dc ^=J1hՐW7^ypys)݅ 7\:0 ڼ'eӰ `QqZH~)@;/S -+^Nݮ=<4ah{87S8؅*K0  -+X8Q ~&Q$s\R7(4Ңx5yۅ, -+T -+%Vch -+80bx4W=:Mx߼ 𧕁KEo䩂 ~YI"ͣ0oY. g__T@U,La8e8~hEPL*Zdd=z -+ff f+XffN1o*G^4E(=bP۠k^a(*gZ{1h^=K3v,EZi`1(8w`4H]hh^2 3c'ϵjw2H[8k]w -+`s_vwGwo+ds zm G~o*.P8b,J5 -+w^"{N9wg\oy:Fywe~wyvJfywZ<z_ZtMR6_DH4Be_gvDF/8F. KH{{{{{{{{||/|?|O|_|o||ȏ|ɟ|ʯ|˿||ͯ! ,K H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ -+JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿S}L #^̸ǐ#KL˘3k̹ϠCMӨS^ͺuC®cT,۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟O}PAeB @? ЂF$3a ?AA2""aϸ!."<⌂=s-#I#=CJ?U!}jHbePq]z 7͘AL D p -܂w Ig_ l7XHR 'Z ræ7)o' Itm(w.Kj @FP'55d4'h7=s%jd ̤=T-D(N-$) RD9:0< x"'_4S[@ĤR&a -+1 SԜBԢ}9[p hyp^¥~ruHZ7>t0,})]X$%L'K!l|$xWc4\ -+$&. ?C @x$"EIf5*Ra92Ry3q PqKc Ѽ=;ZmcȰW--/$Tk *iH Lj`X[3w XC!EDTFb<)x0f({  t!@j_.5FL p@b7@,.lp!xx~i8^ r#aǬf!- -+D{;עo[;H3@ -+@!8l21RXH5PDP̰1JC["reG9HCt(}cl!"yPgTaQ͟M{ = -+ yx8 Pm|@D'"L/PB !e[Qln E0~( `5 -+3vBda3RJ@ ⫹9Dy´3 Skt6N)?W2A`l# Y0i(@ -+;= GL9 3rۗq "#bmS"UPoVPf@q 0FvPht ilP;-4KPїu #01YZŌ -+("81PtfptpE@ -+ U`X8P3 -+YV^<+D®l p*`v ]A@82}+"ppW8mb{U qn a wˍd* B@IV!P$+l +m` '>KxceE`G9K]04ūNj +l g gk0鎕$#6\ЁB0wߋ j㋵P}P6IPZtDk}e)¦;js!P \$ `m+(((pr -+uJ0@ :&4L` k=8{mplO<P @@xӲH+!w& Z3 ;jj } 0 l*r+ mJkl% B ߐ1Lj?< -+r!0 -[8#ZI*+z4@,|倱019,0A'%0 c T#`"/' /D N`́IHHmtڂ0q9L@(HjB%T]ìjF E2}%$X8qńN@€0@L!K TO -` -+* CP 4p!}B Lz&O6 &A2$$%M$Ld@< 59(] =-(B]`JpϠ v F p9x<`HJә#P&'+ 9IPsIq@1ԁ -+c=VS`đ(p -+-k`&fN&K)] VF"6(Lʲ L.oLW f&-59;ۗ~ q -+P@4 -+rK -+s#@LcAx% B(l;S2p`p9|0na ݂l -+%g@ζ`+";P dpe0 ahQpئ ٌ(%xW % k"3x $Cd*yΈQ(P;~0àʢ&P<'֪&⪔zR$S$ n @n`O=ӻ -+`Ȍ-Po.xWkw0 4]Is7 ǁT|@p͡<ʦ`Xlh | -I[`&"gaqF 1 a -+PխrUR22}L@K$Qa`PV}OPG`0c(F PoKﭽ`N"1 K`@DP.LML`d -+NC @DN_4x/P[X%!Ȳb ϼp -+q m@@ ~P !Hl qgЂnO -+k\ ]a82\ .An;`#6R/̸| $XA .dC%NTTZKʕ悃!E)wA@9L< 1yրCVA^ -+K %ZQx/QAcLCOnzP!U0!$H 8³qΥ[.. -+@YH$΁P <a`gLTZj[\>whO7s;dݷ8C0R{Cy_ "E臠.#G:ge㢖\{%CLhLbޑvgJ 0Qv.$;Pv1:2n8(t{CXwƧ~ &z#I"# ',k1 v -+57 ּ]w*nuZ9 -+*uCڜƨלmʹ@b%`C#by`` $g %'tw _%*Hq_I`%:pj`mA σfxHBe ` -+ x@:X` шnt t-`PRL8X@<<@Z`Nۂ!AŰC N+l Jx/\7uJ҂HaEQ P!K@&x@& G@B$ a 468VU/B<o  7y@Ocl ~NEV(+u 10o0#ҢC,z=#U0}r8 tF&l Q@h^ЂZ4Tt.C;&{`a\Gf.Z@6B_d-L&'8 X=y0K2΀AQ(`؍PYg&Nj*4L fE# "IZ A -+A b -+'` 1o$ -+=Sn4b77$]Y,T#@tC"}" ЩLJ Xa K&@pԁD) +jBA̠ -+CT }elB@r>{B,C1D4?q0&"AF#&P D *aB-B/]3asH!C^V`*g|Q cE7h H -+ZC(P]7~9 "Ap9e2V Z9[498Q'I.1@Pq*,pjܓMlq:"ԀE0% `}Yqq$/iXE +f &$v=G"AgIK AJ pB(v &ev3jݶ;PzaCB Ox`Z ϲGօ4 F*pY:$0ဃB%JPeg["q8P:ux1Oh':k.[Pкn'|WB @  g9%Ѻ͢e -+@*\#7Q[S``e?b vq`0}XWZ6ha&I3;Ep[:E  EP8 PYp 1{B&(H6̺P Р~^#V'z޵wg޳]N/9Ƀ@*p]ts\5! a|m0 ";514@n {Pݴm X;G>6' H\?w?S6鼴^>(d c *v -+'a}K?h?i!8;CzUS?t;;t @]34H߻?  |Ae ?TAC80 0X,LBI K;NK8 -+TB03q<!BA_ C9I1!c0PK9 A;HCCıg>l3(/࿃@Z􎖲9PEg&A@Q"@+V<'|FoojlDSlFxPāt46ԭwG~3~DLM|K -+4NLŚddlN4*fH[Dw„ O) -+x켇c ODaL*dI`Ot[D.ONt{C4fP΋tP1 8do`?D@m>H \,Qd0HQHeQ=QDSH)D1N0t]!EM=HJI^\Ĺ<F)LR,EЅ#1P/L<+3=L'-u|, (xS24Q?uJ<3`,=Ԭ|2_8;](TGE݅F+Aԏ`N`^`n`~`` ` -+` ` ` ```aa.a>aFۀ!,K H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ -+JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pf|Lݻ5˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(O=#+7 x E`H8 RHQeѡ8t8^w^^;PԨ) Tp |X+`658E ,Bkk}ݕgv{Yz džy0Ȋ@9c 숕y[ ׄvW'd u @T<[n@gq0ndz%}fHfj LИF x 'Y@u"pSHPu%ZE gpHvGffmVp`*xy Y459 @CpetpShEp&y<VP -+k)Pyٝ'dXXמW ,ڢG b"ti0TUEoz+0 t {;A}X$ -+GR}Ét! `p.J pU" gD -+pn0aA؅d`}Zb)(!}whjmЭ!%@Scp -+gjH@H -+< lvipްUP@oע+G؎O ! mߤAjА[s@LP Pp)~ 0  ]Z@؊BhiJ J0 hpUuY^Ho w+Q@n t&ӈ 0N۠nPܺu(pZHW*F[V798p5h#p pU- -+.YiU ` x!mgPXh^Kzݐ^ffj op -+N@DKz`_M( @zZtSpa{P -+0Y0X@F^Hг. -+ګi X) +@5 K Se L̠*T`)Jf^0L0 APu\ PT - -+xJJPu5'ƅ 0k@T GՐ\P -+7!1Ģj 0$SP p Lp@a.)9 9QpV M+(pYhpym ppm}p(K S,5@]Z\xy T0YAe5, \JPZUSjKʿj* ʃ*\Uy\r^v4) a -+Bs +ŰV j -+a a [,uiiQPZp8v |O  nК ѯ~Y HIV@DMOд(`U` `Qgp,!;Ωt J -+ -+P-@Э- 5pP(=<` |HPPr&() n` dA |0i`KXɥEh<L y PZP?' (OQXuOjAXIP:iʎܝoŀޏE߄{dPipL4U@跦 ʀJ 4HpO sKgђ`ݭM~P -+L;,:mΥ0ׅj ݐJ,M@ -+mLmw,O@ u -+pQhy7)M' -+C@n)B^=y0 Eu&b cJIjP&nͫ* -+p -+j; P 'KiyQP혋J^쒰S, FـrpQgDP -+IF@Ig Z0O+Ucn؅#P -+MZ d.Zp~2OzpSPaj>I -+Ncʼnώ-- -+`]`>]9=0M0ͱ rc! -+L x +PGQ!nV` #}KVpمyu`, ۭNǢG %U, -+"!ع/~ ̿Z(2K?+ L`ߠKK|H*W6~=yk]ƒ$O!ϰI)UMg1eΜCHqZF") u{,.eSQNZU(݀"s5HO0^|IB6sTV=fB$1 A9Ѣ)@[e̙5ooEYH:t,UKS*B*3*MdTǎ@y6[oO^u 0rڻW*e;$0 B&*:wf@ PQFy ; 4@ɁI4+""0ɒB"@kB 4tEcj" -+uT0#FLD*! CD&g IF,RFJ"-QdzXmB01fS`&vhq&, -+ ha- 5Pa"Je$6~9s'\;BK3!aPjF\s 7!Q\sՕ)]UЂth<Բ>+f`>Z -+I" XI6rgĀvu]] E~-Hi;Q'1*]Ι ^hڙ&pܡLw ܹ^Cv@J{gѢBيAM"TDDBa@p$˜=]`Xdm"W((@ҳ9S',\M7@P hZ >N2>tQo3~ar4G1Y@R%S8\0galoZ $c]ƅ5hcs׽_a7() -+%~[ @cm +D2Pw@Rp\*Ђ3f,Hb !C%&g*ϣΊ)Ny 6T@7z -+ؕ(i^s& -+=}bH}`ʳij /M97v"L GI=I.: -+/Av 0v5St)Zgpc}/#FpB swś -+$ }hcQͨT7<PO0A50Xlq ~nJ?7*EWpZBa9J2H@sԉ~ߴ BE6r8܊r Hasނk /to[<3>$tk ;,W{ş7 ihΠ@rd?eAJF0;|#5 :+ yJ'8BJA|.Y@G%./Mg-+~X`@L6kKSh @ -+XF:@bJh:#s4Nx)* 7b$B&IMk  -+ (1b;Hb1:ɌBw HP7ĉ 8-C$# $/Qb?+:pF/ڍC$L8:(+ʨ,$n(Eo-̌(`ţHCˢp!lMHߢMDECAJLj&$L:F,|\N/A{5 5PĂ(pjF_ ONKZiMOC FD' ˟b "@8P 0KlPНĂ `M -+1Ȁ:ODK;R1ؿvnU|]M؅ oXIMuSHy&} O\l\1;(.j<9e $4.%O*5ŕNk@EP6LSC+ö;4F;B5<;DTL0d!|8ȁ̯+a&b+hb-I_1_0A)&c -+4v-Iܥ""J8c=>; @n4HFaD.]1E怨I>.d @1Ѕ=%&eW~eXeYeZe[e\e]e^e_e`fafb.fc>fdNfe^ffnfg~fhfifjfkflfmfnfofpgqgr.gs>gtNgu^gvngw~gt; -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-5.1.4/ext/gd/tests/bug37360.phpt hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.phpt ---- php-5.1.4/ext/gd/tests/bug37360.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.phpt 2006-09-05 20:31:02.000000000 +0200 -@@ -0,0 +1,14 @@ -+--TEST-- -+Bug #37360 (gdimagecreatefromgif, bad image sizes) -+--SKIPIF-- -+ -+--FILE-- -+ -+--EXPECTF-- -+resource(%d) of type (gd) -diff -Nura php-5.1.4/ext/imap/php_imap.c hardening-patch-5.1.4-0.4.15/ext/imap/php_imap.c ---- php-5.1.4/ext/imap/php_imap.c 2006-01-28 09:07:20.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/imap/php_imap.c 2006-09-05 20:31:02.000000000 +0200 -@@ -26,7 +26,7 @@ - | PHP 4.0 updates: Zeev Suraski | - +----------------------------------------------------------------------+ - */ --/* $Id: php_imap.c,v 1.208.2.7 2006/01/28 08:07:20 mike Exp $ */ -+/* $Id: php_imap.c,v 1.208.2.8 2006/08/04 20:31:41 iliaa Exp $ */ - - #define IMAP41 - -@@ -761,6 +761,13 @@ - efree(IMAPG(imap_password)); - } - -+ /* local filename, need to perform open_basedir and safe_mode checks */ -+ if (Z_STRVAL_PP(mailbox)[0] != '{' && -+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || -+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { -+ RETURN_FALSE; -+ } -+ - IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); - IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); - -diff -Nura php-5.1.4/ext/mysql/php_mysql.c hardening-patch-5.1.4-0.4.15/ext/mysql/php_mysql.c ---- php-5.1.4/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:31:02.000000000 +0200 -@@ -1231,6 +1231,8 @@ - { - php_mysql_conn *mysql; - MYSQL_RES *mysql_result; -+ char *copy_query; -+ int i; - - ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); - -@@ -1281,6 +1283,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #else -@@ -1291,6 +1300,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #endif -diff -Nura php-5.1.4/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.4-0.4.15/ext/mysqli/mysqli_nonapi.c ---- php-5.1.4/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/mysqli/mysqli_nonapi.c 2006-09-05 20:31:02.000000000 +0200 -@@ -184,6 +184,17 @@ - if (mysql_real_query(mysql->mysql, query, query_len)) { - char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; - unsigned int s_errno; -+#if HARDENING_PATCH -+ char *query_copy = estrdup(query); -+ int i; -+ -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } -+#endif - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - - /* we have to save error information, cause -@@ -234,6 +245,17 @@ - MYSQLI_DISABLE_MQ; - - if (mysql_real_query(mysql->mysql, query, query_len)) { -+#if HARDENING_PATCH -+ char *query_copy = estrdup(query); -+ int i; -+ -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } -+#endif - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_FALSE; - } -diff -Nura php-5.1.4/ext/pgsql/pgsql.c hardening-patch-5.1.4-0.4.15/ext/pgsql/pgsql.c ---- php-5.1.4/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:31:04.000000000 +0200 -@@ -1152,10 +1152,28 @@ - case PGRES_EMPTY_QUERY: - case PGRES_BAD_RESPONSE: - case PGRES_NONFATAL_ERROR: -- case PGRES_FATAL_ERROR: -- PHP_PQ_ERROR("Query failed: %s", pgsql); -- PQclear(pgsql_result); -- RETURN_FALSE; -+ case PGRES_FATAL_ERROR: -+ { -+#if HARDENING_PATCH -+ int i; -+ char *query_copy; -+#endif -+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); -+ PQclear(pgsql_result); -+#if HARDENING_PATCH -+ query_copy = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ efree(msgbuf); -+ zend_bailout(); -+ } -+#endif -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); -+ efree(msgbuf); -+ RETURN_FALSE; -+ } - break; - case PGRES_COMMAND_OK: /* successful command that did not return rows */ - default: -diff -Nura php-5.1.4/ext/session/mod_files.c hardening-patch-5.1.4-0.4.15/ext/session/mod_files.c ---- php-5.1.4/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_files.c 2006-09-05 20:31:04.000000000 +0200 -@@ -152,6 +152,7 @@ - - if (!ps_files_valid_key(key)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); -+ PS(invalid_session_id) = 1; - return; - } - if (!ps_files_path_create(buf, sizeof(buf), data, key)) -@@ -401,7 +402,12 @@ - ps_files_close(data); - - if (VCWD_UNLINK(buf) == -1) { -- return FAILURE; -+ /* This is a little safety check for instances when we are dealing with a regenerated session -+ * that was not yet written to disk -+ */ -+ if (!VCWD_ACCESS(buf, F_OK)) { -+ return FAILURE; -+ } - } - } - -@@ -422,6 +428,35 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(files) -+{ -+ char buf[MAXPATHLEN]; -+ int fd; -+ PS_FILES_DATA; -+ -+ if (!ps_files_valid_key(key)) { -+ return FAILURE; -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { -+ return FAILURE; -+ } -+ -+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, -+ data->filemode); -+ -+ if (fd != -1) { -+ close(fd); -+ return SUCCESS; -+ } -+ -+ return FAILURE; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-5.1.4/ext/session/mod_mm.c hardening-patch-5.1.4-0.4.15/ext/session/mod_mm.c ---- php-5.1.4/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_mm.c 2006-09-05 20:31:04.000000000 +0200 -@@ -425,6 +425,42 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(mm) -+{ -+ PS_MM_DATA; -+ ps_sd *sd; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ } -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ mm_lock(data->mm, MM_LOCK_RD); -+ -+ sd = ps_sd_lookup(data, key, 0); -+ if (sd) { -+ mm_unlock(data->mm); -+ return SUCCESS; -+ } -+ -+ mm_unlock(data->mm); -+ -+ return FAILURE; -+} -+ - #endif - - /* -diff -Nura php-5.1.4/ext/session/mod_user.c hardening-patch-5.1.4-0.4.15/ext/session/mod_user.c ---- php-5.1.4/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_user.c 2006-09-05 20:31:04.000000000 +0200 -@@ -23,7 +23,7 @@ - #include "mod_user.h" - - ps_module ps_mod_user = { -- PS_MOD(user) -+ PS_MOD_SID(user) - }; - - #define SESS_ZVAL_LONG(val, a) \ -@@ -174,6 +174,83 @@ - FINISH; - } - -+PS_CREATE_SID_FUNC(user) -+{ -+ int i; -+ char *val = NULL; -+ zval *retval; -+ ps_user *mdata = PS_GET_MOD_DATA(); -+ -+ if (!mdata) -+ return estrndup("", 0); -+ -+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { -+ return php_session_create_id(mod_data, newlen TSRMLS_CC); -+ } -+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); -+ -+ if (retval) { -+ if (Z_TYPE_P(retval) == IS_STRING) { -+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); -+ } else { -+ val = estrndup("", 0); -+ } -+ zval_ptr_dtor(&retval); -+ } else { -+ val = estrndup("", 0); -+ } -+ -+ return val; -+} -+ -+static int ps_user_valid_key(const char *key TSRMLS_DC) -+{ -+ size_t len; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ ret = FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ ret = FAILURE; -+ -+ return ret; -+} -+ -+PS_VALIDATE_SID_FUNC(user) -+{ -+ zval *args[1]; -+ STDVARS; -+ -+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { -+ return ps_user_valid_key(key TSRMLS_CC); -+ } -+ SESS_ZVAL_STRING(key, args[0]); -+ -+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); -+ -+ if (retval) { -+ convert_to_long(retval); -+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; -+ zval_ptr_dtor(&retval); -+ } -+ -+ return ret; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-5.1.4/ext/session/mod_user.h hardening-patch-5.1.4-0.4.15/ext/session/mod_user.h ---- php-5.1.4/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_user.h 2006-09-05 20:31:04.000000000 +0200 -@@ -22,7 +22,7 @@ - #define MOD_USER_H - - typedef union { -- zval *names[6]; -+ zval *names[8]; - struct { - zval *ps_open; - zval *ps_close; -@@ -30,6 +30,8 @@ - zval *ps_write; - zval *ps_destroy; - zval *ps_gc; -+ zval *ps_create; -+ zval *ps_validate; - } name; - } ps_user; - -diff -Nura php-5.1.4/ext/session/php_session.h hardening-patch-5.1.4-0.4.15/ext/session/php_session.h ---- php-5.1.4/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/session/php_session.h 2006-09-05 20:31:04.000000000 +0200 -@@ -23,7 +23,7 @@ - - #include "ext/standard/php_var.h" - --#define PHP_SESSION_API 20020330 -+#define PHP_SESSION_API 20051121 - - #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC - #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC -@@ -32,6 +32,7 @@ - #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC - #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC - #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC -+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC - - /* default create id function */ - PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); -@@ -45,6 +46,7 @@ - int (*s_destroy)(PS_DESTROY_ARGS); - int (*s_gc)(PS_GC_ARGS); - char *(*s_create_sid)(PS_CREATE_SID_ARGS); -+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); - } ps_module; - - #define PS_GET_MOD_DATA() *mod_data -@@ -57,6 +59,7 @@ - #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) - #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) - #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) -+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) - - #define PS_FUNCS(x) \ - PS_OPEN_FUNC(x); \ -@@ -65,11 +68,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID_FUNC(x) - - #define PS_MOD(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, php_session_create_id -+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x - - /* SID enabled module handler definitions */ - #define PS_FUNCS_SID(x) \ -@@ -79,11 +83,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID(x) - - #define PS_MOD_SID(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, ps_create_sid_##x -+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x - - typedef enum { - php_session_disabled, -@@ -120,11 +125,13 @@ - zend_bool use_only_cookies; - zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ - zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ -+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ - - long hash_func; - long hash_bits_per_character; - int send_cookie; - int define_sid; -+ zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ - } php_ps_globals; - - typedef php_ps_globals zend_ps_globals; -diff -Nura php-5.1.4/ext/session/session.c hardening-patch-5.1.4-0.4.15/ext/session/session.c ---- php-5.1.4/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/session/session.c 2006-09-05 20:31:04.000000000 +0200 -@@ -166,6 +166,7 @@ - STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) -+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals) -@@ -280,9 +281,13 @@ - PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) - { - zval **sym_track = NULL; -- -- zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, -- (void *) &sym_track); -+ -+ IF_SESSION_VARS() { -+ zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, -+ (void *) &sym_track); -+ } else { -+ return; -+ } - - /* - * Set up a proper reference between $_SESSION["x"] and $x. -@@ -758,9 +763,23 @@ - return; - } - -+ /* If there is an ID, use session module to verify it */ -+ if (PS(id)) { -+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ efree(PS(id)); -+ PS(id) = NULL; -+ PS(send_cookie) = 1; -+ } -+ } -+ - /* If there is no ID, use session module to create one */ -- if (!PS(id)) -+ if (!PS(id)) { -+new_session: - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); -+ if (PS(use_cookies)) { -+ PS(send_cookie) = 1; -+ } -+ } - - /* Read data */ - /* Question: if you create a SID here, should you also try to read data? -@@ -769,9 +788,14 @@ - * session information - */ - php_session_track_init(TSRMLS_C); -+ PS(invalid_session_id) = 0; - if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) { - php_session_decode(val, vallen TSRMLS_CC); - efree(val); -+ } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */ -+ PS(invalid_session_id) = 0; -+ efree(PS(id)); -+ goto new_session; - } - } - -@@ -1377,22 +1401,29 @@ - } - /* }}} */ - --/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) -+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) - Sets user-level functions */ - PHP_FUNCTION(session_set_save_handler) - { -- zval **args[6]; -- int i; -+ zval **args[8]; -+ int i, numargs; - ps_user *mdata; - char *name; - -- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) -+ numargs = ZEND_NUM_ARGS(); -+ args[6] = NULL; -+ args[7] = NULL; -+ -+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) - WRONG_PARAM_COUNT; - - if (PS(session_status) != php_session_none) - RETURN_FALSE; - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ continue; -+ } - if (!zend_is_callable(*args[i], 0, &name)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); - efree(name); -@@ -1405,7 +1436,11 @@ - - mdata = emalloc(sizeof(*mdata)); - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ mdata->names[i] = NULL; -+ continue; -+ } - ZVAL_ADDREF(*args[i]); - mdata->names[i] = *args[i]; - } -@@ -1475,6 +1510,11 @@ - WRONG_PARAM_COUNT; - } - -+ if (SG(headers_sent)) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); -+ RETURN_FALSE; -+ } -+ - if (PS(session_status) == php_session_active) { - if (PS(id)) { - if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -@@ -1531,8 +1571,8 @@ - WRONG_PARAM_COUNT; - - if (ac == 1) { -- convert_to_long_ex(p_cache_expire); -- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); -+ convert_to_string_ex(p_cache_expire); -+ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - } - - RETVAL_LONG(old); -diff -Nura php-5.1.4/ext/session/tests/014.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/014.phpt ---- php-5.1.4/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:31:04.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.bug_compat_42=1 -diff -Nura php-5.1.4/ext/session/tests/015.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/015.phpt ---- php-5.1.4/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:31:04.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - arg_separator.output=& - session.name=PHPSESSID -diff -Nura php-5.1.4/ext/session/tests/018.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/018.phpt ---- php-5.1.4/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:31:04.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - session.name=PHPSESSID -diff -Nura php-5.1.4/ext/session/tests/019.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/019.phpt ---- php-5.1.4/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/019.phpt 2006-09-05 20:31:04.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.serialize_handler=php -diff -Nura php-5.1.4/ext/session/tests/020.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/020.phpt ---- php-5.1.4/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:31:04.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - arg_separator.output=& -diff -Nura php-5.1.4/ext/session/tests/021.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/021.phpt ---- php-5.1.4/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:31:04.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" -diff -Nura php-5.1.4/ext/session/tests/bug38377.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/bug38377.phpt ---- php-5.1.4/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:31:04.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+bug #38377 (session_destroy() gives warning after session_regenerate_id()) -+--SKIPIF-- -+ -+--FILE-- -+ -+--EXPECT-- -+Done -diff -Nura php-5.1.4/ext/sockets/sockets.c hardening-patch-5.1.4-0.4.15/ext/sockets/sockets.c ---- php-5.1.4/ext/sockets/sockets.c 2006-04-07 16:04:36.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/sockets/sockets.c 2006-09-05 20:31:04.000000000 +0200 -@@ -533,6 +533,7 @@ - { - zval **element; - php_socket *php_sock; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -547,9 +548,10 @@ - if (php_sock->bsd_socket > *max_fd) { - *max_fd = php_sock->bsd_socket; - } -+ num++; - } - -- return 1; -+ return num ? 1 : 0; - } - - static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) -@@ -558,6 +560,7 @@ - zval **dest_element; - php_socket *php_sock; - HashTable *new_hash; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -575,6 +578,7 @@ - zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); - if (dest_element) zval_add_ref(dest_element); - } -+ num++; - } - - /* Destroy old array, add new one */ -@@ -584,7 +588,7 @@ - zend_hash_internal_pointer_reset(new_hash); - Z_ARRVAL_P(sock_array) = new_hash; - -- return 1; -+ return num ? 1 : 0; - } - - /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds, int tv_sec[, int tv_usec]) -diff -Nura php-5.1.4/ext/sqlite/sess_sqlite.c hardening-patch-5.1.4-0.4.15/ext/sqlite/sess_sqlite.c ---- php-5.1.4/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/sqlite/sess_sqlite.c 2006-09-05 20:31:04.000000000 +0200 -@@ -185,6 +185,76 @@ - return SQLITE_RETVAL(rv); - } - -+PS_VALIDATE_SID_FUNC(sqlite) -+{ -+ PS_SQLITE_DATA; -+ char *query; -+ const char *tail; -+ sqlite_vm *vm; -+ int colcount, result; -+ const char **rowdata, **colnames; -+ char *error; -+ size_t len; -+ const char *p; -+ char c; -+ int ret = FAILURE; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ return FAILURE; -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key); -+ if (query == NULL) { -+ /* no memory */ -+ return FAILURE; -+ } -+ -+ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error); -+ sqlite_freemem(error); -+ sqlite_freemem(query); -+ return FAILURE; -+ } -+ -+ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) { -+ case SQLITE_ROW: -+ if (rowdata[0] != NULL) { -+ ret = SUCCESS; -+ } -+ break; -+ default: -+ sqlite_freemem(error); -+ error = NULL; -+ } -+ -+ if (SQLITE_OK != sqlite_finalize(vm, &error)) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error); -+ sqlite_freemem(error); -+ error = NULL; -+ } -+ -+ sqlite_freemem(query); -+ -+ return ret; -+} -+ - #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */ - - /* -diff -Nura php-5.1.4/ext/sqlite/sqlite.c hardening-patch-5.1.4-0.4.15/ext/sqlite/sqlite.c ---- php-5.1.4/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/sqlite/sqlite.c 2006-09-05 20:31:04.000000000 +0200 -@@ -1530,6 +1530,19 @@ - db->last_err_code = ret; - - if (ret != SQLITE_OK) { -+#if HARDENING_PATCH -+ char *query_copy; -+ int i; -+ -+ query_copy = estrdup(sql); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ sqlite_freemem(errtext); -+ zend_bailout(); -+ } -+#endif - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext); - if (errmsg) { - ZVAL_STRING(errmsg, errtext, 1); -diff -Nura php-5.1.4/ext/standard/array.c hardening-patch-5.1.4-0.4.15/ext/standard/array.c ---- php-5.1.4/ext/standard/array.c 2006-04-12 21:30:52.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/array.c 2006-09-05 20:31:04.000000000 +0200 -@@ -92,6 +92,8 @@ - - #define DOUBLE_DRIFT_FIX 0.000000000000001 - -+ZEND_DECLARE_MODULE_GLOBALS(array) -+ - /* {{{ php_array_init_globals - */ - static void php_array_init_globals(zend_array_globals *array_globals) -@@ -1295,6 +1297,32 @@ - } - } - } -+ -+ if (var_name[0] == 'H') { -+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_FILES")==0)|| -+ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { -+ return 0; -+ } -+ } else if (var_name[0] == '_') { -+ if ((strcmp(var_name, "_COOKIE")==0)|| -+ (strcmp(var_name, "_ENV")==0)|| -+ (strcmp(var_name, "_FILES")==0)|| -+ (strcmp(var_name, "_GET")==0)|| -+ (strcmp(var_name, "_POST")==0)|| -+ (strcmp(var_name, "_REQUEST")==0)|| -+ (strcmp(var_name, "_SESSION")==0)|| -+ (strcmp(var_name, "_SERVER")==0)) { -+ return 0; -+ } -+ } else if (strcmp(var_name, "GLOBALS")==0) { -+ return 0; -+ } - - return 1; - } -diff -Nura php-5.1.4/ext/standard/basic_functions.c hardening-patch-5.1.4-0.4.15/ext/standard/basic_functions.c ---- php-5.1.4/ext/standard/basic_functions.c 2006-04-03 15:46:11.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:34:44.000000000 +0200 -@@ -151,12 +151,14 @@ - typedef struct _php_shutdown_function_entry { - zval **arguments; - int arg_count; -+ zend_bool created_by_eval; - } php_shutdown_function_entry; - - typedef struct _user_tick_function_entry { - zval **arguments; - int arg_count; - int calling; -+ zend_bool created_by_eval; - } user_tick_function_entry; - - /* some prototypes for local functions */ -@@ -188,6 +190,8 @@ - PHP_FE(get_html_translation_table, NULL) - PHP_FE(sha1, NULL) - PHP_FE(sha1_file, NULL) -+ PHP_FE(sha256, NULL) -+ PHP_FE(sha256_file, NULL) - PHP_NAMED_FE(md5,php_if_md5, NULL) - PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) - PHP_NAMED_FE(crc32,php_if_crc32, NULL) -@@ -632,7 +636,7 @@ - PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) - - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) -- PHP_FE(realpath, NULL) -+ PHP_STATIC_FE("realpath", zif_real_path, NULL) - #endif - - #ifdef HAVE_FNMATCH -@@ -2034,7 +2038,7 @@ - break; - - case 3: /*save to a file */ -- stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); -+ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); - if (!stream) - return FAILURE; - php_stream_write(stream, message, strlen(message)); -@@ -2279,6 +2283,13 @@ - { - zval retval; - char *function_name = NULL; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (shutdown_function_entry->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { - php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); -@@ -2294,6 +2305,9 @@ - if (function_name) { - efree(function_name); - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - return 0; - } - -@@ -2301,6 +2315,13 @@ - { - zval retval; - zval *function = tick_fe->arguments[0]; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (tick_fe->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - /* Prevent reentrant calls to the same user ticks function */ - if (! tick_fe->calling) { -@@ -2332,6 +2353,9 @@ - - tick_fe->calling = 0; - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - } - - static void run_user_tick_functions(int tick_count) -@@ -2395,6 +2419,13 @@ - } - - shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ shutdown_function_entry.created_by_eval = 1; -+ } else { -+ shutdown_function_entry.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { - efree(shutdown_function_entry.arguments); -@@ -2722,6 +2753,15 @@ - - convert_to_string_ex(varname); - -+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ -+ if (PG(safe_mode)) { -+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || -+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || -+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { -+ RETURN_FALSE; -+ } -+ } -+ - zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); - } - /* }}} */ -@@ -2979,6 +3019,13 @@ - } - - tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ tick_fe.created_by_eval = 1; -+ } else { -+ tick_fe.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { - efree(tick_fe.arguments); -@@ -3282,6 +3329,35 @@ - new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); - } - -+ if (new_key[0] == 'H') { -+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_FILES")==0)|| -+ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (new_key[0] == '_') { -+ if ((strcmp(new_key, "_COOKIE")==0)|| -+ (strcmp(new_key, "_ENV")==0)|| -+ (strcmp(new_key, "_FILES")==0)|| -+ (strcmp(new_key, "_GET")==0)|| -+ (strcmp(new_key, "_POST")==0)|| -+ (strcmp(new_key, "_REQUEST")==0)|| -+ (strcmp(new_key, "_SESSION")==0)|| -+ (strcmp(new_key, "_SERVER")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (strcmp(new_key, "GLOBALS")==0) { -+ efree(new_key); -+ return 0; -+ } -+ - zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); - -diff -Nura php-5.1.4/ext/standard/config.m4 hardening-patch-5.1.4-0.4.15/ext/standard/config.m4 ---- php-5.1.4/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/config.m4 2006-09-05 20:31:04.000000000 +0200 -@@ -203,7 +203,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) - ]) -@@ -489,7 +489,7 @@ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ - var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ -- filters.c proc_open.c streamsfuncs.c http.c) -+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ) - - PHP_ADD_MAKEFILE_FRAGMENT - -diff -Nura php-5.1.4/ext/standard/config.w32 hardening-patch-5.1.4-0.4.15/ext/standard/config.w32 ---- php-5.1.4/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/config.w32 2006-09-05 20:31:04.000000000 +0200 -@@ -16,5 +16,5 @@ - url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ - php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ - user_filters.c uuencode.c filters.c proc_open.c \ -- streamsfuncs.c http.c", false /* never shared */); -+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */); - -diff -Nura php-5.1.4/ext/standard/crypt_blowfish.c hardening-patch-5.1.4-0.4.15/ext/standard/crypt_blowfish.c ---- php-5.1.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:31:04.000000000 +0200 -@@ -0,0 +1,748 @@ -+/* -+ * This code comes from John the Ripper password cracker, with reentrant -+ * and crypt(3) interfaces added, but optimizations specific to password -+ * cracking removed. -+ * -+ * Written by Solar Designer in 1998-2002 and -+ * placed in the public domain. -+ * -+ * There's absolutely no warranty. -+ * -+ * It is my intent that you should be able to use this on your system, -+ * as a part of a software package, or anywhere else to improve security, -+ * ensure compatibility, or for any other purpose. I would appreciate -+ * it if you give credit where it is due and keep your modifications in -+ * the public domain as well, but I don't require that in order to let -+ * you place this code and any modifications you make under a license -+ * of your choice. -+ * -+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) -+ * by Niels Provos , and uses some of his -+ * ideas. The password hashing algorithm was designed by David Mazieres -+ * . -+ * -+ * There's a paper on the algorithm that explains its design decisions: -+ * -+ * http://www.usenix.org/events/usenix99/provos.html -+ * -+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's -+ * Blowfish library (I can't be sure if I would think of something if I -+ * hadn't seen his code). -+ */ -+ -+#include -+ -+#include -+#ifndef __set_errno -+#define __set_errno(val) errno = (val) -+#endif -+ -+#undef __CONST -+#ifdef __GNUC__ -+#define __CONST __const -+#else -+#define __CONST -+#endif -+ -+#ifdef __i386__ -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#elif defined(__alpha__) || defined(__hppa__) -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#else -+#define BF_ASM 0 -+#define BF_SCALE 0 -+#endif -+ -+typedef unsigned int BF_word; -+ -+/* Number of Blowfish rounds, this is also hardcoded into a few places */ -+#define BF_N 16 -+ -+typedef BF_word BF_key[BF_N + 2]; -+ -+typedef struct { -+ BF_word S[4][0x100]; -+ BF_key P; -+} BF_ctx; -+ -+/* -+ * Magic IV for 64 Blowfish encryptions that we do at the end. -+ * The string is "OrpheanBeholderScryDoubt" on big-endian. -+ */ -+static BF_word BF_magic_w[6] = { -+ 0x4F727068, 0x65616E42, 0x65686F6C, -+ 0x64657253, 0x63727944, 0x6F756274 -+}; -+ -+/* -+ * P-box and S-box tables initialized with digits of Pi. -+ */ -+static BF_ctx BF_init_state = { -+ { -+ { -+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, -+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, -+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, -+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, -+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, -+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, -+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, -+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, -+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, -+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, -+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, -+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, -+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, -+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, -+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, -+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, -+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, -+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, -+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, -+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, -+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, -+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, -+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, -+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, -+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, -+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, -+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, -+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, -+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, -+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, -+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, -+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, -+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, -+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, -+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, -+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, -+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, -+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, -+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, -+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, -+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, -+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, -+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, -+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, -+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, -+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, -+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, -+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, -+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, -+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, -+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, -+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, -+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, -+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, -+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, -+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, -+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, -+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, -+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, -+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, -+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, -+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, -+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, -+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a -+ }, { -+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, -+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, -+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, -+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, -+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, -+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, -+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, -+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, -+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, -+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, -+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, -+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, -+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, -+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, -+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, -+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, -+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, -+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, -+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, -+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, -+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, -+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, -+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, -+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, -+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, -+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, -+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, -+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, -+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, -+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, -+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, -+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, -+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, -+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, -+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, -+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, -+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, -+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, -+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, -+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, -+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, -+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, -+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, -+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, -+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, -+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, -+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, -+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, -+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, -+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, -+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, -+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, -+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, -+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, -+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, -+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, -+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, -+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, -+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, -+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, -+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, -+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, -+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, -+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 -+ }, { -+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, -+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, -+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, -+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, -+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, -+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, -+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, -+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, -+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, -+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, -+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, -+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, -+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, -+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, -+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, -+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, -+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, -+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, -+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, -+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, -+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, -+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, -+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, -+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, -+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, -+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, -+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, -+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, -+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, -+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, -+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, -+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, -+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, -+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, -+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, -+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, -+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, -+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, -+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, -+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, -+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, -+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, -+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, -+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, -+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, -+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, -+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, -+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, -+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, -+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, -+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, -+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, -+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, -+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, -+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, -+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, -+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, -+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, -+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, -+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, -+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, -+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, -+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, -+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 -+ }, { -+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, -+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, -+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, -+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, -+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, -+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, -+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, -+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, -+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, -+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, -+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, -+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, -+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, -+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, -+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, -+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, -+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, -+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, -+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, -+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, -+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, -+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, -+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, -+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, -+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, -+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, -+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, -+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, -+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, -+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, -+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, -+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, -+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, -+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, -+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, -+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, -+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, -+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, -+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, -+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, -+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, -+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, -+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, -+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, -+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, -+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, -+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, -+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, -+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, -+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, -+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, -+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, -+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, -+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, -+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, -+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, -+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, -+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, -+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, -+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, -+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, -+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, -+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, -+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 -+ } -+ }, { -+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, -+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, -+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, -+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, -+ 0x9216d5d9, 0x8979fb1b -+ } -+}; -+ -+static unsigned char BF_itoa64[64 + 1] = -+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -+ -+static unsigned char BF_atoi64[0x60] = { -+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, -+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, -+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, -+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, -+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -+}; -+ -+/* -+ * This may be optimized out if built with function inlining and no BF_ASM. -+ */ -+static void clean(void *data, int size) -+{ -+#if BF_ASM -+ extern void _BF_clean(void *data); -+#endif -+ memset(data, 0, size); -+#if BF_ASM -+ _BF_clean(data); -+#endif -+} -+ -+#define BF_safe_atoi64(dst, src) \ -+{ \ -+ tmp = (unsigned char)(src); \ -+ if (tmp == '$') break; \ -+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ -+ tmp = BF_atoi64[tmp]; \ -+ if (tmp > 63) return -1; \ -+ (dst) = tmp; \ -+} -+ -+static int BF_decode(BF_word *dst, __CONST char *src, int size) -+{ -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned char *end = dptr + size; -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned int tmp, c1, c2, c3, c4; -+ -+ do { -+ BF_safe_atoi64(c1, *sptr++); -+ BF_safe_atoi64(c2, *sptr++); -+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c3, *sptr++); -+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c4, *sptr++); -+ *dptr++ = ((c3 & 0x03) << 6) | c4; -+ } while (dptr < end); -+ -+ while (dptr < end) -+ *dptr++ = 0; -+ -+ return 0; -+} -+ -+static void BF_encode(char *dst, __CONST BF_word *src, int size) -+{ -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned char *end = sptr + size; -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned int c1, c2; -+ -+ do { -+ c1 = *sptr++; -+ *dptr++ = BF_itoa64[c1 >> 2]; -+ c1 = (c1 & 0x03) << 4; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 4; -+ *dptr++ = BF_itoa64[c1]; -+ c1 = (c2 & 0x0f) << 2; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 6; -+ *dptr++ = BF_itoa64[c1]; -+ *dptr++ = BF_itoa64[c2 & 0x3f]; -+ } while (sptr < end); -+} -+ -+static void BF_swap(BF_word *x, int count) -+{ -+ static int endianness_check = 1; -+ char *is_little_endian = (char *)&endianness_check; -+ BF_word tmp; -+ -+ if (*is_little_endian) -+ do { -+ tmp = *x; -+ tmp = (tmp << 16) | (tmp >> 16); -+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); -+ } while (--count); -+} -+ -+#if BF_SCALE -+/* Architectures which can shift addresses left by 2 bits with no extra cost */ -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp2 = L >> 8; \ -+ tmp2 &= 0xFF; \ -+ tmp3 = L >> 16; \ -+ tmp3 &= 0xFF; \ -+ tmp4 = L >> 24; \ -+ tmp1 = data.ctx.S[3][tmp1]; \ -+ tmp2 = data.ctx.S[2][tmp2]; \ -+ tmp3 = data.ctx.S[1][tmp3]; \ -+ tmp3 += data.ctx.S[0][tmp4]; \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#else -+/* Architectures with no complicated addressing modes supported */ -+#define BF_INDEX(S, i) \ -+ (*((BF_word *)(((unsigned char *)S) + (i)))) -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp1 <<= 2; \ -+ tmp2 = L >> 6; \ -+ tmp2 &= 0x3FC; \ -+ tmp3 = L >> 14; \ -+ tmp3 &= 0x3FC; \ -+ tmp4 = L >> 22; \ -+ tmp4 &= 0x3FC; \ -+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ -+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ -+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ -+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#endif -+ -+/* -+ * Encrypt one block, BF_N is hardcoded here. -+ */ -+#define BF_ENCRYPT \ -+ L ^= data.ctx.P[0]; \ -+ BF_ROUND(L, R, 0); \ -+ BF_ROUND(R, L, 1); \ -+ BF_ROUND(L, R, 2); \ -+ BF_ROUND(R, L, 3); \ -+ BF_ROUND(L, R, 4); \ -+ BF_ROUND(R, L, 5); \ -+ BF_ROUND(L, R, 6); \ -+ BF_ROUND(R, L, 7); \ -+ BF_ROUND(L, R, 8); \ -+ BF_ROUND(R, L, 9); \ -+ BF_ROUND(L, R, 10); \ -+ BF_ROUND(R, L, 11); \ -+ BF_ROUND(L, R, 12); \ -+ BF_ROUND(R, L, 13); \ -+ BF_ROUND(L, R, 14); \ -+ BF_ROUND(R, L, 15); \ -+ tmp4 = R; \ -+ R = L; \ -+ L = tmp4 ^ data.ctx.P[BF_N + 1]; -+ -+#if BF_ASM -+#define BF_body() \ -+ _BF_body_r(&data.ctx); -+#else -+#define BF_body() \ -+ L = R = 0; \ -+ ptr = data.ctx.P; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.P[BF_N + 2]); \ -+\ -+ ptr = data.ctx.S[0]; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.S[3][0xFF]); -+#endif -+ -+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) -+{ -+ __CONST char *ptr = key; -+ int i, j; -+ BF_word tmp; -+ -+ for (i = 0; i < BF_N + 2; i++) { -+ tmp = 0; -+ for (j = 0; j < 4; j++) { -+ tmp <<= 8; -+ tmp |= *ptr; -+ -+ if (!*ptr) ptr = key; else ptr++; -+ } -+ -+ expanded[i] = tmp; -+ initial[i] = BF_init_state.P[i] ^ tmp; -+ } -+} -+ -+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, -+ char *output, int size) -+{ -+#if BF_ASM -+ extern void _BF_body_r(BF_ctx *ctx); -+#endif -+ struct { -+ BF_ctx ctx; -+ BF_key expanded_key; -+ union { -+ BF_word salt[4]; -+ BF_word output[6]; -+ } binary; -+ } data; -+ BF_word L, R; -+ BF_word tmp1, tmp2, tmp3, tmp4; -+ BF_word *ptr; -+ BF_word count; -+ int i; -+ -+ if (size < 7 + 22 + 31 + 1) { -+ __set_errno(ERANGE); -+ return NULL; -+ } -+ -+ if (setting[0] != '$' || -+ setting[1] != '2' || -+ setting[2] != 'a' || -+ setting[3] != '$' || -+ setting[4] < '0' || setting[4] > '3' || -+ setting[5] < '0' || setting[5] > '9' || -+ setting[6] != '$') { -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); -+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { -+ clean(data.binary.salt, sizeof(data.binary.salt)); -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ BF_swap(data.binary.salt, 4); -+ -+ BF_set_key(key, data.expanded_key, data.ctx.P); -+ -+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); -+ -+ L = R = 0; -+ for (i = 0; i < BF_N + 2; i += 2) { -+ L ^= data.binary.salt[i & 2]; -+ R ^= data.binary.salt[(i & 2) + 1]; -+ BF_ENCRYPT; -+ data.ctx.P[i] = L; -+ data.ctx.P[i + 1] = R; -+ } -+ -+ ptr = data.ctx.S[0]; -+ do { -+ ptr += 4; -+ L ^= data.binary.salt[(BF_N + 2) & 3]; -+ R ^= data.binary.salt[(BF_N + 3) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 4) = L; -+ *(ptr - 3) = R; -+ -+ L ^= data.binary.salt[(BF_N + 4) & 3]; -+ R ^= data.binary.salt[(BF_N + 5) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 2) = L; -+ *(ptr - 1) = R; -+ } while (ptr < &data.ctx.S[3][0xFF]); -+ -+ do { -+ data.ctx.P[0] ^= data.expanded_key[0]; -+ data.ctx.P[1] ^= data.expanded_key[1]; -+ data.ctx.P[2] ^= data.expanded_key[2]; -+ data.ctx.P[3] ^= data.expanded_key[3]; -+ data.ctx.P[4] ^= data.expanded_key[4]; -+ data.ctx.P[5] ^= data.expanded_key[5]; -+ data.ctx.P[6] ^= data.expanded_key[6]; -+ data.ctx.P[7] ^= data.expanded_key[7]; -+ data.ctx.P[8] ^= data.expanded_key[8]; -+ data.ctx.P[9] ^= data.expanded_key[9]; -+ data.ctx.P[10] ^= data.expanded_key[10]; -+ data.ctx.P[11] ^= data.expanded_key[11]; -+ data.ctx.P[12] ^= data.expanded_key[12]; -+ data.ctx.P[13] ^= data.expanded_key[13]; -+ data.ctx.P[14] ^= data.expanded_key[14]; -+ data.ctx.P[15] ^= data.expanded_key[15]; -+ data.ctx.P[16] ^= data.expanded_key[16]; -+ data.ctx.P[17] ^= data.expanded_key[17]; -+ -+ BF_body(); -+ -+ tmp1 = data.binary.salt[0]; -+ tmp2 = data.binary.salt[1]; -+ tmp3 = data.binary.salt[2]; -+ tmp4 = data.binary.salt[3]; -+ data.ctx.P[0] ^= tmp1; -+ data.ctx.P[1] ^= tmp2; -+ data.ctx.P[2] ^= tmp3; -+ data.ctx.P[3] ^= tmp4; -+ data.ctx.P[4] ^= tmp1; -+ data.ctx.P[5] ^= tmp2; -+ data.ctx.P[6] ^= tmp3; -+ data.ctx.P[7] ^= tmp4; -+ data.ctx.P[8] ^= tmp1; -+ data.ctx.P[9] ^= tmp2; -+ data.ctx.P[10] ^= tmp3; -+ data.ctx.P[11] ^= tmp4; -+ data.ctx.P[12] ^= tmp1; -+ data.ctx.P[13] ^= tmp2; -+ data.ctx.P[14] ^= tmp3; -+ data.ctx.P[15] ^= tmp4; -+ data.ctx.P[16] ^= tmp1; -+ data.ctx.P[17] ^= tmp2; -+ -+ BF_body(); -+ } while (--count); -+ -+ for (i = 0; i < 6; i += 2) { -+ L = BF_magic_w[i]; -+ R = BF_magic_w[i + 1]; -+ -+ count = 64; -+ do { -+ BF_ENCRYPT; -+ } while (--count); -+ -+ data.binary.output[i] = L; -+ data.binary.output[i + 1] = R; -+ } -+ -+ memcpy(output, setting, 7 + 22 - 1); -+ output[7 + 22 - 1] = BF_itoa64[(int) -+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; -+ -+/* This has to be bug-compatible with the original implementation, so -+ * only encode 23 of the 24 bytes. :-) */ -+ BF_swap(data.binary.output, 6); -+ BF_encode(&output[7 + 22], data.binary.output, 23); -+ output[7 + 22 + 31] = '\0'; -+ -+/* Overwrite the most obvious sensitive data we have on the stack. Note -+ * that this does not guarantee there's no sensitive data left on the -+ * stack and/or in registers; I'm not aware of portable code that does. */ -+ clean(&data, sizeof(data)); -+ -+ return output; -+} -+ -+char *_crypt_gensalt_blowfish_rn(unsigned long count, -+ __CONST char *input, int size, char *output, int output_size) -+{ -+ if (size < 16 || output_size < 7 + 22 + 1 || -+ (count && (count < 4 || count > 31))) { -+ if (output_size > 0) output[0] = '\0'; -+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); -+ return NULL; -+ } -+ -+ if (!count) count = 5; -+ -+ output[0] = '$'; -+ output[1] = '2'; -+ output[2] = 'a'; -+ output[3] = '$'; -+ output[4] = '0' + count / 10; -+ output[5] = '0' + count % 10; -+ output[6] = '$'; -+ -+ BF_encode(&output[7], (BF_word *)input, 16); -+ output[7 + 22] = '\0'; -+ -+ return output; -+} -diff -Nura php-5.1.4/ext/standard/crypt.c hardening-patch-5.1.4-0.4.15/ext/standard/crypt.c ---- php-5.1.4/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/crypt.c 2006-09-05 20:31:04.000000000 +0200 -@@ -100,6 +100,8 @@ - return SUCCESS; - } - -+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); -+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); - - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -@@ -135,7 +137,14 @@ - - /* The automatic salt generation only covers standard DES and md5-crypt */ - if(!*salt) { --#if PHP_MD5_CRYPT -+#if PHP_BLOWFISH_CRYPT -+ char randat[16]; -+ int i; -+ -+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; -+ -+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); -+#elif PHP_MD5_CRYPT - strcpy(salt, "$1$"); - php_to64(&salt[3], PHP_CRYPT_RAND, 4); - php_to64(&salt[7], PHP_CRYPT_RAND, 4); -@@ -145,8 +154,24 @@ - salt[2] = '\0'; - #endif - } -- -- RETVAL_STRING(crypt(str, salt), 1); -+ -+ if (salt[0] == '$' && -+ salt[1] == '2' && -+ salt[2] == 'a' && -+ salt[3] == '$' && -+ salt[4] >= '0' && salt[4] <= '3' && -+ salt[5] >= '0' && salt[5] <= '9' && -+ salt[6] == '$') { -+ -+ char output[PHP_MAX_SALT_LEN+1]; -+ -+ output[0] = 0; -+ _crypt_blowfish_rn(str, salt, output, sizeof(output)); -+ RETVAL_STRING(output, 1); -+ -+ } else { -+ RETVAL_STRING(crypt(str, salt), 1); -+ } - } - /* }}} */ - #endif -diff -Nura php-5.1.4/ext/standard/dl.c hardening-patch-5.1.4-0.4.15/ext/standard/dl.c ---- php-5.1.4/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/dl.c 2006-09-05 20:31:04.000000000 +0200 -@@ -164,8 +164,35 @@ - RETURN_FALSE; - } - module_entry = get_module(); -+ -+ /* check if Hardening-Patch is installed */ -+ if (module_entry->zend_api < 1000000000) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ -+ /* check if correct Hardening-Patch is installed */ -+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ - if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) -- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { -+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { - /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ - struct pre_4_1_0_module_entry { - char *name; -@@ -199,7 +226,7 @@ - zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; - } else { - name = module_entry->name; -- zend_api = module_entry->zend_api; -+ zend_api = module_entry->real_zend_api; - zend_debug = module_entry->zend_debug; - zts = module_entry->zts; - } -diff -Nura php-5.1.4/ext/standard/file.c hardening-patch-5.1.4-0.4.15/ext/standard/file.c ---- php-5.1.4/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/file.c 2006-09-05 20:31:04.000000000 +0200 -@@ -2302,7 +2302,7 @@ - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) - /* {{{ proto string realpath(string path) - Return the resolved path */ --PHP_FUNCTION(realpath) -+PHP_FUNCTION(real_path) - { - zval **path; - char resolved_path_buff[MAXPATHLEN]; -diff -Nura php-5.1.4/ext/standard/file.h hardening-patch-5.1.4-0.4.15/ext/standard/file.h ---- php-5.1.4/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/file.h 2006-09-05 20:31:04.000000000 +0200 -@@ -61,7 +61,7 @@ - PHP_FUNCTION(fd_set); - PHP_FUNCTION(fd_isset); - #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) --PHP_FUNCTION(realpath); -+PHP_FUNCTION(real_path); - PHP_FUNCTION(fnmatch); - #endif - PHP_NAMED_FUNCTION(php_if_ftruncate); -diff -Nura php-5.1.4/ext/standard/filestat.c hardening-patch-5.1.4-0.4.15/ext/standard/filestat.c ---- php-5.1.4/ext/standard/filestat.c 2006-04-25 10:41:02.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/filestat.c 2006-09-05 20:31:04.000000000 +0200 -@@ -16,7 +16,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: filestat.c,v 1.136.2.8 2006/04/25 08:41:02 tony2001 Exp $ */ -+/* $Id: filestat.c,v 1.136.2.9 2006/08/10 21:30:23 iliaa Exp $ */ - - #include "php.h" - #include "safe_mode.h" -@@ -634,7 +634,7 @@ - } - - if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) { -- if (php_check_open_basedir(local TSRMLS_CC)) { -+ if (php_check_open_basedir(local TSRMLS_CC) || (PG(safe_mode) && !php_checkuid_ex(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS, CHECKUID_NO_ERRORS))) { - RETURN_FALSE; - } - } -diff -Nura php-5.1.4/ext/standard/head.c hardening-patch-5.1.4-0.4.15/ext/standard/head.c ---- php-5.1.4/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/head.c 2006-09-05 20:31:04.000000000 +0200 -@@ -45,7 +45,7 @@ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, - &ctr.line_len, &rep, &ctr.response_code) == FAILURE) - return; -- -+ - sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); - } - /* }}} */ -diff -Nura php-5.1.4/ext/standard/info.c hardening-patch-5.1.4-0.4.15/ext/standard/info.c ---- php-5.1.4/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/info.c 2006-09-05 20:31:04.000000000 +0200 -@@ -154,7 +154,7 @@ - if (Z_TYPE_PP(tmp) == IS_ARRAY) { - if (!sapi_module.phpinfo_as_text) { - PUTS("
");
--					zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
-+					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
- 					PUTS("
"); - } else { - zend_print_zval_r(*tmp, 0 TSRMLS_CC); -@@ -411,7 +411,7 @@ - - if (flag & PHP_INFO_GENERAL) { - char *zend_version = get_zend_version(); -- char temp_api[10]; -+ char temp_api[11]; - char *logo_guid; - - php_uname = php_get_uname('a'); -@@ -434,11 +434,22 @@ - PUTS("\" alt=\"PHP Logo\" />"); - } - -+#if HARDENING_PATCH -+ if (!sapi_module.phpinfo_as_text) { -+ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); -+ } else { -+ char temp_ver[40]; -+ -+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); -+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); -+ } -+#else - if (!sapi_module.phpinfo_as_text) { - php_printf("

PHP Version %s

\n", PHP_VERSION); - } else { - php_info_print_table_row(2, "PHP Version", PHP_VERSION); -- } -+ } -+#endif - php_info_print_box_end(); - php_info_print_table_start(); - php_info_print_table_row(2, "System", php_uname ); -diff -Nura php-5.1.4/ext/standard/mail.c hardening-patch-5.1.4-0.4.15/ext/standard/mail.c ---- php-5.1.4/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/mail.c 2006-09-05 20:31:04.000000000 +0200 -@@ -78,6 +78,25 @@ - } - /* }}} */ - -+/* {{{ hphp_strcasestr */ -+char *hphp_strcasestr(char *haystack, char *needle) -+{ -+ unsigned char *t, *h, *n; -+ -+ h = (unsigned char *) haystack; -+conts: -+ while (*h) { -+ n = (unsigned char *) needle; -+ for (t=h++; *n && *h; t++, n++) { -+ if (toupper(*t) != toupper(*n)) goto conts; -+ } -+ return ((char*)h-1); -+ } -+ -+ return (NULL); -+} -+/* }}} */ -+ - /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) - Send an email message */ - PHP_FUNCTION(mail) -@@ -104,6 +123,44 @@ - return; - } - -+ if (HG(hphp_mailprotect) > 0) { -+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { -+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ /* check for spam attempts with buggy webforms */ -+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (HG(hphp_mailprotect) > 1) { -+ /* search for to, cc or bcc headers */ -+ if (headers_len > 0 && headers != NULL) { -+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { -+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { -+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { -+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ } -+ } -+ } -+ - if (to_len > 0) { - to_r = estrndup(to, to_len); - for (; to_len; to_len--) { -diff -Nura php-5.1.4/ext/standard/php_array.h hardening-patch-5.1.4-0.4.15/ext/standard/php_array.h ---- php-5.1.4/ext/standard/php_array.h 2006-02-07 18:54:24.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/php_array.h 2006-09-05 20:31:04.000000000 +0200 -@@ -19,7 +19,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: php_array.h,v 1.50.2.2 2006/02/07 17:54:24 andrei Exp $ */ -+/* $Id: php_array.h,v 1.50.2.3 2006/06/03 18:59:55 andrei Exp $ */ - - #ifndef PHP_ARRAY_H - #define PHP_ARRAY_H -@@ -108,8 +108,6 @@ - int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC); - ZEND_END_MODULE_GLOBALS(array) - --ZEND_DECLARE_MODULE_GLOBALS(array) -- - #ifdef ZTS - #define ARRAYG(v) TSRMG(array_globals_id, zend_array_globals *, v) - #else -diff -Nura php-5.1.4/ext/standard/php_standard.h hardening-patch-5.1.4-0.4.15/ext/standard/php_standard.h ---- php-5.1.4/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/php_standard.h 2006-09-05 20:31:04.000000000 +0200 -@@ -28,6 +28,7 @@ - #include "php_mail.h" - #include "md5.h" - #include "sha1.h" -+#include "sha256.h" - #include "html.h" - #include "exec.h" - #include "file.h" -diff -Nura php-5.1.4/ext/standard/scanf.c hardening-patch-5.1.4-0.4.15/ext/standard/scanf.c ---- php-5.1.4/ext/standard/scanf.c 2006-01-01 13:50:15.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/scanf.c 2006-09-05 20:31:04.000000000 +0200 -@@ -16,7 +16,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: scanf.c,v 1.31.2.2 2006/01/01 12:50:15 sniper Exp $ */ -+/* $Id: scanf.c,v 1.31.2.3 2006/08/04 20:34:31 tony2001 Exp $ */ - - /* - scanf.c -- -@@ -732,7 +732,7 @@ - if (*end == '$') { - format = end+1; - ch = format++; -- objIndex = varStart + value; -+ objIndex = varStart + value - 1; - } - } - -@@ -762,7 +762,9 @@ - switch (*ch) { - case 'n': - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - zend_uint refcount; - - current = args[objIndex++]; -@@ -888,7 +890,9 @@ - } - } - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - zend_uint refcount; - - current = args[objIndex++]; -@@ -932,7 +936,9 @@ - goto done; - } - if (!(flags & SCAN_SUPPRESS)) { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - zval_dtor( *current ); - ZVAL_STRINGL( *current, string, end-string, 1); -@@ -1089,7 +1095,9 @@ - value = (int) (*fn)(buf, NULL, base); - if ((flags & SCAN_UNSIGNED) && (value < 0)) { - sprintf(buf, "%u", value); /* INTL: ISO digit */ -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - /* change passed value type to string */ - current = args[objIndex++]; - convert_to_string( *current ); -@@ -1098,7 +1106,9 @@ - add_index_string(*return_value, objIndex++, buf, 1); - } - } else { -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - convert_to_long( *current ); - Z_LVAL(**current) = value; -@@ -1206,7 +1216,9 @@ - double dvalue; - *end = '\0'; - dvalue = zend_strtod(buf, NULL); -- if (numVars) { -+ if (numVars && objIndex >= argCount) { -+ break; -+ } else if (numVars) { - current = args[objIndex++]; - convert_to_double( *current ); - Z_DVAL_PP( current ) = dvalue; -diff -Nura php-5.1.4/ext/standard/sha256.c hardening-patch-5.1.4-0.4.15/ext/standard/sha256.c ---- php-5.1.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/sha256.c 2006-09-05 20:31:04.000000000 +0200 -@@ -0,0 +1,388 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ -+ -+#include "php.h" -+ -+/* This code is heavily based on the PHP md5/sha1 implementations */ -+ -+#include "sha256.h" -+ -+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ sprintf(sha256str, "%02x", digest[i]); -+ sha256str += 2; -+ } -+ -+ *sha256str = '\0'; -+} -+ -+/* {{{ proto string sha256(string str [, bool raw_output]) -+ Calculate the sha256 hash of a string */ -+PHP_FUNCTION(sha256) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ PHP_SHA256_CTX context; -+ unsigned char digest[32]; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ sha256str[0] = '\0'; -+ PHP_SHA256Init(&context); -+ PHP_SHA256Update(&context, arg, arg_len); -+ PHP_SHA256Final(digest, &context); -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+ -+} -+ -+/* }}} */ -+ -+/* {{{ proto string sha256_file(string filename [, bool raw_output]) -+ Calculate the sha256 hash of given filename */ -+PHP_FUNCTION(sha256_file) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ unsigned char buf[1024]; -+ unsigned char digest[32]; -+ PHP_SHA256_CTX context; -+ int n; -+ php_stream *stream; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); -+ if (!stream) { -+ RETURN_FALSE; -+ } -+ -+ PHP_SHA256Init(&context); -+ -+ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { -+ PHP_SHA256Update(&context, buf, n); -+ } -+ -+ PHP_SHA256Final(digest, &context); -+ -+ php_stream_close(stream); -+ -+ if (n<0) { -+ RETURN_FALSE; -+ } -+ -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+} -+/* }}} */ -+ -+ -+static void SHA256Transform(php_uint32[8], const unsigned char[64]); -+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); -+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); -+ -+static unsigned char PADDING[64] = -+{ -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* F, G, H and I are basic SHA256 functions. -+ */ -+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) -+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) -+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) -+#define I(x, y, z) (((x) & (y)) | ((~x) & z)) -+ -+/* ROTATE_RIGHT rotates x right n bits. -+ */ -+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) -+ -+/* W[i] -+ */ -+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ -+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ -+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) -+ -+/* ROUND function of sha256 -+ */ -+ -+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ -+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ -+ (h) = F((a)) + G((a), (b), (c)) + t1; \ -+ (d) += t1; \ -+ } -+ -+ -+/* {{{ PHP_SHA256Init -+ * SHA256 initialization. Begins an SHA256 operation, writing a new context. -+ */ -+static void PHP_SHA256Init(PHP_SHA256_CTX * context) -+{ -+ context->count[0] = context->count[1] = 0; -+ /* Load magic initialization constants. -+ */ -+ context->state[0] = 0x6a09e667; -+ context->state[1] = 0xbb67ae85; -+ context->state[2] = 0x3c6ef372; -+ context->state[3] = 0xa54ff53a; -+ context->state[4] = 0x510e527f; -+ context->state[5] = 0x9b05688c; -+ context->state[6] = 0x1f83d9ab; -+ context->state[7] = 0x5be0cd19; -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Update -+ SHA256 block update operation. Continues an SHA256 message-digest -+ operation, processing another message block, and updating the -+ context. -+ */ -+static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, -+ unsigned int inputLen) -+{ -+ unsigned int i, index, partLen; -+ -+ /* Compute number of bytes mod 64 */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); -+ -+ /* Update number of bits */ -+ if ((context->count[0] += ((php_uint32) inputLen << 3)) -+ < ((php_uint32) inputLen << 3)) -+ context->count[1]++; -+ context->count[1] += ((php_uint32) inputLen >> 29); -+ -+ partLen = 64 - index; -+ -+ /* Transform as many times as possible. -+ */ -+ if (inputLen >= partLen) { -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); -+ SHA256Transform(context->state, context->buffer); -+ -+ for (i = partLen; i + 63 < inputLen; i += 64) -+ SHA256Transform(context->state, &input[i]); -+ -+ index = 0; -+ } else -+ i = 0; -+ -+ /* Buffer remaining input */ -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], -+ inputLen - i); -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Final -+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the -+ the message digest and zeroizing the context. -+ */ -+static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) -+{ -+ unsigned char bits[8]; -+ unsigned int index, padLen; -+ -+ /* Save number of bits */ -+ bits[7] = context->count[0] & 0xFF; -+ bits[6] = (context->count[0] >> 8) & 0xFF; -+ bits[5] = (context->count[0] >> 16) & 0xFF; -+ bits[4] = (context->count[0] >> 24) & 0xFF; -+ bits[3] = context->count[1] & 0xFF; -+ bits[2] = (context->count[1] >> 8) & 0xFF; -+ bits[1] = (context->count[1] >> 16) & 0xFF; -+ bits[0] = (context->count[1] >> 24) & 0xFF; -+ -+ /* Pad out to 56 mod 64. -+ */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); -+ padLen = (index < 56) ? (56 - index) : (120 - index); -+ PHP_SHA256Update(context, PADDING, padLen); -+ -+ /* Append length (before padding) */ -+ PHP_SHA256Update(context, bits, 8); -+ -+ /* Store state in digest */ -+ SHA256Encode(digest, context->state, 32); -+ -+ /* Zeroize sensitive information. -+ */ -+ memset((unsigned char*) context, 0, sizeof(*context)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Transform -+ * SHA256 basic transformation. Transforms state based on block. -+ */ -+static void SHA256Transform(state, block) -+php_uint32 state[8]; -+const unsigned char block[64]; -+{ -+ php_uint32 a = state[0], b = state[1], c = state[2]; -+ php_uint32 d = state[3], e = state[4], f = state[5]; -+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; -+ -+ SHA256Decode(x, block, 64); -+ -+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) -+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) -+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) -+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) -+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) -+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) -+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) -+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) -+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) -+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) -+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) -+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) -+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) -+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) -+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) -+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) -+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) -+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) -+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) -+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) -+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) -+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) -+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) -+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) -+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) -+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) -+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) -+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) -+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) -+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) -+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) -+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) -+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) -+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) -+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) -+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) -+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) -+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) -+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) -+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) -+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) -+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) -+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) -+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) -+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) -+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) -+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) -+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) -+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) -+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) -+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) -+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) -+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) -+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) -+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) -+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) -+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) -+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) -+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) -+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) -+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) -+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) -+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) -+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) -+ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ state[4] += e; -+ state[5] += f; -+ state[6] += g; -+ state[7] += h; -+ -+ /* Zeroize sensitive information. */ -+ memset((unsigned char*) x, 0, sizeof(x)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Encode -+ Encodes input (php_uint32) into output (unsigned char). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Encode(output, input, len) -+unsigned char *output; -+php_uint32 *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) { -+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); -+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); -+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); -+ output[j + 3] = (unsigned char) (input[i] & 0xff); -+ } -+} -+/* }}} */ -+ -+/* {{{ SHA256Decode -+ Decodes input (unsigned char) into output (php_uint32). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Decode(output, input, len) -+php_uint32 *output; -+const unsigned char *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) -+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | -+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.4/ext/standard/sha256.h hardening-patch-5.1.4-0.4.15/ext/standard/sha256.h ---- php-5.1.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/sha256.h 2006-09-05 20:31:04.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ -+ -+#ifndef SHA256_H -+#define SHA256_H -+ -+#include "ext/standard/basic_functions.h" -+ -+/* SHA1 context. */ -+typedef struct { -+ php_uint32 state[8]; /* state (ABCD) */ -+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ -+ unsigned char buffer[64]; /* input buffer */ -+} PHP_SHA256_CTX; -+ -+static void PHP_SHA256Init(PHP_SHA256_CTX *); -+static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); -+static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); -+ -+PHP_FUNCTION(sha256); -+PHP_FUNCTION(sha256_file); -+ -+#endif -diff -Nura php-5.1.4/ext/standard/string.c hardening-patch-5.1.4-0.4.15/ext/standard/string.c ---- php-5.1.4/ext/standard/string.c 2006-04-25 14:48:41.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/string.c 2006-09-05 20:31:04.000000000 +0200 -@@ -18,7 +18,7 @@ - +----------------------------------------------------------------------+ - */ - --/* $Id: string.c,v 1.445.2.14 2006/04/25 12:48:41 tony2001 Exp $ */ -+/* $Id: string.c,v 1.445.2.16 2006/08/10 17:46:43 iliaa Exp $ */ - - /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ - -@@ -632,7 +632,8 @@ - { - const char *text, *breakchar = "\n"; - char *newtext; -- int textlen, breakcharlen = 1, newtextlen, alloced, chk; -+ int textlen, breakcharlen = 1, newtextlen, chk; -+ size_t alloced; - long current = 0, laststart = 0, lastspace = 0; - long linelength = 75; - zend_bool docut = 0; -@@ -1612,10 +1613,18 @@ - RETURN_FALSE; - } - -+ if (haystack_len == 0) { -+ RETURN_FALSE; -+ } -+ - haystack_dup = estrndup(haystack, haystack_len); - php_strtolower(haystack_dup, haystack_len); - - if (Z_TYPE_P(needle) == IS_STRING) { -+ if (Z_STRLEN_P(needle) == 0 || Z_STRLEN_P(needle) > haystack_len) { -+ efree(haystack_dup); -+ RETURN_FALSE; -+ } - needle_dup = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle)); - php_strtolower(needle_dup, Z_STRLEN_P(needle)); - found = php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len); -@@ -4194,7 +4203,7 @@ - zval **input_str; /* Input string */ - zval **mult; /* Multiplier */ - char *result; /* Resulting string */ -- int result_len; /* Length of the resulting string */ -+ size_t result_len; /* Length of the resulting string */ - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { - WRONG_PARAM_COUNT; -@@ -4219,11 +4228,7 @@ - - /* Initialize the result string */ - result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); -- if (result_len < 1 || result_len > 2147483647) { -- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes"); -- RETURN_FALSE; -- } -- result = (char *)emalloc(result_len + 1); -+ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1); - - /* Heavy optimization for situations where input string is 1 byte long */ - if (Z_STRLEN_PP(input_str) == 1) { -@@ -4894,7 +4899,7 @@ - offset = (offset < 0) ? 0 : offset; - } - -- if ((offset + len) >= s1_len) { -+ if ((offset + len) > s1_len) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position cannot exceed initial string length"); - RETURN_FALSE; - } -diff -Nura php-5.1.4/ext/standard/syslog.c hardening-patch-5.1.4-0.4.15/ext/standard/syslog.c ---- php-5.1.4/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/standard/syslog.c 2006-09-05 20:31:04.000000000 +0200 -@@ -42,6 +42,7 @@ - */ - PHP_MINIT_FUNCTION(syslog) - { -+#if !HARDENING_PATCH - /* error levels */ - REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ - REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -@@ -97,6 +98,7 @@ - /* AIX doesn't have LOG_PERROR */ - REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ - #endif -+#endif - BG(syslog_device)=NULL; - - return SUCCESS; -diff -Nura php-5.1.4/ext/varfilter/config.m4 hardening-patch-5.1.4-0.4.15/ext/varfilter/config.m4 ---- php-5.1.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/config.m4 2006-09-05 20:31:04.000000000 +0200 -@@ -0,0 +1,11 @@ -+dnl -+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+dnl -+ -+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, -+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) -+ -+if test "$PHP_VARFILTER" != "no"; then -+ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) -+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) -+fi -diff -Nura php-5.1.4/ext/varfilter/CREDITS hardening-patch-5.1.4-0.4.15/ext/varfilter/CREDITS ---- php-5.1.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:31:04.000000000 +0200 -@@ -0,0 +1,2 @@ -+varfilter -+Stefan Esser -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-5.1.4/ext/varfilter/php_varfilter.h hardening-patch-5.1.4-0.4.15/ext/varfilter/php_varfilter.h ---- php-5.1.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:31:04.000000000 +0200 -@@ -0,0 +1,144 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifndef PHP_VARFILTER_H -+#define PHP_VARFILTER_H -+ -+extern zend_module_entry varfilter_module_entry; -+#define phpext_varfilter_ptr &varfilter_module_entry -+ -+#ifdef PHP_WIN32 -+#define PHP_VARFILTER_API __declspec(dllexport) -+#else -+#define PHP_VARFILTER_API -+#endif -+ -+#ifdef ZTS -+#include "TSRM.h" -+#endif -+ -+#include "SAPI.h" -+ -+#include "php_variables.h" -+ -+#ifdef ZEND_ENGINE_2 -+#define HASH_HTTP_GET_VARS 0x2095733f -+#define HASH_HTTP_POST_VARS 0xbfee1265 -+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 -+#define HASH_HTTP_ENV_VARS 0x1fe186a8 -+#define HASH_HTTP_SERVER_VARS 0xc987afd6 -+#define HASH_HTTP_SESSION_VARS 0x7aba0d43 -+#define HASH_HTTP_POST_FILES 0x98eb1ddc -+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec -+#else -+#define HASH_HTTP_GET_VARS 0x8d8645bd -+#define HASH_HTTP_POST_VARS 0x7c699bf3 -+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f -+#define HASH_HTTP_ENV_VARS 0x84da3016 -+#define HASH_HTTP_SERVER_VARS 0x6dbf964e -+#define HASH_HTTP_SESSION_VARS 0x322906f5 -+#define HASH_HTTP_POST_FILES 0xe4e4ce70 -+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e -+#endif -+ -+PHP_MINIT_FUNCTION(varfilter); -+PHP_MSHUTDOWN_FUNCTION(varfilter); -+PHP_RINIT_FUNCTION(varfilter); -+PHP_RSHUTDOWN_FUNCTION(varfilter); -+PHP_MINFO_FUNCTION(varfilter); -+ -+ -+ZEND_BEGIN_MODULE_GLOBALS(varfilter) -+/* request variables */ -+ long max_request_variables; -+ long cur_request_variables; -+ long max_varname_length; -+ long max_totalname_length; -+ long max_value_length; -+ long max_array_depth; -+ long max_array_index_length; -+ zend_bool disallow_nul; -+/* cookie variables */ -+ long max_cookie_vars; -+ long cur_cookie_vars; -+ long max_cookie_name_length; -+ long max_cookie_totalname_length; -+ long max_cookie_value_length; -+ long max_cookie_array_depth; -+ long max_cookie_array_index_length; -+ zend_bool disallow_cookie_nul; -+/* get variables */ -+ long max_get_vars; -+ long cur_get_vars; -+ long max_get_name_length; -+ long max_get_totalname_length; -+ long max_get_value_length; -+ long max_get_array_depth; -+ long max_get_array_index_length; -+ zend_bool disallow_get_nul; -+/* post variables */ -+ long max_post_vars; -+ long cur_post_vars; -+ long max_post_name_length; -+ long max_post_totalname_length; -+ long max_post_value_length; -+ long max_post_array_depth; -+ long max_post_array_index_length; -+ zend_bool disallow_post_nul; -+/* fileupload */ -+ long max_uploads; -+ long cur_uploads; -+ zend_bool disallow_elf_files; -+ char *verification_script; -+ -+ zend_bool no_more_variables; -+ zend_bool no_more_get_variables; -+ zend_bool no_more_post_variables; -+ zend_bool no_more_cookie_variables; -+ zend_bool no_more_uploads; -+ -+ZEND_END_MODULE_GLOBALS(varfilter) -+ -+ -+#ifdef ZTS -+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) -+#else -+#define VARFILTER_G(v) (varfilter_globals.v) -+#endif -+ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); -+SAPI_TREAT_DATA_FUNC(varfilter_treat_data); -+ -+ -+ -+#endif /* PHP_VARFILTER_H */ -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * indent-tabs-mode: t -+ * End: -+ */ -diff -Nura php-5.1.4/ext/varfilter/varfilter.c hardening-patch-5.1.4-0.4.15/ext/varfilter/varfilter.c ---- php-5.1.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:51:41.000000000 +0200 -@@ -0,0 +1,915 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "php.h" -+#include "php_ini.h" -+#include "ext/standard/info.h" -+#include "php_varfilter.h" -+#include "hardening_patch.h" -+ -+ZEND_DECLARE_MODULE_GLOBALS(varfilter) -+ -+/* True global resources - no need for thread safety here */ -+static int le_varfilter; -+ -+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; -+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; -+static zend_bool hooked = 0; -+ -+/* {{{ varfilter_module_entry -+ */ -+zend_module_entry varfilter_module_entry = { -+#if ZEND_MODULE_API_NO >= 20010901 -+ STANDARD_MODULE_HEADER, -+#endif -+ "varfilter", -+ NULL, -+ PHP_MINIT(varfilter), -+ PHP_MSHUTDOWN(varfilter), -+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ -+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ -+ PHP_MINFO(varfilter), -+#if ZEND_MODULE_API_NO >= 20010901 -+ "0.4.15", /* Replace with version number for your extension */ -+#endif -+ STANDARD_MODULE_PROPERTIES -+}; -+/* }}} */ -+ -+#ifdef COMPILE_DL_VARFILTER -+ZEND_GET_MODULE(varfilter) -+#endif -+ -+/* {{{ PHP_INI -+ */ -+PHP_INI_BEGIN() -+ /* for backward compatibility */ -+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) -+ -+ -+PHP_INI_END() -+/* }}} */ -+ -+/* {{{ php_varfilter_init_globals -+ */ -+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) -+{ -+ varfilter_globals->max_request_variables = 200; -+ varfilter_globals->max_varname_length = 64; -+ varfilter_globals->max_value_length = 10000; -+ varfilter_globals->max_array_depth = 100; -+ varfilter_globals->max_totalname_length = 256; -+ varfilter_globals->max_array_index_length = 64; -+ varfilter_globals->disallow_nul = 1; -+ -+ varfilter_globals->max_cookie_vars = 100; -+ varfilter_globals->max_cookie_name_length = 64; -+ varfilter_globals->max_cookie_totalname_length = 256; -+ varfilter_globals->max_cookie_value_length = 10000; -+ varfilter_globals->max_cookie_array_depth = 100; -+ varfilter_globals->max_cookie_array_index_length = 64; -+ varfilter_globals->disallow_cookie_nul = 1; -+ -+ varfilter_globals->max_get_vars = 100; -+ varfilter_globals->max_get_name_length = 64; -+ varfilter_globals->max_get_totalname_length = 256; -+ varfilter_globals->max_get_value_length = 512; -+ varfilter_globals->max_get_array_depth = 50; -+ varfilter_globals->max_get_array_index_length = 64; -+ varfilter_globals->disallow_get_nul = 1; -+ -+ varfilter_globals->max_post_vars = 200; -+ varfilter_globals->max_post_name_length = 64; -+ varfilter_globals->max_post_totalname_length = 256; -+ varfilter_globals->max_post_value_length = 65000; -+ varfilter_globals->max_post_array_depth = 100; -+ varfilter_globals->max_post_array_index_length = 64; -+ varfilter_globals->disallow_post_nul = 1; -+ -+ varfilter_globals->max_uploads = 25; -+ varfilter_globals->disallow_elf_files = 1; -+ varfilter_globals->verification_script = NULL; -+ -+ varfilter_globals->no_more_variables = 0; -+ varfilter_globals->no_more_get_variables = 0; -+ varfilter_globals->no_more_post_variables = 0; -+ varfilter_globals->no_more_cookie_variables = 0; -+ varfilter_globals->no_more_uploads = 0; -+ -+ varfilter_globals->cur_request_variables = 0; -+ varfilter_globals->cur_get_vars = 0; -+ varfilter_globals->cur_post_vars = 0; -+ varfilter_globals->cur_cookie_vars = 0; -+ -+ varfilter_globals->cur_uploads = 0; -+ -+} -+/* }}} */ -+ -+ -+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) -+{ -+ HashTable *svars; -+ int retval, failure=0; -+ -+ orig_register_server_variables(track_vars_array TSRMLS_CC); -+ -+ svars = Z_ARRVAL_P(track_vars_array); -+ -+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ -+ if (failure) { -+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); -+ } -+} -+ -+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) -+{ -+ int retval = SAPI_HEADER_ADD, i; -+ char *tmp; -+ -+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { -+ -+ tmp = sapi_header->header; -+ for (i=0; iheader_len; i++, tmp++) { -+ if (tmp[0] == 0) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); -+ sapi_header->header_len = i; -+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); -+ sapi_header->header_len = i; -+ tmp[0] = 0; -+ } -+ } -+ } -+ -+ if (orig_header_handler) { -+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); -+ } -+ -+ return retval; -+} -+ -+/* {{{ PHP_MINIT_FUNCTION -+ */ -+PHP_MINIT_FUNCTION(varfilter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); -+ REGISTER_INI_ENTRIES(); -+ -+ if (!hooked) { -+ void *temp; -+ hooked = 1; -+ -+ temp = (void *)sapi_module.register_server_variables; -+ if (temp != varfilter_register_server_variables) { -+ orig_register_server_variables = temp; -+ } -+ temp = (void *)sapi_module.header_handler; -+ if (temp != varfilter_header_handler) { -+ orig_header_handler = temp; -+ } -+ } -+ -+ sapi_register_input_filter(varfilter_input_filter); -+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); -+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); -+ sapi_register_upload_content_filter(varfilter_upload_content_filter); -+ sapi_register_post_upload_filter(varfilter_post_upload_filter); -+ -+ sapi_module.header_handler = varfilter_header_handler; -+ sapi_module.register_server_variables = varfilter_register_server_variables; -+ -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MSHUTDOWN_FUNCTION -+ */ -+PHP_MSHUTDOWN_FUNCTION(varfilter) -+{ -+ UNREGISTER_INI_ENTRIES(); -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request start */ -+/* {{{ PHP_RINIT_FUNCTION -+ */ -+PHP_RINIT_FUNCTION(varfilter) -+{ -+ VARFILTER_G(cur_request_variables) = 0; -+ VARFILTER_G(cur_get_vars) = 0; -+ VARFILTER_G(cur_post_vars) = 0; -+ VARFILTER_G(cur_cookie_vars) = 0; -+ -+ VARFILTER_G(cur_uploads) = 0; -+ -+ VARFILTER_G(no_more_variables) = 0; -+ VARFILTER_G(no_more_get_variables) = 0; -+ VARFILTER_G(no_more_post_variables) = 0; -+ VARFILTER_G(no_more_cookie_variables) = 0; -+ VARFILTER_G(no_more_uploads) = 0; -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request end */ -+/* {{{ PHP_RSHUTDOWN_FUNCTION -+ */ -+PHP_RSHUTDOWN_FUNCTION(varfilter) -+{ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MINFO_FUNCTION -+ */ -+PHP_MINFO_FUNCTION(varfilter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); -+ php_info_print_table_end(); -+ -+ DISPLAY_INI_ENTRIES(); -+} -+/* }}} */ -+ -+/* {{{ normalize_varname -+ */ -+static void normalize_varname(char *varname) -+{ -+ char *s=varname, *index=NULL, *indexend=NULL, *p; -+ -+ /* overjump leading space */ -+ while (*s == ' ') { -+ s++; -+ } -+ -+ /* and remove it */ -+ if (s != varname) { -+ memmove(varname, s, strlen(s)+1); -+ } -+ -+ for (p=varname; *p && *p != '['; p++) { -+ switch(*p) { -+ case ' ': -+ case '.': -+ *p='_'; -+ break; -+ } -+ } -+ -+ /* find index */ -+ index = strchr(varname, '['); -+ if (index) { -+ index++; -+ s=index; -+ } else { -+ return; -+ } -+ -+ /* done? */ -+ while (index) { -+ -+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { -+ index++; -+ } -+ indexend = strchr(index, ']'); -+ indexend = indexend ? indexend + 1 : index + strlen(index); -+ -+ if (s != index) { -+ memmove(s, index, strlen(index)+1); -+ s += indexend-index; -+ } else { -+ s = indexend; -+ } -+ -+ if (*s == '[') { -+ s++; -+ index = s; -+ } else { -+ index = NULL; -+ } -+ } -+ *s++='\0'; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC -+ */ -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) -+{ -+ char *index, *prev_index = NULL, *var; -+ unsigned int var_len, total_len, depth = 0; -+ -+ var = estrdup(varname); -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); -+ -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; -+ break; -+ } -+ -+ efree(var); -+ return SUCCESS; -+protected_varname2: -+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); -+return_failure: -+ efree(var); -+ return FAILURE; -+} -+/* }}} */ -+ -+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC -+ */ -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) -+{ -+ /* Drop if no more variables flag is set */ -+ if (VARFILTER_G(no_more_uploads)) { -+ return FAILURE; -+ } -+ /* Drop this fileupload if the limit is reached */ -+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { -+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); -+ VARFILTER_G(no_more_uploads) = 1; -+ return FAILURE; -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC -+ */ -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) -+{ -+ -+ if (VARFILTER_G(disallow_elf_files)) { -+ -+ if (offset == 0 && buffer_len > 10) { -+ -+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { -+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); -+ return FAILURE; -+ } -+ } -+ -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC -+ */ -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) -+{ -+ int retval = SUCCESS; -+ -+ if (VARFILTER_G(verification_script)) { -+ char cmd[8192]; -+ FILE *in; -+ int first=1; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); -+ return FAILURE; -+ } -+ -+ retval = FAILURE; -+ -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ if (first) { -+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; -+ first = 0; -+ } -+ } -+ pclose(in); -+ } -+ -+ if (retval != SUCCESS) { -+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); -+ return FAILURE; -+ } -+ -+ VARFILTER_G(cur_uploads)++; -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_INPUT_FILTER_FUNC -+ */ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) -+{ -+ char *index, *prev_index = NULL; -+ unsigned int var_len, total_len, depth = 0; -+ -+ /* Drop this variable if the limit was reached */ -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(no_more_get_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(no_more_post_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(no_more_cookie_variables)) { -+ return 0; -+ } -+ break; -+ default: /* we do not want to protect parse_str() and friends */ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ return 1; -+ } -+ if (VARFILTER_G(no_more_variables)) { -+ return 0; -+ } -+ -+ /* Drop this variable if the limit is now reached */ -+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { -+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_variables) = 1; -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { -+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_get_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { -+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_cookie_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { -+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_post_variables) = 1; -+ return 0; -+ } -+ break; -+ } -+ -+ -+ /* Drop this variable if it exceeds the value length limit */ -+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { -+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { -+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { -+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { -+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { -+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { -+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Check if variable value is truncated by a \0 */ -+ -+ if (val && *val && val_len != strlen(*val)) { -+ -+ if (VARFILTER_G(disallow_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(disallow_get_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(disallow_cookie_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(disallow_post_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ } -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname; -+ break; -+ } -+ -+ /* Okay let PHP register this variable */ -+ VARFILTER_G(cur_request_variables)++; -+ switch (arg) { -+ case PARSE_GET: -+ VARFILTER_G(cur_get_vars)++; -+ break; -+ case PARSE_COOKIE: -+ VARFILTER_G(cur_cookie_vars)++; -+ break; -+ case PARSE_POST: -+ VARFILTER_G(cur_post_vars)++; -+ break; -+ } -+ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ -+ return 1; -+protected_varname: -+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); -+ return 0; -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: noet sw=4 ts=4 fdm=marker -+ * vim<600: noet sw=4 ts=4 -+ */ -+ -+ -diff -Nura php-5.1.4/ext/wddx/wddx.c hardening-patch-5.1.4-0.4.15/ext/wddx/wddx.c ---- php-5.1.4/ext/wddx/wddx.c 2006-04-23 18:02:05.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/ext/wddx/wddx.c 2006-09-05 20:31:04.000000000 +0200 -@@ -399,9 +399,9 @@ - break; - - default: -- if (iscntrl((int)*(unsigned char *)p)) { -+ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) { - FLUSH_BUF(); -- sprintf(control_buf, WDDX_CHAR, *p); -+ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); - php_wddx_add_chunk(packet, control_buf); - } else - buf[l++] = *p; -@@ -751,7 +751,7 @@ - } else if (!strcmp(name, EL_CHAR)) { - int i; - -- for (i = 0; atts[i]; i++) { -+ if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) { - char tmp_buf[2]; - -@@ -771,7 +771,7 @@ - } else if (!strcmp(name, EL_BOOLEAN)) { - int i; - -- for (i = 0; atts[i]; i++) { -+ if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) { - ent.type = ST_BOOLEAN; - SET_STACK_VARNAME; -@@ -812,7 +812,7 @@ - } else if (!strcmp(name, EL_VAR)) { - int i; - -- for (i = 0; atts[i]; i++) { -+ if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) { - char *decoded; - int decoded_len; -@@ -829,7 +829,7 @@ - MAKE_STD_ZVAL(ent.data); - array_init(ent.data); - -- for (i = 0; atts[i]; i++) { -+ if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) { - zval *tmp; - char *key; -@@ -869,7 +869,7 @@ - ent.varname = NULL; - ent.data = NULL; - -- for (i = 0; atts[i]; i++) { -+ if (atts) for (i = 0; atts[i]; i++) { - if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) { - char *decoded; - int decoded_len; -diff -Nura php-5.1.4/main/fopen_wrappers.c hardening-patch-5.1.4-0.4.15/main/fopen_wrappers.c ---- php-5.1.4/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:55.000000000 +0200 -@@ -104,7 +104,10 @@ - } - - /* Resolve the real path into resolved_name */ -- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { -+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { -+ return -2; -+ } -+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { - /* Handler for basedirs that end with a / */ - resolved_basedir_len = strlen(resolved_basedir); - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { -@@ -114,14 +117,20 @@ - } - } - -+ resolved_name_len = strlen(resolved_name); - if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { -- resolved_name_len = strlen(resolved_name); - if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { - resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; - resolved_name[++resolved_name_len] = '\0'; - } - } - -+ if (resolved_name_len == resolved_basedir_len - 1) { -+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { -+ resolved_basedir_len--; -+ } -+ } -+ - /* Check the path */ - #if defined(PHP_WIN32) || defined(NETWARE) - if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { -@@ -135,7 +144,7 @@ - } - } else { - /* Unable to resolve the real path, return -1 */ -- return -1; -+ return -3; - } - } - /* }}} */ -@@ -154,22 +163,44 @@ - char *pathbuf; - char *ptr; - char *end; -+ char path_copy[MAXPATHLEN]; -+ int path_len; -+ -+ /* Special case path ends with a trailing slash */ -+ path_len = strlen(path); -+ if (path_len >= MAXPATHLEN) { -+ errno = EPERM; /* we deny permission to open it */ -+ return -1; -+ } -+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { -+ memcpy(path_copy, path, path_len+1); -+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; -+ path_copy[path_len] = '\0'; -+ path = (const char *)&path_copy; -+ } - - pathbuf = estrdup(PG(open_basedir)); - - ptr = pathbuf; - - while (ptr && *ptr) { -+ int res; - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - -- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { -+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); -+ if (res == 0) { - efree(pathbuf); - return 0; - } -+ if (res == -2) { -+ efree(pathbuf); -+ errno = EPERM; -+ return -1; -+ } - - ptr = end; - } -diff -Nura php-5.1.4/main/hardened_globals.h hardening-patch-5.1.4-0.4.15/main/hardened_globals.h ---- php-5.1.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/hardened_globals.h 2006-09-05 20:31:05.000000000 +0200 -@@ -0,0 +1,64 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENED_GLOBALS_H -+#define HARDENED_GLOBALS_H -+ -+typedef struct _hardened_globals hardened_globals_struct; -+ -+#ifdef ZTS -+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) -+extern int hardened_globals_id; -+#else -+# define HG(v) (hardened_globals.v) -+extern struct _hardened_globals hardened_globals; -+#endif -+ -+ -+struct _hardened_globals { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_1; -+ unsigned int canary_2; -+#endif -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_3; -+ unsigned int canary_4; -+ unsigned int ll_canary_inited; -+#endif -+ zend_bool hphp_sql_bailout_on_error; -+ zend_bool hphp_multiheader; -+ unsigned long hphp_mailprotect; -+ long hard_memory_limit; -+ HashTable *eval_whitelist; -+ HashTable *eval_blacklist; -+ HashTable *func_whitelist; -+ HashTable *func_blacklist; -+ HashTable *include_whitelist; -+ HashTable *include_blacklist; -+ unsigned int dummy; -+}; -+ -+ -+#endif /* HARDENED_GLOBALS_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-5.1.4/main/hardening_patch.c hardening-patch-5.1.4-0.4.15/main/hardening_patch.c ---- php-5.1.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.c 2006-09-05 20:31:05.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ -+ -+#include "php.h" -+ -+#include -+#include -+ -+#if HAVE_UNISTD_H -+#include -+#endif -+#include "SAPI.h" -+#include "php_globals.h" -+ -+#if HARDENING_PATCH -+ -+#ifdef HAVE_SYS_SOCKET_H -+#include -+#endif -+ -+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) -+#undef AF_UNIX -+#endif -+ -+#if defined(AF_UNIX) -+#include -+#endif -+ -+#define SYSLOG_PATH "/dev/log" -+ -+#include "snprintf.h" -+ -+#include "hardening_patch.h" -+ -+#ifdef ZTS -+#include "hardened_globals.h" -+int hardened_globals_id; -+#else -+struct _hardened_globals hardened_globals; -+#endif -+ -+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) -+{ -+ memset(hardened_globals, 0, sizeof(*hardened_globals)); -+} -+ -+ -+PHPAPI void hardened_startup() -+{ -+#ifdef ZTS -+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); -+#else -+ hardened_globals_ctor(&hardened_globals TSRMLS_CC); -+#endif -+} -+ -+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) -+{ -+ HG(canary_1) = php_canary(); -+ HG(canary_2) = php_canary(); -+} -+ -+char *loglevel2string(int loglevel) -+{ -+ switch (loglevel) { -+ case S_FILES: -+ return "FILES"; -+ case S_INCLUDE: -+ return "INCLUDE"; -+ case S_MEMORY: -+ return "MEMORY"; -+ case S_MISC: -+ return "MISC"; -+ case S_SQL: -+ return "SQL"; -+ case S_EXECUTOR: -+ return "EXECUTOR"; -+ case S_VARS: -+ return "VARS"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+PHPAPI void php_security_log(int loglevel, char *fmt, ...) -+{ -+#if defined(AF_UNIX) -+ int s, r, i=0; -+ struct sockaddr_un saun; -+ char buf[4096+64]; -+ char error[4096+100]; -+ char *ip_address; -+ char *fname; -+ int lineno; -+ va_list ap; -+ TSRMLS_FETCH(); -+ -+ if (EG(hphp_log_use_x_forwarded_for)) { -+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "X-FORWARDED-FOR not set"; -+ } -+ } else { -+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "REMOTE_ADDR not set"; -+ } -+ } -+ -+ -+ va_start(ap, fmt); -+ ap_php_vsnprintf(error, sizeof(error), fmt, ap); -+ va_end(ap); -+ while (error[i]) { -+ if (error[i] < 32) error[i] = '.'; -+ i++; -+ } -+ -+ if (zend_is_executing(TSRMLS_C)) { -+ lineno = zend_get_executed_lineno(TSRMLS_C); -+ fname = zend_get_executed_filename(TSRMLS_C); -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); -+ } else { -+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); -+ if (fname==NULL) { -+ fname = "unknown"; -+ } -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); -+ } -+ -+ /* Syslog-Logging disabled? */ -+ if ((EG(hphp_log_syslog) & loglevel)==0) { -+ goto log_sapi; -+ } -+ -+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); -+ -+ s = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ s = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ goto log_sapi; -+ } -+ } -+ send(s, error, strlen(error), 0); -+ -+ close(s); -+ -+log_sapi: -+ /* SAPI Logging activated? */ -+ if ((EG(hphp_log_sapi) & loglevel)!=0) { -+ sapi_module.log_message(buf); -+ } -+ -+log_script: -+ /* script logging activaed? */ -+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { -+ char cmd[8192], *cmdpos, *bufpos; -+ FILE *in; -+ int space; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); -+ space = sizeof(cmd) - strlen(cmd); -+ cmdpos = cmd + strlen(cmd); -+ bufpos = buf; -+ if (space <= 1) return; -+ while (space > 2 && *bufpos) { -+ if (*bufpos == '\'') { -+ if (space<=5) break; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\\'; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\''; -+ bufpos++; -+ space-=4; -+ } else { -+ *cmdpos++ = *bufpos++; -+ space--; -+ } -+ } -+ *cmdpos++ = '\''; -+ *cmdpos = 0; -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); -+ return; -+ } -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ } -+ pclose(in); -+ } -+ -+#endif -+} -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+PHPAPI unsigned int php_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+ -+PHPAPI int php_is_valid_include(zval *z) -+{ -+ char *filename; -+ int len, i; -+ TSRMLS_FETCH(); -+ -+ /* must be of type string */ -+ if (z->type != IS_STRING || z->value.str.val == NULL) { -+ return (0); -+ } -+ -+ /* short cut */ -+ filename = z->value.str.val; -+ len = z->value.str.len; -+ -+ /* 1. must be shorter than MAXPATHLEN */ -+ if (len > MAXPATHLEN) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 2. must not be cutted */ -+ if (len != strlen(filename)) { -+ char *fname = estrndup(filename, len); -+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ -+ if (strstr(filename, "://")) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ -+ /* no black or whitelist then disallow all */ -+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* whitelist is stronger than blacklist */ -+ if (HG(include_whitelist)) { -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ zend_bool isOk = 0; -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_whitelist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ isOk = 1; -+ break; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_whitelist)); -+ } while (1); -+ -+ /* not found in whitelist */ -+ if (!isOk) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); -+ efree(fname); -+ return 0; -+ } -+ -+ s = h + 3; -+ } while (1); -+ } else { -+ /* okay then handle the blacklist */ -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_blacklist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); -+ efree(fname); -+ return 0; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_blacklist)); -+ } while (1); -+ -+ s = h + 3; -+ } while (1); -+ } -+ -+ efree(fname); -+ } -+ -+ /* 4. must not be an uploaded file */ -+ if (SG(rfc1867_uploaded_files)) { -+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { -+ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); -+ return (0); -+ } -+ } -+ -+ /* passed all tests */ -+ return (1); -+} -+ -+#endif -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.4/main/hardening_patch.h hardening-patch-5.1.4-0.4.15/main/hardening_patch.h ---- php-5.1.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.h 2006-09-07 18:51:30.000000000 +0200 -@@ -0,0 +1,46 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENING_PATCH_H -+#define HARDENING_PATCH_H -+ -+#include "zend.h" -+ -+#if HARDENING_PATCH -+PHPAPI void php_security_log(int loglevel, char *fmt, ...); -+PHPAPI void hardened_startup(); -+#define HARDENING_PATCH_VERSION "0.4.15" -+ -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+PHPAPI unsigned int php_canary(); -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+PHPAPI int php_is_valid_include(zval *z); -+#endif -+ -+#endif /* HARDENING_PATCH_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-5.1.4/main/hardening_patch.m4 hardening-patch-5.1.4-0.4.15/main/hardening_patch.m4 ---- php-5.1.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.m4 2006-09-05 20:31:05.000000000 +0200 -@@ -0,0 +1,95 @@ -+dnl -+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ -+dnl -+dnl This file contains Hardening Patch for PHP specific autoconf functions. -+dnl -+ -+AC_ARG_ENABLE(hardening-patch-mm-protect, -+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-ll-protect, -+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-inc-protect, -+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-fmt-protect, -+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-hash-protect, -+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+]) -+ -+AC_MSG_CHECKING(whether to protect the Zend Memory Manager) -+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the Zend Linked Lists) -+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect include/require statements) -+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect PHP Format String functions) -+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) -+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) -+ -+ -+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) -+fi -+ -diff -Nura php-5.1.4/main/main.c hardening-patch-5.1.4-0.4.15/main/main.c ---- php-5.1.4/main/main.c 2006-04-12 14:49:39.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/main/main.c 2006-09-05 20:31:05.000000000 +0200 -@@ -85,6 +85,10 @@ - - #include "SAPI.h" - #include "rfc1867.h" -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#endif -+ - /* }}} */ - - #ifndef ZTS -@@ -109,17 +113,39 @@ - */ - static PHP_INI_MH(OnChangeMemoryLimit) - { -+#if HARDENING_PATCH -+ long hard_memory_limit = 1<<30; -+ -+ if (stage == ZEND_INI_STAGE_RUNTIME) { -+ if (HG(hard_memory_limit) == 0) { -+ HG(hard_memory_limit) = PG(memory_limit); -+ } -+ hard_memory_limit = HG(hard_memory_limit); -+ } else { -+ HG(hard_memory_limit) = 0; -+ } -+#endif - if (new_value) { - PG(memory_limit) = zend_atoi(new_value, new_value_length); -+#if HARDENING_PATCH -+ if (PG(memory_limit) > hard_memory_limit) { -+ PG(memory_limit) = hard_memory_limit; -+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); -+ return FAILURE; -+ } -+#endif - } else { -+#if HARDENING_PATCH -+ PG(memory_limit) = hard_memory_limit; -+#else - PG(memory_limit) = 1<<30; /* effectively, no limit */ -+#endif - } - return zend_set_memory_limit(PG(memory_limit)); - } - /* }}} */ - #endif - -- - /* {{{ php_disable_functions - */ - static void php_disable_functions(TSRMLS_D) -@@ -1095,6 +1121,13 @@ - sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1); - } - -+ /* Disable realpath cache if safe_mode or open_basedir are set */ -+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { -+ CWDG(realpath_cache_disable) = 1; -+ } else { -+ CWDG(realpath_cache_disable) = 0; -+ } -+ - if (PG(output_handler) && PG(output_handler)[0]) { - php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); - } else if (PG(output_buffering)) { -@@ -1222,6 +1255,9 @@ - - zend_try { - shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); -+#if HARDENING_PATCH -+ hardened_clear_mm_canaries(TSRMLS_C); -+#endif - } zend_end_try(); - - zend_try { -@@ -1393,6 +1429,10 @@ - tsrm_ls = ts_resource(0); - #endif - -+#if HARDENING_PATCH -+ hardened_startup(); -+#endif -+ - module_shutdown = 0; - module_startup = 1; - sapi_initialize_empty_request(TSRMLS_C); -@@ -1406,6 +1446,12 @@ - - php_output_startup(); - -+#if HARDENING_PATCH_INC_PROTECT -+ zuf.is_valid_include = php_is_valid_include; -+#endif -+#if HARDENING_PATCH -+ zuf.security_log_function = php_security_log; -+#endif - zuf.error_function = php_error_cb; - zuf.printf_function = php_printf; - zuf.write_function = php_body_write_wrapper; -@@ -1476,7 +1522,9 @@ - - /* Disable realpath cache if safe_mode or open_basedir are set */ - if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { -- CWDG(realpath_cache_size_limit) = 0; -+ CWDG(realpath_cache_disable) = 1; -+ } else { -+ CWDG(realpath_cache_disable) = 0; - } - - /* initialize stream wrappers registry -@@ -1517,6 +1565,10 @@ - REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS); - 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); - REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); -+#endif - REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); -diff -Nura php-5.1.4/main/php_config.h.in hardening-patch-5.1.4-0.4.15/main/php_config.h.in ---- php-5.1.4/main/php_config.h.in 2006-05-12 16:41:13.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/main/php_config.h.in 2006-09-05 20:31:05.000000000 +0200 -@@ -788,6 +788,39 @@ - /* Enabling BIND8 compatibility for Panther */ - #undef BIND_8_COMPAT - -+/* Hardening-Patch for PHP */ -+#undef HARDENING_PATCH -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ - /* Whether you have AOLserver */ - #undef HAVE_AOLSERVER - -@@ -1131,6 +1164,12 @@ - /* Define if you have the getaddrinfo function */ - #undef HAVE_GETADDRINFO - -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ - /* Whether system headers declare timezone */ - #undef HAVE_DECLARED_TIMEZONE - -diff -Nura php-5.1.4/main/php.h hardening-patch-5.1.4-0.4.15/main/php.h ---- php-5.1.4/main/php.h 2006-03-07 23:37:53.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/php.h 2006-09-05 20:31:05.000000000 +0200 -@@ -35,11 +35,19 @@ - #include "zend_qsort.h" - #include "php_compat.h" - -+ - #include "zend_API.h" - - #undef sprintf - #define sprintf php_sprintf - -+#if HARDENING_PATCH -+#if HAVE_REALPATH -+#undef realpath -+#define realpath php_realpath -+#endif -+#endif -+ - /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ - #undef PHP_DEBUG - #define PHP_DEBUG ZEND_DEBUG -@@ -338,6 +346,7 @@ - #define PHP_FUNCTION ZEND_FUNCTION - #define PHP_METHOD ZEND_METHOD - -+#define PHP_STATIC_FE ZEND_STATIC_FE - #define PHP_NAMED_FE ZEND_NAMED_FE - #define PHP_FE ZEND_FE - #define PHP_DEP_FE ZEND_DEP_FE -@@ -447,6 +456,10 @@ - #endif - #endif /* !XtOffsetOf */ - -+#if HARDENING_PATCH -+#include "hardening_patch.h" -+#endif -+ - #endif - - /* -diff -Nura php-5.1.4/main/php_open_temporary_file.c hardening-patch-5.1.4-0.4.15/main/php_open_temporary_file.c ---- php-5.1.4/main/php_open_temporary_file.c 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/php_open_temporary_file.c 2006-09-05 20:31:05.000000000 +0200 -@@ -114,17 +114,16 @@ - - path_len = strlen(path); - -- if (!(opened_path = emalloc(MAXPATHLEN))) { -- return -1; -- } -- - if (!path_len || IS_SLASH(path[path_len - 1])) { - trailing_slash = ""; - } else { - trailing_slash = "/"; - } - -- (void)snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", path, trailing_slash, pfx); -+ if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", path, trailing_slash, pfx) >= MAXPATHLEN) { -+ efree(opened_path); -+ return -1; -+ } - - #ifdef PHP_WIN32 - if (GetTempFileName(path, pfx, 0, opened_path)) { -diff -Nura php-5.1.4/main/php_variables.c hardening-patch-5.1.4-0.4.15/main/php_variables.c ---- php-5.1.4/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/main/php_variables.c 2006-09-05 20:31:05.000000000 +0200 -@@ -73,6 +73,10 @@ - symtable1 = Z_ARRVAL_P(track_vars_array); - } else if (PG(register_globals)) { - symtable1 = EG(active_symbol_table); -+ /* GLOBALS hijack attempt, reject parameter */ -+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) { -+ symtable1 = NULL; -+ } - } - if (!symtable1) { - /* Nothing to do */ -@@ -513,7 +517,7 @@ - */ - static inline void php_register_server_variables(TSRMLS_D) - { -- zval *array_ptr = NULL; -+ zval *array_ptr = NULL, *vptr; - /* turn off magic_quotes while importing server variables */ - int magic_quotes_gpc = PG(magic_quotes_gpc); - -diff -Nura php-5.1.4/main/rfc1867.c hardening-patch-5.1.4-0.4.15/main/rfc1867.c ---- php-5.1.4/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/rfc1867.c 2006-09-05 20:31:05.000000000 +0200 -@@ -132,6 +132,7 @@ - #define UPLOAD_ERROR_D 4 /* No file uploaded */ - #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ - #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ -+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */ - - void php_rfc1867_register_constants(TSRMLS_D) - { -@@ -142,6 +143,7 @@ - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); - } - - static void normalize_protected_variable(char *varname TSRMLS_DC) -@@ -854,6 +856,7 @@ - char buff[FILLUNIT]; - char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; - int blen=0, wlen=0; -+ unsigned long offset; - - zend_llist_clean(&header); - -@@ -970,7 +973,11 @@ - tmp++; - } - } -- -+ -+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { -+ skip_upload = 1; -+ } -+ - total_bytes = cancel_upload = 0; - - if (!skip_upload) { -@@ -994,6 +1001,11 @@ - cancel_upload = UPLOAD_ERROR_D; - } - -+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ -+ offset = 0; - end = 0; - while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) - { -@@ -1008,6 +1020,10 @@ - #endif - cancel_upload = UPLOAD_ERROR_B; - } else if (blen > 0) { -+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - wlen = write(fd, buff, blen); - - if (wlen < blen) { -@@ -1036,6 +1052,10 @@ - } - #endif - -+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - if (cancel_upload) { - if (temp_filename) { - if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ -diff -Nura php-5.1.4/main/SAPI.c hardening-patch-5.1.4-0.4.15/main/SAPI.c ---- php-5.1.4/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/SAPI.c 2006-09-05 20:31:05.000000000 +0200 -@@ -870,6 +870,36 @@ - post_entry->content_type_len+1); - } - -+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)) -+{ -+ sapi_module.input_filter = input_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) -+{ -+ sapi_module.upload_varname_filter = upload_varname_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) -+{ -+ sapi_module.pre_upload_filter = pre_upload_filter; -+ return SUCCESS; -+} -+ -+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)) -+{ -+ sapi_module.upload_content_filter = upload_content_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) -+{ -+ sapi_module.post_upload_filter = post_upload_filter; -+ return SUCCESS; -+} -+ - - SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)) - { -@@ -884,11 +914,6 @@ - return SUCCESS; - } - --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)) --{ -- sapi_module.input_filter = input_filter; -- return SUCCESS; --} - - SAPI_API int sapi_flush(TSRMLS_D) - { -diff -Nura php-5.1.4/main/SAPI.h hardening-patch-5.1.4-0.4.15/main/SAPI.h ---- php-5.1.4/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/SAPI.h 2006-09-05 20:31:05.000000000 +0200 -@@ -190,6 +190,10 @@ - SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); - 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)); - -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); -+ - SAPI_API int sapi_flush(TSRMLS_D); - SAPI_API struct stat *sapi_get_stat(TSRMLS_D); - SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC); -@@ -254,6 +258,11 @@ - int (*get_target_gid)(gid_t * TSRMLS_DC); - - unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); -+ -+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); -+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); -+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); -+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); - - void (*ini_defaults)(HashTable *configuration_hash); - int phpinfo_as_text; -@@ -279,7 +288,11 @@ - - #define SAPI_DEFAULT_MIMETYPE "text/html" - #define SAPI_DEFAULT_CHARSET "" -+#if HARDENING_PATCH -+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" -+#else - #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION -+#endif - - #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) - #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) -@@ -287,6 +300,11 @@ - #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) - #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) - -+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) -+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) -+#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) -+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) -+ - BEGIN_EXTERN_C() - SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); - SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); -diff -Nura php-5.1.4/main/snprintf.c hardening-patch-5.1.4-0.4.15/main/snprintf.c ---- php-5.1.4/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/snprintf.c 2006-09-05 20:31:05.000000000 +0200 -@@ -1014,7 +1014,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = cc; -+#endif - goto skip_output; - - /* -diff -Nura php-5.1.4/main/spprintf.c hardening-patch-5.1.4-0.4.15/main/spprintf.c ---- php-5.1.4/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/main/spprintf.c 2006-09-05 20:31:05.000000000 +0200 -@@ -630,7 +630,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = xbuf->len; -+#endif - goto skip_output; - - /* -diff -Nura php-5.1.4/pear/Makefile.frag hardening-patch-5.1.4-0.4.15/pear/Makefile.frag ---- php-5.1.4/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/pear/Makefile.frag 2006-09-05 20:31:05.000000000 +0200 -@@ -3,7 +3,7 @@ - peardir=$(PEAR_INSTALLDIR) - - # Skip all php.ini files altogether --PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -+PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar - - install-pear-installer: $(SAPI_CLI_PATH) - @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" -diff -Nura php-5.1.4/php.ini-dist hardening-patch-5.1.4-0.4.15/php.ini-dist ---- php-5.1.4/php.ini-dist 2006-02-09 00:43:48.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/php.ini-dist 2006-09-05 20:31:05.000000000 +0200 -@@ -1197,6 +1197,209 @@ - ; instead of original one. - soap.wsdl_cache_ttl=86400 - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-5.1.4/php.ini-recommended hardening-patch-5.1.4-0.4.15/php.ini-recommended ---- php-5.1.4/php.ini-recommended 2006-02-09 00:43:48.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/php.ini-recommended 2006-09-05 20:31:06.000000000 +0200 -@@ -1255,6 +1255,209 @@ - ; instead of original one. - soap.wsdl_cache_ttl=86400 - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-5.1.4/run-tests.php hardening-patch-5.1.4-0.4.15/run-tests.php ---- php-5.1.4/run-tests.php 2006-05-03 23:37:16.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/run-tests.php 2006-09-05 20:31:06.000000000 +0200 -@@ -161,6 +161,10 @@ - 'error_reporting=4095', - 'display_errors=1', - 'log_errors=0', -+ 'hphp.executor.include.whitelist=cookietest', -+ 'hphp.log.syslog=0', -+ 'hphp.log.sapi=0', -+ 'hphp.log.script=0', - 'html_errors=0', - 'track_errors=1', - 'report_memleaks=1', -diff -Nura php-5.1.4/sapi/apache/mod_php5.c hardening-patch-5.1.4-0.4.15/sapi/apache/mod_php5.c ---- php-5.1.4/sapi/apache/mod_php5.c 2006-04-02 19:58:17.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/sapi/apache/mod_php5.c 2006-09-05 20:31:06.000000000 +0200 -@@ -482,7 +482,7 @@ - sapi_apache_get_fd, - sapi_apache_force_http_10, - sapi_apache_get_target_uid, -- sapi_apache_get_target_gid -+ sapi_apache_get_target_gid, - }; - /* }}} */ - -@@ -936,7 +936,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component("PHP/" PHP_VERSION); -+#endif - } - } - #endif -diff -Nura php-5.1.4/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.4-0.4.15/sapi/apache2filter/sapi_apache2.c ---- php-5.1.4/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:31:06.000000000 +0200 -@@ -573,7 +573,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-5.1.4/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.4-0.4.15/sapi/apache2handler/sapi_apache2.c ---- php-5.1.4/sapi/apache2handler/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:31:06.000000000 +0200 -@@ -341,7 +341,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-5.1.4/sapi/cgi/cgi_main.c hardening-patch-5.1.4-0.4.15/sapi/cgi/cgi_main.c ---- php-5.1.4/sapi/cgi/cgi_main.c 2006-05-03 21:40:58.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:31:06.000000000 +0200 -@@ -1444,10 +1444,18 @@ - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - } -+#if HARDENING_PATCH - #if ZEND_DEBUG -- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -+ 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()); - #else -- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -+ 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()); -+#endif -+#else -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif - #endif - php_end_ob_buffers(1 TSRMLS_CC); - exit(0); -diff -Nura php-5.1.4/sapi/cli/php_cli.c hardening-patch-5.1.4-0.4.15/sapi/cli/php_cli.c ---- php-5.1.4/sapi/cli/php_cli.c 2006-02-21 22:15:13.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:31:06.000000000 +0200 -@@ -753,8 +753,14 @@ - goto err; - } - -+#if HARDENING_PATCH -+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", -+ PHP_VERSION, HARDENING_PATCH_VERSION, -+#else - php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", -- PHP_VERSION, sapi_module.name, __DATE__, __TIME__, -+ PHP_VERSION, -+#endif -+ sapi_module.name, __DATE__, __TIME__, - #if ZEND_DEBUG && defined(HAVE_GCOV) - "(DEBUG GCOV)", - #elif ZEND_DEBUG -diff -Nura php-5.1.4/TSRM/TSRM.h hardening-patch-5.1.4-0.4.15/TSRM/TSRM.h ---- php-5.1.4/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/TSRM/TSRM.h 2006-09-05 20:31:06.000000000 +0200 -@@ -33,6 +33,13 @@ - # define TSRM_API - #endif - -+#if HARDENING_PATCH -+# if HAVE_REALPATH -+# undef realpath -+# define realpath php_realpath -+# endif -+#endif -+ - /* Only compile multi-threading functions if we're in ZTS mode */ - #ifdef ZTS - -@@ -88,6 +95,7 @@ - - #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts - -+ - #ifdef __cplusplus - extern "C" { - #endif -diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.c ---- php-5.1.4/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:31:06.000000000 +0200 -@@ -163,6 +163,7 @@ - static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) - { - CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state); -+ cwd_globals->realpath_cache_disable = 0; - cwd_globals->realpath_cache_size = 0; - cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE; - cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL; -@@ -201,6 +202,176 @@ - return p; - } - -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved) -+{ -+ struct stat sb; -+ char *p, *q, *s; -+ size_t left_len, resolved_len; -+ unsigned symlinks; -+ int serrno, slen; -+ int is_dir = 1; -+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; -+ -+ serrno = errno; -+ symlinks = 0; -+ if (path[0] == '/') { -+ resolved[0] = '/'; -+ resolved[1] = '\0'; -+ if (path[1] == '\0') -+ return (resolved); -+ resolved_len = 1; -+ left_len = strlcpy(left, path + 1, sizeof(left)); -+ } else { -+ if (getcwd(resolved, PATH_MAX) == NULL) { -+ strlcpy(resolved, ".", PATH_MAX); -+ return (NULL); -+ } -+ resolved_len = strlen(resolved); -+ left_len = strlcpy(left, path, sizeof(left)); -+ } -+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ -+ /* -+ * Iterate over path components in `left'. -+ */ -+ while (left_len != 0) { -+ /* -+ * Extract the next path component and adjust `left' -+ * and its length. -+ */ -+ p = strchr(left, '/'); -+ s = p ? p : left + left_len; -+ if (s - left >= sizeof(next_token)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ memcpy(next_token, left, s - left); -+ next_token[s - left] = '\0'; -+ left_len -= s - left; -+ if (p != NULL) -+ memmove(left, s + 1, left_len + 1); -+ if (resolved[resolved_len - 1] != '/') { -+ if (resolved_len + 1 >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ resolved[resolved_len++] = '/'; -+ resolved[resolved_len] = '\0'; -+ } -+ if (next_token[0] == '\0') -+ continue; -+ else if (strcmp(next_token, ".") == 0) -+ continue; -+ else if (strcmp(next_token, "..") == 0) { -+ /* -+ * Strip the last path component except when we have -+ * single "/" -+ */ -+ if (!is_dir) { -+ errno = ENOENT; -+ return (NULL); -+ } -+ if (resolved_len > 1) { -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ continue; -+ } -+ -+ /* -+ * Append the next path component and lstat() it. If -+ * lstat() fails we still can return successfully if -+ * there are no more path components left. -+ */ -+ resolved_len = strlcat(resolved, next_token, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ if (lstat(resolved, &sb) != 0) { -+ if (errno == ENOENT) { -+ if (p == NULL) { -+ errno = serrno; -+ return (resolved); -+ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { -+ resolved_len = strlcat(resolved, "/", PATH_MAX); -+ resolved_len = strlcat(resolved, left, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ errno = serrno; -+ return (resolved); -+ } -+ } -+ return (NULL); -+ } -+ if (S_ISLNK(sb.st_mode)) { -+ if (symlinks++ > MAXSYMLINKS) { -+ errno = ELOOP; -+ return (NULL); -+ } -+ slen = readlink(resolved, symlink, sizeof(symlink) - 1); -+ if (slen < 0) -+ return (NULL); -+ symlink[slen] = '\0'; -+ if (symlink[0] == '/') { -+ resolved[1] = 0; -+ resolved_len = 1; -+ } else if (resolved_len > 1) { -+ /* Strip the last path component. */ -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ -+ /* -+ * If there are any path components left, then -+ * append them to symlink. The result is placed -+ * in `left'. -+ */ -+ if (p != NULL) { -+ if (symlink[slen - 1] != '/') { -+ if (slen + 1 >= sizeof(symlink)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ symlink[slen] = '/'; -+ symlink[slen + 1] = 0; -+ } -+ left_len = strlcat(symlink, left, sizeof(left)); -+ if (left_len >= sizeof(left)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ } -+ left_len = strlcpy(left, symlink, sizeof(left)); -+ } else { -+ if (S_ISDIR(sb.st_mode)) { -+ is_dir = 1; -+ } else { -+ is_dir = 0; -+ } -+ } -+ } -+ -+ /* -+ * Remove trailing slash except when the resolved pathname -+ * is a single "/". -+ */ -+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') -+ resolved[resolved_len - 1] = '\0'; -+ return (resolved); -+} -+#endif -+ - CWD_API void virtual_cwd_startup(void) - { - char cwd[MAXPATHLEN]; -@@ -381,22 +552,33 @@ - #endif - char orig_path[MAXPATHLEN]; - int orig_path_len = 0; -+ int use_realpath_cache = 1; - realpath_cache_bucket *bucket; - time_t t = 0; - TSRMLS_FETCH(); - - if (path_length == 0) - return (0); -- if (path_length >= MAXPATHLEN) -+ if (path_length >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return (1); -+ } -+ -+ /* Disable realpath cache if safe_mode or open_basedir are set */ -+ if (CWDG(realpath_cache_disable)) { -+ use_realpath_cache = 0; -+ } - -- if (use_realpath && CWDG(realpath_cache_size_limit)) { -+ if (use_realpath && use_realpath_cache) { - if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { - memcpy(orig_path, path, path_length+1); - orig_path_len = path_length; - } else { - orig_path_len = path_length + state->cwd_length + 1; - if (orig_path_len >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(orig_path, state->cwd, state->cwd_length); -@@ -414,6 +596,8 @@ - if (verify_path && verify_path(state)) { - CWD_STATE_FREE(state); - *state = old_state; -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } else { - CWD_STATE_FREE(&old_state); -@@ -431,8 +615,9 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - } else { /* Concat current directory with relative path and then run realpath() on it */ -@@ -441,6 +626,8 @@ - - ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); - if (!tmp) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(ptr, state->cwd, state->cwd_length); -@@ -451,6 +638,8 @@ - *ptr = '\0'; - if (strlen(tmp) >= MAXPATHLEN) { - free(tmp); -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - if (use_realpath) { -@@ -458,9 +647,10 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now - free(tmp); -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - free(tmp); -@@ -599,7 +789,7 @@ - #endif - free(free_path); - -- if (use_realpath && CWDG(realpath_cache_size_limit)) { -+ if (use_realpath && use_realpath_cache) { - realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); - } - -diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.h ---- php-5.1.4/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:31:06.000000000 +0200 -@@ -127,6 +127,22 @@ - - typedef int (*verify_path_func)(const cwd_state *); - -+#ifndef HAVE_STRLCPY -+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); -+#undef strlcpy -+#define strlcpy php_strlcpy -+#endif -+ -+#ifndef HAVE_STRLCAT -+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); -+#undef strlcat -+#define strlcat php_strlcat -+#endif -+ -+ -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved); -+#endif - CWD_API void virtual_cwd_startup(void); - CWD_API void virtual_cwd_shutdown(void); - CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); -@@ -199,6 +215,7 @@ - long realpath_cache_size_limit; - long realpath_cache_ttl; - realpath_cache_bucket *realpath_cache[1024]; -+ int realpath_cache_disable; - } virtual_cwd_globals; - - #ifdef ZTS -diff -Nura php-5.1.4/Zend/zend_alloc.c hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.c ---- php-5.1.4/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.c 2006-09-05 20:31:06.000000000 +0200 -@@ -64,6 +64,11 @@ - # define END_MAGIC_SIZE 0 - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+# define CANARY_SIZE sizeof(unsigned int) -+#else -+# define CANARY_SIZE 0 -+#endif - - # if MEMORY_LIMIT - # if ZEND_DEBUG -@@ -72,7 +77,15 @@ - #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) - # endif - --#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ -+#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ -+ if (file) { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ -+ } else { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ -+ } \ -+ exit(1); \ -+ } \ -+ AG(allocated_memory) += rs;\ - if (AG(memory_limit)pNext; \ - } else { \ -+ if (p != p->pLast->pNext) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pLast->pNext = p->pNext; \ - } \ - if (p->pNext) { \ -+ if (p != p->pNext->pLast) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pNext->pLast = p->pLast; \ - } - #else -@@ -127,7 +148,7 @@ - #endif - - #define DECLARE_CACHE_VARS() \ -- unsigned int real_size; \ -+ size_t real_size; \ - unsigned int cache_index - - #define REAL_SIZE(size) ((size+7) & ~0x7) -@@ -142,12 +163,22 @@ - - ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -- zend_mem_header *p; -+ zend_mem_header *p = NULL; - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { -+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); -+ exit(1); -+ } -+#endif - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - -+ if (size > INT_MAX || SIZE < size) { -+ goto emalloc_error; -+ } -+ - #if !ZEND_DISABLE_MEMORY_CACHE - if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { - p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; -@@ -164,6 +195,10 @@ - AG(cache_stats)[CACHE_INDEX][1]++; - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } else { -@@ -179,11 +214,13 @@ - AG(allocated_memory_peak) = AG(allocated_memory); - } - #endif -- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); - #if !ZEND_DISABLE_MEMORY_CACHE - } - #endif - -+emalloc_error: -+ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (!p) { -@@ -210,7 +247,10 @@ - # endif - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -- -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } -@@ -238,6 +278,10 @@ - } - } - -+ -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); -+#endif - zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset); - return 0; - } -@@ -270,9 +314,25 @@ - - ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); -+ -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+efree_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); -+ exit(1); -+ } -+ /* to catch double efree()s */ -+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); -+ p->canary = 0; -+#endif - - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { -@@ -313,23 +373,35 @@ - - ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -- void *p; -- int final_size = size*nmemb; -+ char *p; -+ size_t _size = nmemb * size; -+ -+ if (nmemb && (_size/nmemb!=size)) { -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); -+#endif -+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); -+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID -+ kill(getpid(), SIGSEGV); -+#else -+ exit(1); -+#endif -+ } - -- HANDLE_BLOCK_INTERRUPTIONS(); -- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -- if (!p) { -- HANDLE_UNBLOCK_INTERRUPTIONS(); -- return (void *) p; -+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -+ if (p) { -+ memset(p, 0, _size); - } -- memset(p, 0, final_size); -- HANDLE_UNBLOCK_INTERRUPTIONS(); -- return p; -+ -+ return ((void *)p); - } - - - ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p; - zend_mem_header *orig; - DECLARE_CACHE_VARS(); -@@ -341,6 +413,16 @@ - - p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+erealloc_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); -+ exit(1); -+ } -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - void *new_p; -@@ -357,6 +439,13 @@ - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - - HANDLE_BLOCK_INTERRUPTIONS(); -+ -+ if (size > INT_MAX || SIZE < size) { -+ REMOVE_POINTER_FROM_LIST(p); -+ p = NULL; -+ goto erealloc_error; -+ } -+ - #if MEMORY_LIMIT - CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); - if (AG(allocated_memory) > AG(allocated_memory_peak)) { -@@ -364,7 +453,8 @@ - } - #endif - REMOVE_POINTER_FROM_LIST(p); -- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); -+erealloc_error: - if (!p) { - if (!allow_failure) { - fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); -@@ -386,6 +476,9 @@ - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - - HANDLE_UNBLOCK_INTERRUPTIONS(); -@@ -460,6 +553,10 @@ - { - AG(head) = NULL; - -+#if HARDENING_PATCH_MM_PROTECT -+ HG(canary_1) = zend_canary(); -+ HG(canary_2) = zend_canary(); -+#endif - #if MEMORY_LIMIT - AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ - AG(allocated_memory) = 0; -diff -Nura php-5.1.4/Zend/zend_alloc.h hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.h ---- php-5.1.4/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.h 2006-09-05 20:31:06.000000000 +0200 -@@ -35,6 +35,9 @@ - #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL - - typedef struct _zend_mem_header { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary; -+#endif - #if ZEND_DEBUG - long magic; - char *filename; -diff -Nura php-5.1.4/Zend/zend_API.h hardening-patch-5.1.4-0.4.15/Zend/zend_API.h ---- php-5.1.4/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_API.h 2006-09-05 20:31:06.000000000 +0200 -@@ -47,6 +47,7 @@ - #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) - - #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 }, -+#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 }, - - #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0) - #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0) -diff -Nura php-5.1.4/Zend/zend_builtin_functions.c hardening-patch-5.1.4-0.4.15/Zend/zend_builtin_functions.c ---- php-5.1.4/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:31:06.000000000 +0200 -@@ -53,6 +53,9 @@ - static ZEND_FUNCTION(crash); - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+static ZEND_FUNCTION(heap_overflow); -+#endif - static ZEND_FUNCTION(get_included_files); - static ZEND_FUNCTION(is_subclass_of); - static ZEND_FUNCTION(is_a); -@@ -113,6 +116,9 @@ - ZEND_FE(crash, NULL) - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ ZEND_FE(heap_overflow, NULL) -+#endif - ZEND_FE(get_included_files, NULL) - ZEND_FALIAS(get_required_files, get_included_files, NULL) - ZEND_FE(is_subclass_of, NULL) -@@ -1103,6 +1109,19 @@ - - #endif /* ZEND_DEBUG */ - -+ -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ZEND_FUNCTION(heap_overflow) -+{ -+ char *nowhere = emalloc(10); -+ -+ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); -+ -+ efree(nowhere); -+} -+#endif -+ -+ - /* {{{ proto array get_included_files(void) - Returns an array with the file names that were include_once()'d */ - ZEND_FUNCTION(get_included_files) -diff -Nura php-5.1.4/Zend/zend.c hardening-patch-5.1.4-0.4.15/Zend/zend.c ---- php-5.1.4/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend.c 2006-09-05 20:31:06.000000000 +0200 -@@ -55,6 +55,12 @@ - ZEND_API void (*zend_unblock_interruptions)(void); - ZEND_API void (*zend_ticks_function)(int ticks); - ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); -+#if HARDENING_PATCH -+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); - ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); - -@@ -74,9 +80,391 @@ - return SUCCESS; - } - -+#if HARDENING_PATCH -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; -+ } else { -+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_facility) = LOG_USER; -+ } else { -+ EG(hphp_log_syslog_facility) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_priority) = LOG_ALERT; -+ } else { -+ EG(hphp_log_syslog_priority) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_sapi) -+{ -+ if (!new_value) { -+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; -+ } else { -+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_script) -+{ -+ if (!new_value) { -+ EG(hphp_log_script) = S_ALL & ~S_MEMORY; -+ } else { -+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) -+{ -+ if (EG(hphp_log_scriptname)) { -+ pefree(EG(hphp_log_scriptname),1); -+ } -+ EG(hphp_log_scriptname) = NULL; -+ if (new_value) { -+ EG(hphp_log_scriptname) = pestrdup(new_value,1); -+ } -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_whitelist_destroy: -+ if (HG(include_whitelist)) { -+ zend_hash_destroy(HG(include_whitelist)); -+ pefree(HG(include_whitelist),1); -+ } -+ HG(include_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_whitelist_destroy; -+ } -+ -+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_blacklist_destroy: -+ if (HG(include_blacklist)) { -+ zend_hash_destroy(HG(include_blacklist)); -+ pefree(HG(include_blacklist),1); -+ } -+ HG(include_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_blacklist_destroy; -+ } -+ -+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_whitelist_destroy: -+ if (HG(eval_whitelist)) { -+ zend_hash_destroy(HG(eval_whitelist)); -+ pefree(HG(eval_whitelist),1); -+ } -+ HG(eval_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_whitelist_destroy; -+ } -+ -+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_blacklist_destroy: -+ if (HG(eval_blacklist)) { -+ zend_hash_destroy(HG(eval_blacklist)); -+ pefree(HG(eval_blacklist), 1); -+ } -+ HG(eval_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_blacklist_destroy; -+ } -+ -+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_whitelist_destroy: -+ if (HG(func_whitelist)) { -+ zend_hash_destroy(HG(func_whitelist)); -+ pefree(HG(func_whitelist),1); -+ } -+ HG(func_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_whitelist_destroy; -+ } -+ -+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_blacklist_destroy: -+ if (HG(func_blacklist)) { -+ zend_hash_destroy(HG(func_blacklist)); -+ pefree(HG(func_blacklist),1); -+ } -+ HG(func_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_blacklist_destroy; -+ } -+ -+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+#endif - - ZEND_INI_BEGIN() - ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) -+#if HARDENING_PATCH -+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) -+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) -+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) -+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) -+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) -+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) -+ 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) -+ -+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) -+ -+ 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) -+ 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) -+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) -+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) -+#endif - STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals) - #ifdef ZEND_MULTIBYTE - STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) -@@ -501,9 +889,13 @@ - EG(user_error_handler) = NULL; - EG(user_exception_handler) = NULL; - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(in_autoload) = NULL; - EG(current_execute_data) = NULL; - EG(current_module) = NULL; -+#if HARDENING_PATCH -+ EG(hphp_log_scriptname) = NULL; -+#endif - } - - -@@ -574,6 +966,14 @@ - extern zend_scanner_globals language_scanner_globals; - #endif - -+ /* Set up Hardening-Patch utility functions first */ -+#if HARDENING_PATCH -+ zend_security_log = utility_functions->security_log_function; -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ zend_is_valid_include = utility_functions->is_valid_include; -+#endif -+ - #ifdef ZTS - ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); - #else -@@ -777,6 +1177,7 @@ - } - CG(unclean_shutdown) = 1; - CG(in_compilation) = EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(current_execute_data) = NULL; - longjmp(EG(bailout), FAILURE); - } -diff -Nura php-5.1.4/Zend/zend_canary.c hardening-patch-5.1.4-0.4.15/Zend/zend_canary.c ---- php-5.1.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_canary.c 2006-09-05 20:31:06.000000000 +0200 -@@ -0,0 +1,58 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ -+ -+#include "zend.h" -+ -+#include -+#include -+ -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+ZEND_API unsigned int zend_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.4/Zend/zend_compile.c hardening-patch-5.1.4-0.4.15/Zend/zend_compile.c ---- php-5.1.4/Zend/zend_compile.c 2006-05-02 17:49:26.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_compile.c 2006-09-05 20:31:06.000000000 +0200 -@@ -1093,6 +1093,13 @@ - op_array.prototype = NULL; - - op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array.created_by_eval = 1; -+ } else { -+ op_array.created_by_eval = 0; -+ } -+#endif - - if (is_method) { - char *short_class_name = CG(active_class_entry)->name; -diff -Nura php-5.1.4/Zend/zend_compile.h hardening-patch-5.1.4-0.4.15/Zend/zend_compile.h ---- php-5.1.4/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_compile.h 2006-09-05 20:31:06.000000000 +0200 -@@ -217,6 +217,9 @@ - zend_uint doc_comment_len; - - void *reserved[ZEND_MAX_RESERVED_RESOURCES]; -+#if HARDENING_PATCH -+ zend_bool created_by_eval; -+#endif - }; - - -@@ -295,6 +298,8 @@ - zval ***CVs; - zend_bool original_in_execution; - HashTable *symbol_table; -+ zend_uint original_in_code_type; -+ zend_uint execute_depth; - struct _zend_execute_data *prev_execute_data; - zval *old_error_reporting; - }; -@@ -617,6 +622,7 @@ - #define ZEND_OVERLOADED_FUNCTION 3 - #define ZEND_EVAL_CODE 4 - #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5 -+#define ZEND_SANDBOX_CODE 6 - - #define ZEND_INTERNAL_CLASS 1 - #define ZEND_USER_CLASS 2 -diff -Nura php-5.1.4/Zend/zend_constants.c hardening-patch-5.1.4-0.4.15/Zend/zend_constants.c ---- php-5.1.4/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_constants.c 2006-09-05 20:31:06.000000000 +0200 -@@ -109,6 +109,74 @@ - REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); - - REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); -+ -+ /* error levels */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); -+ /* facility: type of program logging the message */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NEWS -+ /* No LOG_NEWS on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ -+#endif -+#ifdef LOG_UUCP -+ /* No LOG_UUCP on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_CRON -+ /* apparently some systems don't have this one */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_AUTHPRIV -+ /* AIX doesn't have LOG_AUTHPRIV */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); -+#endif -+#if !defined(PHP_WIN32) && !defined(NETWARE) -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); -+#endif -+ /* options */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NOWAIT -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_PERROR -+ /* AIX doesn't have LOG_PERROR */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ -+#endif -+#endif - - /* true/false constants */ - { -diff -Nura php-5.1.4/Zend/zend_errors.h hardening-patch-5.1.4-0.4.15/Zend/zend_errors.h ---- php-5.1.4/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_errors.h 2006-09-05 20:31:06.000000000 +0200 -@@ -38,6 +38,19 @@ - #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) - #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) - -+#if HARDENING_PATCH -+#define S_MEMORY (1<<0L) -+#define S_VARS (1<<1L) -+#define S_FILES (1<<2L) -+#define S_INCLUDE (1<<3L) -+#define S_SQL (1<<4L) -+#define S_EXECUTOR (1<<5L) -+#define S_MAIL (1<<6L) -+#define S_MISC (1<<30L) -+#define S_INTERNAL (1<<29L) -+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) -+#endif -+ - #endif /* ZEND_ERRORS_H */ - - /* -diff -Nura php-5.1.4/Zend/zend_execute_API.c hardening-patch-5.1.4-0.4.15/Zend/zend_execute_API.c ---- php-5.1.4/Zend/zend_execute_API.c 2006-04-21 00:49:20.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:31:06.000000000 +0200 -@@ -142,6 +142,7 @@ - EG(class_table) = CG(class_table); - - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(in_autoload) = NULL; - EG(autoload_func) = NULL; - -@@ -784,6 +785,39 @@ - if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) { - EX(function_state).function = NULL; - } -+#if HARDENING_PATCH -+ else { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - efree(function_name_lc); - } - -@@ -1076,7 +1110,7 @@ - return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC); - } - --ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC) - { - zval pv; - zend_op_array *new_op_array; -@@ -1109,6 +1143,7 @@ - zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); - zend_op **original_opline_ptr = EG(opline_ptr); - -+ new_op_array->type = type; - EG(return_value_ptr_ptr) = &local_retval_ptr; - EG(active_op_array) = new_op_array; - EG(no_extensions)=1; -@@ -1143,6 +1178,12 @@ - } - - -+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+{ -+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); -+} -+ -+ - ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) - { - int result; -diff -Nura php-5.1.4/Zend/zend_execute.c hardening-patch-5.1.4-0.4.15/Zend/zend_execute.c ---- php-5.1.4/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_execute.c 2006-09-05 20:31:06.000000000 +0200 -@@ -1351,6 +1351,37 @@ - /* OBJ-TBI - doesn't support new object model! */ - zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - return 0; - } -@@ -1396,6 +1427,7 @@ - efree(EX(Ts)); \ - } \ - EG(in_execution) = EX(original_in_execution); \ -+ EG(in_code_type) = EX(original_in_code_type); \ - EG(current_execute_data) = EX(prev_execute_data); \ - ZEND_VM_RETURN() - -diff -Nura php-5.1.4/Zend/zend_extensions.c hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.c ---- php-5.1.4/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.c 2006-09-05 20:31:06.000000000 +0200 -@@ -55,23 +55,44 @@ - return FAILURE; - } - -+ /* check if module is compiled against Hardening-Patch */ -+ if (extension_version_info->zend_extension_api_no < 1000000000) { -+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } -+ -+ -+ /* check if module is compiled against correct Hardening-Patch version */ -+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { -+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ extension_version_info->zend_extension_api_no, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } - - /* allow extension to proclaim compatibility with any Zend version */ -- 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)) { -- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { -+ 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)) { -+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is outdated.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO); - DL_UNLOAD(handle); - return FAILURE; -- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { -+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is newer.\n" - "Contact %s at %s for a later version of %s.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO, - new_extension->author, - new_extension->URL, -diff -Nura php-5.1.4/Zend/zend_extensions.h hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.h ---- php-5.1.4/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.h 2006-09-05 20:31:06.000000000 +0200 -@@ -24,9 +24,11 @@ - - #include "zend_compile.h" - --/* The first number is the engine version and the rest is the date. -+/* The first API number is a flag saying that Hardening-Patch is used. -+ * The second number is the engine version and the date. - * This way engine 2 API no. is always greater than engine 1 API no.. - */ -+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106 - #define ZEND_EXTENSION_API_NO 220051025 - - typedef struct _zend_extension_version_info { -@@ -34,6 +36,7 @@ - char *required_zend_version; - unsigned char thread_safe; - unsigned char debug; -+ int real_zend_extension_api_no; - } zend_extension_version_info; - - -@@ -101,7 +104,7 @@ - - - #define ZEND_EXTENSION() \ -- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } -+ 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 } - - #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 - #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 -diff -Nura php-5.1.4/Zend/zend_globals.h hardening-patch-5.1.4-0.4.15/Zend/zend_globals.h ---- php-5.1.4/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_globals.h 2006-09-05 20:31:06.000000000 +0200 -@@ -180,6 +180,16 @@ - - int error_reporting; - int orig_error_reporting; -+#if HARDENING_PATCH -+ int hphp_log_syslog; -+ int hphp_log_syslog_facility; -+ int hphp_log_syslog_priority; -+ int hphp_log_sapi; -+ int hphp_log_script; -+ char *hphp_log_scriptname; -+ zend_bool hphp_log_use_x_forwarded_for; -+ long hphp_executor_max_depth; -+#endif - int exit_status; - - zend_op_array *active_op_array; -@@ -197,6 +207,7 @@ - int ticks_count; - - zend_bool in_execution; -+ zend_uint in_code_type; - HashTable *in_autoload; - zend_function *autoload_func; - zend_bool bailout_set; -diff -Nura php-5.1.4/Zend/zend.h hardening-patch-5.1.4-0.4.15/Zend/zend.h ---- php-5.1.4/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend.h 2006-09-05 20:31:06.000000000 +0200 -@@ -297,6 +297,7 @@ - /* Variable information */ - zvalue_value value; /* value */ - zend_uint refcount; -+ zend_ushort flags; - zend_uchar type; /* active type */ - zend_uchar is_ref; - }; -@@ -382,6 +383,12 @@ - int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); - int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); - char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); -+#if HARDENING_PATCH -+ void (*security_log_function)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ int (*is_valid_include)(zval *z); -+#endif - } zend_utility_functions; - - -@@ -519,7 +526,16 @@ - extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); - extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); - extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); -+#if HARDENING_PATCH -+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+extern ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ZEND_API unsigned int zend_canary(void); -+#endif - - ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); - -@@ -644,6 +660,11 @@ - - #include "zend_variables.h" - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#include "php_syslog.h" -+#endif -+ - #endif /* ZEND_H */ - - /* -diff -Nura php-5.1.4/Zend/zend_hash.c hardening-patch-5.1.4-0.4.15/Zend/zend_hash.c ---- php-5.1.4/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_hash.c 2006-09-05 20:31:06.000000000 +0200 -@@ -21,6 +21,18 @@ - - #include "zend.h" - -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int zend_hash_canary = 0x1234567; -+ zend_bool zend_hash_canary_inited = 0; -+#endif -+ -+#define CHECK_HASH_CANARY(hash) \ -+ if (zend_hash_canary != (hash)->canary) { \ -+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+ - #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ - (element)->pNext = (list_head); \ - (element)->pLast = NULL; \ -@@ -138,6 +150,9 @@ - { - uint i = 3; - Bucket **tmp; -+#if HARDENING_PATCH_HASH_PROTECT -+ TSRMLS_FETCH(); -+#endif - - SET_INCONSISTENT(HT_OK); - -@@ -147,6 +162,13 @@ - - ht->nTableSize = 1 << i; - ht->nTableMask = ht->nTableSize - 1; -+#if HARDENING_PATCH_HASH_PROTECT -+ if (zend_hash_canary_inited==0) { -+ zend_hash_canary = zend_canary(); -+ zend_hash_canary_inited = 1; -+ } -+ ht->canary = zend_hash_canary; -+#endif - ht->pDestructor = pDestructor; - ht->arBuckets = NULL; - ht->pListHead = NULL; -@@ -226,6 +248,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -291,6 +316,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -366,6 +394,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -414,7 +445,7 @@ - IS_CONSISTENT(ht); - - if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ -- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); -+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); - if (t) { - HANDLE_BLOCK_INTERRUPTIONS(); - ht->arBuckets = t; -@@ -424,6 +455,7 @@ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return SUCCESS; - } -+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); - return FAILURE; - } - return SUCCESS; -@@ -489,6 +521,9 @@ - ht->pInternalPointer = p->pListNext; - } - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (p->pData != &p->pDataPtr) { -@@ -513,6 +548,11 @@ - - SET_INCONSISTENT(HT_IS_DESTROYING); - -+#if HARDENING_PATCH_HASH_PROTECT -+ if (ht->pDestructor) { -+ CHECK_HASH_CANARY(ht); -+ } -+#endif - p = ht->pListHead; - while (p != NULL) { - q = p; -@@ -539,6 +579,11 @@ - - SET_INCONSISTENT(HT_CLEANING); - -+#if HARDENING_PATCH_HASH_PROTECT -+ if (ht->pDestructor) { -+ CHECK_HASH_CANARY(ht); -+ } -+#endif - p = ht->pListHead; - while (p != NULL) { - q = p; -@@ -573,6 +618,9 @@ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (p->pData != &p->pDataPtr) { -diff -Nura php-5.1.4/Zend/zend_hash.h hardening-patch-5.1.4-0.4.15/Zend/zend_hash.h ---- php-5.1.4/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_hash.h 2006-09-05 20:31:06.000000000 +0200 -@@ -58,6 +58,9 @@ - } Bucket; - - typedef struct _hashtable { -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int canary; -+#endif - uint nTableSize; - uint nTableMask; - uint nNumOfElements; -diff -Nura php-5.1.4/Zend/zend_ini.c hardening-patch-5.1.4-0.4.15/Zend/zend_ini.c ---- php-5.1.4/Zend/zend_ini.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:18.000000000 +0200 -@@ -256,7 +256,8 @@ - zend_ini_entry *ini_entry; - TSRMLS_FETCH(); - -- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { -+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || -+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) { - return FAILURE; - } - -diff -Nura php-5.1.4/Zend/zend_language_scanner.l hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.l ---- php-5.1.4/Zend/zend_language_scanner.l 2006-04-13 15:48:28.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:31:06.000000000 +0200 -@@ -389,6 +389,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-5.1.4/Zend/zend_language_scanner.c hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.c ---- php-5.1.4/Zend/zend_language_scanner.c 2006-05-12 16:41:13.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:31:06.000000000 +0200 -@@ -3075,6 +3075,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-5.1.4/Zend/zend_llist.c hardening-patch-5.1.4-0.4.15/Zend/zend_llist.c ---- php-5.1.4/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_llist.c 2006-09-05 20:31:06.000000000 +0200 -@@ -22,9 +22,49 @@ - #include "zend.h" - #include "zend_llist.h" - #include "zend_qsort.h" -+#include "zend_globals.h" -+ -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int zend_llist_canary_1 = 0x1234567; -+ unsigned int zend_llist_canary_2 = 0x1553425; -+ zend_bool zend_llist_canary_inited = 0; -+#endif -+ -+#define CHECK_LIST_CANARY(list) \ -+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ -+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ -+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+#define CHECK_LISTELEMENT_CANARY(elem, list) \ -+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ -+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ -+ exit(1); \ -+ } -+ - - ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ -+ if (persistent) { -+ if (!zend_llist_canary_inited) { -+ /* do not change order to ensure thread safety */ -+ zend_llist_canary_1 = zend_canary(); -+ zend_llist_canary_2 = zend_canary(); -+ zend_llist_canary_inited = 1; -+ } -+ } else -+ if (!HG(ll_canary_inited)) { -+ HG(canary_3) = zend_canary(); -+ HG(canary_4) = zend_canary(); -+ HG(ll_canary_inited) = 1; -+ } -+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); -+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); -+#endif - l->head = NULL; - l->tail = NULL; - l->count = 0; -@@ -38,6 +78,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->prev = l->tail; - tmp->next = NULL; - if (l->tail) { -@@ -56,6 +101,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->next = l->head; - tmp->prev = NULL; - if (l->head) { -@@ -93,10 +143,20 @@ - zend_llist_element *current=l->head; - zend_llist_element *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (compare(current->data, element)) { - DEL_LLIST_ELEMENT(current, l); -+#if HARDENING_PATCH_LL_PROTECT -+ current->canary = 0; -+#endif - break; - } - current = next; -@@ -108,7 +168,14 @@ - { - zend_llist_element *current=l->head, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (l->dtor) { - l->dtor(current->data); -@@ -133,7 +200,14 @@ - zend_llist_element *old_tail; - void *data; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if ((old_tail = l->tail)) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(old_tail, l) -+#endif - if (l->tail->prev) { - l->tail->prev->next = NULL; - } -@@ -159,9 +233,16 @@ - { - zend_llist_element *ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(src) -+#endif - zend_llist_init(dst, src->size, src->dtor, src->persistent); - ptr = src->head; - while (ptr) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(ptr, src) -+#endif - zend_llist_add_element(dst, ptr->data); - ptr = ptr->next; - } -@@ -172,11 +253,21 @@ - { - zend_llist_element *element, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - element=l->head; - while (element) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - next = element->next; - if (func(element->data)) { - DEL_LLIST_ELEMENT(element, l); -+#if HARDENING_PATCH_LL_PROTECT -+ element->canary = 0; -+#endif - } - element = next; - } -@@ -187,7 +278,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data TSRMLS_CC); - } - } -@@ -199,6 +296,9 @@ - zend_llist_element **elements; - zend_llist_element *element, **ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - if (l->count <= 0) { - return; - } -@@ -208,6 +308,9 @@ - ptr = &elements[0]; - - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - *ptr++ = element; - } - -@@ -230,7 +333,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, arg TSRMLS_CC); - } - } -@@ -241,8 +350,14 @@ - zend_llist_element *element; - va_list args; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - va_start(args, num_args); - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, num_args, args TSRMLS_CC); - } - va_end(args); -@@ -251,6 +366,10 @@ - - ZEND_API int zend_llist_count(zend_llist *l) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - return l->count; - } - -@@ -259,8 +378,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->head; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -272,8 +398,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->tail; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -285,9 +418,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->next; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -@@ -299,9 +442,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->prev; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -diff -Nura php-5.1.4/Zend/zend_llist.h hardening-patch-5.1.4-0.4.15/Zend/zend_llist.h ---- php-5.1.4/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_llist.h 2006-09-05 20:31:06.000000000 +0200 -@@ -23,6 +23,9 @@ - #define ZEND_LLIST_H - - typedef struct _zend_llist_element { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary, padding; -+#endif - struct _zend_llist_element *next; - struct _zend_llist_element *prev; - char data[1]; /* Needs to always be last in the struct */ -@@ -35,6 +38,9 @@ - typedef void (*llist_apply_func_t)(void * TSRMLS_DC); - - typedef struct _zend_llist { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_h; /* head */ -+#endif - zend_llist_element *head; - zend_llist_element *tail; - size_t count; -@@ -42,6 +48,9 @@ - llist_dtor_func_t dtor; - unsigned char persistent; - zend_llist_element *traverse_ptr; -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_t; /* tail */ -+#endif - } zend_llist; - - typedef zend_llist_element* zend_llist_position; -diff -Nura php-5.1.4/Zend/zend_modules.h hardening-patch-5.1.4-0.4.15/Zend/zend_modules.h ---- php-5.1.4/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_modules.h 2006-09-05 20:31:06.000000000 +0200 -@@ -39,6 +39,7 @@ - extern struct _zend_arg_info fifth_arg_force_ref[6]; - extern struct _zend_arg_info all_args_by_ref[1]; - -+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106 - #define ZEND_MODULE_API_NO 20050922 - #ifdef ZTS - #define USING_ZTS 1 -@@ -46,13 +47,13 @@ - #define USING_ZTS 0 - #endif - --#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS -+#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS - #define STANDARD_MODULE_HEADER \ - STANDARD_MODULE_HEADER_EX, NULL, NULL - #define ZE2_STANDARD_MODULE_HEADER \ - STANDARD_MODULE_HEADER_EX, ini_entries, NULL - --#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 -+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO - - #define STANDARD_MODULE_PROPERTIES \ - NULL, STANDARD_MODULE_PROPERTIES_EX -@@ -87,6 +88,7 @@ - unsigned char type; - void *handle; - int module_number; -+ unsigned int real_zend_api; - }; - - #define MODULE_DEP_REQUIRED 1 -diff -Nura php-5.1.4/Zend/zend_opcode.c hardening-patch-5.1.4-0.4.15/Zend/zend_opcode.c ---- php-5.1.4/Zend/zend_opcode.c 2006-04-10 14:26:53.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_opcode.c 2006-09-05 20:31:06.000000000 +0200 -@@ -98,6 +98,9 @@ - op_array->uses_this = 0; - - op_array->start_op = NULL; -+#if HARDENING_PATCH -+ op_array->created_by_eval = 0; -+#endif - - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); - } -diff -Nura php-5.1.4/Zend/zend_vm_def.h hardening-patch-5.1.4-0.4.15/Zend/zend_vm_def.h ---- php-5.1.4/Zend/zend_vm_def.h 2006-04-12 13:37:50.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_def.h 2006-09-05 20:31:06.000000000 +0200 -@@ -1769,6 +1769,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (OP2_TYPE != IS_CONST) { -@@ -1994,6 +2025,34 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+#endif -+ - EX(object) = NULL; - - FREE_OP1(); -@@ -2709,7 +2768,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -2734,6 +2798,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -diff -Nura php-5.1.4/Zend/zend_vm_execute.h hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.h ---- php-5.1.4/Zend/zend_vm_execute.h 2006-04-12 13:37:50.000000000 +0200 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.h 2006-09-05 20:31:07.000000000 +0200 -@@ -56,6 +56,16 @@ - EX(symbol_table) = EG(active_symbol_table); - EX(prev_execute_data) = EG(current_execute_data); - EG(current_execute_data) = &execute_data; -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif - - EG(in_execution) = 1; - if (op_array->start_op) { -@@ -81,6 +91,18 @@ - */ - EX(function_state).function_symbol_table = NULL; - #endif -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif - - while (1) { - #ifdef ZEND_WIN32 -@@ -724,6 +746,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_CONST != IS_CONST) { -@@ -925,6 +978,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_TMP_VAR != IS_CONST) { -@@ -1083,6 +1167,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_VAR != IS_CONST) { -@@ -1330,6 +1445,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_CV != IS_CONST) { -@@ -1635,6 +1781,34 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+#endif -+ - EX(object) = NULL; - - return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); -@@ -1914,7 +2088,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -1939,6 +2118,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -4345,7 +4529,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -4370,6 +4559,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -7358,7 +7552,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -7383,6 +7582,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -19470,7 +19674,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -19495,6 +19704,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -diff -Nura php-5.1.4/Zend/zend_vm_execute.skl hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.skl ---- php-5.1.4/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100 -+++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.skl 2006-09-05 20:31:07.000000000 +0200 -@@ -27,6 +27,16 @@ - EX(symbol_table) = EG(active_symbol_table); - EX(prev_execute_data) = EG(current_execute_data); - EG(current_execute_data) = &execute_data; -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif - - EG(in_execution) = 1; - if (op_array->start_op) { -@@ -52,6 +62,18 @@ - */ - EX(function_state).function_symbol_table = NULL; - #endif -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif - - while (1) { - {%ZEND_VM_CONTINUE_LABEL%} diff --git a/hardening-patch-5.1.5-0.4.15.patch b/hardening-patch-5.1.5-0.4.15.patch deleted file mode 100644 index ff15548..0000000 --- a/hardening-patch-5.1.5-0.4.15.patch +++ /dev/null @@ -1,8817 +0,0 @@ -diff -Nura php-5.1.5/Changelog.hphp hardening-patch-5.1.5-0.4.15/Changelog.hphp ---- php-5.1.5/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Changelog.hphp 2006-09-07 19:32:16.000000000 +0200 -@@ -0,0 +1,61 @@ -+Changelog of the Hardening-Patch -+-------------------------------- -+ -+0.4.15 - 07. September 2006 -+ -+ PHP4: -+ [+] Fix for potential DOS in handling of include blacklists -+ -+ PHP4+5: -+ [+] Backported a fix for open_basedir problems with insanse PHP scripts -+ [+] Added a fix for ini_restore() PHP security vulnerability -+ -+0.4.14 - 11. August 2006 -+ -+ PHP4: -+ [+] Remove unecessary call to AC_BROKEN_REALPATH -+ -+ PHP5: -+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant -+ -+ PHP4+5: -+ [+] Added a few PHP security fixes / see changelog.secfix for details -+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits -+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments -+ -+0.4.13 - 07. August 2006 -+ -+ PHP4+5: -+ [+] Added a fix for a compile problem on solaris due to missing strcasestr() -+ -+0.4.12 - 19. July 2006 -+ -+ PHP4: -+ [+] Added fixes from sf4 security patch / see changelog.secfix for details -+ -+ PHP5: -+ [+] Added fixes from sf5 security patch / see changelog.secfix for details -+ -+ PHP4+5: -+ [+] Added anti mail spam feature -+ [+] Speedup of zend_hash canary (clear/destroy) -+ [+] Added a fix for a DOS in the handling of URL blacklists -+ -+0.4.11 - 13. May 2006 -+ -+ PHP5: -+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache -+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 -+ -+ PHP4+5: -+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories -+ -+ -+0.4.10 - 11. May 2006 -+ -+ PHP4: -+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed -+ -+ PHP4+5: -+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir -+ -diff -Nura php-5.1.5/Changelog.secfix hardening-patch-5.1.5-0.4.15/Changelog.secfix ---- php-5.1.5/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Changelog.secfix 2006-09-05 20:31:22.000000000 +0200 -@@ -0,0 +1,40 @@ -+Changelog of PHP 5.1.4 Security Fixes -+ -+Release 6 - 11. August 2006 -+ -+ [+] Added IMAP open_basedir/safe_mode check -+ [+] Added a fix for previous ext/session fixes -+ [+] Added upstream fix to ext/socket -+ [+] Added sscanf() security fix -+ [+] Added fixes for handling of corrupt .gif files to gdlib -+ -+Release 5 - 13. July 2006 -+ -+ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode -+ -+Release 4 - 13. July 2006 -+ -+ [+] Added a recursive array printing fix to the phpinfo() XSS fix -+ [+] Added a fix for stat() on non existing files in safe_mode -+ -+Release 3 - 07. July 2006 -+ -+ [+] Added a fix for an integer overflow in str_repeat() -+ [+] Added a *working* wordwrap() fix -+ [+] Added code to make memory_limit work on 64bit systems -+ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability -+ [+] Added a fix for overlong tempfilename -+ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl -+ [+] Added a high characters fix to ext/wddx -+ -+Release 2 - 16. May 2006 -+ -+ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP -+ tarball got updated -+ -+Release 1 - 13. May 2006 -+ -+ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball -+ and is downloaded when make install is called (usually as root -> security risk) -+ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache -+ -diff -Nura php-5.1.5/configure hardening-patch-5.1.5-0.4.15/configure ---- php-5.1.5/configure 2006-08-15 14:55:40.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/configure 2006-09-05 20:31:22.000000000 +0200 -@@ -942,6 +942,16 @@ - ac_help="$ac_help - --with-libdir=NAME Look for libraries in .../NAME rather than .../lib" - ac_help="$ac_help -+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." -+ac_help="$ac_help -+ --disable-hardening-patch-ll-protect Disable the Linked List protection." -+ac_help="$ac_help -+ --disable-hardening-patch-inc-protect Disable include/require protection." -+ac_help="$ac_help -+ --disable-hardening-patch-fmt-protect Disable format string protection." -+ac_help="$ac_help -+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." -+ac_help="$ac_help - - SAPI modules: - " -@@ -1410,6 +1420,8 @@ - ac_help="$ac_help - --enable-wddx Enable WDDX support" - ac_help="$ac_help -+ --disable-varfilter Disable Hardening-Patch's variable filter" -+ac_help="$ac_help - --disable-xml Disable XML support" - ac_help="$ac_help - --with-libxml-dir=DIR XML: libxml2 install prefix" -@@ -3618,6 +3630,157 @@ - - - -+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. -+if test "${enable_hardening_patch_mm_protect+set}" = set; then -+ enableval="$enable_hardening_patch_mm_protect" -+ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. -+if test "${enable_hardening_patch_ll_protect+set}" = set; then -+ enableval="$enable_hardening_patch_ll_protect" -+ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. -+if test "${enable_hardening_patch_inc_protect+set}" = set; then -+ enableval="$enable_hardening_patch_inc_protect" -+ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. -+if test "${enable_hardening_patch_fmt_protect+set}" = set; then -+ enableval="$enable_hardening_patch_fmt_protect" -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. -+if test "${enable_hardening_patch_hash_protect+set}" = set; then -+ enableval="$enable_hardening_patch_hash_protect" -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+ -+fi -+ -+ -+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 -+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 -+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 -+echo "configure:2733: checking whether to protect include/require statements" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect PHP Format String functions" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 -+ -+ -+cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH 1 -+EOF -+ -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 0 -+EOF -+ -+fi - - - -@@ -18607,6 +18770,62 @@ - fi - - -+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 -+echo "configure:14928: checking whether realpath is broken" >&5 -+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then -+ echo $ac_n "(cached) $ac_c" 1>&6 -+else -+ -+ if test "$cross_compiling" = yes; then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -+then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ echo "configure: failed program was:" >&5 -+ cat conftest.$ac_ext >&5 -+ rm -fr conftest* -+ -+ ac_cv_broken_realpath=yes -+ -+fi -+rm -fr conftest* -+fi -+ -+ -+fi -+ -+echo "$ac_t""$ac_cv_broken_realpath" 1>&6 -+ if test "$ac_cv_broken_realpath" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 1 -+EOF -+ -+ else -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 0 -+EOF -+ -+ fi -+ -+ - echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 - echo "configure:18612: checking for declared timezone" >&5 - if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then -@@ -89422,7 +89641,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - cat >> confdefs.h <&6 -+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 -+# Check whether --enable-varfilter or --disable-varfilter was given. -+if test "${enable_varfilter+set}" = set; then -+ enableval="$enable_varfilter" -+ PHP_VARFILTER=$enableval -+else -+ -+ PHP_VARFILTER=yes -+ -+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then -+ PHP_VARFILTER=$PHP_ENABLE_ALL -+ fi -+ -+fi -+ -+ -+ -+ext_output="yes, shared" -+ext_shared=yes -+case $PHP_VARFILTER in -+shared,*) -+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` -+ ;; -+shared) -+ PHP_VARFILTER=yes -+ ;; -+no) -+ ext_output=no -+ ext_shared=no -+ ;; -+*) -+ ext_output=yes -+ ext_shared=no -+ ;; -+esac -+ -+ -+ -+echo "$ac_t""$ext_output" 1>&6 -+ -+ -+ -+ -+if test "$PHP_VARFILTER" != "no"; then -+ cat >> confdefs.h <<\EOF -+#define HAVE_VARFILTER 1 -+EOF -+ -+ -+ ext_builddir=ext/varfilter -+ ext_srcdir=$abs_srcdir/ext/varfilter -+ -+ ac_extra= -+ -+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then -+ -+ -+ -+ case ext/varfilter in -+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; -+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; -+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; -+ esac -+ -+ -+ -+ b_c_pre=$php_c_pre -+ b_cxx_pre=$php_cxx_pre -+ b_c_meta=$php_c_meta -+ b_cxx_meta=$php_cxx_meta -+ b_c_post=$php_c_post -+ b_cxx_post=$php_cxx_post -+ b_lo=$php_lo -+ -+ -+ old_IFS=$IFS -+ for ac_src in varfilter.c; do -+ -+ IFS=. -+ set $ac_src -+ ac_obj=$1 -+ IFS=$old_IFS -+ -+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" -+ -+ case $ac_src in -+ *.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" ;; -+ *.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" ;; -+ esac -+ -+ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 -@@ -112351,7 +112829,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_logos.c \ -- output.c ; do -+ output.c hardening_patch.c ; do - - IFS=. - set $ac_src -@@ -112596,7 +113074,7 @@ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ - zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ -- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do -+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do - - IFS=. - set $ac_src -diff -Nura php-5.1.5/configure.in hardening-patch-5.1.5-0.4.15/configure.in ---- php-5.1.5/configure.in 2006-08-15 15:14:47.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/configure.in 2006-09-05 20:31:22.000000000 +0200 -@@ -209,7 +209,7 @@ - - sinclude(Zend/Zend.m4) - sinclude(TSRM/tsrm.m4) -- -+sinclude(main/hardening_patch.m4) - - divert(2) - -@@ -1275,7 +1275,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_logos.c \ -- output.c ) -+ output.c hardening_patch.c ) - - PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ - plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c) -@@ -1302,7 +1302,7 @@ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ - zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ -- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c) -+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c ) - - if test -r "$abs_srcdir/Zend/zend_objects.c"; then - PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \ -diff -Nura php-5.1.5/ext/curl/interface.c hardening-patch-5.1.5-0.4.15/ext/curl/interface.c ---- php-5.1.5/ext/curl/interface.c 2006-08-10 19:16:35.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/curl/interface.c 2006-09-05 20:31:22.000000000 +0200 -@@ -172,6 +172,11 @@ - RETURN_FALSE; \ - } \ - \ -+ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ -+ RETURN_FALSE; \ -+ } \ -+ \ - if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ - (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ - ) { \ -diff -Nura php-5.1.5/ext/fbsql/php_fbsql.c hardening-patch-5.1.5-0.4.15/ext/fbsql/php_fbsql.c ---- php-5.1.5/ext/fbsql/php_fbsql.c 2006-08-14 20:40:20.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:31:23.000000000 +0200 -@@ -1949,8 +1949,24 @@ - } - else if (fbcmdErrorsFound(md)) - { -+#if HARDENING_PATCH -+ char* query_copy; -+ int i; -+#endif - FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); - char* emg = fbcemdAllErrorMessages(emd); -+#if HARDENING_PATCH -+ query_copy=estrdup(query_copy); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ free(emg); -+ fbcemdRelease(emd); -+ result = 0; -+ zend_bailout(); -+ } -+#endif - if (FB_SQL_G(generateWarnings)) - { - if (emg) -diff -Nura php-5.1.5/ext/imap/php_imap.c hardening-patch-5.1.5-0.4.15/ext/imap/php_imap.c ---- php-5.1.5/ext/imap/php_imap.c 2006-08-11 17:07:13.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/imap/php_imap.c 2006-09-05 20:31:23.000000000 +0200 -@@ -768,6 +768,13 @@ - RETURN_FALSE; - } - -+ /* local filename, need to perform open_basedir and safe_mode checks */ -+ if (Z_STRVAL_PP(mailbox)[0] != '{' && -+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || -+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { -+ RETURN_FALSE; -+ } -+ - IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); - IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); - -diff -Nura php-5.1.5/ext/mysql/php_mysql.c hardening-patch-5.1.5-0.4.15/ext/mysql/php_mysql.c ---- php-5.1.5/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:31:23.000000000 +0200 -@@ -1231,6 +1231,8 @@ - { - php_mysql_conn *mysql; - MYSQL_RES *mysql_result; -+ char *copy_query; -+ int i; - - ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); - -@@ -1281,6 +1283,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #else -@@ -1291,6 +1300,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #endif -diff -Nura php-5.1.5/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.5-0.4.15/ext/mysqli/mysqli_nonapi.c ---- php-5.1.5/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/mysqli/mysqli_nonapi.c 2006-09-05 20:31:23.000000000 +0200 -@@ -184,6 +184,17 @@ - if (mysql_real_query(mysql->mysql, query, query_len)) { - char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; - unsigned int s_errno; -+#if HARDENING_PATCH -+ char *query_copy = estrdup(query); -+ int i; -+ -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } -+#endif - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - - /* we have to save error information, cause -@@ -234,6 +245,17 @@ - MYSQLI_DISABLE_MQ; - - if (mysql_real_query(mysql->mysql, query, query_len)) { -+#if HARDENING_PATCH -+ char *query_copy = estrdup(query); -+ int i; -+ -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } -+#endif - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_FALSE; - } -diff -Nura php-5.1.5/ext/pgsql/pgsql.c hardening-patch-5.1.5-0.4.15/ext/pgsql/pgsql.c ---- php-5.1.5/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:31:23.000000000 +0200 -@@ -1152,10 +1152,28 @@ - case PGRES_EMPTY_QUERY: - case PGRES_BAD_RESPONSE: - case PGRES_NONFATAL_ERROR: -- case PGRES_FATAL_ERROR: -- PHP_PQ_ERROR("Query failed: %s", pgsql); -- PQclear(pgsql_result); -- RETURN_FALSE; -+ case PGRES_FATAL_ERROR: -+ { -+#if HARDENING_PATCH -+ int i; -+ char *query_copy; -+#endif -+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); -+ PQclear(pgsql_result); -+#if HARDENING_PATCH -+ query_copy = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ efree(msgbuf); -+ zend_bailout(); -+ } -+#endif -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); -+ efree(msgbuf); -+ RETURN_FALSE; -+ } - break; - case PGRES_COMMAND_OK: /* successful command that did not return rows */ - default: -diff -Nura php-5.1.5/ext/session/mod_files.c hardening-patch-5.1.5-0.4.15/ext/session/mod_files.c ---- php-5.1.5/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/session/mod_files.c 2006-09-05 20:31:23.000000000 +0200 -@@ -152,6 +152,7 @@ - - if (!ps_files_valid_key(key)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); -+ PS(invalid_session_id) = 1; - return; - } - if (!ps_files_path_create(buf, sizeof(buf), data, key)) -@@ -401,7 +402,12 @@ - ps_files_close(data); - - if (VCWD_UNLINK(buf) == -1) { -- return FAILURE; -+ /* This is a little safety check for instances when we are dealing with a regenerated session -+ * that was not yet written to disk -+ */ -+ if (!VCWD_ACCESS(buf, F_OK)) { -+ return FAILURE; -+ } - } - } - -@@ -422,6 +428,35 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(files) -+{ -+ char buf[MAXPATHLEN]; -+ int fd; -+ PS_FILES_DATA; -+ -+ if (!ps_files_valid_key(key)) { -+ return FAILURE; -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { -+ return FAILURE; -+ } -+ -+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, -+ data->filemode); -+ -+ if (fd != -1) { -+ close(fd); -+ return SUCCESS; -+ } -+ -+ return FAILURE; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-5.1.5/ext/session/mod_mm.c hardening-patch-5.1.5-0.4.15/ext/session/mod_mm.c ---- php-5.1.5/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/session/mod_mm.c 2006-09-05 20:31:23.000000000 +0200 -@@ -425,6 +425,42 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(mm) -+{ -+ PS_MM_DATA; -+ ps_sd *sd; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ } -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ mm_lock(data->mm, MM_LOCK_RD); -+ -+ sd = ps_sd_lookup(data, key, 0); -+ if (sd) { -+ mm_unlock(data->mm); -+ return SUCCESS; -+ } -+ -+ mm_unlock(data->mm); -+ -+ return FAILURE; -+} -+ - #endif - - /* -diff -Nura php-5.1.5/ext/session/mod_user.c hardening-patch-5.1.5-0.4.15/ext/session/mod_user.c ---- php-5.1.5/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/session/mod_user.c 2006-09-05 20:31:23.000000000 +0200 -@@ -23,7 +23,7 @@ - #include "mod_user.h" - - ps_module ps_mod_user = { -- PS_MOD(user) -+ PS_MOD_SID(user) - }; - - #define SESS_ZVAL_LONG(val, a) \ -@@ -174,6 +174,83 @@ - FINISH; - } - -+PS_CREATE_SID_FUNC(user) -+{ -+ int i; -+ char *val = NULL; -+ zval *retval; -+ ps_user *mdata = PS_GET_MOD_DATA(); -+ -+ if (!mdata) -+ return estrndup("", 0); -+ -+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { -+ return php_session_create_id(mod_data, newlen TSRMLS_CC); -+ } -+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); -+ -+ if (retval) { -+ if (Z_TYPE_P(retval) == IS_STRING) { -+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); -+ } else { -+ val = estrndup("", 0); -+ } -+ zval_ptr_dtor(&retval); -+ } else { -+ val = estrndup("", 0); -+ } -+ -+ return val; -+} -+ -+static int ps_user_valid_key(const char *key TSRMLS_DC) -+{ -+ size_t len; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ ret = FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ ret = FAILURE; -+ -+ return ret; -+} -+ -+PS_VALIDATE_SID_FUNC(user) -+{ -+ zval *args[1]; -+ STDVARS; -+ -+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { -+ return ps_user_valid_key(key TSRMLS_CC); -+ } -+ SESS_ZVAL_STRING(key, args[0]); -+ -+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); -+ -+ if (retval) { -+ convert_to_long(retval); -+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; -+ zval_ptr_dtor(&retval); -+ } -+ -+ return ret; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-5.1.5/ext/session/mod_user.h hardening-patch-5.1.5-0.4.15/ext/session/mod_user.h ---- php-5.1.5/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/session/mod_user.h 2006-09-05 20:31:23.000000000 +0200 -@@ -22,7 +22,7 @@ - #define MOD_USER_H - - typedef union { -- zval *names[6]; -+ zval *names[8]; - struct { - zval *ps_open; - zval *ps_close; -@@ -30,6 +30,8 @@ - zval *ps_write; - zval *ps_destroy; - zval *ps_gc; -+ zval *ps_create; -+ zval *ps_validate; - } name; - } ps_user; - -diff -Nura php-5.1.5/ext/session/php_session.h hardening-patch-5.1.5-0.4.15/ext/session/php_session.h ---- php-5.1.5/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/session/php_session.h 2006-09-05 20:31:23.000000000 +0200 -@@ -23,7 +23,7 @@ - - #include "ext/standard/php_var.h" - --#define PHP_SESSION_API 20020330 -+#define PHP_SESSION_API 20051121 - - #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC - #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC -@@ -32,6 +32,7 @@ - #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC - #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC - #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC -+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC - - /* default create id function */ - PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); -@@ -45,6 +46,7 @@ - int (*s_destroy)(PS_DESTROY_ARGS); - int (*s_gc)(PS_GC_ARGS); - char *(*s_create_sid)(PS_CREATE_SID_ARGS); -+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); - } ps_module; - - #define PS_GET_MOD_DATA() *mod_data -@@ -57,6 +59,7 @@ - #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) - #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) - #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) -+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) - - #define PS_FUNCS(x) \ - PS_OPEN_FUNC(x); \ -@@ -65,11 +68,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID_FUNC(x) - - #define PS_MOD(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, php_session_create_id -+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x - - /* SID enabled module handler definitions */ - #define PS_FUNCS_SID(x) \ -@@ -79,11 +83,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID(x) - - #define PS_MOD_SID(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, ps_create_sid_##x -+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x - - typedef enum { - php_session_disabled, -@@ -120,11 +125,13 @@ - zend_bool use_only_cookies; - zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ - zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ -+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ - - long hash_func; - long hash_bits_per_character; - int send_cookie; - int define_sid; -+ zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ - } php_ps_globals; - - typedef php_ps_globals zend_ps_globals; -diff -Nura php-5.1.5/ext/session/session.c hardening-patch-5.1.5-0.4.15/ext/session/session.c ---- php-5.1.5/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/session/session.c 2006-09-05 20:31:23.000000000 +0200 -@@ -166,6 +166,7 @@ - STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) -+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals) -@@ -280,9 +281,13 @@ - PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) - { - zval **sym_track = NULL; -- -- zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, -- (void *) &sym_track); -+ -+ IF_SESSION_VARS() { -+ zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, -+ (void *) &sym_track); -+ } else { -+ return; -+ } - - /* - * Set up a proper reference between $_SESSION["x"] and $x. -@@ -758,9 +763,23 @@ - return; - } - -+ /* If there is an ID, use session module to verify it */ -+ if (PS(id)) { -+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ efree(PS(id)); -+ PS(id) = NULL; -+ PS(send_cookie) = 1; -+ } -+ } -+ - /* If there is no ID, use session module to create one */ -- if (!PS(id)) -+ if (!PS(id)) { -+new_session: - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); -+ if (PS(use_cookies)) { -+ PS(send_cookie) = 1; -+ } -+ } - - /* Read data */ - /* Question: if you create a SID here, should you also try to read data? -@@ -769,9 +788,14 @@ - * session information - */ - php_session_track_init(TSRMLS_C); -+ PS(invalid_session_id) = 0; - if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) { - php_session_decode(val, vallen TSRMLS_CC); - efree(val); -+ } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */ -+ PS(invalid_session_id) = 0; -+ efree(PS(id)); -+ goto new_session; - } - } - -@@ -1377,22 +1401,29 @@ - } - /* }}} */ - --/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) -+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) - Sets user-level functions */ - PHP_FUNCTION(session_set_save_handler) - { -- zval **args[6]; -- int i; -+ zval **args[8]; -+ int i, numargs; - ps_user *mdata; - char *name; - -- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) -+ numargs = ZEND_NUM_ARGS(); -+ args[6] = NULL; -+ args[7] = NULL; -+ -+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) - WRONG_PARAM_COUNT; - - if (PS(session_status) != php_session_none) - RETURN_FALSE; - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ continue; -+ } - if (!zend_is_callable(*args[i], 0, &name)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); - efree(name); -@@ -1405,7 +1436,11 @@ - - mdata = emalloc(sizeof(*mdata)); - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ mdata->names[i] = NULL; -+ continue; -+ } - ZVAL_ADDREF(*args[i]); - mdata->names[i] = *args[i]; - } -@@ -1475,6 +1510,11 @@ - WRONG_PARAM_COUNT; - } - -+ if (SG(headers_sent)) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); -+ RETURN_FALSE; -+ } -+ - if (PS(session_status) == php_session_active) { - if (PS(id)) { - if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -@@ -1531,8 +1571,8 @@ - WRONG_PARAM_COUNT; - - if (ac == 1) { -- convert_to_long_ex(p_cache_expire); -- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); -+ convert_to_string_ex(p_cache_expire); -+ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - } - - RETVAL_LONG(old); -diff -Nura php-5.1.5/ext/session/tests/014.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/014.phpt ---- php-5.1.5/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:31:23.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.bug_compat_42=1 -diff -Nura php-5.1.5/ext/session/tests/015.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/015.phpt ---- php-5.1.5/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:31:23.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - arg_separator.output=& - session.name=PHPSESSID -diff -Nura php-5.1.5/ext/session/tests/018.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/018.phpt ---- php-5.1.5/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:31:23.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - session.name=PHPSESSID -diff -Nura php-5.1.5/ext/session/tests/019.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/019.phpt ---- php-5.1.5/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/session/tests/019.phpt 2006-09-05 20:31:23.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.serialize_handler=php -diff -Nura php-5.1.5/ext/session/tests/020.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/020.phpt ---- php-5.1.5/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:31:23.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - arg_separator.output=& -diff -Nura php-5.1.5/ext/session/tests/021.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/021.phpt ---- php-5.1.5/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:31:23.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" -diff -Nura php-5.1.5/ext/session/tests/bug38377.phpt hardening-patch-5.1.5-0.4.15/ext/session/tests/bug38377.phpt ---- php-5.1.5/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:31:23.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+bug #38377 (session_destroy() gives warning after session_regenerate_id()) -+--SKIPIF-- -+ -+--FILE-- -+ -+--EXPECT-- -+Done -diff -Nura php-5.1.5/ext/sockets/sockets.c hardening-patch-5.1.5-0.4.15/ext/sockets/sockets.c ---- php-5.1.5/ext/sockets/sockets.c 2006-04-07 16:04:36.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/sockets/sockets.c 2006-09-05 20:31:23.000000000 +0200 -@@ -533,6 +533,7 @@ - { - zval **element; - php_socket *php_sock; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -547,9 +548,10 @@ - if (php_sock->bsd_socket > *max_fd) { - *max_fd = php_sock->bsd_socket; - } -+ num++; - } - -- return 1; -+ return num ? 1 : 0; - } - - static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) -@@ -558,6 +560,7 @@ - zval **dest_element; - php_socket *php_sock; - HashTable *new_hash; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -575,6 +578,7 @@ - zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); - if (dest_element) zval_add_ref(dest_element); - } -+ num++; - } - - /* Destroy old array, add new one */ -@@ -584,7 +588,7 @@ - zend_hash_internal_pointer_reset(new_hash); - Z_ARRVAL_P(sock_array) = new_hash; - -- return 1; -+ return num ? 1 : 0; - } - - /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds, int tv_sec[, int tv_usec]) -diff -Nura php-5.1.5/ext/sqlite/sess_sqlite.c hardening-patch-5.1.5-0.4.15/ext/sqlite/sess_sqlite.c ---- php-5.1.5/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/sqlite/sess_sqlite.c 2006-09-05 20:31:23.000000000 +0200 -@@ -185,6 +185,76 @@ - return SQLITE_RETVAL(rv); - } - -+PS_VALIDATE_SID_FUNC(sqlite) -+{ -+ PS_SQLITE_DATA; -+ char *query; -+ const char *tail; -+ sqlite_vm *vm; -+ int colcount, result; -+ const char **rowdata, **colnames; -+ char *error; -+ size_t len; -+ const char *p; -+ char c; -+ int ret = FAILURE; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ return FAILURE; -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key); -+ if (query == NULL) { -+ /* no memory */ -+ return FAILURE; -+ } -+ -+ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error); -+ sqlite_freemem(error); -+ sqlite_freemem(query); -+ return FAILURE; -+ } -+ -+ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) { -+ case SQLITE_ROW: -+ if (rowdata[0] != NULL) { -+ ret = SUCCESS; -+ } -+ break; -+ default: -+ sqlite_freemem(error); -+ error = NULL; -+ } -+ -+ if (SQLITE_OK != sqlite_finalize(vm, &error)) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error); -+ sqlite_freemem(error); -+ error = NULL; -+ } -+ -+ sqlite_freemem(query); -+ -+ return ret; -+} -+ - #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */ - - /* -diff -Nura php-5.1.5/ext/sqlite/sqlite.c hardening-patch-5.1.5-0.4.15/ext/sqlite/sqlite.c ---- php-5.1.5/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/sqlite/sqlite.c 2006-09-05 20:31:23.000000000 +0200 -@@ -1530,6 +1530,19 @@ - db->last_err_code = ret; - - if (ret != SQLITE_OK) { -+#if HARDENING_PATCH -+ char *query_copy; -+ int i; -+ -+ query_copy = estrdup(sql); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ sqlite_freemem(errtext); -+ zend_bailout(); -+ } -+#endif - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext); - if (errmsg) { - ZVAL_STRING(errmsg, errtext, 1); -diff -Nura php-5.1.5/ext/standard/array.c hardening-patch-5.1.5-0.4.15/ext/standard/array.c ---- php-5.1.5/ext/standard/array.c 2006-06-03 20:59:55.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/array.c 2006-09-05 20:31:23.000000000 +0200 -@@ -1297,6 +1297,32 @@ - } - } - } -+ -+ if (var_name[0] == 'H') { -+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_FILES")==0)|| -+ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { -+ return 0; -+ } -+ } else if (var_name[0] == '_') { -+ if ((strcmp(var_name, "_COOKIE")==0)|| -+ (strcmp(var_name, "_ENV")==0)|| -+ (strcmp(var_name, "_FILES")==0)|| -+ (strcmp(var_name, "_GET")==0)|| -+ (strcmp(var_name, "_POST")==0)|| -+ (strcmp(var_name, "_REQUEST")==0)|| -+ (strcmp(var_name, "_SESSION")==0)|| -+ (strcmp(var_name, "_SERVER")==0)) { -+ return 0; -+ } -+ } else if (strcmp(var_name, "GLOBALS")==0) { -+ return 0; -+ } - - return 1; - } -diff -Nura php-5.1.5/ext/standard/basic_functions.c hardening-patch-5.1.5-0.4.15/ext/standard/basic_functions.c ---- php-5.1.5/ext/standard/basic_functions.c 2006-06-29 00:08:59.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:19:27.000000000 +0200 -@@ -151,12 +151,14 @@ - typedef struct _php_shutdown_function_entry { - zval **arguments; - int arg_count; -+ zend_bool created_by_eval; - } php_shutdown_function_entry; - - typedef struct _user_tick_function_entry { - zval **arguments; - int arg_count; - int calling; -+ zend_bool created_by_eval; - } user_tick_function_entry; - - /* some prototypes for local functions */ -@@ -188,6 +190,8 @@ - PHP_FE(get_html_translation_table, NULL) - PHP_FE(sha1, NULL) - PHP_FE(sha1_file, NULL) -+ PHP_FE(sha256, NULL) -+ PHP_FE(sha256_file, NULL) - PHP_NAMED_FE(md5,php_if_md5, NULL) - PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) - PHP_NAMED_FE(crc32,php_if_crc32, NULL) -@@ -632,7 +636,7 @@ - PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) - - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) -- PHP_FE(realpath, NULL) -+ PHP_STATIC_FE("realpath", zif_real_path, NULL) - #endif - - #ifdef HAVE_FNMATCH -@@ -2279,6 +2283,13 @@ - { - zval retval; - char *function_name = NULL; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (shutdown_function_entry->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { - php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); -@@ -2294,6 +2305,9 @@ - if (function_name) { - efree(function_name); - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - return 0; - } - -@@ -2301,6 +2315,13 @@ - { - zval retval; - zval *function = tick_fe->arguments[0]; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (tick_fe->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - /* Prevent reentrant calls to the same user ticks function */ - if (! tick_fe->calling) { -@@ -2332,6 +2353,9 @@ - - tick_fe->calling = 0; - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - } - - static void run_user_tick_functions(int tick_count) -@@ -2395,6 +2419,13 @@ - } - - shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ shutdown_function_entry.created_by_eval = 1; -+ } else { -+ shutdown_function_entry.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { - efree(shutdown_function_entry.arguments); -@@ -2722,6 +2753,15 @@ - - convert_to_string_ex(varname); - -+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ -+ if (PG(safe_mode)) { -+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || -+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || -+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { -+ RETURN_FALSE; -+ } -+ } -+ - zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); - } - /* }}} */ -@@ -2979,6 +3019,13 @@ - } - - tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ tick_fe.created_by_eval = 1; -+ } else { -+ tick_fe.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { - efree(tick_fe.arguments); -@@ -3282,6 +3329,35 @@ - new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); - } - -+ if (new_key[0] == 'H') { -+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_FILES")==0)|| -+ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (new_key[0] == '_') { -+ if ((strcmp(new_key, "_COOKIE")==0)|| -+ (strcmp(new_key, "_ENV")==0)|| -+ (strcmp(new_key, "_FILES")==0)|| -+ (strcmp(new_key, "_GET")==0)|| -+ (strcmp(new_key, "_POST")==0)|| -+ (strcmp(new_key, "_REQUEST")==0)|| -+ (strcmp(new_key, "_SESSION")==0)|| -+ (strcmp(new_key, "_SERVER")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (strcmp(new_key, "GLOBALS")==0) { -+ efree(new_key); -+ return 0; -+ } -+ - zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); - -diff -Nura php-5.1.5/ext/standard/config.m4 hardening-patch-5.1.5-0.4.15/ext/standard/config.m4 ---- php-5.1.5/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/config.m4 2006-09-05 20:31:23.000000000 +0200 -@@ -203,7 +203,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) - ]) -@@ -489,7 +489,7 @@ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ - var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ -- filters.c proc_open.c streamsfuncs.c http.c) -+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ) - - PHP_ADD_MAKEFILE_FRAGMENT - -diff -Nura php-5.1.5/ext/standard/config.w32 hardening-patch-5.1.5-0.4.15/ext/standard/config.w32 ---- php-5.1.5/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/config.w32 2006-09-05 20:31:23.000000000 +0200 -@@ -16,5 +16,5 @@ - url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ - php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ - user_filters.c uuencode.c filters.c proc_open.c \ -- streamsfuncs.c http.c", false /* never shared */); -+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */); - -diff -Nura php-5.1.5/ext/standard/crypt_blowfish.c hardening-patch-5.1.5-0.4.15/ext/standard/crypt_blowfish.c ---- php-5.1.5/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:31:23.000000000 +0200 -@@ -0,0 +1,748 @@ -+/* -+ * This code comes from John the Ripper password cracker, with reentrant -+ * and crypt(3) interfaces added, but optimizations specific to password -+ * cracking removed. -+ * -+ * Written by Solar Designer in 1998-2002 and -+ * placed in the public domain. -+ * -+ * There's absolutely no warranty. -+ * -+ * It is my intent that you should be able to use this on your system, -+ * as a part of a software package, or anywhere else to improve security, -+ * ensure compatibility, or for any other purpose. I would appreciate -+ * it if you give credit where it is due and keep your modifications in -+ * the public domain as well, but I don't require that in order to let -+ * you place this code and any modifications you make under a license -+ * of your choice. -+ * -+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) -+ * by Niels Provos , and uses some of his -+ * ideas. The password hashing algorithm was designed by David Mazieres -+ * . -+ * -+ * There's a paper on the algorithm that explains its design decisions: -+ * -+ * http://www.usenix.org/events/usenix99/provos.html -+ * -+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's -+ * Blowfish library (I can't be sure if I would think of something if I -+ * hadn't seen his code). -+ */ -+ -+#include -+ -+#include -+#ifndef __set_errno -+#define __set_errno(val) errno = (val) -+#endif -+ -+#undef __CONST -+#ifdef __GNUC__ -+#define __CONST __const -+#else -+#define __CONST -+#endif -+ -+#ifdef __i386__ -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#elif defined(__alpha__) || defined(__hppa__) -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#else -+#define BF_ASM 0 -+#define BF_SCALE 0 -+#endif -+ -+typedef unsigned int BF_word; -+ -+/* Number of Blowfish rounds, this is also hardcoded into a few places */ -+#define BF_N 16 -+ -+typedef BF_word BF_key[BF_N + 2]; -+ -+typedef struct { -+ BF_word S[4][0x100]; -+ BF_key P; -+} BF_ctx; -+ -+/* -+ * Magic IV for 64 Blowfish encryptions that we do at the end. -+ * The string is "OrpheanBeholderScryDoubt" on big-endian. -+ */ -+static BF_word BF_magic_w[6] = { -+ 0x4F727068, 0x65616E42, 0x65686F6C, -+ 0x64657253, 0x63727944, 0x6F756274 -+}; -+ -+/* -+ * P-box and S-box tables initialized with digits of Pi. -+ */ -+static BF_ctx BF_init_state = { -+ { -+ { -+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, -+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, -+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, -+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, -+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, -+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, -+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, -+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, -+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, -+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, -+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, -+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, -+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, -+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, -+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, -+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, -+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, -+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, -+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, -+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, -+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, -+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, -+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, -+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, -+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, -+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, -+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, -+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, -+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, -+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, -+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, -+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, -+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, -+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, -+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, -+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, -+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, -+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, -+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, -+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, -+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, -+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, -+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, -+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, -+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, -+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, -+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, -+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, -+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, -+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, -+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, -+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, -+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, -+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, -+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, -+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, -+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, -+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, -+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, -+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, -+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, -+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, -+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, -+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a -+ }, { -+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, -+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, -+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, -+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, -+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, -+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, -+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, -+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, -+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, -+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, -+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, -+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, -+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, -+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, -+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, -+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, -+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, -+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, -+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, -+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, -+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, -+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, -+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, -+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, -+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, -+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, -+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, -+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, -+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, -+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, -+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, -+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, -+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, -+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, -+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, -+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, -+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, -+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, -+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, -+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, -+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, -+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, -+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, -+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, -+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, -+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, -+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, -+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, -+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, -+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, -+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, -+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, -+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, -+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, -+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, -+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, -+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, -+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, -+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, -+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, -+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, -+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, -+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, -+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 -+ }, { -+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, -+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, -+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, -+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, -+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, -+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, -+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, -+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, -+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, -+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, -+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, -+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, -+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, -+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, -+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, -+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, -+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, -+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, -+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, -+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, -+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, -+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, -+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, -+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, -+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, -+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, -+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, -+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, -+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, -+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, -+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, -+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, -+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, -+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, -+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, -+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, -+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, -+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, -+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, -+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, -+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, -+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, -+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, -+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, -+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, -+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, -+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, -+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, -+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, -+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, -+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, -+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, -+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, -+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, -+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, -+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, -+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, -+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, -+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, -+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, -+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, -+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, -+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, -+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 -+ }, { -+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, -+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, -+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, -+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, -+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, -+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, -+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, -+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, -+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, -+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, -+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, -+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, -+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, -+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, -+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, -+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, -+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, -+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, -+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, -+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, -+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, -+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, -+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, -+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, -+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, -+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, -+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, -+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, -+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, -+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, -+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, -+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, -+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, -+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, -+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, -+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, -+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, -+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, -+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, -+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, -+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, -+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, -+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, -+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, -+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, -+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, -+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, -+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, -+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, -+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, -+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, -+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, -+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, -+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, -+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, -+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, -+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, -+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, -+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, -+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, -+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, -+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, -+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, -+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 -+ } -+ }, { -+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, -+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, -+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, -+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, -+ 0x9216d5d9, 0x8979fb1b -+ } -+}; -+ -+static unsigned char BF_itoa64[64 + 1] = -+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -+ -+static unsigned char BF_atoi64[0x60] = { -+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, -+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, -+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, -+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, -+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -+}; -+ -+/* -+ * This may be optimized out if built with function inlining and no BF_ASM. -+ */ -+static void clean(void *data, int size) -+{ -+#if BF_ASM -+ extern void _BF_clean(void *data); -+#endif -+ memset(data, 0, size); -+#if BF_ASM -+ _BF_clean(data); -+#endif -+} -+ -+#define BF_safe_atoi64(dst, src) \ -+{ \ -+ tmp = (unsigned char)(src); \ -+ if (tmp == '$') break; \ -+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ -+ tmp = BF_atoi64[tmp]; \ -+ if (tmp > 63) return -1; \ -+ (dst) = tmp; \ -+} -+ -+static int BF_decode(BF_word *dst, __CONST char *src, int size) -+{ -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned char *end = dptr + size; -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned int tmp, c1, c2, c3, c4; -+ -+ do { -+ BF_safe_atoi64(c1, *sptr++); -+ BF_safe_atoi64(c2, *sptr++); -+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c3, *sptr++); -+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c4, *sptr++); -+ *dptr++ = ((c3 & 0x03) << 6) | c4; -+ } while (dptr < end); -+ -+ while (dptr < end) -+ *dptr++ = 0; -+ -+ return 0; -+} -+ -+static void BF_encode(char *dst, __CONST BF_word *src, int size) -+{ -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned char *end = sptr + size; -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned int c1, c2; -+ -+ do { -+ c1 = *sptr++; -+ *dptr++ = BF_itoa64[c1 >> 2]; -+ c1 = (c1 & 0x03) << 4; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 4; -+ *dptr++ = BF_itoa64[c1]; -+ c1 = (c2 & 0x0f) << 2; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 6; -+ *dptr++ = BF_itoa64[c1]; -+ *dptr++ = BF_itoa64[c2 & 0x3f]; -+ } while (sptr < end); -+} -+ -+static void BF_swap(BF_word *x, int count) -+{ -+ static int endianness_check = 1; -+ char *is_little_endian = (char *)&endianness_check; -+ BF_word tmp; -+ -+ if (*is_little_endian) -+ do { -+ tmp = *x; -+ tmp = (tmp << 16) | (tmp >> 16); -+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); -+ } while (--count); -+} -+ -+#if BF_SCALE -+/* Architectures which can shift addresses left by 2 bits with no extra cost */ -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp2 = L >> 8; \ -+ tmp2 &= 0xFF; \ -+ tmp3 = L >> 16; \ -+ tmp3 &= 0xFF; \ -+ tmp4 = L >> 24; \ -+ tmp1 = data.ctx.S[3][tmp1]; \ -+ tmp2 = data.ctx.S[2][tmp2]; \ -+ tmp3 = data.ctx.S[1][tmp3]; \ -+ tmp3 += data.ctx.S[0][tmp4]; \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#else -+/* Architectures with no complicated addressing modes supported */ -+#define BF_INDEX(S, i) \ -+ (*((BF_word *)(((unsigned char *)S) + (i)))) -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp1 <<= 2; \ -+ tmp2 = L >> 6; \ -+ tmp2 &= 0x3FC; \ -+ tmp3 = L >> 14; \ -+ tmp3 &= 0x3FC; \ -+ tmp4 = L >> 22; \ -+ tmp4 &= 0x3FC; \ -+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ -+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ -+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ -+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#endif -+ -+/* -+ * Encrypt one block, BF_N is hardcoded here. -+ */ -+#define BF_ENCRYPT \ -+ L ^= data.ctx.P[0]; \ -+ BF_ROUND(L, R, 0); \ -+ BF_ROUND(R, L, 1); \ -+ BF_ROUND(L, R, 2); \ -+ BF_ROUND(R, L, 3); \ -+ BF_ROUND(L, R, 4); \ -+ BF_ROUND(R, L, 5); \ -+ BF_ROUND(L, R, 6); \ -+ BF_ROUND(R, L, 7); \ -+ BF_ROUND(L, R, 8); \ -+ BF_ROUND(R, L, 9); \ -+ BF_ROUND(L, R, 10); \ -+ BF_ROUND(R, L, 11); \ -+ BF_ROUND(L, R, 12); \ -+ BF_ROUND(R, L, 13); \ -+ BF_ROUND(L, R, 14); \ -+ BF_ROUND(R, L, 15); \ -+ tmp4 = R; \ -+ R = L; \ -+ L = tmp4 ^ data.ctx.P[BF_N + 1]; -+ -+#if BF_ASM -+#define BF_body() \ -+ _BF_body_r(&data.ctx); -+#else -+#define BF_body() \ -+ L = R = 0; \ -+ ptr = data.ctx.P; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.P[BF_N + 2]); \ -+\ -+ ptr = data.ctx.S[0]; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.S[3][0xFF]); -+#endif -+ -+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) -+{ -+ __CONST char *ptr = key; -+ int i, j; -+ BF_word tmp; -+ -+ for (i = 0; i < BF_N + 2; i++) { -+ tmp = 0; -+ for (j = 0; j < 4; j++) { -+ tmp <<= 8; -+ tmp |= *ptr; -+ -+ if (!*ptr) ptr = key; else ptr++; -+ } -+ -+ expanded[i] = tmp; -+ initial[i] = BF_init_state.P[i] ^ tmp; -+ } -+} -+ -+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, -+ char *output, int size) -+{ -+#if BF_ASM -+ extern void _BF_body_r(BF_ctx *ctx); -+#endif -+ struct { -+ BF_ctx ctx; -+ BF_key expanded_key; -+ union { -+ BF_word salt[4]; -+ BF_word output[6]; -+ } binary; -+ } data; -+ BF_word L, R; -+ BF_word tmp1, tmp2, tmp3, tmp4; -+ BF_word *ptr; -+ BF_word count; -+ int i; -+ -+ if (size < 7 + 22 + 31 + 1) { -+ __set_errno(ERANGE); -+ return NULL; -+ } -+ -+ if (setting[0] != '$' || -+ setting[1] != '2' || -+ setting[2] != 'a' || -+ setting[3] != '$' || -+ setting[4] < '0' || setting[4] > '3' || -+ setting[5] < '0' || setting[5] > '9' || -+ setting[6] != '$') { -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); -+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { -+ clean(data.binary.salt, sizeof(data.binary.salt)); -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ BF_swap(data.binary.salt, 4); -+ -+ BF_set_key(key, data.expanded_key, data.ctx.P); -+ -+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); -+ -+ L = R = 0; -+ for (i = 0; i < BF_N + 2; i += 2) { -+ L ^= data.binary.salt[i & 2]; -+ R ^= data.binary.salt[(i & 2) + 1]; -+ BF_ENCRYPT; -+ data.ctx.P[i] = L; -+ data.ctx.P[i + 1] = R; -+ } -+ -+ ptr = data.ctx.S[0]; -+ do { -+ ptr += 4; -+ L ^= data.binary.salt[(BF_N + 2) & 3]; -+ R ^= data.binary.salt[(BF_N + 3) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 4) = L; -+ *(ptr - 3) = R; -+ -+ L ^= data.binary.salt[(BF_N + 4) & 3]; -+ R ^= data.binary.salt[(BF_N + 5) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 2) = L; -+ *(ptr - 1) = R; -+ } while (ptr < &data.ctx.S[3][0xFF]); -+ -+ do { -+ data.ctx.P[0] ^= data.expanded_key[0]; -+ data.ctx.P[1] ^= data.expanded_key[1]; -+ data.ctx.P[2] ^= data.expanded_key[2]; -+ data.ctx.P[3] ^= data.expanded_key[3]; -+ data.ctx.P[4] ^= data.expanded_key[4]; -+ data.ctx.P[5] ^= data.expanded_key[5]; -+ data.ctx.P[6] ^= data.expanded_key[6]; -+ data.ctx.P[7] ^= data.expanded_key[7]; -+ data.ctx.P[8] ^= data.expanded_key[8]; -+ data.ctx.P[9] ^= data.expanded_key[9]; -+ data.ctx.P[10] ^= data.expanded_key[10]; -+ data.ctx.P[11] ^= data.expanded_key[11]; -+ data.ctx.P[12] ^= data.expanded_key[12]; -+ data.ctx.P[13] ^= data.expanded_key[13]; -+ data.ctx.P[14] ^= data.expanded_key[14]; -+ data.ctx.P[15] ^= data.expanded_key[15]; -+ data.ctx.P[16] ^= data.expanded_key[16]; -+ data.ctx.P[17] ^= data.expanded_key[17]; -+ -+ BF_body(); -+ -+ tmp1 = data.binary.salt[0]; -+ tmp2 = data.binary.salt[1]; -+ tmp3 = data.binary.salt[2]; -+ tmp4 = data.binary.salt[3]; -+ data.ctx.P[0] ^= tmp1; -+ data.ctx.P[1] ^= tmp2; -+ data.ctx.P[2] ^= tmp3; -+ data.ctx.P[3] ^= tmp4; -+ data.ctx.P[4] ^= tmp1; -+ data.ctx.P[5] ^= tmp2; -+ data.ctx.P[6] ^= tmp3; -+ data.ctx.P[7] ^= tmp4; -+ data.ctx.P[8] ^= tmp1; -+ data.ctx.P[9] ^= tmp2; -+ data.ctx.P[10] ^= tmp3; -+ data.ctx.P[11] ^= tmp4; -+ data.ctx.P[12] ^= tmp1; -+ data.ctx.P[13] ^= tmp2; -+ data.ctx.P[14] ^= tmp3; -+ data.ctx.P[15] ^= tmp4; -+ data.ctx.P[16] ^= tmp1; -+ data.ctx.P[17] ^= tmp2; -+ -+ BF_body(); -+ } while (--count); -+ -+ for (i = 0; i < 6; i += 2) { -+ L = BF_magic_w[i]; -+ R = BF_magic_w[i + 1]; -+ -+ count = 64; -+ do { -+ BF_ENCRYPT; -+ } while (--count); -+ -+ data.binary.output[i] = L; -+ data.binary.output[i + 1] = R; -+ } -+ -+ memcpy(output, setting, 7 + 22 - 1); -+ output[7 + 22 - 1] = BF_itoa64[(int) -+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; -+ -+/* This has to be bug-compatible with the original implementation, so -+ * only encode 23 of the 24 bytes. :-) */ -+ BF_swap(data.binary.output, 6); -+ BF_encode(&output[7 + 22], data.binary.output, 23); -+ output[7 + 22 + 31] = '\0'; -+ -+/* Overwrite the most obvious sensitive data we have on the stack. Note -+ * that this does not guarantee there's no sensitive data left on the -+ * stack and/or in registers; I'm not aware of portable code that does. */ -+ clean(&data, sizeof(data)); -+ -+ return output; -+} -+ -+char *_crypt_gensalt_blowfish_rn(unsigned long count, -+ __CONST char *input, int size, char *output, int output_size) -+{ -+ if (size < 16 || output_size < 7 + 22 + 1 || -+ (count && (count < 4 || count > 31))) { -+ if (output_size > 0) output[0] = '\0'; -+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); -+ return NULL; -+ } -+ -+ if (!count) count = 5; -+ -+ output[0] = '$'; -+ output[1] = '2'; -+ output[2] = 'a'; -+ output[3] = '$'; -+ output[4] = '0' + count / 10; -+ output[5] = '0' + count % 10; -+ output[6] = '$'; -+ -+ BF_encode(&output[7], (BF_word *)input, 16); -+ output[7 + 22] = '\0'; -+ -+ return output; -+} -diff -Nura php-5.1.5/ext/standard/crypt.c hardening-patch-5.1.5-0.4.15/ext/standard/crypt.c ---- php-5.1.5/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/crypt.c 2006-09-05 20:31:23.000000000 +0200 -@@ -100,6 +100,8 @@ - return SUCCESS; - } - -+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); -+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); - - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -@@ -135,7 +137,14 @@ - - /* The automatic salt generation only covers standard DES and md5-crypt */ - if(!*salt) { --#if PHP_MD5_CRYPT -+#if PHP_BLOWFISH_CRYPT -+ char randat[16]; -+ int i; -+ -+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; -+ -+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); -+#elif PHP_MD5_CRYPT - strcpy(salt, "$1$"); - php_to64(&salt[3], PHP_CRYPT_RAND, 4); - php_to64(&salt[7], PHP_CRYPT_RAND, 4); -@@ -145,8 +154,24 @@ - salt[2] = '\0'; - #endif - } -- -- RETVAL_STRING(crypt(str, salt), 1); -+ -+ if (salt[0] == '$' && -+ salt[1] == '2' && -+ salt[2] == 'a' && -+ salt[3] == '$' && -+ salt[4] >= '0' && salt[4] <= '3' && -+ salt[5] >= '0' && salt[5] <= '9' && -+ salt[6] == '$') { -+ -+ char output[PHP_MAX_SALT_LEN+1]; -+ -+ output[0] = 0; -+ _crypt_blowfish_rn(str, salt, output, sizeof(output)); -+ RETVAL_STRING(output, 1); -+ -+ } else { -+ RETVAL_STRING(crypt(str, salt), 1); -+ } - } - /* }}} */ - #endif -diff -Nura php-5.1.5/ext/standard/dl.c hardening-patch-5.1.5-0.4.15/ext/standard/dl.c ---- php-5.1.5/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/dl.c 2006-09-05 20:31:23.000000000 +0200 -@@ -164,8 +164,35 @@ - RETURN_FALSE; - } - module_entry = get_module(); -+ -+ /* check if Hardening-Patch is installed */ -+ if (module_entry->zend_api < 1000000000) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ -+ /* check if correct Hardening-Patch is installed */ -+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ - if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) -- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { -+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { - /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ - struct pre_4_1_0_module_entry { - char *name; -@@ -199,7 +226,7 @@ - zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; - } else { - name = module_entry->name; -- zend_api = module_entry->zend_api; -+ zend_api = module_entry->real_zend_api; - zend_debug = module_entry->zend_debug; - zts = module_entry->zts; - } -diff -Nura php-5.1.5/ext/standard/file.c hardening-patch-5.1.5-0.4.15/ext/standard/file.c ---- php-5.1.5/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/file.c 2006-09-05 20:31:23.000000000 +0200 -@@ -2302,7 +2302,7 @@ - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) - /* {{{ proto string realpath(string path) - Return the resolved path */ --PHP_FUNCTION(realpath) -+PHP_FUNCTION(real_path) - { - zval **path; - char resolved_path_buff[MAXPATHLEN]; -diff -Nura php-5.1.5/ext/standard/file.h hardening-patch-5.1.5-0.4.15/ext/standard/file.h ---- php-5.1.5/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/file.h 2006-09-05 20:31:23.000000000 +0200 -@@ -61,7 +61,7 @@ - PHP_FUNCTION(fd_set); - PHP_FUNCTION(fd_isset); - #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) --PHP_FUNCTION(realpath); -+PHP_FUNCTION(real_path); - PHP_FUNCTION(fnmatch); - #endif - PHP_NAMED_FUNCTION(php_if_ftruncate); -diff -Nura php-5.1.5/ext/standard/head.c hardening-patch-5.1.5-0.4.15/ext/standard/head.c ---- php-5.1.5/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/head.c 2006-09-05 20:31:23.000000000 +0200 -@@ -45,7 +45,7 @@ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, - &ctr.line_len, &rep, &ctr.response_code) == FAILURE) - return; -- -+ - sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); - } - /* }}} */ -diff -Nura php-5.1.5/ext/standard/info.c hardening-patch-5.1.5-0.4.15/ext/standard/info.c ---- php-5.1.5/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/info.c 2006-09-05 20:31:23.000000000 +0200 -@@ -154,7 +154,7 @@ - if (Z_TYPE_PP(tmp) == IS_ARRAY) { - if (!sapi_module.phpinfo_as_text) { - PUTS("
");
--					zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
-+					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
- 					PUTS("
"); - } else { - zend_print_zval_r(*tmp, 0 TSRMLS_CC); -@@ -411,7 +411,7 @@ - - if (flag & PHP_INFO_GENERAL) { - char *zend_version = get_zend_version(); -- char temp_api[10]; -+ char temp_api[11]; - char *logo_guid; - - php_uname = php_get_uname('a'); -@@ -434,11 +434,22 @@ - PUTS("\" alt=\"PHP Logo\" />"); - } - -+#if HARDENING_PATCH -+ if (!sapi_module.phpinfo_as_text) { -+ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); -+ } else { -+ char temp_ver[40]; -+ -+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); -+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); -+ } -+#else - if (!sapi_module.phpinfo_as_text) { - php_printf("

PHP Version %s

\n", PHP_VERSION); - } else { - php_info_print_table_row(2, "PHP Version", PHP_VERSION); -- } -+ } -+#endif - php_info_print_box_end(); - php_info_print_table_start(); - php_info_print_table_row(2, "System", php_uname ); -diff -Nura php-5.1.5/ext/standard/mail.c hardening-patch-5.1.5-0.4.15/ext/standard/mail.c ---- php-5.1.5/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/mail.c 2006-09-05 20:31:23.000000000 +0200 -@@ -78,6 +78,25 @@ - } - /* }}} */ - -+/* {{{ hphp_strcasestr */ -+char *hphp_strcasestr(char *haystack, char *needle) -+{ -+ unsigned char *t, *h, *n; -+ -+ h = (unsigned char *) haystack; -+conts: -+ while (*h) { -+ n = (unsigned char *) needle; -+ for (t=h++; *n && *h; t++, n++) { -+ if (toupper(*t) != toupper(*n)) goto conts; -+ } -+ return ((char*)h-1); -+ } -+ -+ return (NULL); -+} -+/* }}} */ -+ - /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) - Send an email message */ - PHP_FUNCTION(mail) -@@ -104,6 +123,44 @@ - return; - } - -+ if (HG(hphp_mailprotect) > 0) { -+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { -+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ /* check for spam attempts with buggy webforms */ -+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (HG(hphp_mailprotect) > 1) { -+ /* search for to, cc or bcc headers */ -+ if (headers_len > 0 && headers != NULL) { -+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { -+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { -+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { -+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ } -+ } -+ } -+ - if (to_len > 0) { - to_r = estrndup(to, to_len); - for (; to_len; to_len--) { -diff -Nura php-5.1.5/ext/standard/php_standard.h hardening-patch-5.1.5-0.4.15/ext/standard/php_standard.h ---- php-5.1.5/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/php_standard.h 2006-09-05 20:31:23.000000000 +0200 -@@ -28,6 +28,7 @@ - #include "php_mail.h" - #include "md5.h" - #include "sha1.h" -+#include "sha256.h" - #include "html.h" - #include "exec.h" - #include "file.h" -diff -Nura php-5.1.5/ext/standard/sha256.c hardening-patch-5.1.5-0.4.15/ext/standard/sha256.c ---- php-5.1.5/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/sha256.c 2006-09-05 20:31:23.000000000 +0200 -@@ -0,0 +1,388 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ -+ -+#include "php.h" -+ -+/* This code is heavily based on the PHP md5/sha1 implementations */ -+ -+#include "sha256.h" -+ -+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ sprintf(sha256str, "%02x", digest[i]); -+ sha256str += 2; -+ } -+ -+ *sha256str = '\0'; -+} -+ -+/* {{{ proto string sha256(string str [, bool raw_output]) -+ Calculate the sha256 hash of a string */ -+PHP_FUNCTION(sha256) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ PHP_SHA256_CTX context; -+ unsigned char digest[32]; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ sha256str[0] = '\0'; -+ PHP_SHA256Init(&context); -+ PHP_SHA256Update(&context, arg, arg_len); -+ PHP_SHA256Final(digest, &context); -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+ -+} -+ -+/* }}} */ -+ -+/* {{{ proto string sha256_file(string filename [, bool raw_output]) -+ Calculate the sha256 hash of given filename */ -+PHP_FUNCTION(sha256_file) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ unsigned char buf[1024]; -+ unsigned char digest[32]; -+ PHP_SHA256_CTX context; -+ int n; -+ php_stream *stream; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); -+ if (!stream) { -+ RETURN_FALSE; -+ } -+ -+ PHP_SHA256Init(&context); -+ -+ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { -+ PHP_SHA256Update(&context, buf, n); -+ } -+ -+ PHP_SHA256Final(digest, &context); -+ -+ php_stream_close(stream); -+ -+ if (n<0) { -+ RETURN_FALSE; -+ } -+ -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+} -+/* }}} */ -+ -+ -+static void SHA256Transform(php_uint32[8], const unsigned char[64]); -+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); -+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); -+ -+static unsigned char PADDING[64] = -+{ -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* F, G, H and I are basic SHA256 functions. -+ */ -+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) -+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) -+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) -+#define I(x, y, z) (((x) & (y)) | ((~x) & z)) -+ -+/* ROTATE_RIGHT rotates x right n bits. -+ */ -+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) -+ -+/* W[i] -+ */ -+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ -+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ -+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) -+ -+/* ROUND function of sha256 -+ */ -+ -+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ -+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ -+ (h) = F((a)) + G((a), (b), (c)) + t1; \ -+ (d) += t1; \ -+ } -+ -+ -+/* {{{ PHP_SHA256Init -+ * SHA256 initialization. Begins an SHA256 operation, writing a new context. -+ */ -+static void PHP_SHA256Init(PHP_SHA256_CTX * context) -+{ -+ context->count[0] = context->count[1] = 0; -+ /* Load magic initialization constants. -+ */ -+ context->state[0] = 0x6a09e667; -+ context->state[1] = 0xbb67ae85; -+ context->state[2] = 0x3c6ef372; -+ context->state[3] = 0xa54ff53a; -+ context->state[4] = 0x510e527f; -+ context->state[5] = 0x9b05688c; -+ context->state[6] = 0x1f83d9ab; -+ context->state[7] = 0x5be0cd19; -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Update -+ SHA256 block update operation. Continues an SHA256 message-digest -+ operation, processing another message block, and updating the -+ context. -+ */ -+static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, -+ unsigned int inputLen) -+{ -+ unsigned int i, index, partLen; -+ -+ /* Compute number of bytes mod 64 */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); -+ -+ /* Update number of bits */ -+ if ((context->count[0] += ((php_uint32) inputLen << 3)) -+ < ((php_uint32) inputLen << 3)) -+ context->count[1]++; -+ context->count[1] += ((php_uint32) inputLen >> 29); -+ -+ partLen = 64 - index; -+ -+ /* Transform as many times as possible. -+ */ -+ if (inputLen >= partLen) { -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); -+ SHA256Transform(context->state, context->buffer); -+ -+ for (i = partLen; i + 63 < inputLen; i += 64) -+ SHA256Transform(context->state, &input[i]); -+ -+ index = 0; -+ } else -+ i = 0; -+ -+ /* Buffer remaining input */ -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], -+ inputLen - i); -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Final -+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the -+ the message digest and zeroizing the context. -+ */ -+static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) -+{ -+ unsigned char bits[8]; -+ unsigned int index, padLen; -+ -+ /* Save number of bits */ -+ bits[7] = context->count[0] & 0xFF; -+ bits[6] = (context->count[0] >> 8) & 0xFF; -+ bits[5] = (context->count[0] >> 16) & 0xFF; -+ bits[4] = (context->count[0] >> 24) & 0xFF; -+ bits[3] = context->count[1] & 0xFF; -+ bits[2] = (context->count[1] >> 8) & 0xFF; -+ bits[1] = (context->count[1] >> 16) & 0xFF; -+ bits[0] = (context->count[1] >> 24) & 0xFF; -+ -+ /* Pad out to 56 mod 64. -+ */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); -+ padLen = (index < 56) ? (56 - index) : (120 - index); -+ PHP_SHA256Update(context, PADDING, padLen); -+ -+ /* Append length (before padding) */ -+ PHP_SHA256Update(context, bits, 8); -+ -+ /* Store state in digest */ -+ SHA256Encode(digest, context->state, 32); -+ -+ /* Zeroize sensitive information. -+ */ -+ memset((unsigned char*) context, 0, sizeof(*context)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Transform -+ * SHA256 basic transformation. Transforms state based on block. -+ */ -+static void SHA256Transform(state, block) -+php_uint32 state[8]; -+const unsigned char block[64]; -+{ -+ php_uint32 a = state[0], b = state[1], c = state[2]; -+ php_uint32 d = state[3], e = state[4], f = state[5]; -+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; -+ -+ SHA256Decode(x, block, 64); -+ -+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) -+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) -+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) -+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) -+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) -+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) -+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) -+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) -+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) -+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) -+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) -+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) -+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) -+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) -+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) -+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) -+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) -+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) -+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) -+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) -+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) -+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) -+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) -+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) -+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) -+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) -+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) -+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) -+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) -+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) -+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) -+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) -+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) -+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) -+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) -+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) -+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) -+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) -+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) -+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) -+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) -+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) -+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) -+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) -+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) -+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) -+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) -+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) -+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) -+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) -+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) -+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) -+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) -+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) -+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) -+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) -+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) -+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) -+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) -+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) -+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) -+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) -+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) -+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) -+ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ state[4] += e; -+ state[5] += f; -+ state[6] += g; -+ state[7] += h; -+ -+ /* Zeroize sensitive information. */ -+ memset((unsigned char*) x, 0, sizeof(x)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Encode -+ Encodes input (php_uint32) into output (unsigned char). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Encode(output, input, len) -+unsigned char *output; -+php_uint32 *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) { -+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); -+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); -+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); -+ output[j + 3] = (unsigned char) (input[i] & 0xff); -+ } -+} -+/* }}} */ -+ -+/* {{{ SHA256Decode -+ Decodes input (unsigned char) into output (php_uint32). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Decode(output, input, len) -+php_uint32 *output; -+const unsigned char *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) -+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | -+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.5/ext/standard/sha256.h hardening-patch-5.1.5-0.4.15/ext/standard/sha256.h ---- php-5.1.5/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/sha256.h 2006-09-05 20:31:23.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ -+ -+#ifndef SHA256_H -+#define SHA256_H -+ -+#include "ext/standard/basic_functions.h" -+ -+/* SHA1 context. */ -+typedef struct { -+ php_uint32 state[8]; /* state (ABCD) */ -+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ -+ unsigned char buffer[64]; /* input buffer */ -+} PHP_SHA256_CTX; -+ -+static void PHP_SHA256Init(PHP_SHA256_CTX *); -+static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); -+static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); -+ -+PHP_FUNCTION(sha256); -+PHP_FUNCTION(sha256_file); -+ -+#endif -diff -Nura php-5.1.5/ext/standard/syslog.c hardening-patch-5.1.5-0.4.15/ext/standard/syslog.c ---- php-5.1.5/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/standard/syslog.c 2006-09-05 20:31:23.000000000 +0200 -@@ -42,6 +42,7 @@ - */ - PHP_MINIT_FUNCTION(syslog) - { -+#if !HARDENING_PATCH - /* error levels */ - REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ - REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -@@ -97,6 +98,7 @@ - /* AIX doesn't have LOG_PERROR */ - REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ - #endif -+#endif - BG(syslog_device)=NULL; - - return SUCCESS; -diff -Nura php-5.1.5/ext/varfilter/config.m4 hardening-patch-5.1.5-0.4.15/ext/varfilter/config.m4 ---- php-5.1.5/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/varfilter/config.m4 2006-09-05 20:31:23.000000000 +0200 -@@ -0,0 +1,11 @@ -+dnl -+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+dnl -+ -+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, -+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) -+ -+if test "$PHP_VARFILTER" != "no"; then -+ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) -+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) -+fi -diff -Nura php-5.1.5/ext/varfilter/CREDITS hardening-patch-5.1.5-0.4.15/ext/varfilter/CREDITS ---- php-5.1.5/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:31:23.000000000 +0200 -@@ -0,0 +1,2 @@ -+varfilter -+Stefan Esser -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-5.1.5/ext/varfilter/php_varfilter.h hardening-patch-5.1.5-0.4.15/ext/varfilter/php_varfilter.h ---- php-5.1.5/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:31:23.000000000 +0200 -@@ -0,0 +1,144 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifndef PHP_VARFILTER_H -+#define PHP_VARFILTER_H -+ -+extern zend_module_entry varfilter_module_entry; -+#define phpext_varfilter_ptr &varfilter_module_entry -+ -+#ifdef PHP_WIN32 -+#define PHP_VARFILTER_API __declspec(dllexport) -+#else -+#define PHP_VARFILTER_API -+#endif -+ -+#ifdef ZTS -+#include "TSRM.h" -+#endif -+ -+#include "SAPI.h" -+ -+#include "php_variables.h" -+ -+#ifdef ZEND_ENGINE_2 -+#define HASH_HTTP_GET_VARS 0x2095733f -+#define HASH_HTTP_POST_VARS 0xbfee1265 -+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 -+#define HASH_HTTP_ENV_VARS 0x1fe186a8 -+#define HASH_HTTP_SERVER_VARS 0xc987afd6 -+#define HASH_HTTP_SESSION_VARS 0x7aba0d43 -+#define HASH_HTTP_POST_FILES 0x98eb1ddc -+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec -+#else -+#define HASH_HTTP_GET_VARS 0x8d8645bd -+#define HASH_HTTP_POST_VARS 0x7c699bf3 -+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f -+#define HASH_HTTP_ENV_VARS 0x84da3016 -+#define HASH_HTTP_SERVER_VARS 0x6dbf964e -+#define HASH_HTTP_SESSION_VARS 0x322906f5 -+#define HASH_HTTP_POST_FILES 0xe4e4ce70 -+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e -+#endif -+ -+PHP_MINIT_FUNCTION(varfilter); -+PHP_MSHUTDOWN_FUNCTION(varfilter); -+PHP_RINIT_FUNCTION(varfilter); -+PHP_RSHUTDOWN_FUNCTION(varfilter); -+PHP_MINFO_FUNCTION(varfilter); -+ -+ -+ZEND_BEGIN_MODULE_GLOBALS(varfilter) -+/* request variables */ -+ long max_request_variables; -+ long cur_request_variables; -+ long max_varname_length; -+ long max_totalname_length; -+ long max_value_length; -+ long max_array_depth; -+ long max_array_index_length; -+ zend_bool disallow_nul; -+/* cookie variables */ -+ long max_cookie_vars; -+ long cur_cookie_vars; -+ long max_cookie_name_length; -+ long max_cookie_totalname_length; -+ long max_cookie_value_length; -+ long max_cookie_array_depth; -+ long max_cookie_array_index_length; -+ zend_bool disallow_cookie_nul; -+/* get variables */ -+ long max_get_vars; -+ long cur_get_vars; -+ long max_get_name_length; -+ long max_get_totalname_length; -+ long max_get_value_length; -+ long max_get_array_depth; -+ long max_get_array_index_length; -+ zend_bool disallow_get_nul; -+/* post variables */ -+ long max_post_vars; -+ long cur_post_vars; -+ long max_post_name_length; -+ long max_post_totalname_length; -+ long max_post_value_length; -+ long max_post_array_depth; -+ long max_post_array_index_length; -+ zend_bool disallow_post_nul; -+/* fileupload */ -+ long max_uploads; -+ long cur_uploads; -+ zend_bool disallow_elf_files; -+ char *verification_script; -+ -+ zend_bool no_more_variables; -+ zend_bool no_more_get_variables; -+ zend_bool no_more_post_variables; -+ zend_bool no_more_cookie_variables; -+ zend_bool no_more_uploads; -+ -+ZEND_END_MODULE_GLOBALS(varfilter) -+ -+ -+#ifdef ZTS -+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) -+#else -+#define VARFILTER_G(v) (varfilter_globals.v) -+#endif -+ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); -+SAPI_TREAT_DATA_FUNC(varfilter_treat_data); -+ -+ -+ -+#endif /* PHP_VARFILTER_H */ -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * indent-tabs-mode: t -+ * End: -+ */ -diff -Nura php-5.1.5/ext/varfilter/varfilter.c hardening-patch-5.1.5-0.4.15/ext/varfilter/varfilter.c ---- php-5.1.5/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:52:22.000000000 +0200 -@@ -0,0 +1,915 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "php.h" -+#include "php_ini.h" -+#include "ext/standard/info.h" -+#include "php_varfilter.h" -+#include "hardening_patch.h" -+ -+ZEND_DECLARE_MODULE_GLOBALS(varfilter) -+ -+/* True global resources - no need for thread safety here */ -+static int le_varfilter; -+ -+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; -+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; -+static zend_bool hooked = 0; -+ -+/* {{{ varfilter_module_entry -+ */ -+zend_module_entry varfilter_module_entry = { -+#if ZEND_MODULE_API_NO >= 20010901 -+ STANDARD_MODULE_HEADER, -+#endif -+ "varfilter", -+ NULL, -+ PHP_MINIT(varfilter), -+ PHP_MSHUTDOWN(varfilter), -+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ -+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ -+ PHP_MINFO(varfilter), -+#if ZEND_MODULE_API_NO >= 20010901 -+ "0.4.15", /* Replace with version number for your extension */ -+#endif -+ STANDARD_MODULE_PROPERTIES -+}; -+/* }}} */ -+ -+#ifdef COMPILE_DL_VARFILTER -+ZEND_GET_MODULE(varfilter) -+#endif -+ -+/* {{{ PHP_INI -+ */ -+PHP_INI_BEGIN() -+ /* for backward compatibility */ -+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) -+ -+ -+PHP_INI_END() -+/* }}} */ -+ -+/* {{{ php_varfilter_init_globals -+ */ -+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) -+{ -+ varfilter_globals->max_request_variables = 200; -+ varfilter_globals->max_varname_length = 64; -+ varfilter_globals->max_value_length = 10000; -+ varfilter_globals->max_array_depth = 100; -+ varfilter_globals->max_totalname_length = 256; -+ varfilter_globals->max_array_index_length = 64; -+ varfilter_globals->disallow_nul = 1; -+ -+ varfilter_globals->max_cookie_vars = 100; -+ varfilter_globals->max_cookie_name_length = 64; -+ varfilter_globals->max_cookie_totalname_length = 256; -+ varfilter_globals->max_cookie_value_length = 10000; -+ varfilter_globals->max_cookie_array_depth = 100; -+ varfilter_globals->max_cookie_array_index_length = 64; -+ varfilter_globals->disallow_cookie_nul = 1; -+ -+ varfilter_globals->max_get_vars = 100; -+ varfilter_globals->max_get_name_length = 64; -+ varfilter_globals->max_get_totalname_length = 256; -+ varfilter_globals->max_get_value_length = 512; -+ varfilter_globals->max_get_array_depth = 50; -+ varfilter_globals->max_get_array_index_length = 64; -+ varfilter_globals->disallow_get_nul = 1; -+ -+ varfilter_globals->max_post_vars = 200; -+ varfilter_globals->max_post_name_length = 64; -+ varfilter_globals->max_post_totalname_length = 256; -+ varfilter_globals->max_post_value_length = 65000; -+ varfilter_globals->max_post_array_depth = 100; -+ varfilter_globals->max_post_array_index_length = 64; -+ varfilter_globals->disallow_post_nul = 1; -+ -+ varfilter_globals->max_uploads = 25; -+ varfilter_globals->disallow_elf_files = 1; -+ varfilter_globals->verification_script = NULL; -+ -+ varfilter_globals->no_more_variables = 0; -+ varfilter_globals->no_more_get_variables = 0; -+ varfilter_globals->no_more_post_variables = 0; -+ varfilter_globals->no_more_cookie_variables = 0; -+ varfilter_globals->no_more_uploads = 0; -+ -+ varfilter_globals->cur_request_variables = 0; -+ varfilter_globals->cur_get_vars = 0; -+ varfilter_globals->cur_post_vars = 0; -+ varfilter_globals->cur_cookie_vars = 0; -+ -+ varfilter_globals->cur_uploads = 0; -+ -+} -+/* }}} */ -+ -+ -+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) -+{ -+ HashTable *svars; -+ int retval, failure=0; -+ -+ orig_register_server_variables(track_vars_array TSRMLS_CC); -+ -+ svars = Z_ARRVAL_P(track_vars_array); -+ -+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ -+ if (failure) { -+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); -+ } -+} -+ -+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) -+{ -+ int retval = SAPI_HEADER_ADD, i; -+ char *tmp; -+ -+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { -+ -+ tmp = sapi_header->header; -+ for (i=0; iheader_len; i++, tmp++) { -+ if (tmp[0] == 0) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); -+ sapi_header->header_len = i; -+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); -+ sapi_header->header_len = i; -+ tmp[0] = 0; -+ } -+ } -+ } -+ -+ if (orig_header_handler) { -+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); -+ } -+ -+ return retval; -+} -+ -+/* {{{ PHP_MINIT_FUNCTION -+ */ -+PHP_MINIT_FUNCTION(varfilter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); -+ REGISTER_INI_ENTRIES(); -+ -+ if (!hooked) { -+ void *temp; -+ hooked = 1; -+ -+ temp = (void *)sapi_module.register_server_variables; -+ if (temp != varfilter_register_server_variables) { -+ orig_register_server_variables = temp; -+ } -+ temp = (void *)sapi_module.header_handler; -+ if (temp != varfilter_header_handler) { -+ orig_header_handler = temp; -+ } -+ } -+ -+ sapi_register_input_filter(varfilter_input_filter); -+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); -+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); -+ sapi_register_upload_content_filter(varfilter_upload_content_filter); -+ sapi_register_post_upload_filter(varfilter_post_upload_filter); -+ -+ sapi_module.header_handler = varfilter_header_handler; -+ sapi_module.register_server_variables = varfilter_register_server_variables; -+ -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MSHUTDOWN_FUNCTION -+ */ -+PHP_MSHUTDOWN_FUNCTION(varfilter) -+{ -+ UNREGISTER_INI_ENTRIES(); -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request start */ -+/* {{{ PHP_RINIT_FUNCTION -+ */ -+PHP_RINIT_FUNCTION(varfilter) -+{ -+ VARFILTER_G(cur_request_variables) = 0; -+ VARFILTER_G(cur_get_vars) = 0; -+ VARFILTER_G(cur_post_vars) = 0; -+ VARFILTER_G(cur_cookie_vars) = 0; -+ -+ VARFILTER_G(cur_uploads) = 0; -+ -+ VARFILTER_G(no_more_variables) = 0; -+ VARFILTER_G(no_more_get_variables) = 0; -+ VARFILTER_G(no_more_post_variables) = 0; -+ VARFILTER_G(no_more_cookie_variables) = 0; -+ VARFILTER_G(no_more_uploads) = 0; -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request end */ -+/* {{{ PHP_RSHUTDOWN_FUNCTION -+ */ -+PHP_RSHUTDOWN_FUNCTION(varfilter) -+{ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MINFO_FUNCTION -+ */ -+PHP_MINFO_FUNCTION(varfilter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); -+ php_info_print_table_end(); -+ -+ DISPLAY_INI_ENTRIES(); -+} -+/* }}} */ -+ -+/* {{{ normalize_varname -+ */ -+static void normalize_varname(char *varname) -+{ -+ char *s=varname, *index=NULL, *indexend=NULL, *p; -+ -+ /* overjump leading space */ -+ while (*s == ' ') { -+ s++; -+ } -+ -+ /* and remove it */ -+ if (s != varname) { -+ memmove(varname, s, strlen(s)+1); -+ } -+ -+ for (p=varname; *p && *p != '['; p++) { -+ switch(*p) { -+ case ' ': -+ case '.': -+ *p='_'; -+ break; -+ } -+ } -+ -+ /* find index */ -+ index = strchr(varname, '['); -+ if (index) { -+ index++; -+ s=index; -+ } else { -+ return; -+ } -+ -+ /* done? */ -+ while (index) { -+ -+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { -+ index++; -+ } -+ indexend = strchr(index, ']'); -+ indexend = indexend ? indexend + 1 : index + strlen(index); -+ -+ if (s != index) { -+ memmove(s, index, strlen(index)+1); -+ s += indexend-index; -+ } else { -+ s = indexend; -+ } -+ -+ if (*s == '[') { -+ s++; -+ index = s; -+ } else { -+ index = NULL; -+ } -+ } -+ *s++='\0'; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC -+ */ -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) -+{ -+ char *index, *prev_index = NULL, *var; -+ unsigned int var_len, total_len, depth = 0; -+ -+ var = estrdup(varname); -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); -+ -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; -+ break; -+ } -+ -+ efree(var); -+ return SUCCESS; -+protected_varname2: -+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); -+return_failure: -+ efree(var); -+ return FAILURE; -+} -+/* }}} */ -+ -+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC -+ */ -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) -+{ -+ /* Drop if no more variables flag is set */ -+ if (VARFILTER_G(no_more_uploads)) { -+ return FAILURE; -+ } -+ /* Drop this fileupload if the limit is reached */ -+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { -+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); -+ VARFILTER_G(no_more_uploads) = 1; -+ return FAILURE; -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC -+ */ -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) -+{ -+ -+ if (VARFILTER_G(disallow_elf_files)) { -+ -+ if (offset == 0 && buffer_len > 10) { -+ -+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { -+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); -+ return FAILURE; -+ } -+ } -+ -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC -+ */ -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) -+{ -+ int retval = SUCCESS; -+ -+ if (VARFILTER_G(verification_script)) { -+ char cmd[8192]; -+ FILE *in; -+ int first=1; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); -+ return FAILURE; -+ } -+ -+ retval = FAILURE; -+ -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ if (first) { -+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; -+ first = 0; -+ } -+ } -+ pclose(in); -+ } -+ -+ if (retval != SUCCESS) { -+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); -+ return FAILURE; -+ } -+ -+ VARFILTER_G(cur_uploads)++; -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_INPUT_FILTER_FUNC -+ */ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) -+{ -+ char *index, *prev_index = NULL; -+ unsigned int var_len, total_len, depth = 0; -+ -+ /* Drop this variable if the limit was reached */ -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(no_more_get_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(no_more_post_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(no_more_cookie_variables)) { -+ return 0; -+ } -+ break; -+ default: /* we do not want to protect parse_str() and friends */ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ return 1; -+ } -+ if (VARFILTER_G(no_more_variables)) { -+ return 0; -+ } -+ -+ /* Drop this variable if the limit is now reached */ -+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { -+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_variables) = 1; -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { -+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_get_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { -+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_cookie_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { -+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_post_variables) = 1; -+ return 0; -+ } -+ break; -+ } -+ -+ -+ /* Drop this variable if it exceeds the value length limit */ -+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { -+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { -+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { -+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { -+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { -+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { -+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Check if variable value is truncated by a \0 */ -+ -+ if (val && *val && val_len != strlen(*val)) { -+ -+ if (VARFILTER_G(disallow_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(disallow_get_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(disallow_cookie_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(disallow_post_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ } -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname; -+ break; -+ } -+ -+ /* Okay let PHP register this variable */ -+ VARFILTER_G(cur_request_variables)++; -+ switch (arg) { -+ case PARSE_GET: -+ VARFILTER_G(cur_get_vars)++; -+ break; -+ case PARSE_COOKIE: -+ VARFILTER_G(cur_cookie_vars)++; -+ break; -+ case PARSE_POST: -+ VARFILTER_G(cur_post_vars)++; -+ break; -+ } -+ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ -+ return 1; -+protected_varname: -+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); -+ return 0; -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: noet sw=4 ts=4 fdm=marker -+ * vim<600: noet sw=4 ts=4 -+ */ -+ -+ -diff -Nura php-5.1.5/ext/wddx/wddx.c hardening-patch-5.1.5-0.4.15/ext/wddx/wddx.c ---- php-5.1.5/ext/wddx/wddx.c 2006-05-25 12:01:30.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/ext/wddx/wddx.c 2006-09-05 20:31:23.000000000 +0200 -@@ -399,9 +399,9 @@ - break; - - default: -- if (iscntrl((int)*(unsigned char *)p)) { -+ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) { - FLUSH_BUF(); -- sprintf(control_buf, WDDX_CHAR, *p); -+ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); - php_wddx_add_chunk(packet, control_buf); - } else - buf[l++] = *p; -diff -Nura php-5.1.5/main/fopen_wrappers.c hardening-patch-5.1.5-0.4.15/main/fopen_wrappers.c ---- php-5.1.5/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/fopen_wrappers.c 2006-09-07 18:54:01.000000000 +0200 -@@ -104,7 +104,10 @@ - } - - /* Resolve the real path into resolved_name */ -- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { -+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { -+ return -2; -+ } -+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { - /* Handler for basedirs that end with a / */ - resolved_basedir_len = strlen(resolved_basedir); - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { -@@ -114,14 +117,20 @@ - } - } - -+ resolved_name_len = strlen(resolved_name); - if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { -- resolved_name_len = strlen(resolved_name); - if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { - resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; - resolved_name[++resolved_name_len] = '\0'; - } - } - -+ if (resolved_name_len == resolved_basedir_len - 1) { -+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { -+ resolved_basedir_len--; -+ } -+ } -+ - /* Check the path */ - #if defined(PHP_WIN32) || defined(NETWARE) - if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { -@@ -135,7 +144,7 @@ - } - } else { - /* Unable to resolve the real path, return -1 */ -- return -1; -+ return -3; - } - } - /* }}} */ -@@ -154,22 +163,44 @@ - char *pathbuf; - char *ptr; - char *end; -+ char path_copy[MAXPATHLEN]; -+ int path_len; -+ -+ /* Special case path ends with a trailing slash */ -+ path_len = strlen(path); -+ if (path_len >= MAXPATHLEN) { -+ errno = EPERM; /* we deny permission to open it */ -+ return -1; -+ } -+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { -+ memcpy(path_copy, path, path_len+1); -+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; -+ path_copy[path_len] = '\0'; -+ path = (const char *)&path_copy; -+ } - - pathbuf = estrdup(PG(open_basedir)); - - ptr = pathbuf; - - while (ptr && *ptr) { -+ int res; - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - -- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { -+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); -+ if (res == 0) { - efree(pathbuf); - return 0; - } -+ if (res == -2) { -+ efree(pathbuf); -+ errno = EPERM; -+ return -1; -+ } - - ptr = end; - } -diff -Nura php-5.1.5/main/hardened_globals.h hardening-patch-5.1.5-0.4.15/main/hardened_globals.h ---- php-5.1.5/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/hardened_globals.h 2006-09-05 20:31:24.000000000 +0200 -@@ -0,0 +1,64 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENED_GLOBALS_H -+#define HARDENED_GLOBALS_H -+ -+typedef struct _hardened_globals hardened_globals_struct; -+ -+#ifdef ZTS -+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) -+extern int hardened_globals_id; -+#else -+# define HG(v) (hardened_globals.v) -+extern struct _hardened_globals hardened_globals; -+#endif -+ -+ -+struct _hardened_globals { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_1; -+ unsigned int canary_2; -+#endif -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_3; -+ unsigned int canary_4; -+ unsigned int ll_canary_inited; -+#endif -+ zend_bool hphp_sql_bailout_on_error; -+ zend_bool hphp_multiheader; -+ unsigned long hphp_mailprotect; -+ long hard_memory_limit; -+ HashTable *eval_whitelist; -+ HashTable *eval_blacklist; -+ HashTable *func_whitelist; -+ HashTable *func_blacklist; -+ HashTable *include_whitelist; -+ HashTable *include_blacklist; -+ unsigned int dummy; -+}; -+ -+ -+#endif /* HARDENED_GLOBALS_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-5.1.5/main/hardening_patch.c hardening-patch-5.1.5-0.4.15/main/hardening_patch.c ---- php-5.1.5/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/hardening_patch.c 2006-09-05 20:31:24.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ -+ -+#include "php.h" -+ -+#include -+#include -+ -+#if HAVE_UNISTD_H -+#include -+#endif -+#include "SAPI.h" -+#include "php_globals.h" -+ -+#if HARDENING_PATCH -+ -+#ifdef HAVE_SYS_SOCKET_H -+#include -+#endif -+ -+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) -+#undef AF_UNIX -+#endif -+ -+#if defined(AF_UNIX) -+#include -+#endif -+ -+#define SYSLOG_PATH "/dev/log" -+ -+#include "snprintf.h" -+ -+#include "hardening_patch.h" -+ -+#ifdef ZTS -+#include "hardened_globals.h" -+int hardened_globals_id; -+#else -+struct _hardened_globals hardened_globals; -+#endif -+ -+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) -+{ -+ memset(hardened_globals, 0, sizeof(*hardened_globals)); -+} -+ -+ -+PHPAPI void hardened_startup() -+{ -+#ifdef ZTS -+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); -+#else -+ hardened_globals_ctor(&hardened_globals TSRMLS_CC); -+#endif -+} -+ -+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) -+{ -+ HG(canary_1) = php_canary(); -+ HG(canary_2) = php_canary(); -+} -+ -+char *loglevel2string(int loglevel) -+{ -+ switch (loglevel) { -+ case S_FILES: -+ return "FILES"; -+ case S_INCLUDE: -+ return "INCLUDE"; -+ case S_MEMORY: -+ return "MEMORY"; -+ case S_MISC: -+ return "MISC"; -+ case S_SQL: -+ return "SQL"; -+ case S_EXECUTOR: -+ return "EXECUTOR"; -+ case S_VARS: -+ return "VARS"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+PHPAPI void php_security_log(int loglevel, char *fmt, ...) -+{ -+#if defined(AF_UNIX) -+ int s, r, i=0; -+ struct sockaddr_un saun; -+ char buf[4096+64]; -+ char error[4096+100]; -+ char *ip_address; -+ char *fname; -+ int lineno; -+ va_list ap; -+ TSRMLS_FETCH(); -+ -+ if (EG(hphp_log_use_x_forwarded_for)) { -+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "X-FORWARDED-FOR not set"; -+ } -+ } else { -+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "REMOTE_ADDR not set"; -+ } -+ } -+ -+ -+ va_start(ap, fmt); -+ ap_php_vsnprintf(error, sizeof(error), fmt, ap); -+ va_end(ap); -+ while (error[i]) { -+ if (error[i] < 32) error[i] = '.'; -+ i++; -+ } -+ -+ if (zend_is_executing(TSRMLS_C)) { -+ lineno = zend_get_executed_lineno(TSRMLS_C); -+ fname = zend_get_executed_filename(TSRMLS_C); -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); -+ } else { -+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); -+ if (fname==NULL) { -+ fname = "unknown"; -+ } -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); -+ } -+ -+ /* Syslog-Logging disabled? */ -+ if ((EG(hphp_log_syslog) & loglevel)==0) { -+ goto log_sapi; -+ } -+ -+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); -+ -+ s = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ s = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ goto log_sapi; -+ } -+ } -+ send(s, error, strlen(error), 0); -+ -+ close(s); -+ -+log_sapi: -+ /* SAPI Logging activated? */ -+ if ((EG(hphp_log_sapi) & loglevel)!=0) { -+ sapi_module.log_message(buf); -+ } -+ -+log_script: -+ /* script logging activaed? */ -+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { -+ char cmd[8192], *cmdpos, *bufpos; -+ FILE *in; -+ int space; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); -+ space = sizeof(cmd) - strlen(cmd); -+ cmdpos = cmd + strlen(cmd); -+ bufpos = buf; -+ if (space <= 1) return; -+ while (space > 2 && *bufpos) { -+ if (*bufpos == '\'') { -+ if (space<=5) break; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\\'; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\''; -+ bufpos++; -+ space-=4; -+ } else { -+ *cmdpos++ = *bufpos++; -+ space--; -+ } -+ } -+ *cmdpos++ = '\''; -+ *cmdpos = 0; -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); -+ return; -+ } -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ } -+ pclose(in); -+ } -+ -+#endif -+} -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+PHPAPI unsigned int php_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+ -+PHPAPI int php_is_valid_include(zval *z) -+{ -+ char *filename; -+ int len, i; -+ TSRMLS_FETCH(); -+ -+ /* must be of type string */ -+ if (z->type != IS_STRING || z->value.str.val == NULL) { -+ return (0); -+ } -+ -+ /* short cut */ -+ filename = z->value.str.val; -+ len = z->value.str.len; -+ -+ /* 1. must be shorter than MAXPATHLEN */ -+ if (len > MAXPATHLEN) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 2. must not be cutted */ -+ if (len != strlen(filename)) { -+ char *fname = estrndup(filename, len); -+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ -+ if (strstr(filename, "://")) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ -+ /* no black or whitelist then disallow all */ -+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* whitelist is stronger than blacklist */ -+ if (HG(include_whitelist)) { -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ zend_bool isOk = 0; -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_whitelist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ isOk = 1; -+ break; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_whitelist)); -+ } while (1); -+ -+ /* not found in whitelist */ -+ if (!isOk) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); -+ efree(fname); -+ return 0; -+ } -+ -+ s = h + 3; -+ } while (1); -+ } else { -+ /* okay then handle the blacklist */ -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_blacklist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); -+ efree(fname); -+ return 0; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_blacklist)); -+ } while (1); -+ -+ s = h + 3; -+ } while (1); -+ } -+ -+ efree(fname); -+ } -+ -+ /* 4. must not be an uploaded file */ -+ if (SG(rfc1867_uploaded_files)) { -+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { -+ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); -+ return (0); -+ } -+ } -+ -+ /* passed all tests */ -+ return (1); -+} -+ -+#endif -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.5/main/hardening_patch.h hardening-patch-5.1.5-0.4.15/main/hardening_patch.h ---- php-5.1.5/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/hardening_patch.h 2006-09-07 18:52:11.000000000 +0200 -@@ -0,0 +1,46 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENING_PATCH_H -+#define HARDENING_PATCH_H -+ -+#include "zend.h" -+ -+#if HARDENING_PATCH -+PHPAPI void php_security_log(int loglevel, char *fmt, ...); -+PHPAPI void hardened_startup(); -+#define HARDENING_PATCH_VERSION "0.4.15" -+ -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+PHPAPI unsigned int php_canary(); -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+PHPAPI int php_is_valid_include(zval *z); -+#endif -+ -+#endif /* HARDENING_PATCH_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-5.1.5/main/hardening_patch.m4 hardening-patch-5.1.5-0.4.15/main/hardening_patch.m4 ---- php-5.1.5/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/hardening_patch.m4 2006-09-05 20:31:24.000000000 +0200 -@@ -0,0 +1,95 @@ -+dnl -+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ -+dnl -+dnl This file contains Hardening Patch for PHP specific autoconf functions. -+dnl -+ -+AC_ARG_ENABLE(hardening-patch-mm-protect, -+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-ll-protect, -+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-inc-protect, -+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-fmt-protect, -+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-hash-protect, -+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+]) -+ -+AC_MSG_CHECKING(whether to protect the Zend Memory Manager) -+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the Zend Linked Lists) -+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect include/require statements) -+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect PHP Format String functions) -+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) -+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) -+ -+ -+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) -+fi -+ -diff -Nura php-5.1.5/main/main.c hardening-patch-5.1.5-0.4.15/main/main.c ---- php-5.1.5/main/main.c 2006-08-10 23:49:56.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/main/main.c 2006-09-05 20:31:24.000000000 +0200 -@@ -85,6 +85,10 @@ - - #include "SAPI.h" - #include "rfc1867.h" -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#endif -+ - /* }}} */ - - #ifndef ZTS -@@ -109,17 +113,39 @@ - */ - static PHP_INI_MH(OnChangeMemoryLimit) - { -+#if HARDENING_PATCH -+ long hard_memory_limit = 1<<30; -+ -+ if (stage == ZEND_INI_STAGE_RUNTIME) { -+ if (HG(hard_memory_limit) == 0) { -+ HG(hard_memory_limit) = PG(memory_limit); -+ } -+ hard_memory_limit = HG(hard_memory_limit); -+ } else { -+ HG(hard_memory_limit) = 0; -+ } -+#endif - if (new_value) { - PG(memory_limit) = zend_atoi(new_value, new_value_length); -+#if HARDENING_PATCH -+ if (PG(memory_limit) > hard_memory_limit) { -+ PG(memory_limit) = hard_memory_limit; -+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); -+ return FAILURE; -+ } -+#endif - } else { -+#if HARDENING_PATCH -+ PG(memory_limit) = hard_memory_limit; -+#else - PG(memory_limit) = 1<<30; /* effectively, no limit */ -+#endif - } - return zend_set_memory_limit(PG(memory_limit)); - } - /* }}} */ - #endif - -- - /* {{{ php_disable_functions - */ - static void php_disable_functions(TSRMLS_D) -@@ -1100,6 +1126,13 @@ - sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1); - } - -+ /* Disable realpath cache if safe_mode or open_basedir are set */ -+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { -+ CWDG(realpath_cache_disable) = 1; -+ } else { -+ CWDG(realpath_cache_disable) = 0; -+ } -+ - if (PG(output_handler) && PG(output_handler)[0]) { - php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); - } else if (PG(output_buffering)) { -@@ -1227,6 +1260,9 @@ - - zend_try { - shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); -+#if HARDENING_PATCH -+ hardened_clear_mm_canaries(TSRMLS_C); -+#endif - } zend_end_try(); - - zend_try { -@@ -1398,6 +1434,10 @@ - tsrm_ls = ts_resource(0); - #endif - -+#if HARDENING_PATCH -+ hardened_startup(); -+#endif -+ - module_shutdown = 0; - module_startup = 1; - sapi_initialize_empty_request(TSRMLS_C); -@@ -1411,6 +1451,12 @@ - - php_output_startup(); - -+#if HARDENING_PATCH_INC_PROTECT -+ zuf.is_valid_include = php_is_valid_include; -+#endif -+#if HARDENING_PATCH -+ zuf.security_log_function = php_security_log; -+#endif - zuf.error_function = php_error_cb; - zuf.printf_function = php_printf; - zuf.write_function = php_body_write_wrapper; -@@ -1481,7 +1527,9 @@ - - /* Disable realpath cache if safe_mode or open_basedir are set */ - if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { -- CWDG(realpath_cache_size_limit) = 0; -+ CWDG(realpath_cache_disable) = 1; -+ } else { -+ CWDG(realpath_cache_disable) = 0; - } - - /* initialize stream wrappers registry -@@ -1522,6 +1570,10 @@ - REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS); - 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); - REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); -+#endif - REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); -diff -Nura php-5.1.5/main/php_config.h.in hardening-patch-5.1.5-0.4.15/main/php_config.h.in ---- php-5.1.5/main/php_config.h.in 2006-08-15 14:55:43.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/main/php_config.h.in 2006-09-05 20:31:24.000000000 +0200 -@@ -788,6 +788,39 @@ - /* Enabling BIND8 compatibility for Panther */ - #undef BIND_8_COMPAT - -+/* Hardening-Patch for PHP */ -+#undef HARDENING_PATCH -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ - /* Whether you have AOLserver */ - #undef HAVE_AOLSERVER - -@@ -1131,6 +1164,12 @@ - /* Define if you have the getaddrinfo function */ - #undef HAVE_GETADDRINFO - -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ - /* Whether system headers declare timezone */ - #undef HAVE_DECLARED_TIMEZONE - -diff -Nura php-5.1.5/main/php.h hardening-patch-5.1.5-0.4.15/main/php.h ---- php-5.1.5/main/php.h 2006-03-07 23:37:53.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/php.h 2006-09-05 20:31:24.000000000 +0200 -@@ -35,11 +35,19 @@ - #include "zend_qsort.h" - #include "php_compat.h" - -+ - #include "zend_API.h" - - #undef sprintf - #define sprintf php_sprintf - -+#if HARDENING_PATCH -+#if HAVE_REALPATH -+#undef realpath -+#define realpath php_realpath -+#endif -+#endif -+ - /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ - #undef PHP_DEBUG - #define PHP_DEBUG ZEND_DEBUG -@@ -338,6 +346,7 @@ - #define PHP_FUNCTION ZEND_FUNCTION - #define PHP_METHOD ZEND_METHOD - -+#define PHP_STATIC_FE ZEND_STATIC_FE - #define PHP_NAMED_FE ZEND_NAMED_FE - #define PHP_FE ZEND_FE - #define PHP_DEP_FE ZEND_DEP_FE -@@ -447,6 +456,10 @@ - #endif - #endif /* !XtOffsetOf */ - -+#if HARDENING_PATCH -+#include "hardening_patch.h" -+#endif -+ - #endif - - /* -diff -Nura php-5.1.5/main/php_variables.c hardening-patch-5.1.5-0.4.15/main/php_variables.c ---- php-5.1.5/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/main/php_variables.c 2006-09-05 20:31:24.000000000 +0200 -@@ -73,6 +73,10 @@ - symtable1 = Z_ARRVAL_P(track_vars_array); - } else if (PG(register_globals)) { - symtable1 = EG(active_symbol_table); -+ /* GLOBALS hijack attempt, reject parameter */ -+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) { -+ symtable1 = NULL; -+ } - } - if (!symtable1) { - /* Nothing to do */ -@@ -513,7 +517,7 @@ - */ - static inline void php_register_server_variables(TSRMLS_D) - { -- zval *array_ptr = NULL; -+ zval *array_ptr = NULL, *vptr; - /* turn off magic_quotes while importing server variables */ - int magic_quotes_gpc = PG(magic_quotes_gpc); - -diff -Nura php-5.1.5/main/rfc1867.c hardening-patch-5.1.5-0.4.15/main/rfc1867.c ---- php-5.1.5/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/rfc1867.c 2006-09-05 20:31:24.000000000 +0200 -@@ -132,6 +132,7 @@ - #define UPLOAD_ERROR_D 4 /* No file uploaded */ - #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ - #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ -+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */ - - void php_rfc1867_register_constants(TSRMLS_D) - { -@@ -142,6 +143,7 @@ - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); - } - - static void normalize_protected_variable(char *varname TSRMLS_DC) -@@ -854,6 +856,7 @@ - char buff[FILLUNIT]; - char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; - int blen=0, wlen=0; -+ unsigned long offset; - - zend_llist_clean(&header); - -@@ -970,7 +973,11 @@ - tmp++; - } - } -- -+ -+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { -+ skip_upload = 1; -+ } -+ - total_bytes = cancel_upload = 0; - - if (!skip_upload) { -@@ -994,6 +1001,11 @@ - cancel_upload = UPLOAD_ERROR_D; - } - -+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ -+ offset = 0; - end = 0; - while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) - { -@@ -1008,6 +1020,10 @@ - #endif - cancel_upload = UPLOAD_ERROR_B; - } else if (blen > 0) { -+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - wlen = write(fd, buff, blen); - - if (wlen < blen) { -@@ -1036,6 +1052,10 @@ - } - #endif - -+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - if (cancel_upload) { - if (temp_filename) { - if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ -diff -Nura php-5.1.5/main/SAPI.c hardening-patch-5.1.5-0.4.15/main/SAPI.c ---- php-5.1.5/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/SAPI.c 2006-09-05 20:31:24.000000000 +0200 -@@ -870,6 +870,36 @@ - post_entry->content_type_len+1); - } - -+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)) -+{ -+ sapi_module.input_filter = input_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) -+{ -+ sapi_module.upload_varname_filter = upload_varname_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) -+{ -+ sapi_module.pre_upload_filter = pre_upload_filter; -+ return SUCCESS; -+} -+ -+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)) -+{ -+ sapi_module.upload_content_filter = upload_content_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) -+{ -+ sapi_module.post_upload_filter = post_upload_filter; -+ return SUCCESS; -+} -+ - - SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)) - { -@@ -884,11 +914,6 @@ - return SUCCESS; - } - --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)) --{ -- sapi_module.input_filter = input_filter; -- return SUCCESS; --} - - SAPI_API int sapi_flush(TSRMLS_D) - { -diff -Nura php-5.1.5/main/SAPI.h hardening-patch-5.1.5-0.4.15/main/SAPI.h ---- php-5.1.5/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/SAPI.h 2006-09-05 20:31:24.000000000 +0200 -@@ -190,6 +190,10 @@ - SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); - 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)); - -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); -+ - SAPI_API int sapi_flush(TSRMLS_D); - SAPI_API struct stat *sapi_get_stat(TSRMLS_D); - SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC); -@@ -254,6 +258,11 @@ - int (*get_target_gid)(gid_t * TSRMLS_DC); - - unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); -+ -+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); -+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); -+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); -+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); - - void (*ini_defaults)(HashTable *configuration_hash); - int phpinfo_as_text; -@@ -279,7 +288,11 @@ - - #define SAPI_DEFAULT_MIMETYPE "text/html" - #define SAPI_DEFAULT_CHARSET "" -+#if HARDENING_PATCH -+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" -+#else - #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION -+#endif - - #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) - #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) -@@ -287,6 +300,11 @@ - #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) - #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) - -+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) -+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) -+#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) -+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) -+ - BEGIN_EXTERN_C() - SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); - SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); -diff -Nura php-5.1.5/main/snprintf.c hardening-patch-5.1.5-0.4.15/main/snprintf.c ---- php-5.1.5/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/snprintf.c 2006-09-05 20:31:24.000000000 +0200 -@@ -1014,7 +1014,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = cc; -+#endif - goto skip_output; - - /* -diff -Nura php-5.1.5/main/spprintf.c hardening-patch-5.1.5-0.4.15/main/spprintf.c ---- php-5.1.5/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/main/spprintf.c 2006-09-05 20:31:24.000000000 +0200 -@@ -630,7 +630,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = xbuf->len; -+#endif - goto skip_output; - - /* -diff -Nura php-5.1.5/pear/Makefile.frag hardening-patch-5.1.5-0.4.15/pear/Makefile.frag ---- php-5.1.5/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/pear/Makefile.frag 2006-09-05 20:31:24.000000000 +0200 -@@ -3,7 +3,7 @@ - peardir=$(PEAR_INSTALLDIR) - - # Skip all php.ini files altogether --PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -+PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar - - install-pear-installer: $(SAPI_CLI_PATH) - @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" -diff -Nura php-5.1.5/php.ini-dist hardening-patch-5.1.5-0.4.15/php.ini-dist ---- php-5.1.5/php.ini-dist 2006-08-14 20:40:19.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/php.ini-dist 2006-09-05 20:31:24.000000000 +0200 -@@ -1198,6 +1198,209 @@ - ; instead of original one. - soap.wsdl_cache_ttl=86400 - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-5.1.5/php.ini-recommended hardening-patch-5.1.5-0.4.15/php.ini-recommended ---- php-5.1.5/php.ini-recommended 2006-08-14 20:40:19.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/php.ini-recommended 2006-09-05 20:31:24.000000000 +0200 -@@ -1256,6 +1256,209 @@ - ; instead of original one. - soap.wsdl_cache_ttl=86400 - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-5.1.5/run-tests.php hardening-patch-5.1.5-0.4.15/run-tests.php ---- php-5.1.5/run-tests.php 2006-05-03 23:37:16.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/run-tests.php 2006-09-05 20:31:24.000000000 +0200 -@@ -161,6 +161,10 @@ - 'error_reporting=4095', - 'display_errors=1', - 'log_errors=0', -+ 'hphp.executor.include.whitelist=cookietest', -+ 'hphp.log.syslog=0', -+ 'hphp.log.sapi=0', -+ 'hphp.log.script=0', - 'html_errors=0', - 'track_errors=1', - 'report_memleaks=1', -diff -Nura php-5.1.5/sapi/apache/mod_php5.c hardening-patch-5.1.5-0.4.15/sapi/apache/mod_php5.c ---- php-5.1.5/sapi/apache/mod_php5.c 2006-05-14 00:03:51.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/sapi/apache/mod_php5.c 2006-09-05 20:31:26.000000000 +0200 -@@ -482,7 +482,7 @@ - sapi_apache_get_fd, - sapi_apache_force_http_10, - sapi_apache_get_target_uid, -- sapi_apache_get_target_gid -+ sapi_apache_get_target_gid, - }; - /* }}} */ - -@@ -936,7 +936,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component("PHP/" PHP_VERSION); -+#endif - } - } - #endif -diff -Nura php-5.1.5/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.5-0.4.15/sapi/apache2filter/sapi_apache2.c ---- php-5.1.5/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:31:26.000000000 +0200 -@@ -573,7 +573,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-5.1.5/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.5-0.4.15/sapi/apache2handler/sapi_apache2.c ---- php-5.1.5/sapi/apache2handler/sapi_apache2.c 2006-08-08 15:11:39.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:31:26.000000000 +0200 -@@ -341,7 +341,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-5.1.5/sapi/cgi/cgi_main.c hardening-patch-5.1.5-0.4.15/sapi/cgi/cgi_main.c ---- php-5.1.5/sapi/cgi/cgi_main.c 2006-05-24 09:55:38.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:31:26.000000000 +0200 -@@ -1448,10 +1448,18 @@ - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - } -+#if HARDENING_PATCH - #if ZEND_DEBUG -- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -+ 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()); - #else -- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -+ 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()); -+#endif -+#else -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif - #endif - php_end_ob_buffers(1 TSRMLS_CC); - exit(0); -diff -Nura php-5.1.5/sapi/cli/php_cli.c hardening-patch-5.1.5-0.4.15/sapi/cli/php_cli.c ---- php-5.1.5/sapi/cli/php_cli.c 2006-05-12 00:11:17.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:31:26.000000000 +0200 -@@ -754,8 +754,14 @@ - goto err; - } - -+#if HARDENING_PATCH -+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", -+ PHP_VERSION, HARDENING_PATCH_VERSION, -+#else - php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", -- PHP_VERSION, sapi_module.name, __DATE__, __TIME__, -+ PHP_VERSION, -+#endif -+ sapi_module.name, __DATE__, __TIME__, - #if ZEND_DEBUG && defined(HAVE_GCOV) - "(DEBUG GCOV)", - #elif ZEND_DEBUG -diff -Nura php-5.1.5/TSRM/TSRM.h hardening-patch-5.1.5-0.4.15/TSRM/TSRM.h ---- php-5.1.5/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/TSRM/TSRM.h 2006-09-05 20:31:26.000000000 +0200 -@@ -33,6 +33,13 @@ - # define TSRM_API - #endif - -+#if HARDENING_PATCH -+# if HAVE_REALPATH -+# undef realpath -+# define realpath php_realpath -+# endif -+#endif -+ - /* Only compile multi-threading functions if we're in ZTS mode */ - #ifdef ZTS - -@@ -88,6 +95,7 @@ - - #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts - -+ - #ifdef __cplusplus - extern "C" { - #endif -diff -Nura php-5.1.5/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.c ---- php-5.1.5/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:31:26.000000000 +0200 -@@ -163,6 +163,7 @@ - static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) - { - CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state); -+ cwd_globals->realpath_cache_disable = 0; - cwd_globals->realpath_cache_size = 0; - cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE; - cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL; -@@ -201,6 +202,176 @@ - return p; - } - -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved) -+{ -+ struct stat sb; -+ char *p, *q, *s; -+ size_t left_len, resolved_len; -+ unsigned symlinks; -+ int serrno, slen; -+ int is_dir = 1; -+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; -+ -+ serrno = errno; -+ symlinks = 0; -+ if (path[0] == '/') { -+ resolved[0] = '/'; -+ resolved[1] = '\0'; -+ if (path[1] == '\0') -+ return (resolved); -+ resolved_len = 1; -+ left_len = strlcpy(left, path + 1, sizeof(left)); -+ } else { -+ if (getcwd(resolved, PATH_MAX) == NULL) { -+ strlcpy(resolved, ".", PATH_MAX); -+ return (NULL); -+ } -+ resolved_len = strlen(resolved); -+ left_len = strlcpy(left, path, sizeof(left)); -+ } -+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ -+ /* -+ * Iterate over path components in `left'. -+ */ -+ while (left_len != 0) { -+ /* -+ * Extract the next path component and adjust `left' -+ * and its length. -+ */ -+ p = strchr(left, '/'); -+ s = p ? p : left + left_len; -+ if (s - left >= sizeof(next_token)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ memcpy(next_token, left, s - left); -+ next_token[s - left] = '\0'; -+ left_len -= s - left; -+ if (p != NULL) -+ memmove(left, s + 1, left_len + 1); -+ if (resolved[resolved_len - 1] != '/') { -+ if (resolved_len + 1 >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ resolved[resolved_len++] = '/'; -+ resolved[resolved_len] = '\0'; -+ } -+ if (next_token[0] == '\0') -+ continue; -+ else if (strcmp(next_token, ".") == 0) -+ continue; -+ else if (strcmp(next_token, "..") == 0) { -+ /* -+ * Strip the last path component except when we have -+ * single "/" -+ */ -+ if (!is_dir) { -+ errno = ENOENT; -+ return (NULL); -+ } -+ if (resolved_len > 1) { -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ continue; -+ } -+ -+ /* -+ * Append the next path component and lstat() it. If -+ * lstat() fails we still can return successfully if -+ * there are no more path components left. -+ */ -+ resolved_len = strlcat(resolved, next_token, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ if (lstat(resolved, &sb) != 0) { -+ if (errno == ENOENT) { -+ if (p == NULL) { -+ errno = serrno; -+ return (resolved); -+ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { -+ resolved_len = strlcat(resolved, "/", PATH_MAX); -+ resolved_len = strlcat(resolved, left, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ errno = serrno; -+ return (resolved); -+ } -+ } -+ return (NULL); -+ } -+ if (S_ISLNK(sb.st_mode)) { -+ if (symlinks++ > MAXSYMLINKS) { -+ errno = ELOOP; -+ return (NULL); -+ } -+ slen = readlink(resolved, symlink, sizeof(symlink) - 1); -+ if (slen < 0) -+ return (NULL); -+ symlink[slen] = '\0'; -+ if (symlink[0] == '/') { -+ resolved[1] = 0; -+ resolved_len = 1; -+ } else if (resolved_len > 1) { -+ /* Strip the last path component. */ -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ -+ /* -+ * If there are any path components left, then -+ * append them to symlink. The result is placed -+ * in `left'. -+ */ -+ if (p != NULL) { -+ if (symlink[slen - 1] != '/') { -+ if (slen + 1 >= sizeof(symlink)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ symlink[slen] = '/'; -+ symlink[slen + 1] = 0; -+ } -+ left_len = strlcat(symlink, left, sizeof(left)); -+ if (left_len >= sizeof(left)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ } -+ left_len = strlcpy(left, symlink, sizeof(left)); -+ } else { -+ if (S_ISDIR(sb.st_mode)) { -+ is_dir = 1; -+ } else { -+ is_dir = 0; -+ } -+ } -+ } -+ -+ /* -+ * Remove trailing slash except when the resolved pathname -+ * is a single "/". -+ */ -+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') -+ resolved[resolved_len - 1] = '\0'; -+ return (resolved); -+} -+#endif -+ - CWD_API void virtual_cwd_startup(void) - { - char cwd[MAXPATHLEN]; -@@ -381,22 +552,33 @@ - #endif - char orig_path[MAXPATHLEN]; - int orig_path_len = 0; -+ int use_realpath_cache = 1; - realpath_cache_bucket *bucket; - time_t t = 0; - TSRMLS_FETCH(); - - if (path_length == 0) - return (0); -- if (path_length >= MAXPATHLEN) -+ if (path_length >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return (1); -+ } -+ -+ /* Disable realpath cache if safe_mode or open_basedir are set */ -+ if (CWDG(realpath_cache_disable)) { -+ use_realpath_cache = 0; -+ } - -- if (use_realpath && CWDG(realpath_cache_size_limit)) { -+ if (use_realpath && use_realpath_cache) { - if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { - memcpy(orig_path, path, path_length+1); - orig_path_len = path_length; - } else { - orig_path_len = path_length + state->cwd_length + 1; - if (orig_path_len >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(orig_path, state->cwd, state->cwd_length); -@@ -414,6 +596,8 @@ - if (verify_path && verify_path(state)) { - CWD_STATE_FREE(state); - *state = old_state; -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } else { - CWD_STATE_FREE(&old_state); -@@ -431,8 +615,9 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - } else { /* Concat current directory with relative path and then run realpath() on it */ -@@ -441,6 +626,8 @@ - - ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); - if (!tmp) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(ptr, state->cwd, state->cwd_length); -@@ -451,6 +638,8 @@ - *ptr = '\0'; - if (strlen(tmp) >= MAXPATHLEN) { - free(tmp); -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - if (use_realpath) { -@@ -458,9 +647,10 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now - free(tmp); -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - free(tmp); -@@ -599,7 +789,7 @@ - #endif - free(free_path); - -- if (use_realpath && CWDG(realpath_cache_size_limit)) { -+ if (use_realpath && use_realpath_cache) { - realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); - } - -diff -Nura php-5.1.5/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.h ---- php-5.1.5/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:31:26.000000000 +0200 -@@ -127,6 +127,22 @@ - - typedef int (*verify_path_func)(const cwd_state *); - -+#ifndef HAVE_STRLCPY -+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); -+#undef strlcpy -+#define strlcpy php_strlcpy -+#endif -+ -+#ifndef HAVE_STRLCAT -+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); -+#undef strlcat -+#define strlcat php_strlcat -+#endif -+ -+ -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved); -+#endif - CWD_API void virtual_cwd_startup(void); - CWD_API void virtual_cwd_shutdown(void); - CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); -@@ -199,6 +215,7 @@ - long realpath_cache_size_limit; - long realpath_cache_ttl; - realpath_cache_bucket *realpath_cache[1024]; -+ int realpath_cache_disable; - } virtual_cwd_globals; - - #ifdef ZTS -diff -Nura php-5.1.5/Zend/zend_alloc.c hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.c ---- php-5.1.5/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.c 2006-09-05 20:31:26.000000000 +0200 -@@ -64,6 +64,11 @@ - # define END_MAGIC_SIZE 0 - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+# define CANARY_SIZE sizeof(unsigned int) -+#else -+# define CANARY_SIZE 0 -+#endif - - # if MEMORY_LIMIT - # if ZEND_DEBUG -@@ -72,7 +77,15 @@ - #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0) - # endif - --#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\ -+#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \ -+ if (file) { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \ -+ } else { \ -+ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \ -+ } \ -+ exit(1); \ -+ } \ -+ AG(allocated_memory) += rs;\ - if (AG(memory_limit)pNext; \ - } else { \ -+ if (p != p->pLast->pNext) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pLast->pNext = p->pNext; \ - } \ - if (p->pNext) { \ -+ if (p != p->pNext->pLast) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pNext->pLast = p->pLast; \ - } - #else -@@ -127,7 +148,7 @@ - #endif - - #define DECLARE_CACHE_VARS() \ -- unsigned int real_size; \ -+ size_t real_size; \ - unsigned int cache_index - - #define REAL_SIZE(size) ((size+7) & ~0x7) -@@ -142,12 +163,22 @@ - - ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -- zend_mem_header *p; -+ zend_mem_header *p = NULL; - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { -+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); -+ exit(1); -+ } -+#endif - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - -+ if (size > INT_MAX || SIZE < size) { -+ goto emalloc_error; -+ } -+ - #if !ZEND_DISABLE_MEMORY_CACHE - if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) { - p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]]; -@@ -164,6 +195,10 @@ - AG(cache_stats)[CACHE_INDEX][1]++; - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } else { -@@ -179,11 +214,13 @@ - AG(allocated_memory_peak) = AG(allocated_memory); - } - #endif -- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); - #if !ZEND_DISABLE_MEMORY_CACHE - } - #endif - -+emalloc_error: -+ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (!p) { -@@ -210,7 +247,10 @@ - # endif - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -- -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } -@@ -238,6 +278,10 @@ - } - } - -+ -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); -+#endif - zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset); - return 0; - } -@@ -270,9 +314,25 @@ - - ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); -+ -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+efree_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); -+ exit(1); -+ } -+ /* to catch double efree()s */ -+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); -+ p->canary = 0; -+#endif - - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { -@@ -313,23 +373,35 @@ - - ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -- void *p; -- int final_size = size*nmemb; -+ char *p; -+ size_t _size = nmemb * size; -+ -+ if (nmemb && (_size/nmemb!=size)) { -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); -+#endif -+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); -+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID -+ kill(getpid(), SIGSEGV); -+#else -+ exit(1); -+#endif -+ } - -- HANDLE_BLOCK_INTERRUPTIONS(); -- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -- if (!p) { -- HANDLE_UNBLOCK_INTERRUPTIONS(); -- return (void *) p; -+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -+ if (p) { -+ memset(p, 0, _size); - } -- memset(p, 0, final_size); -- HANDLE_UNBLOCK_INTERRUPTIONS(); -- return p; -+ -+ return ((void *)p); - } - - - ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p; - zend_mem_header *orig; - DECLARE_CACHE_VARS(); -@@ -341,6 +413,16 @@ - - p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+erealloc_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); -+ exit(1); -+ } -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - void *new_p; -@@ -357,6 +439,13 @@ - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - - HANDLE_BLOCK_INTERRUPTIONS(); -+ -+ if (size > INT_MAX || SIZE < size) { -+ REMOVE_POINTER_FROM_LIST(p); -+ p = NULL; -+ goto erealloc_error; -+ } -+ - #if MEMORY_LIMIT - CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size)); - if (AG(allocated_memory) > AG(allocated_memory_peak)) { -@@ -364,7 +453,8 @@ - } - #endif - REMOVE_POINTER_FROM_LIST(p); -- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); -+erealloc_error: - if (!p) { - if (!allow_failure) { - fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size); -@@ -386,6 +476,9 @@ - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - - HANDLE_UNBLOCK_INTERRUPTIONS(); -@@ -460,6 +553,10 @@ - { - AG(head) = NULL; - -+#if HARDENING_PATCH_MM_PROTECT -+ HG(canary_1) = zend_canary(); -+ HG(canary_2) = zend_canary(); -+#endif - #if MEMORY_LIMIT - AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ - AG(allocated_memory) = 0; -diff -Nura php-5.1.5/Zend/zend_alloc.h hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.h ---- php-5.1.5/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_alloc.h 2006-09-05 20:31:26.000000000 +0200 -@@ -35,6 +35,9 @@ - #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL - - typedef struct _zend_mem_header { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary; -+#endif - #if ZEND_DEBUG - long magic; - char *filename; -diff -Nura php-5.1.5/Zend/zend_API.h hardening-patch-5.1.5-0.4.15/Zend/zend_API.h ---- php-5.1.5/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_API.h 2006-09-05 20:31:26.000000000 +0200 -@@ -47,6 +47,7 @@ - #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) - - #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 }, -+#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 }, - - #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0) - #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0) -diff -Nura php-5.1.5/Zend/zend_builtin_functions.c hardening-patch-5.1.5-0.4.15/Zend/zend_builtin_functions.c ---- php-5.1.5/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:31:26.000000000 +0200 -@@ -53,6 +53,9 @@ - static ZEND_FUNCTION(crash); - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+static ZEND_FUNCTION(heap_overflow); -+#endif - static ZEND_FUNCTION(get_included_files); - static ZEND_FUNCTION(is_subclass_of); - static ZEND_FUNCTION(is_a); -@@ -113,6 +116,9 @@ - ZEND_FE(crash, NULL) - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ ZEND_FE(heap_overflow, NULL) -+#endif - ZEND_FE(get_included_files, NULL) - ZEND_FALIAS(get_required_files, get_included_files, NULL) - ZEND_FE(is_subclass_of, NULL) -@@ -1103,6 +1109,19 @@ - - #endif /* ZEND_DEBUG */ - -+ -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ZEND_FUNCTION(heap_overflow) -+{ -+ char *nowhere = emalloc(10); -+ -+ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); -+ -+ efree(nowhere); -+} -+#endif -+ -+ - /* {{{ proto array get_included_files(void) - Returns an array with the file names that were include_once()'d */ - ZEND_FUNCTION(get_included_files) -diff -Nura php-5.1.5/Zend/zend.c hardening-patch-5.1.5-0.4.15/Zend/zend.c ---- php-5.1.5/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend.c 2006-09-05 20:31:26.000000000 +0200 -@@ -55,6 +55,12 @@ - ZEND_API void (*zend_unblock_interruptions)(void); - ZEND_API void (*zend_ticks_function)(int ticks); - ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); -+#if HARDENING_PATCH -+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); - ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); - -@@ -74,9 +80,391 @@ - return SUCCESS; - } - -+#if HARDENING_PATCH -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; -+ } else { -+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_facility) = LOG_USER; -+ } else { -+ EG(hphp_log_syslog_facility) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_priority) = LOG_ALERT; -+ } else { -+ EG(hphp_log_syslog_priority) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_sapi) -+{ -+ if (!new_value) { -+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; -+ } else { -+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_script) -+{ -+ if (!new_value) { -+ EG(hphp_log_script) = S_ALL & ~S_MEMORY; -+ } else { -+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) -+{ -+ if (EG(hphp_log_scriptname)) { -+ pefree(EG(hphp_log_scriptname),1); -+ } -+ EG(hphp_log_scriptname) = NULL; -+ if (new_value) { -+ EG(hphp_log_scriptname) = pestrdup(new_value,1); -+ } -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_whitelist_destroy: -+ if (HG(include_whitelist)) { -+ zend_hash_destroy(HG(include_whitelist)); -+ pefree(HG(include_whitelist),1); -+ } -+ HG(include_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_whitelist_destroy; -+ } -+ -+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_blacklist_destroy: -+ if (HG(include_blacklist)) { -+ zend_hash_destroy(HG(include_blacklist)); -+ pefree(HG(include_blacklist),1); -+ } -+ HG(include_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_blacklist_destroy; -+ } -+ -+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_whitelist_destroy: -+ if (HG(eval_whitelist)) { -+ zend_hash_destroy(HG(eval_whitelist)); -+ pefree(HG(eval_whitelist),1); -+ } -+ HG(eval_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_whitelist_destroy; -+ } -+ -+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_blacklist_destroy: -+ if (HG(eval_blacklist)) { -+ zend_hash_destroy(HG(eval_blacklist)); -+ pefree(HG(eval_blacklist), 1); -+ } -+ HG(eval_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_blacklist_destroy; -+ } -+ -+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_whitelist_destroy: -+ if (HG(func_whitelist)) { -+ zend_hash_destroy(HG(func_whitelist)); -+ pefree(HG(func_whitelist),1); -+ } -+ HG(func_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_whitelist_destroy; -+ } -+ -+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_blacklist_destroy: -+ if (HG(func_blacklist)) { -+ zend_hash_destroy(HG(func_blacklist)); -+ pefree(HG(func_blacklist),1); -+ } -+ HG(func_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_blacklist_destroy; -+ } -+ -+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+#endif - - ZEND_INI_BEGIN() - ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) -+#if HARDENING_PATCH -+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) -+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) -+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) -+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) -+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) -+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) -+ 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) -+ -+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) -+ -+ 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) -+ 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) -+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) -+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) -+#endif - STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals) - #ifdef ZEND_MULTIBYTE - STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) -@@ -501,9 +889,13 @@ - EG(user_error_handler) = NULL; - EG(user_exception_handler) = NULL; - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(in_autoload) = NULL; - EG(current_execute_data) = NULL; - EG(current_module) = NULL; -+#if HARDENING_PATCH -+ EG(hphp_log_scriptname) = NULL; -+#endif - } - - -@@ -574,6 +966,14 @@ - extern zend_scanner_globals language_scanner_globals; - #endif - -+ /* Set up Hardening-Patch utility functions first */ -+#if HARDENING_PATCH -+ zend_security_log = utility_functions->security_log_function; -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ zend_is_valid_include = utility_functions->is_valid_include; -+#endif -+ - #ifdef ZTS - ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); - #else -@@ -777,6 +1177,7 @@ - } - CG(unclean_shutdown) = 1; - CG(in_compilation) = EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(current_execute_data) = NULL; - longjmp(EG(bailout), FAILURE); - } -diff -Nura php-5.1.5/Zend/zend_canary.c hardening-patch-5.1.5-0.4.15/Zend/zend_canary.c ---- php-5.1.5/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_canary.c 2006-09-05 20:31:26.000000000 +0200 -@@ -0,0 +1,58 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ -+ -+#include "zend.h" -+ -+#include -+#include -+ -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+ZEND_API unsigned int zend_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.5/Zend/zend_compile.c hardening-patch-5.1.5-0.4.15/Zend/zend_compile.c ---- php-5.1.5/Zend/zend_compile.c 2006-03-27 10:09:18.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_compile.c 2006-09-05 20:31:26.000000000 +0200 -@@ -1092,6 +1092,13 @@ - op_array.prototype = NULL; - - op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array.created_by_eval = 1; -+ } else { -+ op_array.created_by_eval = 0; -+ } -+#endif - - if (is_method) { - char *short_class_name = CG(active_class_entry)->name; -diff -Nura php-5.1.5/Zend/zend_compile.h hardening-patch-5.1.5-0.4.15/Zend/zend_compile.h ---- php-5.1.5/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_compile.h 2006-09-05 20:31:26.000000000 +0200 -@@ -217,6 +217,9 @@ - zend_uint doc_comment_len; - - void *reserved[ZEND_MAX_RESERVED_RESOURCES]; -+#if HARDENING_PATCH -+ zend_bool created_by_eval; -+#endif - }; - - -@@ -295,6 +298,8 @@ - zval ***CVs; - zend_bool original_in_execution; - HashTable *symbol_table; -+ zend_uint original_in_code_type; -+ zend_uint execute_depth; - struct _zend_execute_data *prev_execute_data; - zval *old_error_reporting; - }; -@@ -617,6 +622,7 @@ - #define ZEND_OVERLOADED_FUNCTION 3 - #define ZEND_EVAL_CODE 4 - #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5 -+#define ZEND_SANDBOX_CODE 6 - - #define ZEND_INTERNAL_CLASS 1 - #define ZEND_USER_CLASS 2 -diff -Nura php-5.1.5/Zend/zend_constants.c hardening-patch-5.1.5-0.4.15/Zend/zend_constants.c ---- php-5.1.5/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_constants.c 2006-09-05 20:31:26.000000000 +0200 -@@ -109,6 +109,74 @@ - REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); - - REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); -+ -+ /* error levels */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); -+ /* facility: type of program logging the message */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NEWS -+ /* No LOG_NEWS on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ -+#endif -+#ifdef LOG_UUCP -+ /* No LOG_UUCP on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_CRON -+ /* apparently some systems don't have this one */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_AUTHPRIV -+ /* AIX doesn't have LOG_AUTHPRIV */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); -+#endif -+#if !defined(PHP_WIN32) && !defined(NETWARE) -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); -+#endif -+ /* options */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NOWAIT -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_PERROR -+ /* AIX doesn't have LOG_PERROR */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ -+#endif -+#endif - - /* true/false constants */ - { -diff -Nura php-5.1.5/Zend/zend_errors.h hardening-patch-5.1.5-0.4.15/Zend/zend_errors.h ---- php-5.1.5/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_errors.h 2006-09-05 20:31:26.000000000 +0200 -@@ -38,6 +38,19 @@ - #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) - #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) - -+#if HARDENING_PATCH -+#define S_MEMORY (1<<0L) -+#define S_VARS (1<<1L) -+#define S_FILES (1<<2L) -+#define S_INCLUDE (1<<3L) -+#define S_SQL (1<<4L) -+#define S_EXECUTOR (1<<5L) -+#define S_MAIL (1<<6L) -+#define S_MISC (1<<30L) -+#define S_INTERNAL (1<<29L) -+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) -+#endif -+ - #endif /* ZEND_ERRORS_H */ - - /* -diff -Nura php-5.1.5/Zend/zend_execute_API.c hardening-patch-5.1.5-0.4.15/Zend/zend_execute_API.c ---- php-5.1.5/Zend/zend_execute_API.c 2006-03-17 09:47:41.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:31:26.000000000 +0200 -@@ -142,6 +142,7 @@ - EG(class_table) = CG(class_table); - - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(in_autoload) = NULL; - EG(autoload_func) = NULL; - -@@ -784,6 +785,39 @@ - if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) { - EX(function_state).function = NULL; - } -+#if HARDENING_PATCH -+ else { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - efree(function_name_lc); - } - -@@ -1076,7 +1110,7 @@ - return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC); - } - --ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC) - { - zval pv; - zend_op_array *new_op_array; -@@ -1109,6 +1143,7 @@ - zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); - zend_op **original_opline_ptr = EG(opline_ptr); - -+ new_op_array->type = type; - EG(return_value_ptr_ptr) = &local_retval_ptr; - EG(active_op_array) = new_op_array; - EG(no_extensions)=1; -@@ -1143,6 +1178,12 @@ - } - - -+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+{ -+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); -+} -+ -+ - ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) - { - int result; -diff -Nura php-5.1.5/Zend/zend_execute.c hardening-patch-5.1.5-0.4.15/Zend/zend_execute.c ---- php-5.1.5/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_execute.c 2006-09-05 20:31:26.000000000 +0200 -@@ -1351,6 +1351,37 @@ - /* OBJ-TBI - doesn't support new object model! */ - zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - return 0; - } -@@ -1396,6 +1427,7 @@ - efree(EX(Ts)); \ - } \ - EG(in_execution) = EX(original_in_execution); \ -+ EG(in_code_type) = EX(original_in_code_type); \ - EG(current_execute_data) = EX(prev_execute_data); \ - ZEND_VM_RETURN() - -diff -Nura php-5.1.5/Zend/zend_extensions.c hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.c ---- php-5.1.5/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.c 2006-09-05 20:31:26.000000000 +0200 -@@ -55,23 +55,44 @@ - return FAILURE; - } - -+ /* check if module is compiled against Hardening-Patch */ -+ if (extension_version_info->zend_extension_api_no < 1000000000) { -+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } -+ -+ -+ /* check if module is compiled against correct Hardening-Patch version */ -+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { -+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ extension_version_info->zend_extension_api_no, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } - - /* allow extension to proclaim compatibility with any Zend version */ -- 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)) { -- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { -+ 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)) { -+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is outdated.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO); - DL_UNLOAD(handle); - return FAILURE; -- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { -+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is newer.\n" - "Contact %s at %s for a later version of %s.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO, - new_extension->author, - new_extension->URL, -diff -Nura php-5.1.5/Zend/zend_extensions.h hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.h ---- php-5.1.5/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_extensions.h 2006-09-05 20:31:26.000000000 +0200 -@@ -24,9 +24,11 @@ - - #include "zend_compile.h" - --/* The first number is the engine version and the rest is the date. -+/* The first API number is a flag saying that Hardening-Patch is used. -+ * The second number is the engine version and the date. - * This way engine 2 API no. is always greater than engine 1 API no.. - */ -+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106 - #define ZEND_EXTENSION_API_NO 220051025 - - typedef struct _zend_extension_version_info { -@@ -34,6 +36,7 @@ - char *required_zend_version; - unsigned char thread_safe; - unsigned char debug; -+ int real_zend_extension_api_no; - } zend_extension_version_info; - - -@@ -101,7 +104,7 @@ - - - #define ZEND_EXTENSION() \ -- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } -+ 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 } - - #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 - #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 -diff -Nura php-5.1.5/Zend/zend_globals.h hardening-patch-5.1.5-0.4.15/Zend/zend_globals.h ---- php-5.1.5/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_globals.h 2006-09-05 20:31:26.000000000 +0200 -@@ -180,6 +180,16 @@ - - int error_reporting; - int orig_error_reporting; -+#if HARDENING_PATCH -+ int hphp_log_syslog; -+ int hphp_log_syslog_facility; -+ int hphp_log_syslog_priority; -+ int hphp_log_sapi; -+ int hphp_log_script; -+ char *hphp_log_scriptname; -+ zend_bool hphp_log_use_x_forwarded_for; -+ long hphp_executor_max_depth; -+#endif - int exit_status; - - zend_op_array *active_op_array; -@@ -197,6 +207,7 @@ - int ticks_count; - - zend_bool in_execution; -+ zend_uint in_code_type; - HashTable *in_autoload; - zend_function *autoload_func; - zend_bool bailout_set; -diff -Nura php-5.1.5/Zend/zend.h hardening-patch-5.1.5-0.4.15/Zend/zend.h ---- php-5.1.5/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend.h 2006-09-05 20:31:26.000000000 +0200 -@@ -297,6 +297,7 @@ - /* Variable information */ - zvalue_value value; /* value */ - zend_uint refcount; -+ zend_ushort flags; - zend_uchar type; /* active type */ - zend_uchar is_ref; - }; -@@ -382,6 +383,12 @@ - int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); - int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); - char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); -+#if HARDENING_PATCH -+ void (*security_log_function)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ int (*is_valid_include)(zval *z); -+#endif - } zend_utility_functions; - - -@@ -519,7 +526,16 @@ - extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); - extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); - extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); -+#if HARDENING_PATCH -+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+extern ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ZEND_API unsigned int zend_canary(void); -+#endif - - ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); - -@@ -644,6 +660,11 @@ - - #include "zend_variables.h" - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#include "php_syslog.h" -+#endif -+ - #endif /* ZEND_H */ - - /* -diff -Nura php-5.1.5/Zend/zend_hash.c hardening-patch-5.1.5-0.4.15/Zend/zend_hash.c ---- php-5.1.5/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_hash.c 2006-09-05 20:31:26.000000000 +0200 -@@ -21,6 +21,18 @@ - - #include "zend.h" - -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int zend_hash_canary = 0x1234567; -+ zend_bool zend_hash_canary_inited = 0; -+#endif -+ -+#define CHECK_HASH_CANARY(hash) \ -+ if (zend_hash_canary != (hash)->canary) { \ -+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+ - #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ - (element)->pNext = (list_head); \ - (element)->pLast = NULL; \ -@@ -138,6 +150,9 @@ - { - uint i = 3; - Bucket **tmp; -+#if HARDENING_PATCH_HASH_PROTECT -+ TSRMLS_FETCH(); -+#endif - - SET_INCONSISTENT(HT_OK); - -@@ -147,6 +162,13 @@ - - ht->nTableSize = 1 << i; - ht->nTableMask = ht->nTableSize - 1; -+#if HARDENING_PATCH_HASH_PROTECT -+ if (zend_hash_canary_inited==0) { -+ zend_hash_canary = zend_canary(); -+ zend_hash_canary_inited = 1; -+ } -+ ht->canary = zend_hash_canary; -+#endif - ht->pDestructor = pDestructor; - ht->arBuckets = NULL; - ht->pListHead = NULL; -@@ -226,6 +248,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -291,6 +316,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -366,6 +394,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -414,7 +445,7 @@ - IS_CONSISTENT(ht); - - if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ -- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); -+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); - if (t) { - HANDLE_BLOCK_INTERRUPTIONS(); - ht->arBuckets = t; -@@ -424,6 +455,7 @@ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return SUCCESS; - } -+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); - return FAILURE; - } - return SUCCESS; -@@ -489,6 +521,9 @@ - ht->pInternalPointer = p->pListNext; - } - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (p->pData != &p->pDataPtr) { -@@ -513,6 +548,11 @@ - - SET_INCONSISTENT(HT_IS_DESTROYING); - -+#if HARDENING_PATCH_HASH_PROTECT -+ if (ht->pDestructor) { -+ CHECK_HASH_CANARY(ht); -+ } -+#endif - p = ht->pListHead; - while (p != NULL) { - q = p; -@@ -539,6 +579,11 @@ - - SET_INCONSISTENT(HT_CLEANING); - -+#if HARDENING_PATCH_HASH_PROTECT -+ if (ht->pDestructor) { -+ CHECK_HASH_CANARY(ht); -+ } -+#endif - p = ht->pListHead; - while (p != NULL) { - q = p; -@@ -573,6 +618,9 @@ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (p->pData != &p->pDataPtr) { -diff -Nura php-5.1.5/Zend/zend_hash.h hardening-patch-5.1.5-0.4.15/Zend/zend_hash.h ---- php-5.1.5/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_hash.h 2006-09-05 20:31:26.000000000 +0200 -@@ -58,6 +58,9 @@ - } Bucket; - - typedef struct _hashtable { -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int canary; -+#endif - uint nTableSize; - uint nTableMask; - uint nNumOfElements; -diff -Nura php-5.1.5/Zend/zend_ini.c hardening-patch-5.1.5-0.4.15/Zend/zend_ini.c ---- php-5.1.5/Zend/zend_ini.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_ini.c 2006-09-07 19:12:58.000000000 +0200 -@@ -256,7 +256,8 @@ - zend_ini_entry *ini_entry; - TSRMLS_FETCH(); - -- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { -+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || -+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) { - return FAILURE; - } - -diff -Nura php-5.1.5/Zend/zend_language_scanner.l hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.l ---- php-5.1.5/Zend/zend_language_scanner.l 2006-01-17 10:39:57.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:31:26.000000000 +0200 -@@ -389,6 +389,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-5.1.5/Zend/zend_language_scanner.c hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.c ---- php-5.1.5/Zend/zend_language_scanner.c 2006-08-15 14:55:43.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:31:26.000000000 +0200 -@@ -3075,6 +3075,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-5.1.5/Zend/zend_llist.c hardening-patch-5.1.5-0.4.15/Zend/zend_llist.c ---- php-5.1.5/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_llist.c 2006-09-05 20:31:26.000000000 +0200 -@@ -22,9 +22,49 @@ - #include "zend.h" - #include "zend_llist.h" - #include "zend_qsort.h" -+#include "zend_globals.h" -+ -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int zend_llist_canary_1 = 0x1234567; -+ unsigned int zend_llist_canary_2 = 0x1553425; -+ zend_bool zend_llist_canary_inited = 0; -+#endif -+ -+#define CHECK_LIST_CANARY(list) \ -+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ -+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ -+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+#define CHECK_LISTELEMENT_CANARY(elem, list) \ -+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ -+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ -+ exit(1); \ -+ } -+ - - ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ -+ if (persistent) { -+ if (!zend_llist_canary_inited) { -+ /* do not change order to ensure thread safety */ -+ zend_llist_canary_1 = zend_canary(); -+ zend_llist_canary_2 = zend_canary(); -+ zend_llist_canary_inited = 1; -+ } -+ } else -+ if (!HG(ll_canary_inited)) { -+ HG(canary_3) = zend_canary(); -+ HG(canary_4) = zend_canary(); -+ HG(ll_canary_inited) = 1; -+ } -+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); -+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); -+#endif - l->head = NULL; - l->tail = NULL; - l->count = 0; -@@ -38,6 +78,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->prev = l->tail; - tmp->next = NULL; - if (l->tail) { -@@ -56,6 +101,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->next = l->head; - tmp->prev = NULL; - if (l->head) { -@@ -93,10 +143,20 @@ - zend_llist_element *current=l->head; - zend_llist_element *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (compare(current->data, element)) { - DEL_LLIST_ELEMENT(current, l); -+#if HARDENING_PATCH_LL_PROTECT -+ current->canary = 0; -+#endif - break; - } - current = next; -@@ -108,7 +168,14 @@ - { - zend_llist_element *current=l->head, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (l->dtor) { - l->dtor(current->data); -@@ -133,7 +200,14 @@ - zend_llist_element *old_tail; - void *data; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if ((old_tail = l->tail)) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(old_tail, l) -+#endif - if (l->tail->prev) { - l->tail->prev->next = NULL; - } -@@ -159,9 +233,16 @@ - { - zend_llist_element *ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(src) -+#endif - zend_llist_init(dst, src->size, src->dtor, src->persistent); - ptr = src->head; - while (ptr) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(ptr, src) -+#endif - zend_llist_add_element(dst, ptr->data); - ptr = ptr->next; - } -@@ -172,11 +253,21 @@ - { - zend_llist_element *element, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - element=l->head; - while (element) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - next = element->next; - if (func(element->data)) { - DEL_LLIST_ELEMENT(element, l); -+#if HARDENING_PATCH_LL_PROTECT -+ element->canary = 0; -+#endif - } - element = next; - } -@@ -187,7 +278,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data TSRMLS_CC); - } - } -@@ -199,6 +296,9 @@ - zend_llist_element **elements; - zend_llist_element *element, **ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - if (l->count <= 0) { - return; - } -@@ -208,6 +308,9 @@ - ptr = &elements[0]; - - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - *ptr++ = element; - } - -@@ -230,7 +333,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, arg TSRMLS_CC); - } - } -@@ -241,8 +350,14 @@ - zend_llist_element *element; - va_list args; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - va_start(args, num_args); - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, num_args, args TSRMLS_CC); - } - va_end(args); -@@ -251,6 +366,10 @@ - - ZEND_API int zend_llist_count(zend_llist *l) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - return l->count; - } - -@@ -259,8 +378,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->head; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -272,8 +398,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->tail; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -285,9 +418,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->next; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -@@ -299,9 +442,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->prev; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -diff -Nura php-5.1.5/Zend/zend_llist.h hardening-patch-5.1.5-0.4.15/Zend/zend_llist.h ---- php-5.1.5/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_llist.h 2006-09-05 20:31:26.000000000 +0200 -@@ -23,6 +23,9 @@ - #define ZEND_LLIST_H - - typedef struct _zend_llist_element { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary, padding; -+#endif - struct _zend_llist_element *next; - struct _zend_llist_element *prev; - char data[1]; /* Needs to always be last in the struct */ -@@ -35,6 +38,9 @@ - typedef void (*llist_apply_func_t)(void * TSRMLS_DC); - - typedef struct _zend_llist { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_h; /* head */ -+#endif - zend_llist_element *head; - zend_llist_element *tail; - size_t count; -@@ -42,6 +48,9 @@ - llist_dtor_func_t dtor; - unsigned char persistent; - zend_llist_element *traverse_ptr; -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_t; /* tail */ -+#endif - } zend_llist; - - typedef zend_llist_element* zend_llist_position; -diff -Nura php-5.1.5/Zend/zend_modules.h hardening-patch-5.1.5-0.4.15/Zend/zend_modules.h ---- php-5.1.5/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_modules.h 2006-09-05 20:31:26.000000000 +0200 -@@ -39,6 +39,7 @@ - extern struct _zend_arg_info fifth_arg_force_ref[6]; - extern struct _zend_arg_info all_args_by_ref[1]; - -+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106 - #define ZEND_MODULE_API_NO 20050922 - #ifdef ZTS - #define USING_ZTS 1 -@@ -46,13 +47,13 @@ - #define USING_ZTS 0 - #endif - --#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS -+#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS - #define STANDARD_MODULE_HEADER \ - STANDARD_MODULE_HEADER_EX, NULL, NULL - #define ZE2_STANDARD_MODULE_HEADER \ - STANDARD_MODULE_HEADER_EX, ini_entries, NULL - --#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 -+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO - - #define STANDARD_MODULE_PROPERTIES \ - NULL, STANDARD_MODULE_PROPERTIES_EX -@@ -87,6 +88,7 @@ - unsigned char type; - void *handle; - int module_number; -+ unsigned int real_zend_api; - }; - - #define MODULE_DEP_REQUIRED 1 -diff -Nura php-5.1.5/Zend/zend_opcode.c hardening-patch-5.1.5-0.4.15/Zend/zend_opcode.c ---- php-5.1.5/Zend/zend_opcode.c 2006-03-14 12:24:45.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_opcode.c 2006-09-05 20:31:26.000000000 +0200 -@@ -98,6 +98,9 @@ - op_array->uses_this = 0; - - op_array->start_op = NULL; -+#if HARDENING_PATCH -+ op_array->created_by_eval = 0; -+#endif - - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); - } -diff -Nura php-5.1.5/Zend/zend_vm_def.h hardening-patch-5.1.5-0.4.15/Zend/zend_vm_def.h ---- php-5.1.5/Zend/zend_vm_def.h 2006-03-15 12:12:45.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_vm_def.h 2006-09-05 20:31:26.000000000 +0200 -@@ -1769,6 +1769,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (OP2_TYPE != IS_CONST) { -@@ -1994,6 +2025,34 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+#endif -+ - EX(object) = NULL; - - FREE_OP1(); -@@ -2709,7 +2768,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -2734,6 +2798,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -diff -Nura php-5.1.5/Zend/zend_vm_execute.h hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.h ---- php-5.1.5/Zend/zend_vm_execute.h 2006-03-15 12:12:45.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.h 2006-09-05 20:31:26.000000000 +0200 -@@ -56,6 +56,16 @@ - EX(symbol_table) = EG(active_symbol_table); - EX(prev_execute_data) = EG(current_execute_data); - EG(current_execute_data) = &execute_data; -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif - - EG(in_execution) = 1; - if (op_array->start_op) { -@@ -81,6 +91,18 @@ - */ - EX(function_state).function_symbol_table = NULL; - #endif -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif - - while (1) { - #ifdef ZEND_WIN32 -@@ -724,6 +746,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_CONST != IS_CONST) { -@@ -925,6 +978,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_TMP_VAR != IS_CONST) { -@@ -1083,6 +1167,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_VAR != IS_CONST) { -@@ -1330,6 +1445,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_CV != IS_CONST) { -@@ -1635,6 +1781,34 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+#endif -+ - EX(object) = NULL; - - return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); -@@ -1914,7 +2088,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -1939,6 +2118,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -4332,7 +4516,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -4357,6 +4546,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -7332,7 +7526,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -7357,6 +7556,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -19429,7 +19633,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -19454,6 +19663,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -diff -Nura php-5.1.5/Zend/zend_vm_execute.skl hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.skl ---- php-5.1.5/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100 -+++ hardening-patch-5.1.5-0.4.15/Zend/zend_vm_execute.skl 2006-09-05 20:31:26.000000000 +0200 -@@ -27,6 +27,16 @@ - EX(symbol_table) = EG(active_symbol_table); - EX(prev_execute_data) = EG(current_execute_data); - EG(current_execute_data) = &execute_data; -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif - - EG(in_execution) = 1; - if (op_array->start_op) { -@@ -52,6 +62,18 @@ - */ - EX(function_state).function_symbol_table = NULL; - #endif -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif - - while (1) { - {%ZEND_VM_CONTINUE_LABEL%} diff --git a/hardening-patch-5.1.6-0.4.15.patch b/hardening-patch-5.1.6-0.4.15.patch deleted file mode 100644 index dff3280..0000000 --- a/hardening-patch-5.1.6-0.4.15.patch +++ /dev/null @@ -1,8759 +0,0 @@ -diff -Nura php-5.1.6/Changelog.hphp hardening-patch-5.1.6-0.4.15/Changelog.hphp ---- php-5.1.6/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Changelog.hphp 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,61 @@ -+Changelog of the Hardening-Patch -+-------------------------------- -+ -+0.4.15 - 07. September 2006 -+ -+ PHP4: -+ [+] Fix for potential DOS in handling of include blacklists -+ -+ PHP4+5: -+ [+] Backported a fix for open_basedir problems with insanse PHP scripts -+ [+] Added a fix for ini_restore() PHP security vulnerability -+ -+0.4.14 - 11. August 2006 -+ -+ PHP4: -+ [+] Remove unecessary call to AC_BROKEN_REALPATH -+ -+ PHP5: -+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant -+ -+ PHP4+5: -+ [+] Added a few PHP security fixes / see changelog.secfix for details -+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits -+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments -+ -+0.4.13 - 07. August 2006 -+ -+ PHP4+5: -+ [+] Added a fix for a compile problem on solaris due to missing strcasestr() -+ -+0.4.12 - 19. July 2006 -+ -+ PHP4: -+ [+] Added fixes from sf4 security patch / see changelog.secfix for details -+ -+ PHP5: -+ [+] Added fixes from sf5 security patch / see changelog.secfix for details -+ -+ PHP4+5: -+ [+] Added anti mail spam feature -+ [+] Speedup of zend_hash canary (clear/destroy) -+ [+] Added a fix for a DOS in the handling of URL blacklists -+ -+0.4.11 - 13. May 2006 -+ -+ PHP5: -+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache -+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4 -+ -+ PHP4+5: -+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories -+ -+ -+0.4.10 - 11. May 2006 -+ -+ PHP4: -+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed -+ -+ PHP4+5: -+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir -+ -diff -Nura php-5.1.6/Changelog.secfix hardening-patch-5.1.6-0.4.15/Changelog.secfix ---- php-5.1.6/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Changelog.secfix 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,40 @@ -+Changelog of PHP 5.1.4 Security Fixes -+ -+Release 6 - 11. August 2006 -+ -+ [+] Added IMAP open_basedir/safe_mode check -+ [+] Added a fix for previous ext/session fixes -+ [+] Added upstream fix to ext/socket -+ [+] Added sscanf() security fix -+ [+] Added fixes for handling of corrupt .gif files to gdlib -+ -+Release 5 - 13. July 2006 -+ -+ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode -+ -+Release 4 - 13. July 2006 -+ -+ [+] Added a recursive array printing fix to the phpinfo() XSS fix -+ [+] Added a fix for stat() on non existing files in safe_mode -+ -+Release 3 - 07. July 2006 -+ -+ [+] Added a fix for an integer overflow in str_repeat() -+ [+] Added a *working* wordwrap() fix -+ [+] Added code to make memory_limit work on 64bit systems -+ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability -+ [+] Added a fix for overlong tempfilename -+ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl -+ [+] Added a high characters fix to ext/wddx -+ -+Release 2 - 16. May 2006 -+ -+ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP -+ tarball got updated -+ -+Release 1 - 13. May 2006 -+ -+ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball -+ and is downloaded when make install is called (usually as root -> security risk) -+ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache -+ -diff -Nura php-5.1.6/configure hardening-patch-5.1.6-0.4.15/configure ---- php-5.1.6/configure 2006-08-23 14:55:02.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/configure 2006-09-07 19:41:16.000000000 +0200 -@@ -942,6 +942,16 @@ - ac_help="$ac_help - --with-libdir=NAME Look for libraries in .../NAME rather than .../lib" - ac_help="$ac_help -+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection." -+ac_help="$ac_help -+ --disable-hardening-patch-ll-protect Disable the Linked List protection." -+ac_help="$ac_help -+ --disable-hardening-patch-inc-protect Disable include/require protection." -+ac_help="$ac_help -+ --disable-hardening-patch-fmt-protect Disable format string protection." -+ac_help="$ac_help -+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection." -+ac_help="$ac_help - - SAPI modules: - " -@@ -1410,6 +1420,8 @@ - ac_help="$ac_help - --enable-wddx Enable WDDX support" - ac_help="$ac_help -+ --disable-varfilter Disable Hardening-Patch's variable filter" -+ac_help="$ac_help - --disable-xml Disable XML support" - ac_help="$ac_help - --with-libxml-dir=DIR XML: libxml2 install prefix" -@@ -3618,6 +3630,157 @@ - - - -+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given. -+if test "${enable_hardening_patch_mm_protect+set}" = set; then -+ enableval="$enable_hardening_patch_mm_protect" -+ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given. -+if test "${enable_hardening_patch_ll_protect+set}" = set; then -+ enableval="$enable_hardening_patch_ll_protect" -+ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given. -+if test "${enable_hardening_patch_inc_protect+set}" = set; then -+ enableval="$enable_hardening_patch_inc_protect" -+ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given. -+if test "${enable_hardening_patch_fmt_protect+set}" = set; then -+ enableval="$enable_hardening_patch_fmt_protect" -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+ -+fi -+ -+ -+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given. -+if test "${enable_hardening_patch_hash_protect+set}" = set; then -+ enableval="$enable_hardening_patch_hash_protect" -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+ -+else -+ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+ -+fi -+ -+ -+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6 -+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6 -+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6 -+echo "configure:2733: checking whether to protect include/require statements" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect PHP Format String functions" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6 -+ -+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6 -+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5 -+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6 -+ -+ -+cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH 1 -+EOF -+ -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_MM_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_LL_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_INC_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_FMT_PROTECT 0 -+EOF -+ -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 1 -+EOF -+ -+else -+ cat >> confdefs.h <<\EOF -+#define HARDENING_PATCH_HASH_PROTECT 0 -+EOF -+ -+fi - - - -@@ -18607,6 +18770,62 @@ - fi - - -+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6 -+echo "configure:14928: checking whether realpath is broken" >&5 -+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then -+ echo $ac_n "(cached) $ac_c" 1>&6 -+else -+ -+ if test "$cross_compiling" = yes; then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -+then -+ -+ ac_cv_broken_realpath=no -+ -+else -+ echo "configure: failed program was:" >&5 -+ cat conftest.$ac_ext >&5 -+ rm -fr conftest* -+ -+ ac_cv_broken_realpath=yes -+ -+fi -+rm -fr conftest* -+fi -+ -+ -+fi -+ -+echo "$ac_t""$ac_cv_broken_realpath" 1>&6 -+ if test "$ac_cv_broken_realpath" = "yes"; then -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 1 -+EOF -+ -+ else -+ cat >> confdefs.h <<\EOF -+#define PHP_BROKEN_REALPATH 0 -+EOF -+ -+ fi -+ -+ - echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 - echo "configure:18612: checking for declared timezone" >&5 - if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then -@@ -89422,7 +89641,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - cat >> confdefs.h <&6 -+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5 -+# Check whether --enable-varfilter or --disable-varfilter was given. -+if test "${enable_varfilter+set}" = set; then -+ enableval="$enable_varfilter" -+ PHP_VARFILTER=$enableval -+else -+ -+ PHP_VARFILTER=yes -+ -+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then -+ PHP_VARFILTER=$PHP_ENABLE_ALL -+ fi -+ -+fi -+ -+ -+ -+ext_output="yes, shared" -+ext_shared=yes -+case $PHP_VARFILTER in -+shared,*) -+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'` -+ ;; -+shared) -+ PHP_VARFILTER=yes -+ ;; -+no) -+ ext_output=no -+ ext_shared=no -+ ;; -+*) -+ ext_output=yes -+ ext_shared=no -+ ;; -+esac -+ -+ -+ -+echo "$ac_t""$ext_output" 1>&6 -+ -+ -+ -+ -+if test "$PHP_VARFILTER" != "no"; then -+ cat >> confdefs.h <<\EOF -+#define HAVE_VARFILTER 1 -+EOF -+ -+ -+ ext_builddir=ext/varfilter -+ ext_srcdir=$abs_srcdir/ext/varfilter -+ -+ ac_extra= -+ -+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then -+ -+ -+ -+ case ext/varfilter in -+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;; -+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;; -+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;; -+ esac -+ -+ -+ -+ b_c_pre=$php_c_pre -+ b_cxx_pre=$php_cxx_pre -+ b_c_meta=$php_c_meta -+ b_cxx_meta=$php_cxx_meta -+ b_c_post=$php_c_post -+ b_cxx_post=$php_cxx_post -+ b_lo=$php_lo -+ -+ -+ old_IFS=$IFS -+ for ac_src in varfilter.c; do -+ -+ IFS=. -+ set $ac_src -+ ac_obj=$1 -+ IFS=$old_IFS -+ -+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo" -+ -+ case $ac_src in -+ *.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" ;; -+ *.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" ;; -+ esac -+ -+ cat >>Makefile.objects<>Makefile.objects<>Makefile.objects<> confdefs.h <>Makefile.objects<>Makefile.objects<&6 -@@ -112351,7 +112829,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_logos.c \ -- output.c ; do -+ output.c hardening_patch.c ; do - - IFS=. - set $ac_src -@@ -112596,7 +113074,7 @@ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ - zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ -- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do -+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do - - IFS=. - set $ac_src -diff -Nura php-5.1.6/configure.in hardening-patch-5.1.6-0.4.15/configure.in ---- php-5.1.6/configure.in 2006-08-23 15:17:36.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/configure.in 2006-09-07 19:41:16.000000000 +0200 -@@ -209,7 +209,7 @@ - - sinclude(Zend/Zend.m4) - sinclude(TSRM/tsrm.m4) -- -+sinclude(main/hardening_patch.m4) - - divert(2) - -@@ -1275,7 +1275,7 @@ - php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \ - network.c php_open_temporary_file.c php_logos.c \ -- output.c ) -+ output.c hardening_patch.c ) - - PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \ - plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c) -@@ -1302,7 +1302,7 @@ - zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ - zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ -- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c) -+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c ) - - if test -r "$abs_srcdir/Zend/zend_objects.c"; then - PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \ -diff -Nura php-5.1.6/ext/curl/interface.c hardening-patch-5.1.6-0.4.15/ext/curl/interface.c ---- php-5.1.6/ext/curl/interface.c 2006-08-10 19:16:35.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/curl/interface.c 2006-09-07 19:41:16.000000000 +0200 -@@ -172,6 +172,11 @@ - RETURN_FALSE; \ - } \ - \ -+ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \ -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \ -+ RETURN_FALSE; \ -+ } \ -+ \ - if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \ - (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \ - ) { \ -diff -Nura php-5.1.6/ext/fbsql/php_fbsql.c hardening-patch-5.1.6-0.4.15/ext/fbsql/php_fbsql.c ---- php-5.1.6/ext/fbsql/php_fbsql.c 2006-08-14 20:40:20.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/fbsql/php_fbsql.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1949,8 +1949,24 @@ - } - else if (fbcmdErrorsFound(md)) - { -+#if HARDENING_PATCH -+ char* query_copy; -+ int i; -+#endif - FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md); - char* emg = fbcemdAllErrorMessages(emd); -+#if HARDENING_PATCH -+ query_copy=estrdup(query_copy); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ free(emg); -+ fbcemdRelease(emd); -+ result = 0; -+ zend_bailout(); -+ } -+#endif - if (FB_SQL_G(generateWarnings)) - { - if (emg) -diff -Nura php-5.1.6/ext/imap/php_imap.c hardening-patch-5.1.6-0.4.15/ext/imap/php_imap.c ---- php-5.1.6/ext/imap/php_imap.c 2006-08-11 17:07:13.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/imap/php_imap.c 2006-09-07 19:41:16.000000000 +0200 -@@ -768,6 +768,13 @@ - RETURN_FALSE; - } - -+ /* local filename, need to perform open_basedir and safe_mode checks */ -+ if (Z_STRVAL_PP(mailbox)[0] != '{' && -+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) || -+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) { -+ RETURN_FALSE; -+ } -+ - IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user)); - IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd)); - -diff -Nura php-5.1.6/ext/mysql/php_mysql.c hardening-patch-5.1.6-0.4.15/ext/mysql/php_mysql.c ---- php-5.1.6/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/mysql/php_mysql.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1231,6 +1231,8 @@ - { - php_mysql_conn *mysql; - MYSQL_RES *mysql_result; -+ char *copy_query; -+ int i; - - ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink); - -@@ -1281,6 +1283,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #else -@@ -1291,6 +1300,13 @@ - php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); - } - } -+ copy_query = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.'; -+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query); -+ efree(copy_query); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } - RETURN_FALSE; - } - #endif -diff -Nura php-5.1.6/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.6-0.4.15/ext/mysqli/mysqli_nonapi.c ---- php-5.1.6/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/mysqli/mysqli_nonapi.c 2006-09-07 19:41:16.000000000 +0200 -@@ -184,6 +184,17 @@ - if (mysql_real_query(mysql->mysql, query, query_len)) { - char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1]; - unsigned int s_errno; -+#if HARDENING_PATCH -+ char *query_copy = estrdup(query); -+ int i; -+ -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } -+#endif - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - - /* we have to save error information, cause -@@ -234,6 +245,17 @@ - MYSQLI_DISABLE_MQ; - - if (mysql_real_query(mysql->mysql, query, query_len)) { -+#if HARDENING_PATCH -+ char *query_copy = estrdup(query); -+ int i; -+ -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ zend_bailout(); -+ } -+#endif - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_FALSE; - } -diff -Nura php-5.1.6/ext/pgsql/pgsql.c hardening-patch-5.1.6-0.4.15/ext/pgsql/pgsql.c ---- php-5.1.6/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/pgsql/pgsql.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1152,10 +1152,28 @@ - case PGRES_EMPTY_QUERY: - case PGRES_BAD_RESPONSE: - case PGRES_NONFATAL_ERROR: -- case PGRES_FATAL_ERROR: -- PHP_PQ_ERROR("Query failed: %s", pgsql); -- PQclear(pgsql_result); -- RETURN_FALSE; -+ case PGRES_FATAL_ERROR: -+ { -+#if HARDENING_PATCH -+ int i; -+ char *query_copy; -+#endif -+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); -+ PQclear(pgsql_result); -+#if HARDENING_PATCH -+ query_copy = estrdup(Z_STRVAL_PP(query)); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ efree(msgbuf); -+ zend_bailout(); -+ } -+#endif -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf); -+ efree(msgbuf); -+ RETURN_FALSE; -+ } - break; - case PGRES_COMMAND_OK: /* successful command that did not return rows */ - default: -diff -Nura php-5.1.6/ext/session/mod_files.c hardening-patch-5.1.6-0.4.15/ext/session/mod_files.c ---- php-5.1.6/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/session/mod_files.c 2006-09-07 19:41:16.000000000 +0200 -@@ -152,6 +152,7 @@ - - if (!ps_files_valid_key(key)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'"); -+ PS(invalid_session_id) = 1; - return; - } - if (!ps_files_path_create(buf, sizeof(buf), data, key)) -@@ -401,7 +402,12 @@ - ps_files_close(data); - - if (VCWD_UNLINK(buf) == -1) { -- return FAILURE; -+ /* This is a little safety check for instances when we are dealing with a regenerated session -+ * that was not yet written to disk -+ */ -+ if (!VCWD_ACCESS(buf, F_OK)) { -+ return FAILURE; -+ } - } - } - -@@ -422,6 +428,35 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(files) -+{ -+ char buf[MAXPATHLEN]; -+ int fd; -+ PS_FILES_DATA; -+ -+ if (!ps_files_valid_key(key)) { -+ return FAILURE; -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) { -+ return FAILURE; -+ } -+ -+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, -+ data->filemode); -+ -+ if (fd != -1) { -+ close(fd); -+ return SUCCESS; -+ } -+ -+ return FAILURE; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-5.1.6/ext/session/mod_mm.c hardening-patch-5.1.6-0.4.15/ext/session/mod_mm.c ---- php-5.1.6/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/session/mod_mm.c 2006-09-07 19:41:16.000000000 +0200 -@@ -425,6 +425,42 @@ - return SUCCESS; - } - -+PS_VALIDATE_SID_FUNC(mm) -+{ -+ PS_MM_DATA; -+ ps_sd *sd; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ } -+ } -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ mm_lock(data->mm, MM_LOCK_RD); -+ -+ sd = ps_sd_lookup(data, key, 0); -+ if (sd) { -+ mm_unlock(data->mm); -+ return SUCCESS; -+ } -+ -+ mm_unlock(data->mm); -+ -+ return FAILURE; -+} -+ - #endif - - /* -diff -Nura php-5.1.6/ext/session/mod_user.c hardening-patch-5.1.6-0.4.15/ext/session/mod_user.c ---- php-5.1.6/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/session/mod_user.c 2006-09-07 19:41:16.000000000 +0200 -@@ -23,7 +23,7 @@ - #include "mod_user.h" - - ps_module ps_mod_user = { -- PS_MOD(user) -+ PS_MOD_SID(user) - }; - - #define SESS_ZVAL_LONG(val, a) \ -@@ -174,6 +174,83 @@ - FINISH; - } - -+PS_CREATE_SID_FUNC(user) -+{ -+ int i; -+ char *val = NULL; -+ zval *retval; -+ ps_user *mdata = PS_GET_MOD_DATA(); -+ -+ if (!mdata) -+ return estrndup("", 0); -+ -+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) { -+ return php_session_create_id(mod_data, newlen TSRMLS_CC); -+ } -+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC); -+ -+ if (retval) { -+ if (Z_TYPE_P(retval) == IS_STRING) { -+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); -+ } else { -+ val = estrndup("", 0); -+ } -+ zval_ptr_dtor(&retval); -+ } else { -+ val = estrndup("", 0); -+ } -+ -+ return val; -+} -+ -+static int ps_user_valid_key(const char *key TSRMLS_DC) -+{ -+ size_t len; -+ const char *p; -+ char c; -+ int ret = SUCCESS; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ ret = FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ ret = FAILURE; -+ -+ return ret; -+} -+ -+PS_VALIDATE_SID_FUNC(user) -+{ -+ zval *args[1]; -+ STDVARS; -+ -+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) { -+ return ps_user_valid_key(key TSRMLS_CC); -+ } -+ SESS_ZVAL_STRING(key, args[0]); -+ -+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC); -+ -+ if (retval) { -+ convert_to_long(retval); -+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE; -+ zval_ptr_dtor(&retval); -+ } -+ -+ return ret; -+} -+ - /* - * Local variables: - * tab-width: 4 -diff -Nura php-5.1.6/ext/session/mod_user.h hardening-patch-5.1.6-0.4.15/ext/session/mod_user.h ---- php-5.1.6/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/session/mod_user.h 2006-09-07 19:41:16.000000000 +0200 -@@ -22,7 +22,7 @@ - #define MOD_USER_H - - typedef union { -- zval *names[6]; -+ zval *names[8]; - struct { - zval *ps_open; - zval *ps_close; -@@ -30,6 +30,8 @@ - zval *ps_write; - zval *ps_destroy; - zval *ps_gc; -+ zval *ps_create; -+ zval *ps_validate; - } name; - } ps_user; - -diff -Nura php-5.1.6/ext/session/php_session.h hardening-patch-5.1.6-0.4.15/ext/session/php_session.h ---- php-5.1.6/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/session/php_session.h 2006-09-07 19:41:16.000000000 +0200 -@@ -23,7 +23,7 @@ - - #include "ext/standard/php_var.h" - --#define PHP_SESSION_API 20020330 -+#define PHP_SESSION_API 20051121 - - #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC - #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC -@@ -32,6 +32,7 @@ - #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC - #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC - #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC -+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC - - /* default create id function */ - PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); -@@ -45,6 +46,7 @@ - int (*s_destroy)(PS_DESTROY_ARGS); - int (*s_gc)(PS_GC_ARGS); - char *(*s_create_sid)(PS_CREATE_SID_ARGS); -+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS); - } ps_module; - - #define PS_GET_MOD_DATA() *mod_data -@@ -57,6 +59,7 @@ - #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS) - #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS) - #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS) -+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) - - #define PS_FUNCS(x) \ - PS_OPEN_FUNC(x); \ -@@ -65,11 +68,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID_FUNC(x) - - #define PS_MOD(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, php_session_create_id -+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x - - /* SID enabled module handler definitions */ - #define PS_FUNCS_SID(x) \ -@@ -79,11 +83,12 @@ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ -- PS_CREATE_SID_FUNC(x) -+ PS_CREATE_SID_FUNC(x); \ -+ PS_VALIDATE_SID(x) - - #define PS_MOD_SID(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ -- ps_delete_##x, ps_gc_##x, ps_create_sid_##x -+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x - - typedef enum { - php_session_disabled, -@@ -120,11 +125,13 @@ - zend_bool use_only_cookies; - zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ - zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ -+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ - - long hash_func; - long hash_bits_per_character; - int send_cookie; - int define_sid; -+ zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ - } php_ps_globals; - - typedef php_ps_globals zend_ps_globals; -diff -Nura php-5.1.6/ext/session/session.c hardening-patch-5.1.6-0.4.15/ext/session/session.c ---- php-5.1.6/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/session/session.c 2006-09-07 19:41:16.000000000 +0200 -@@ -166,6 +166,7 @@ - STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals) -+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals) -@@ -280,9 +281,13 @@ - PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) - { - zval **sym_track = NULL; -- -- zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, -- (void *) &sym_track); -+ -+ IF_SESSION_VARS() { -+ zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1, -+ (void *) &sym_track); -+ } else { -+ return; -+ } - - /* - * Set up a proper reference between $_SESSION["x"] and $x. -@@ -758,9 +763,23 @@ - return; - } - -+ /* If there is an ID, use session module to verify it */ -+ if (PS(id)) { -+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -+ efree(PS(id)); -+ PS(id) = NULL; -+ PS(send_cookie) = 1; -+ } -+ } -+ - /* If there is no ID, use session module to create one */ -- if (!PS(id)) -+ if (!PS(id)) { -+new_session: - PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); -+ if (PS(use_cookies)) { -+ PS(send_cookie) = 1; -+ } -+ } - - /* Read data */ - /* Question: if you create a SID here, should you also try to read data? -@@ -769,9 +788,14 @@ - * session information - */ - php_session_track_init(TSRMLS_C); -+ PS(invalid_session_id) = 0; - if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) { - php_session_decode(val, vallen TSRMLS_CC); - efree(val); -+ } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */ -+ PS(invalid_session_id) = 0; -+ efree(PS(id)); -+ goto new_session; - } - } - -@@ -1377,22 +1401,29 @@ - } - /* }}} */ - --/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) -+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate]) - Sets user-level functions */ - PHP_FUNCTION(session_set_save_handler) - { -- zval **args[6]; -- int i; -+ zval **args[8]; -+ int i, numargs; - ps_user *mdata; - char *name; - -- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) -+ numargs = ZEND_NUM_ARGS(); -+ args[6] = NULL; -+ args[7] = NULL; -+ -+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE) - WRONG_PARAM_COUNT; - - if (PS(session_status) != php_session_none) - RETURN_FALSE; - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ continue; -+ } - if (!zend_is_callable(*args[i], 0, &name)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1); - efree(name); -@@ -1405,7 +1436,11 @@ - - mdata = emalloc(sizeof(*mdata)); - -- for (i = 0; i < 6; i++) { -+ for (i = 0; i < 8; i++) { -+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) { -+ mdata->names[i] = NULL; -+ continue; -+ } - ZVAL_ADDREF(*args[i]); - mdata->names[i] = *args[i]; - } -@@ -1475,6 +1510,11 @@ - WRONG_PARAM_COUNT; - } - -+ if (SG(headers_sent)) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent"); -+ RETURN_FALSE; -+ } -+ - if (PS(session_status) == php_session_active) { - if (PS(id)) { - if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { -@@ -1531,8 +1571,8 @@ - WRONG_PARAM_COUNT; - - if (ac == 1) { -- convert_to_long_ex(p_cache_expire); -- PS(cache_expire) = Z_LVAL_PP(p_cache_expire); -+ convert_to_string_ex(p_cache_expire); -+ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - } - - RETVAL_LONG(old); -diff -Nura php-5.1.6/ext/session/tests/014.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/014.phpt ---- php-5.1.6/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/session/tests/014.phpt 2006-09-07 19:41:16.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.bug_compat_42=1 -diff -Nura php-5.1.6/ext/session/tests/015.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/015.phpt ---- php-5.1.6/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/session/tests/015.phpt 2006-09-07 19:41:16.000000000 +0200 -@@ -5,6 +5,7 @@ - --INI-- - session.use_trans_sid=1 - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - arg_separator.output=& - session.name=PHPSESSID -diff -Nura php-5.1.6/ext/session/tests/018.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/018.phpt ---- php-5.1.6/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/session/tests/018.phpt 2006-09-07 19:41:16.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - session.name=PHPSESSID -diff -Nura php-5.1.6/ext/session/tests/019.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/019.phpt ---- php-5.1.6/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/session/tests/019.phpt 2006-09-07 19:41:16.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - register_globals=1 - session.serialize_handler=php -diff -Nura php-5.1.6/ext/session/tests/020.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/020.phpt ---- php-5.1.6/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/session/tests/020.phpt 2006-09-07 19:41:16.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - arg_separator.output=& -diff -Nura php-5.1.6/ext/session/tests/021.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/021.phpt ---- php-5.1.6/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/session/tests/021.phpt 2006-09-07 19:41:16.000000000 +0200 -@@ -4,6 +4,7 @@ - - --INI-- - session.use_cookies=0 -+session.use_strict_mode=0 - session.cache_limiter= - session.use_trans_sid=1 - url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset=" -diff -Nura php-5.1.6/ext/session/tests/bug38377.phpt hardening-patch-5.1.6-0.4.15/ext/session/tests/bug38377.phpt ---- php-5.1.6/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/session/tests/bug38377.phpt 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,13 @@ -+--TEST-- -+bug #38377 (session_destroy() gives warning after session_regenerate_id()) -+--SKIPIF-- -+ -+--FILE-- -+ -+--EXPECT-- -+Done -diff -Nura php-5.1.6/ext/sockets/sockets.c hardening-patch-5.1.6-0.4.15/ext/sockets/sockets.c ---- php-5.1.6/ext/sockets/sockets.c 2006-04-07 16:04:36.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/sockets/sockets.c 2006-09-07 19:41:16.000000000 +0200 -@@ -533,6 +533,7 @@ - { - zval **element; - php_socket *php_sock; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -547,9 +548,10 @@ - if (php_sock->bsd_socket > *max_fd) { - *max_fd = php_sock->bsd_socket; - } -+ num++; - } - -- return 1; -+ return num ? 1 : 0; - } - - static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC) -@@ -558,6 +560,7 @@ - zval **dest_element; - php_socket *php_sock; - HashTable *new_hash; -+ int num = 0; - - if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0; - -@@ -575,6 +578,7 @@ - zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element); - if (dest_element) zval_add_ref(dest_element); - } -+ num++; - } - - /* Destroy old array, add new one */ -@@ -584,7 +588,7 @@ - zend_hash_internal_pointer_reset(new_hash); - Z_ARRVAL_P(sock_array) = new_hash; - -- return 1; -+ return num ? 1 : 0; - } - - /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds, int tv_sec[, int tv_usec]) -diff -Nura php-5.1.6/ext/sqlite/sess_sqlite.c hardening-patch-5.1.6-0.4.15/ext/sqlite/sess_sqlite.c ---- php-5.1.6/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/sqlite/sess_sqlite.c 2006-09-07 19:41:16.000000000 +0200 -@@ -185,6 +185,76 @@ - return SQLITE_RETVAL(rv); - } - -+PS_VALIDATE_SID_FUNC(sqlite) -+{ -+ PS_SQLITE_DATA; -+ char *query; -+ const char *tail; -+ sqlite_vm *vm; -+ int colcount, result; -+ const char **rowdata, **colnames; -+ char *error; -+ size_t len; -+ const char *p; -+ char c; -+ int ret = FAILURE; -+ -+ for (p = key; (c = *p); p++) { -+ /* valid characters are a..z,A..Z,0..9 */ -+ if (!((c >= 'a' && c <= 'z') -+ || (c >= 'A' && c <= 'Z') -+ || (c >= '0' && c <= '9') -+ || c == ',' -+ || c == '-')) { -+ return FAILURE; -+ break; -+ } -+ } -+ -+ len = p - key; -+ -+ if (len == 0) -+ return FAILURE; -+ -+ if (!PS(use_strict_mode)) { -+ return SUCCESS; -+ } -+ -+ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key); -+ if (query == NULL) { -+ /* no memory */ -+ return FAILURE; -+ } -+ -+ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error); -+ sqlite_freemem(error); -+ sqlite_freemem(query); -+ return FAILURE; -+ } -+ -+ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) { -+ case SQLITE_ROW: -+ if (rowdata[0] != NULL) { -+ ret = SUCCESS; -+ } -+ break; -+ default: -+ sqlite_freemem(error); -+ error = NULL; -+ } -+ -+ if (SQLITE_OK != sqlite_finalize(vm, &error)) { -+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error); -+ sqlite_freemem(error); -+ error = NULL; -+ } -+ -+ sqlite_freemem(query); -+ -+ return ret; -+} -+ - #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */ - - /* -diff -Nura php-5.1.6/ext/sqlite/sqlite.c hardening-patch-5.1.6-0.4.15/ext/sqlite/sqlite.c ---- php-5.1.6/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/sqlite/sqlite.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1530,6 +1530,19 @@ - db->last_err_code = ret; - - if (ret != SQLITE_OK) { -+#if HARDENING_PATCH -+ char *query_copy; -+ int i; -+ -+ query_copy = estrdup(sql); -+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.'; -+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy); -+ efree(query_copy); -+ if (HG(hphp_sql_bailout_on_error)) { -+ sqlite_freemem(errtext); -+ zend_bailout(); -+ } -+#endif - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext); - if (errmsg) { - ZVAL_STRING(errmsg, errtext, 1); -diff -Nura php-5.1.6/ext/standard/array.c hardening-patch-5.1.6-0.4.15/ext/standard/array.c ---- php-5.1.6/ext/standard/array.c 2006-06-03 20:59:55.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/array.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1297,6 +1297,32 @@ - } - } - } -+ -+ if (var_name[0] == 'H') { -+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_VARS")==0)|| -+ (strcmp(var_name, "HTTP_POST_FILES")==0)|| -+ (strcmp(var_name, "HTTP_ENV_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) { -+ return 0; -+ } -+ } else if (var_name[0] == '_') { -+ if ((strcmp(var_name, "_COOKIE")==0)|| -+ (strcmp(var_name, "_ENV")==0)|| -+ (strcmp(var_name, "_FILES")==0)|| -+ (strcmp(var_name, "_GET")==0)|| -+ (strcmp(var_name, "_POST")==0)|| -+ (strcmp(var_name, "_REQUEST")==0)|| -+ (strcmp(var_name, "_SESSION")==0)|| -+ (strcmp(var_name, "_SERVER")==0)) { -+ return 0; -+ } -+ } else if (strcmp(var_name, "GLOBALS")==0) { -+ return 0; -+ } - - return 1; - } -diff -Nura php-5.1.6/ext/standard/basic_functions.c hardening-patch-5.1.6-0.4.15/ext/standard/basic_functions.c ---- php-5.1.6/ext/standard/basic_functions.c 2006-06-29 00:08:59.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:41:16.000000000 +0200 -@@ -151,12 +151,14 @@ - typedef struct _php_shutdown_function_entry { - zval **arguments; - int arg_count; -+ zend_bool created_by_eval; - } php_shutdown_function_entry; - - typedef struct _user_tick_function_entry { - zval **arguments; - int arg_count; - int calling; -+ zend_bool created_by_eval; - } user_tick_function_entry; - - /* some prototypes for local functions */ -@@ -188,6 +190,8 @@ - PHP_FE(get_html_translation_table, NULL) - PHP_FE(sha1, NULL) - PHP_FE(sha1_file, NULL) -+ PHP_FE(sha256, NULL) -+ PHP_FE(sha256_file, NULL) - PHP_NAMED_FE(md5,php_if_md5, NULL) - PHP_NAMED_FE(md5_file,php_if_md5_file, NULL) - PHP_NAMED_FE(crc32,php_if_crc32, NULL) -@@ -632,7 +636,7 @@ - PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL) - - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) -- PHP_FE(realpath, NULL) -+ PHP_STATIC_FE("realpath", zif_real_path, NULL) - #endif - - #ifdef HAVE_FNMATCH -@@ -2279,6 +2283,13 @@ - { - zval retval; - char *function_name = NULL; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (shutdown_function_entry->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { - php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); -@@ -2294,6 +2305,9 @@ - if (function_name) { - efree(function_name); - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - return 0; - } - -@@ -2301,6 +2315,13 @@ - { - zval retval; - zval *function = tick_fe->arguments[0]; -+#if HARDENING_PATCH -+ zend_uint orig_code_type = EG(in_code_type); -+ -+ if (tick_fe->created_by_eval) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } -+#endif - - /* Prevent reentrant calls to the same user ticks function */ - if (! tick_fe->calling) { -@@ -2332,6 +2353,9 @@ - - tick_fe->calling = 0; - } -+#if HARDENING_PATCH -+ EG(in_code_type) = orig_code_type; -+#endif - } - - static void run_user_tick_functions(int tick_count) -@@ -2395,6 +2419,13 @@ - } - - shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ shutdown_function_entry.created_by_eval = 1; -+ } else { -+ shutdown_function_entry.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { - efree(shutdown_function_entry.arguments); -@@ -2722,6 +2753,15 @@ - - convert_to_string_ex(varname); - -+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */ -+ if (PG(safe_mode)) { -+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) || -+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) || -+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) { -+ RETURN_FALSE; -+ } -+ } -+ - zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME); - } - /* }}} */ -@@ -2979,6 +3019,13 @@ - } - - tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ tick_fe.created_by_eval = 1; -+ } else { -+ tick_fe.created_by_eval = 0; -+ } -+#endif - - if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) { - efree(tick_fe.arguments); -@@ -3282,6 +3329,35 @@ - new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); - } - -+ if (new_key[0] == 'H') { -+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_VARS")==0)|| -+ (strcmp(new_key, "HTTP_POST_FILES")==0)|| -+ (strcmp(new_key, "HTTP_ENV_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)|| -+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)|| -+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)|| -+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (new_key[0] == '_') { -+ if ((strcmp(new_key, "_COOKIE")==0)|| -+ (strcmp(new_key, "_ENV")==0)|| -+ (strcmp(new_key, "_FILES")==0)|| -+ (strcmp(new_key, "_GET")==0)|| -+ (strcmp(new_key, "_POST")==0)|| -+ (strcmp(new_key, "_REQUEST")==0)|| -+ (strcmp(new_key, "_SESSION")==0)|| -+ (strcmp(new_key, "_SERVER")==0)) { -+ efree(new_key); -+ return 0; -+ } -+ } else if (strcmp(new_key, "GLOBALS")==0) { -+ efree(new_key); -+ return 0; -+ } -+ - zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); - ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0); - -diff -Nura php-5.1.6/ext/standard/config.m4 hardening-patch-5.1.6-0.4.15/ext/standard/config.m4 ---- php-5.1.6/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/config.m4 2006-09-07 19:41:16.000000000 +0200 -@@ -203,7 +203,7 @@ - if test "$ac_cv_crypt_blowfish" = "yes"; then - ac_result=1 - else -- ac_result=0 -+ ac_result=1 - fi - AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt]) - ]) -@@ -489,7 +489,7 @@ - incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ - http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ - var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ -- filters.c proc_open.c streamsfuncs.c http.c) -+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ) - - PHP_ADD_MAKEFILE_FRAGMENT - -diff -Nura php-5.1.6/ext/standard/config.w32 hardening-patch-5.1.6-0.4.15/ext/standard/config.w32 ---- php-5.1.6/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/config.w32 2006-09-07 19:41:16.000000000 +0200 -@@ -16,5 +16,5 @@ - url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ - php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ - user_filters.c uuencode.c filters.c proc_open.c \ -- streamsfuncs.c http.c", false /* never shared */); -+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */); - -diff -Nura php-5.1.6/ext/standard/crypt_blowfish.c hardening-patch-5.1.6-0.4.15/ext/standard/crypt_blowfish.c ---- php-5.1.6/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/crypt_blowfish.c 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,748 @@ -+/* -+ * This code comes from John the Ripper password cracker, with reentrant -+ * and crypt(3) interfaces added, but optimizations specific to password -+ * cracking removed. -+ * -+ * Written by Solar Designer in 1998-2002 and -+ * placed in the public domain. -+ * -+ * There's absolutely no warranty. -+ * -+ * It is my intent that you should be able to use this on your system, -+ * as a part of a software package, or anywhere else to improve security, -+ * ensure compatibility, or for any other purpose. I would appreciate -+ * it if you give credit where it is due and keep your modifications in -+ * the public domain as well, but I don't require that in order to let -+ * you place this code and any modifications you make under a license -+ * of your choice. -+ * -+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a) -+ * by Niels Provos , and uses some of his -+ * ideas. The password hashing algorithm was designed by David Mazieres -+ * . -+ * -+ * There's a paper on the algorithm that explains its design decisions: -+ * -+ * http://www.usenix.org/events/usenix99/provos.html -+ * -+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's -+ * Blowfish library (I can't be sure if I would think of something if I -+ * hadn't seen his code). -+ */ -+ -+#include -+ -+#include -+#ifndef __set_errno -+#define __set_errno(val) errno = (val) -+#endif -+ -+#undef __CONST -+#ifdef __GNUC__ -+#define __CONST __const -+#else -+#define __CONST -+#endif -+ -+#ifdef __i386__ -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#elif defined(__alpha__) || defined(__hppa__) -+#define BF_ASM 0 -+#define BF_SCALE 1 -+#else -+#define BF_ASM 0 -+#define BF_SCALE 0 -+#endif -+ -+typedef unsigned int BF_word; -+ -+/* Number of Blowfish rounds, this is also hardcoded into a few places */ -+#define BF_N 16 -+ -+typedef BF_word BF_key[BF_N + 2]; -+ -+typedef struct { -+ BF_word S[4][0x100]; -+ BF_key P; -+} BF_ctx; -+ -+/* -+ * Magic IV for 64 Blowfish encryptions that we do at the end. -+ * The string is "OrpheanBeholderScryDoubt" on big-endian. -+ */ -+static BF_word BF_magic_w[6] = { -+ 0x4F727068, 0x65616E42, 0x65686F6C, -+ 0x64657253, 0x63727944, 0x6F756274 -+}; -+ -+/* -+ * P-box and S-box tables initialized with digits of Pi. -+ */ -+static BF_ctx BF_init_state = { -+ { -+ { -+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, -+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, -+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, -+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, -+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, -+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, -+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, -+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, -+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, -+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, -+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, -+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, -+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, -+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, -+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, -+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, -+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, -+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, -+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, -+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, -+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, -+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, -+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, -+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, -+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, -+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, -+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, -+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, -+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, -+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, -+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, -+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, -+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, -+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, -+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, -+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, -+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, -+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, -+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, -+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, -+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, -+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, -+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, -+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, -+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, -+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, -+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, -+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, -+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, -+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, -+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, -+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, -+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, -+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, -+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, -+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, -+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, -+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, -+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, -+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, -+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, -+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, -+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, -+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a -+ }, { -+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, -+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, -+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, -+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, -+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, -+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, -+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, -+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, -+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, -+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, -+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, -+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, -+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, -+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, -+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, -+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, -+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, -+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, -+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, -+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, -+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, -+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, -+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, -+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, -+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, -+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, -+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, -+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, -+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, -+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, -+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, -+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, -+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, -+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, -+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, -+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, -+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, -+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, -+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, -+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, -+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, -+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, -+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, -+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, -+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, -+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, -+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, -+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, -+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, -+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, -+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, -+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, -+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, -+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, -+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, -+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, -+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, -+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, -+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, -+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, -+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, -+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, -+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, -+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 -+ }, { -+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, -+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, -+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, -+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, -+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, -+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, -+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, -+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, -+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, -+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, -+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, -+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, -+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, -+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, -+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, -+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, -+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, -+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, -+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, -+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, -+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, -+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, -+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, -+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, -+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, -+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, -+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, -+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, -+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, -+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, -+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, -+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, -+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, -+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, -+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, -+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, -+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, -+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, -+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, -+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, -+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, -+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, -+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, -+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, -+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, -+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, -+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, -+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, -+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, -+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, -+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, -+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, -+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, -+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, -+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, -+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, -+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, -+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, -+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, -+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, -+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, -+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, -+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, -+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 -+ }, { -+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, -+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, -+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, -+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, -+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, -+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, -+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, -+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, -+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, -+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, -+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, -+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, -+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, -+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, -+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, -+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, -+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, -+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, -+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, -+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, -+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, -+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, -+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, -+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, -+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, -+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, -+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, -+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, -+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, -+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, -+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, -+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, -+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, -+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, -+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, -+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, -+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, -+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, -+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, -+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, -+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, -+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, -+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, -+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, -+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, -+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, -+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, -+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, -+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, -+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, -+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, -+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, -+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, -+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, -+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, -+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, -+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, -+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, -+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, -+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, -+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, -+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, -+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, -+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 -+ } -+ }, { -+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, -+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, -+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, -+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, -+ 0x9216d5d9, 0x8979fb1b -+ } -+}; -+ -+static unsigned char BF_itoa64[64 + 1] = -+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -+ -+static unsigned char BF_atoi64[0x60] = { -+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, -+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, -+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, -+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, -+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -+}; -+ -+/* -+ * This may be optimized out if built with function inlining and no BF_ASM. -+ */ -+static void clean(void *data, int size) -+{ -+#if BF_ASM -+ extern void _BF_clean(void *data); -+#endif -+ memset(data, 0, size); -+#if BF_ASM -+ _BF_clean(data); -+#endif -+} -+ -+#define BF_safe_atoi64(dst, src) \ -+{ \ -+ tmp = (unsigned char)(src); \ -+ if (tmp == '$') break; \ -+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ -+ tmp = BF_atoi64[tmp]; \ -+ if (tmp > 63) return -1; \ -+ (dst) = tmp; \ -+} -+ -+static int BF_decode(BF_word *dst, __CONST char *src, int size) -+{ -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned char *end = dptr + size; -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned int tmp, c1, c2, c3, c4; -+ -+ do { -+ BF_safe_atoi64(c1, *sptr++); -+ BF_safe_atoi64(c2, *sptr++); -+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c3, *sptr++); -+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); -+ if (dptr >= end) break; -+ -+ BF_safe_atoi64(c4, *sptr++); -+ *dptr++ = ((c3 & 0x03) << 6) | c4; -+ } while (dptr < end); -+ -+ while (dptr < end) -+ *dptr++ = 0; -+ -+ return 0; -+} -+ -+static void BF_encode(char *dst, __CONST BF_word *src, int size) -+{ -+ unsigned char *sptr = (unsigned char *)src; -+ unsigned char *end = sptr + size; -+ unsigned char *dptr = (unsigned char *)dst; -+ unsigned int c1, c2; -+ -+ do { -+ c1 = *sptr++; -+ *dptr++ = BF_itoa64[c1 >> 2]; -+ c1 = (c1 & 0x03) << 4; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 4; -+ *dptr++ = BF_itoa64[c1]; -+ c1 = (c2 & 0x0f) << 2; -+ if (sptr >= end) { -+ *dptr++ = BF_itoa64[c1]; -+ break; -+ } -+ -+ c2 = *sptr++; -+ c1 |= c2 >> 6; -+ *dptr++ = BF_itoa64[c1]; -+ *dptr++ = BF_itoa64[c2 & 0x3f]; -+ } while (sptr < end); -+} -+ -+static void BF_swap(BF_word *x, int count) -+{ -+ static int endianness_check = 1; -+ char *is_little_endian = (char *)&endianness_check; -+ BF_word tmp; -+ -+ if (*is_little_endian) -+ do { -+ tmp = *x; -+ tmp = (tmp << 16) | (tmp >> 16); -+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); -+ } while (--count); -+} -+ -+#if BF_SCALE -+/* Architectures which can shift addresses left by 2 bits with no extra cost */ -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp2 = L >> 8; \ -+ tmp2 &= 0xFF; \ -+ tmp3 = L >> 16; \ -+ tmp3 &= 0xFF; \ -+ tmp4 = L >> 24; \ -+ tmp1 = data.ctx.S[3][tmp1]; \ -+ tmp2 = data.ctx.S[2][tmp2]; \ -+ tmp3 = data.ctx.S[1][tmp3]; \ -+ tmp3 += data.ctx.S[0][tmp4]; \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#else -+/* Architectures with no complicated addressing modes supported */ -+#define BF_INDEX(S, i) \ -+ (*((BF_word *)(((unsigned char *)S) + (i)))) -+#define BF_ROUND(L, R, N) \ -+ tmp1 = L & 0xFF; \ -+ tmp1 <<= 2; \ -+ tmp2 = L >> 6; \ -+ tmp2 &= 0x3FC; \ -+ tmp3 = L >> 14; \ -+ tmp3 &= 0x3FC; \ -+ tmp4 = L >> 22; \ -+ tmp4 &= 0x3FC; \ -+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ -+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ -+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ -+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ -+ tmp3 ^= tmp2; \ -+ R ^= data.ctx.P[N + 1]; \ -+ tmp3 += tmp1; \ -+ R ^= tmp3; -+#endif -+ -+/* -+ * Encrypt one block, BF_N is hardcoded here. -+ */ -+#define BF_ENCRYPT \ -+ L ^= data.ctx.P[0]; \ -+ BF_ROUND(L, R, 0); \ -+ BF_ROUND(R, L, 1); \ -+ BF_ROUND(L, R, 2); \ -+ BF_ROUND(R, L, 3); \ -+ BF_ROUND(L, R, 4); \ -+ BF_ROUND(R, L, 5); \ -+ BF_ROUND(L, R, 6); \ -+ BF_ROUND(R, L, 7); \ -+ BF_ROUND(L, R, 8); \ -+ BF_ROUND(R, L, 9); \ -+ BF_ROUND(L, R, 10); \ -+ BF_ROUND(R, L, 11); \ -+ BF_ROUND(L, R, 12); \ -+ BF_ROUND(R, L, 13); \ -+ BF_ROUND(L, R, 14); \ -+ BF_ROUND(R, L, 15); \ -+ tmp4 = R; \ -+ R = L; \ -+ L = tmp4 ^ data.ctx.P[BF_N + 1]; -+ -+#if BF_ASM -+#define BF_body() \ -+ _BF_body_r(&data.ctx); -+#else -+#define BF_body() \ -+ L = R = 0; \ -+ ptr = data.ctx.P; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.P[BF_N + 2]); \ -+\ -+ ptr = data.ctx.S[0]; \ -+ do { \ -+ ptr += 2; \ -+ BF_ENCRYPT; \ -+ *(ptr - 2) = L; \ -+ *(ptr - 1) = R; \ -+ } while (ptr < &data.ctx.S[3][0xFF]); -+#endif -+ -+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial) -+{ -+ __CONST char *ptr = key; -+ int i, j; -+ BF_word tmp; -+ -+ for (i = 0; i < BF_N + 2; i++) { -+ tmp = 0; -+ for (j = 0; j < 4; j++) { -+ tmp <<= 8; -+ tmp |= *ptr; -+ -+ if (!*ptr) ptr = key; else ptr++; -+ } -+ -+ expanded[i] = tmp; -+ initial[i] = BF_init_state.P[i] ^ tmp; -+ } -+} -+ -+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting, -+ char *output, int size) -+{ -+#if BF_ASM -+ extern void _BF_body_r(BF_ctx *ctx); -+#endif -+ struct { -+ BF_ctx ctx; -+ BF_key expanded_key; -+ union { -+ BF_word salt[4]; -+ BF_word output[6]; -+ } binary; -+ } data; -+ BF_word L, R; -+ BF_word tmp1, tmp2, tmp3, tmp4; -+ BF_word *ptr; -+ BF_word count; -+ int i; -+ -+ if (size < 7 + 22 + 31 + 1) { -+ __set_errno(ERANGE); -+ return NULL; -+ } -+ -+ if (setting[0] != '$' || -+ setting[1] != '2' || -+ setting[2] != 'a' || -+ setting[3] != '$' || -+ setting[4] < '0' || setting[4] > '3' || -+ setting[5] < '0' || setting[5] > '9' || -+ setting[6] != '$') { -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); -+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) { -+ clean(data.binary.salt, sizeof(data.binary.salt)); -+ __set_errno(EINVAL); -+ return NULL; -+ } -+ -+ BF_swap(data.binary.salt, 4); -+ -+ BF_set_key(key, data.expanded_key, data.ctx.P); -+ -+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); -+ -+ L = R = 0; -+ for (i = 0; i < BF_N + 2; i += 2) { -+ L ^= data.binary.salt[i & 2]; -+ R ^= data.binary.salt[(i & 2) + 1]; -+ BF_ENCRYPT; -+ data.ctx.P[i] = L; -+ data.ctx.P[i + 1] = R; -+ } -+ -+ ptr = data.ctx.S[0]; -+ do { -+ ptr += 4; -+ L ^= data.binary.salt[(BF_N + 2) & 3]; -+ R ^= data.binary.salt[(BF_N + 3) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 4) = L; -+ *(ptr - 3) = R; -+ -+ L ^= data.binary.salt[(BF_N + 4) & 3]; -+ R ^= data.binary.salt[(BF_N + 5) & 3]; -+ BF_ENCRYPT; -+ *(ptr - 2) = L; -+ *(ptr - 1) = R; -+ } while (ptr < &data.ctx.S[3][0xFF]); -+ -+ do { -+ data.ctx.P[0] ^= data.expanded_key[0]; -+ data.ctx.P[1] ^= data.expanded_key[1]; -+ data.ctx.P[2] ^= data.expanded_key[2]; -+ data.ctx.P[3] ^= data.expanded_key[3]; -+ data.ctx.P[4] ^= data.expanded_key[4]; -+ data.ctx.P[5] ^= data.expanded_key[5]; -+ data.ctx.P[6] ^= data.expanded_key[6]; -+ data.ctx.P[7] ^= data.expanded_key[7]; -+ data.ctx.P[8] ^= data.expanded_key[8]; -+ data.ctx.P[9] ^= data.expanded_key[9]; -+ data.ctx.P[10] ^= data.expanded_key[10]; -+ data.ctx.P[11] ^= data.expanded_key[11]; -+ data.ctx.P[12] ^= data.expanded_key[12]; -+ data.ctx.P[13] ^= data.expanded_key[13]; -+ data.ctx.P[14] ^= data.expanded_key[14]; -+ data.ctx.P[15] ^= data.expanded_key[15]; -+ data.ctx.P[16] ^= data.expanded_key[16]; -+ data.ctx.P[17] ^= data.expanded_key[17]; -+ -+ BF_body(); -+ -+ tmp1 = data.binary.salt[0]; -+ tmp2 = data.binary.salt[1]; -+ tmp3 = data.binary.salt[2]; -+ tmp4 = data.binary.salt[3]; -+ data.ctx.P[0] ^= tmp1; -+ data.ctx.P[1] ^= tmp2; -+ data.ctx.P[2] ^= tmp3; -+ data.ctx.P[3] ^= tmp4; -+ data.ctx.P[4] ^= tmp1; -+ data.ctx.P[5] ^= tmp2; -+ data.ctx.P[6] ^= tmp3; -+ data.ctx.P[7] ^= tmp4; -+ data.ctx.P[8] ^= tmp1; -+ data.ctx.P[9] ^= tmp2; -+ data.ctx.P[10] ^= tmp3; -+ data.ctx.P[11] ^= tmp4; -+ data.ctx.P[12] ^= tmp1; -+ data.ctx.P[13] ^= tmp2; -+ data.ctx.P[14] ^= tmp3; -+ data.ctx.P[15] ^= tmp4; -+ data.ctx.P[16] ^= tmp1; -+ data.ctx.P[17] ^= tmp2; -+ -+ BF_body(); -+ } while (--count); -+ -+ for (i = 0; i < 6; i += 2) { -+ L = BF_magic_w[i]; -+ R = BF_magic_w[i + 1]; -+ -+ count = 64; -+ do { -+ BF_ENCRYPT; -+ } while (--count); -+ -+ data.binary.output[i] = L; -+ data.binary.output[i + 1] = R; -+ } -+ -+ memcpy(output, setting, 7 + 22 - 1); -+ output[7 + 22 - 1] = BF_itoa64[(int) -+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30]; -+ -+/* This has to be bug-compatible with the original implementation, so -+ * only encode 23 of the 24 bytes. :-) */ -+ BF_swap(data.binary.output, 6); -+ BF_encode(&output[7 + 22], data.binary.output, 23); -+ output[7 + 22 + 31] = '\0'; -+ -+/* Overwrite the most obvious sensitive data we have on the stack. Note -+ * that this does not guarantee there's no sensitive data left on the -+ * stack and/or in registers; I'm not aware of portable code that does. */ -+ clean(&data, sizeof(data)); -+ -+ return output; -+} -+ -+char *_crypt_gensalt_blowfish_rn(unsigned long count, -+ __CONST char *input, int size, char *output, int output_size) -+{ -+ if (size < 16 || output_size < 7 + 22 + 1 || -+ (count && (count < 4 || count > 31))) { -+ if (output_size > 0) output[0] = '\0'; -+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); -+ return NULL; -+ } -+ -+ if (!count) count = 5; -+ -+ output[0] = '$'; -+ output[1] = '2'; -+ output[2] = 'a'; -+ output[3] = '$'; -+ output[4] = '0' + count / 10; -+ output[5] = '0' + count % 10; -+ output[6] = '$'; -+ -+ BF_encode(&output[7], (BF_word *)input, 16); -+ output[7 + 22] = '\0'; -+ -+ return output; -+} -diff -Nura php-5.1.6/ext/standard/crypt.c hardening-patch-5.1.6-0.4.15/ext/standard/crypt.c ---- php-5.1.6/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/crypt.c 2006-09-07 19:41:16.000000000 +0200 -@@ -100,6 +100,8 @@ - return SUCCESS; - } - -+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size); -+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size); - - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -@@ -135,7 +137,14 @@ - - /* The automatic salt generation only covers standard DES and md5-crypt */ - if(!*salt) { --#if PHP_MD5_CRYPT -+#if PHP_BLOWFISH_CRYPT -+ char randat[16]; -+ int i; -+ -+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND; -+ -+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt)); -+#elif PHP_MD5_CRYPT - strcpy(salt, "$1$"); - php_to64(&salt[3], PHP_CRYPT_RAND, 4); - php_to64(&salt[7], PHP_CRYPT_RAND, 4); -@@ -145,8 +154,24 @@ - salt[2] = '\0'; - #endif - } -- -- RETVAL_STRING(crypt(str, salt), 1); -+ -+ if (salt[0] == '$' && -+ salt[1] == '2' && -+ salt[2] == 'a' && -+ salt[3] == '$' && -+ salt[4] >= '0' && salt[4] <= '3' && -+ salt[5] >= '0' && salt[5] <= '9' && -+ salt[6] == '$') { -+ -+ char output[PHP_MAX_SALT_LEN+1]; -+ -+ output[0] = 0; -+ _crypt_blowfish_rn(str, salt, output, sizeof(output)); -+ RETVAL_STRING(output, 1); -+ -+ } else { -+ RETVAL_STRING(crypt(str, salt), 1); -+ } - } - /* }}} */ - #endif -diff -Nura php-5.1.6/ext/standard/dl.c hardening-patch-5.1.6-0.4.15/ext/standard/dl.c ---- php-5.1.6/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/dl.c 2006-09-07 19:41:16.000000000 +0200 -@@ -164,8 +164,35 @@ - RETURN_FALSE; - } - module_entry = get_module(); -+ -+ /* check if Hardening-Patch is installed */ -+ if (module_entry->zend_api < 1000000000) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ -+ /* check if correct Hardening-Patch is installed */ -+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) { -+ php_error_docref(NULL TSRMLS_CC, error_type, -+ "%s: Unable to initialize module\n" -+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n" -+ "These options need to match\n", -+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts, -+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS); -+ DL_UNLOAD(handle); -+ RETURN_FALSE; -+ } -+ - if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS) -- || (module_entry->zend_api != ZEND_MODULE_API_NO)) { -+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) { - /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */ - struct pre_4_1_0_module_entry { - char *name; -@@ -199,7 +226,7 @@ - zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts; - } else { - name = module_entry->name; -- zend_api = module_entry->zend_api; -+ zend_api = module_entry->real_zend_api; - zend_debug = module_entry->zend_debug; - zts = module_entry->zts; - } -diff -Nura php-5.1.6/ext/standard/file.c hardening-patch-5.1.6-0.4.15/ext/standard/file.c ---- php-5.1.6/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/file.c 2006-09-07 19:41:16.000000000 +0200 -@@ -2302,7 +2302,7 @@ - #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) - /* {{{ proto string realpath(string path) - Return the resolved path */ --PHP_FUNCTION(realpath) -+PHP_FUNCTION(real_path) - { - zval **path; - char resolved_path_buff[MAXPATHLEN]; -diff -Nura php-5.1.6/ext/standard/file.h hardening-patch-5.1.6-0.4.15/ext/standard/file.h ---- php-5.1.6/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/file.h 2006-09-07 19:41:16.000000000 +0200 -@@ -61,7 +61,7 @@ - PHP_FUNCTION(fd_set); - PHP_FUNCTION(fd_isset); - #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS) --PHP_FUNCTION(realpath); -+PHP_FUNCTION(real_path); - PHP_FUNCTION(fnmatch); - #endif - PHP_NAMED_FUNCTION(php_if_ftruncate); -diff -Nura php-5.1.6/ext/standard/head.c hardening-patch-5.1.6-0.4.15/ext/standard/head.c ---- php-5.1.6/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/head.c 2006-09-07 19:41:16.000000000 +0200 -@@ -45,7 +45,7 @@ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line, - &ctr.line_len, &rep, &ctr.response_code) == FAILURE) - return; -- -+ - sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC); - } - /* }}} */ -diff -Nura php-5.1.6/ext/standard/info.c hardening-patch-5.1.6-0.4.15/ext/standard/info.c ---- php-5.1.6/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/info.c 2006-09-07 19:41:16.000000000 +0200 -@@ -154,7 +154,7 @@ - if (Z_TYPE_PP(tmp) == IS_ARRAY) { - if (!sapi_module.phpinfo_as_text) { - PUTS("
");
--					zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
-+					zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
- 					PUTS("
"); - } else { - zend_print_zval_r(*tmp, 0 TSRMLS_CC); -@@ -411,7 +411,7 @@ - - if (flag & PHP_INFO_GENERAL) { - char *zend_version = get_zend_version(); -- char temp_api[10]; -+ char temp_api[11]; - char *logo_guid; - - php_uname = php_get_uname('a'); -@@ -434,11 +434,22 @@ - PUTS("\" alt=\"PHP Logo\" />"); - } - -+#if HARDENING_PATCH -+ if (!sapi_module.phpinfo_as_text) { -+ php_printf("

PHP Version %s with Hardening-Patch %s

\n", PHP_VERSION, HARDENING_PATCH_VERSION); -+ } else { -+ char temp_ver[40]; -+ -+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION); -+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver); -+ } -+#else - if (!sapi_module.phpinfo_as_text) { - php_printf("

PHP Version %s

\n", PHP_VERSION); - } else { - php_info_print_table_row(2, "PHP Version", PHP_VERSION); -- } -+ } -+#endif - php_info_print_box_end(); - php_info_print_table_start(); - php_info_print_table_row(2, "System", php_uname ); -diff -Nura php-5.1.6/ext/standard/mail.c hardening-patch-5.1.6-0.4.15/ext/standard/mail.c ---- php-5.1.6/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/mail.c 2006-09-07 19:41:16.000000000 +0200 -@@ -78,6 +78,25 @@ - } - /* }}} */ - -+/* {{{ hphp_strcasestr */ -+char *hphp_strcasestr(char *haystack, char *needle) -+{ -+ unsigned char *t, *h, *n; -+ -+ h = (unsigned char *) haystack; -+conts: -+ while (*h) { -+ n = (unsigned char *) needle; -+ for (t=h++; *n && *h; t++, n++) { -+ if (toupper(*t) != toupper(*n)) goto conts; -+ } -+ return ((char*)h-1); -+ } -+ -+ return (NULL); -+} -+/* }}} */ -+ - /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) - Send an email message */ - PHP_FUNCTION(mail) -@@ -104,6 +123,44 @@ - return; - } - -+ if (HG(hphp_mailprotect) > 0) { -+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) { -+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ /* check for spam attempts with buggy webforms */ -+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) { -+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped"); -+ RETURN_FALSE; -+ } -+ -+ if (HG(hphp_mailprotect) > 1) { -+ /* search for to, cc or bcc headers */ -+ if (headers_len > 0 && headers != NULL) { -+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) { -+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) { -+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ -+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) { -+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter."); -+ RETURN_FALSE; -+ } -+ } -+ } -+ } -+ - if (to_len > 0) { - to_r = estrndup(to, to_len); - for (; to_len; to_len--) { -diff -Nura php-5.1.6/ext/standard/php_standard.h hardening-patch-5.1.6-0.4.15/ext/standard/php_standard.h ---- php-5.1.6/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/php_standard.h 2006-09-07 19:41:16.000000000 +0200 -@@ -28,6 +28,7 @@ - #include "php_mail.h" - #include "md5.h" - #include "sha1.h" -+#include "sha256.h" - #include "html.h" - #include "exec.h" - #include "file.h" -diff -Nura php-5.1.6/ext/standard/sha256.c hardening-patch-5.1.6-0.4.15/ext/standard/sha256.c ---- php-5.1.6/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/sha256.c 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,388 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */ -+ -+#include "php.h" -+ -+/* This code is heavily based on the PHP md5/sha1 implementations */ -+ -+#include "sha256.h" -+ -+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ sprintf(sha256str, "%02x", digest[i]); -+ sha256str += 2; -+ } -+ -+ *sha256str = '\0'; -+} -+ -+/* {{{ proto string sha256(string str [, bool raw_output]) -+ Calculate the sha256 hash of a string */ -+PHP_FUNCTION(sha256) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ PHP_SHA256_CTX context; -+ unsigned char digest[32]; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ sha256str[0] = '\0'; -+ PHP_SHA256Init(&context); -+ PHP_SHA256Update(&context, arg, arg_len); -+ PHP_SHA256Final(digest, &context); -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+ -+} -+ -+/* }}} */ -+ -+/* {{{ proto string sha256_file(string filename [, bool raw_output]) -+ Calculate the sha256 hash of given filename */ -+PHP_FUNCTION(sha256_file) -+{ -+ char *arg; -+ int arg_len; -+ zend_bool raw_output = 0; -+ char sha256str[65]; -+ unsigned char buf[1024]; -+ unsigned char digest[32]; -+ PHP_SHA256_CTX context; -+ int n; -+ php_stream *stream; -+ -+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { -+ return; -+ } -+ -+ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); -+ if (!stream) { -+ RETURN_FALSE; -+ } -+ -+ PHP_SHA256Init(&context); -+ -+ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { -+ PHP_SHA256Update(&context, buf, n); -+ } -+ -+ PHP_SHA256Final(digest, &context); -+ -+ php_stream_close(stream); -+ -+ if (n<0) { -+ RETURN_FALSE; -+ } -+ -+ if (raw_output) { -+ RETURN_STRINGL(digest, 32, 1); -+ } else { -+ make_sha256_digest(sha256str, digest); -+ RETVAL_STRING(sha256str, 1); -+ } -+} -+/* }}} */ -+ -+ -+static void SHA256Transform(php_uint32[8], const unsigned char[64]); -+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int); -+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int); -+ -+static unsigned char PADDING[64] = -+{ -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* F, G, H and I are basic SHA256 functions. -+ */ -+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22)) -+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x)))) -+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25)) -+#define I(x, y, z) (((x) & (y)) | ((~x) & z)) -+ -+/* ROTATE_RIGHT rotates x right n bits. -+ */ -+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n)))) -+ -+/* W[i] -+ */ -+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \ -+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \ -+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) ) -+ -+/* ROUND function of sha256 -+ */ -+ -+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \ -+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \ -+ (h) = F((a)) + G((a), (b), (c)) + t1; \ -+ (d) += t1; \ -+ } -+ -+ -+/* {{{ PHP_SHA256Init -+ * SHA256 initialization. Begins an SHA256 operation, writing a new context. -+ */ -+static void PHP_SHA256Init(PHP_SHA256_CTX * context) -+{ -+ context->count[0] = context->count[1] = 0; -+ /* Load magic initialization constants. -+ */ -+ context->state[0] = 0x6a09e667; -+ context->state[1] = 0xbb67ae85; -+ context->state[2] = 0x3c6ef372; -+ context->state[3] = 0xa54ff53a; -+ context->state[4] = 0x510e527f; -+ context->state[5] = 0x9b05688c; -+ context->state[6] = 0x1f83d9ab; -+ context->state[7] = 0x5be0cd19; -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Update -+ SHA256 block update operation. Continues an SHA256 message-digest -+ operation, processing another message block, and updating the -+ context. -+ */ -+static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, -+ unsigned int inputLen) -+{ -+ unsigned int i, index, partLen; -+ -+ /* Compute number of bytes mod 64 */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); -+ -+ /* Update number of bits */ -+ if ((context->count[0] += ((php_uint32) inputLen << 3)) -+ < ((php_uint32) inputLen << 3)) -+ context->count[1]++; -+ context->count[1] += ((php_uint32) inputLen >> 29); -+ -+ partLen = 64 - index; -+ -+ /* Transform as many times as possible. -+ */ -+ if (inputLen >= partLen) { -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); -+ SHA256Transform(context->state, context->buffer); -+ -+ for (i = partLen; i + 63 < inputLen; i += 64) -+ SHA256Transform(context->state, &input[i]); -+ -+ index = 0; -+ } else -+ i = 0; -+ -+ /* Buffer remaining input */ -+ memcpy -+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], -+ inputLen - i); -+} -+/* }}} */ -+ -+/* {{{ PHP_SHA256Final -+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the -+ the message digest and zeroizing the context. -+ */ -+static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context) -+{ -+ unsigned char bits[8]; -+ unsigned int index, padLen; -+ -+ /* Save number of bits */ -+ bits[7] = context->count[0] & 0xFF; -+ bits[6] = (context->count[0] >> 8) & 0xFF; -+ bits[5] = (context->count[0] >> 16) & 0xFF; -+ bits[4] = (context->count[0] >> 24) & 0xFF; -+ bits[3] = context->count[1] & 0xFF; -+ bits[2] = (context->count[1] >> 8) & 0xFF; -+ bits[1] = (context->count[1] >> 16) & 0xFF; -+ bits[0] = (context->count[1] >> 24) & 0xFF; -+ -+ /* Pad out to 56 mod 64. -+ */ -+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); -+ padLen = (index < 56) ? (56 - index) : (120 - index); -+ PHP_SHA256Update(context, PADDING, padLen); -+ -+ /* Append length (before padding) */ -+ PHP_SHA256Update(context, bits, 8); -+ -+ /* Store state in digest */ -+ SHA256Encode(digest, context->state, 32); -+ -+ /* Zeroize sensitive information. -+ */ -+ memset((unsigned char*) context, 0, sizeof(*context)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Transform -+ * SHA256 basic transformation. Transforms state based on block. -+ */ -+static void SHA256Transform(state, block) -+php_uint32 state[8]; -+const unsigned char block[64]; -+{ -+ php_uint32 a = state[0], b = state[1], c = state[2]; -+ php_uint32 d = state[3], e = state[4], f = state[5]; -+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1; -+ -+ SHA256Decode(x, block, 64); -+ -+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98) -+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491) -+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf) -+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5) -+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b) -+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1) -+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4) -+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5) -+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98) -+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01) -+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be) -+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3) -+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74) -+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe) -+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7) -+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174) -+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1) -+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786) -+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6) -+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc) -+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f) -+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa) -+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc) -+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da) -+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152) -+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d) -+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8) -+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7) -+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3) -+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147) -+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351) -+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967) -+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85) -+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138) -+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc) -+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13) -+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354) -+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb) -+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e) -+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85) -+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1) -+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b) -+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70) -+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3) -+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819) -+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624) -+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585) -+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070) -+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116) -+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08) -+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c) -+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5) -+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3) -+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a) -+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f) -+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3) -+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee) -+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f) -+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814) -+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208) -+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa) -+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb) -+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7) -+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2) -+ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ state[4] += e; -+ state[5] += f; -+ state[6] += g; -+ state[7] += h; -+ -+ /* Zeroize sensitive information. */ -+ memset((unsigned char*) x, 0, sizeof(x)); -+} -+/* }}} */ -+ -+/* {{{ SHA256Encode -+ Encodes input (php_uint32) into output (unsigned char). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Encode(output, input, len) -+unsigned char *output; -+php_uint32 *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) { -+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff); -+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); -+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); -+ output[j + 3] = (unsigned char) (input[i] & 0xff); -+ } -+} -+/* }}} */ -+ -+/* {{{ SHA256Decode -+ Decodes input (unsigned char) into output (php_uint32). Assumes len is -+ a multiple of 4. -+ */ -+static void SHA256Decode(output, input, len) -+php_uint32 *output; -+const unsigned char *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) -+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) | -+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24); -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.6/ext/standard/sha256.h hardening-patch-5.1.6-0.4.15/ext/standard/sha256.h ---- php-5.1.6/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/sha256.h 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,40 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | PHP Version 5 | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 1997-2004 The PHP Group | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 3.0 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available through the world-wide-web at the following url: | -+ | http://www.php.net/license/3_0.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+*/ -+ -+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */ -+ -+#ifndef SHA256_H -+#define SHA256_H -+ -+#include "ext/standard/basic_functions.h" -+ -+/* SHA1 context. */ -+typedef struct { -+ php_uint32 state[8]; /* state (ABCD) */ -+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ -+ unsigned char buffer[64]; /* input buffer */ -+} PHP_SHA256_CTX; -+ -+static void PHP_SHA256Init(PHP_SHA256_CTX *); -+static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int); -+static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *); -+ -+PHP_FUNCTION(sha256); -+PHP_FUNCTION(sha256_file); -+ -+#endif -diff -Nura php-5.1.6/ext/standard/syslog.c hardening-patch-5.1.6-0.4.15/ext/standard/syslog.c ---- php-5.1.6/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/standard/syslog.c 2006-09-07 19:41:16.000000000 +0200 -@@ -42,6 +42,7 @@ - */ - PHP_MINIT_FUNCTION(syslog) - { -+#if !HARDENING_PATCH - /* error levels */ - REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ - REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -@@ -97,6 +98,7 @@ - /* AIX doesn't have LOG_PERROR */ - REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ - #endif -+#endif - BG(syslog_device)=NULL; - - return SUCCESS; -diff -Nura php-5.1.6/ext/varfilter/config.m4 hardening-patch-5.1.6-0.4.15/ext/varfilter/config.m4 ---- php-5.1.6/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/varfilter/config.m4 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,11 @@ -+dnl -+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+dnl -+ -+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter, -+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes) -+ -+if test "$PHP_VARFILTER" != "no"; then -+ AC_DEFINE(HAVE_VARFILTER, 1, [ ]) -+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared) -+fi -diff -Nura php-5.1.6/ext/varfilter/CREDITS hardening-patch-5.1.6-0.4.15/ext/varfilter/CREDITS ---- php-5.1.6/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/varfilter/CREDITS 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,2 @@ -+varfilter -+Stefan Esser -\ Kein Zeilenumbruch am Dateiende. -diff -Nura php-5.1.6/ext/varfilter/php_varfilter.h hardening-patch-5.1.6-0.4.15/ext/varfilter/php_varfilter.h ---- php-5.1.6/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/varfilter/php_varfilter.h 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,144 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifndef PHP_VARFILTER_H -+#define PHP_VARFILTER_H -+ -+extern zend_module_entry varfilter_module_entry; -+#define phpext_varfilter_ptr &varfilter_module_entry -+ -+#ifdef PHP_WIN32 -+#define PHP_VARFILTER_API __declspec(dllexport) -+#else -+#define PHP_VARFILTER_API -+#endif -+ -+#ifdef ZTS -+#include "TSRM.h" -+#endif -+ -+#include "SAPI.h" -+ -+#include "php_variables.h" -+ -+#ifdef ZEND_ENGINE_2 -+#define HASH_HTTP_GET_VARS 0x2095733f -+#define HASH_HTTP_POST_VARS 0xbfee1265 -+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99 -+#define HASH_HTTP_ENV_VARS 0x1fe186a8 -+#define HASH_HTTP_SERVER_VARS 0xc987afd6 -+#define HASH_HTTP_SESSION_VARS 0x7aba0d43 -+#define HASH_HTTP_POST_FILES 0x98eb1ddc -+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec -+#else -+#define HASH_HTTP_GET_VARS 0x8d8645bd -+#define HASH_HTTP_POST_VARS 0x7c699bf3 -+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f -+#define HASH_HTTP_ENV_VARS 0x84da3016 -+#define HASH_HTTP_SERVER_VARS 0x6dbf964e -+#define HASH_HTTP_SESSION_VARS 0x322906f5 -+#define HASH_HTTP_POST_FILES 0xe4e4ce70 -+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e -+#endif -+ -+PHP_MINIT_FUNCTION(varfilter); -+PHP_MSHUTDOWN_FUNCTION(varfilter); -+PHP_RINIT_FUNCTION(varfilter); -+PHP_RSHUTDOWN_FUNCTION(varfilter); -+PHP_MINFO_FUNCTION(varfilter); -+ -+ -+ZEND_BEGIN_MODULE_GLOBALS(varfilter) -+/* request variables */ -+ long max_request_variables; -+ long cur_request_variables; -+ long max_varname_length; -+ long max_totalname_length; -+ long max_value_length; -+ long max_array_depth; -+ long max_array_index_length; -+ zend_bool disallow_nul; -+/* cookie variables */ -+ long max_cookie_vars; -+ long cur_cookie_vars; -+ long max_cookie_name_length; -+ long max_cookie_totalname_length; -+ long max_cookie_value_length; -+ long max_cookie_array_depth; -+ long max_cookie_array_index_length; -+ zend_bool disallow_cookie_nul; -+/* get variables */ -+ long max_get_vars; -+ long cur_get_vars; -+ long max_get_name_length; -+ long max_get_totalname_length; -+ long max_get_value_length; -+ long max_get_array_depth; -+ long max_get_array_index_length; -+ zend_bool disallow_get_nul; -+/* post variables */ -+ long max_post_vars; -+ long cur_post_vars; -+ long max_post_name_length; -+ long max_post_totalname_length; -+ long max_post_value_length; -+ long max_post_array_depth; -+ long max_post_array_index_length; -+ zend_bool disallow_post_nul; -+/* fileupload */ -+ long max_uploads; -+ long cur_uploads; -+ zend_bool disallow_elf_files; -+ char *verification_script; -+ -+ zend_bool no_more_variables; -+ zend_bool no_more_get_variables; -+ zend_bool no_more_post_variables; -+ zend_bool no_more_cookie_variables; -+ zend_bool no_more_uploads; -+ -+ZEND_END_MODULE_GLOBALS(varfilter) -+ -+ -+#ifdef ZTS -+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v) -+#else -+#define VARFILTER_G(v) (varfilter_globals.v) -+#endif -+ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter); -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter); -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter); -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter); -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter); -+SAPI_TREAT_DATA_FUNC(varfilter_treat_data); -+ -+ -+ -+#endif /* PHP_VARFILTER_H */ -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * indent-tabs-mode: t -+ * End: -+ */ -diff -Nura php-5.1.6/ext/varfilter/varfilter.c hardening-patch-5.1.6-0.4.15/ext/varfilter/varfilter.c ---- php-5.1.6/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/ext/varfilter/varfilter.c 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,915 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardened-PHP Project's varfilter extension | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ -+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ -+*/ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include "php.h" -+#include "php_ini.h" -+#include "ext/standard/info.h" -+#include "php_varfilter.h" -+#include "hardening_patch.h" -+ -+ZEND_DECLARE_MODULE_GLOBALS(varfilter) -+ -+/* True global resources - no need for thread safety here */ -+static int le_varfilter; -+ -+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL; -+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; -+static zend_bool hooked = 0; -+ -+/* {{{ varfilter_module_entry -+ */ -+zend_module_entry varfilter_module_entry = { -+#if ZEND_MODULE_API_NO >= 20010901 -+ STANDARD_MODULE_HEADER, -+#endif -+ "varfilter", -+ NULL, -+ PHP_MINIT(varfilter), -+ PHP_MSHUTDOWN(varfilter), -+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */ -+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */ -+ PHP_MINFO(varfilter), -+#if ZEND_MODULE_API_NO >= 20010901 -+ "0.4.15", /* Replace with version number for your extension */ -+#endif -+ STANDARD_MODULE_PROPERTIES -+}; -+/* }}} */ -+ -+#ifdef COMPILE_DL_VARFILTER -+ZEND_GET_MODULE(varfilter) -+#endif -+ -+/* {{{ PHP_INI -+ */ -+PHP_INI_BEGIN() -+ /* for backward compatibility */ -+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals) -+ 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) -+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals) -+ -+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals) -+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals) -+ -+ -+PHP_INI_END() -+/* }}} */ -+ -+/* {{{ php_varfilter_init_globals -+ */ -+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals) -+{ -+ varfilter_globals->max_request_variables = 200; -+ varfilter_globals->max_varname_length = 64; -+ varfilter_globals->max_value_length = 10000; -+ varfilter_globals->max_array_depth = 100; -+ varfilter_globals->max_totalname_length = 256; -+ varfilter_globals->max_array_index_length = 64; -+ varfilter_globals->disallow_nul = 1; -+ -+ varfilter_globals->max_cookie_vars = 100; -+ varfilter_globals->max_cookie_name_length = 64; -+ varfilter_globals->max_cookie_totalname_length = 256; -+ varfilter_globals->max_cookie_value_length = 10000; -+ varfilter_globals->max_cookie_array_depth = 100; -+ varfilter_globals->max_cookie_array_index_length = 64; -+ varfilter_globals->disallow_cookie_nul = 1; -+ -+ varfilter_globals->max_get_vars = 100; -+ varfilter_globals->max_get_name_length = 64; -+ varfilter_globals->max_get_totalname_length = 256; -+ varfilter_globals->max_get_value_length = 512; -+ varfilter_globals->max_get_array_depth = 50; -+ varfilter_globals->max_get_array_index_length = 64; -+ varfilter_globals->disallow_get_nul = 1; -+ -+ varfilter_globals->max_post_vars = 200; -+ varfilter_globals->max_post_name_length = 64; -+ varfilter_globals->max_post_totalname_length = 256; -+ varfilter_globals->max_post_value_length = 65000; -+ varfilter_globals->max_post_array_depth = 100; -+ varfilter_globals->max_post_array_index_length = 64; -+ varfilter_globals->disallow_post_nul = 1; -+ -+ varfilter_globals->max_uploads = 25; -+ varfilter_globals->disallow_elf_files = 1; -+ varfilter_globals->verification_script = NULL; -+ -+ varfilter_globals->no_more_variables = 0; -+ varfilter_globals->no_more_get_variables = 0; -+ varfilter_globals->no_more_post_variables = 0; -+ varfilter_globals->no_more_cookie_variables = 0; -+ varfilter_globals->no_more_uploads = 0; -+ -+ varfilter_globals->cur_request_variables = 0; -+ varfilter_globals->cur_get_vars = 0; -+ varfilter_globals->cur_post_vars = 0; -+ varfilter_globals->cur_cookie_vars = 0; -+ -+ varfilter_globals->cur_uploads = 0; -+ -+} -+/* }}} */ -+ -+ -+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC) -+{ -+ HashTable *svars; -+ int retval, failure=0; -+ -+ orig_register_server_variables(track_vars_array TSRMLS_CC); -+ -+ svars = Z_ARRVAL_P(track_vars_array); -+ -+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX); -+ if (retval == SUCCESS) failure = 1; -+ -+ if (failure) { -+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header"); -+ } -+} -+ -+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) -+{ -+ int retval = SAPI_HEADER_ADD, i; -+ char *tmp; -+ -+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) { -+ -+ tmp = sapi_header->header; -+ for (i=0; iheader_len; i++, tmp++) { -+ if (tmp[0] == 0) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname); -+ sapi_header->header_len = i; -+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) { -+ char *fname = get_active_function_name(TSRMLS_C); -+ -+ if (!fname) { -+ fname = "unknown"; -+ } -+ -+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname); -+ sapi_header->header_len = i; -+ tmp[0] = 0; -+ } -+ } -+ } -+ -+ if (orig_header_handler) { -+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); -+ } -+ -+ return retval; -+} -+ -+/* {{{ PHP_MINIT_FUNCTION -+ */ -+PHP_MINIT_FUNCTION(varfilter) -+{ -+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL); -+ REGISTER_INI_ENTRIES(); -+ -+ if (!hooked) { -+ void *temp; -+ hooked = 1; -+ -+ temp = (void *)sapi_module.register_server_variables; -+ if (temp != varfilter_register_server_variables) { -+ orig_register_server_variables = temp; -+ } -+ temp = (void *)sapi_module.header_handler; -+ if (temp != varfilter_header_handler) { -+ orig_header_handler = temp; -+ } -+ } -+ -+ sapi_register_input_filter(varfilter_input_filter); -+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter); -+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter); -+ sapi_register_upload_content_filter(varfilter_upload_content_filter); -+ sapi_register_post_upload_filter(varfilter_post_upload_filter); -+ -+ sapi_module.header_handler = varfilter_header_handler; -+ sapi_module.register_server_variables = varfilter_register_server_variables; -+ -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MSHUTDOWN_FUNCTION -+ */ -+PHP_MSHUTDOWN_FUNCTION(varfilter) -+{ -+ UNREGISTER_INI_ENTRIES(); -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request start */ -+/* {{{ PHP_RINIT_FUNCTION -+ */ -+PHP_RINIT_FUNCTION(varfilter) -+{ -+ VARFILTER_G(cur_request_variables) = 0; -+ VARFILTER_G(cur_get_vars) = 0; -+ VARFILTER_G(cur_post_vars) = 0; -+ VARFILTER_G(cur_cookie_vars) = 0; -+ -+ VARFILTER_G(cur_uploads) = 0; -+ -+ VARFILTER_G(no_more_variables) = 0; -+ VARFILTER_G(no_more_get_variables) = 0; -+ VARFILTER_G(no_more_post_variables) = 0; -+ VARFILTER_G(no_more_cookie_variables) = 0; -+ VARFILTER_G(no_more_uploads) = 0; -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* Remove if there's nothing to do at request end */ -+/* {{{ PHP_RSHUTDOWN_FUNCTION -+ */ -+PHP_RSHUTDOWN_FUNCTION(varfilter) -+{ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ PHP_MINFO_FUNCTION -+ */ -+PHP_MINFO_FUNCTION(varfilter) -+{ -+ php_info_print_table_start(); -+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled"); -+ php_info_print_table_end(); -+ -+ DISPLAY_INI_ENTRIES(); -+} -+/* }}} */ -+ -+/* {{{ normalize_varname -+ */ -+static void normalize_varname(char *varname) -+{ -+ char *s=varname, *index=NULL, *indexend=NULL, *p; -+ -+ /* overjump leading space */ -+ while (*s == ' ') { -+ s++; -+ } -+ -+ /* and remove it */ -+ if (s != varname) { -+ memmove(varname, s, strlen(s)+1); -+ } -+ -+ for (p=varname; *p && *p != '['; p++) { -+ switch(*p) { -+ case ' ': -+ case '.': -+ *p='_'; -+ break; -+ } -+ } -+ -+ /* find index */ -+ index = strchr(varname, '['); -+ if (index) { -+ index++; -+ s=index; -+ } else { -+ return; -+ } -+ -+ /* done? */ -+ while (index) { -+ -+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { -+ index++; -+ } -+ indexend = strchr(index, ']'); -+ indexend = indexend ? indexend + 1 : index + strlen(index); -+ -+ if (s != index) { -+ memmove(s, index, strlen(index)+1); -+ s += indexend-index; -+ } else { -+ s = indexend; -+ } -+ -+ if (*s == '[') { -+ s++; -+ index = s; -+ } else { -+ index = NULL; -+ } -+ } -+ *s++='\0'; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC -+ */ -+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter) -+{ -+ char *index, *prev_index = NULL, *var; -+ unsigned int var_len, total_len, depth = 0; -+ -+ var = estrdup(varname); -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var); -+ -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var); -+ goto return_failure; -+ } -+ -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2; -+ break; -+ } -+ -+ efree(var); -+ return SUCCESS; -+protected_varname2: -+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var); -+return_failure: -+ efree(var); -+ return FAILURE; -+} -+/* }}} */ -+ -+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC -+ */ -+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter) -+{ -+ /* Drop if no more variables flag is set */ -+ if (VARFILTER_G(no_more_uploads)) { -+ return FAILURE; -+ } -+ /* Drop this fileupload if the limit is reached */ -+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) { -+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped"); -+ VARFILTER_G(no_more_uploads) = 1; -+ return FAILURE; -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC -+ */ -+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter) -+{ -+ -+ if (VARFILTER_G(disallow_elf_files)) { -+ -+ if (offset == 0 && buffer_len > 10) { -+ -+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') { -+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped"); -+ return FAILURE; -+ } -+ } -+ -+ } -+ -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC -+ */ -+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter) -+{ -+ int retval = SUCCESS; -+ -+ if (VARFILTER_G(verification_script)) { -+ char cmd[8192]; -+ FILE *in; -+ int first=1; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename); -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script)); -+ return FAILURE; -+ } -+ -+ retval = FAILURE; -+ -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ if (first) { -+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE; -+ first = 0; -+ } -+ } -+ pclose(in); -+ } -+ -+ if (retval != SUCCESS) { -+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped"); -+ return FAILURE; -+ } -+ -+ VARFILTER_G(cur_uploads)++; -+ return SUCCESS; -+} -+/* }}} */ -+ -+/* {{{ SAPI_INPUT_FILTER_FUNC -+ */ -+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter) -+{ -+ char *index, *prev_index = NULL; -+ unsigned int var_len, total_len, depth = 0; -+ -+ /* Drop this variable if the limit was reached */ -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(no_more_get_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(no_more_post_variables)) { -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(no_more_cookie_variables)) { -+ return 0; -+ } -+ break; -+ default: /* we do not want to protect parse_str() and friends */ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ return 1; -+ } -+ if (VARFILTER_G(no_more_variables)) { -+ return 0; -+ } -+ -+ /* Drop this variable if the limit is now reached */ -+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) { -+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_variables) = 1; -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) { -+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_get_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) { -+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_cookie_variables) = 1; -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) { -+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var); -+ VARFILTER_G(no_more_post_variables) = 1; -+ return 0; -+ } -+ break; -+ } -+ -+ -+ /* Drop this variable if it exceeds the value length limit */ -+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) { -+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) { -+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) { -+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) { -+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Normalize the variable name */ -+ normalize_varname(var); -+ -+ /* Find length of variable name */ -+ index = strchr(var, '['); -+ total_len = strlen(var); -+ var_len = index ? index-var : total_len; -+ -+ /* Drop this variable if it exceeds the varname/total length limit */ -+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) { -+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) { -+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) { -+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Find out array depth */ -+ while (index) { -+ unsigned int index_length; -+ -+ depth++; -+ index = strchr(index+1, '['); -+ -+ if (prev_index) { -+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index); -+ -+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) { -+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ prev_index = index; -+ } -+ -+ } -+ -+ /* Drop this variable if it exceeds the array depth limit */ -+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) { -+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) { -+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) { -+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) { -+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ -+ /* Check if variable value is truncated by a \0 */ -+ -+ if (val && *val && val_len != strlen(*val)) { -+ -+ if (VARFILTER_G(disallow_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var); -+ return 0; -+ } -+ switch (arg) { -+ case PARSE_GET: -+ if (VARFILTER_G(disallow_get_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_COOKIE: -+ if (VARFILTER_G(disallow_cookie_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ case PARSE_POST: -+ if (VARFILTER_G(disallow_post_nul)) { -+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var); -+ return 0; -+ } -+ break; -+ } -+ } -+ -+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */ -+ /* This is to protect several silly scripts that do globalizing themself */ -+ -+ switch (var_len) { -+ case 18: -+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname; -+ break; -+ case 17: -+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname; -+ break; -+ case 16: -+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname; -+ break; -+ case 15: -+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname; -+ break; -+ case 14: -+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname; -+ break; -+ case 13: -+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname; -+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname; -+ break; -+ case 8: -+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname; -+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname; -+ break; -+ case 7: -+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname; -+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname; -+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname; -+ break; -+ case 6: -+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname; -+ break; -+ case 5: -+ if (memcmp(var, "_POST", 5)==0) goto protected_varname; -+ break; -+ case 4: -+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname; -+ if (memcmp(var, "_GET", 4)==0) goto protected_varname; -+ break; -+ } -+ -+ /* Okay let PHP register this variable */ -+ VARFILTER_G(cur_request_variables)++; -+ switch (arg) { -+ case PARSE_GET: -+ VARFILTER_G(cur_get_vars)++; -+ break; -+ case PARSE_COOKIE: -+ VARFILTER_G(cur_cookie_vars)++; -+ break; -+ case PARSE_POST: -+ VARFILTER_G(cur_post_vars)++; -+ break; -+ } -+ -+ if (new_val_len) { -+ *new_val_len = val_len; -+ } -+ -+ return 1; -+protected_varname: -+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE"); -+ return 0; -+} -+/* }}} */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: noet sw=4 ts=4 fdm=marker -+ * vim<600: noet sw=4 ts=4 -+ */ -+ -+ -diff -Nura php-5.1.6/ext/wddx/wddx.c hardening-patch-5.1.6-0.4.15/ext/wddx/wddx.c ---- php-5.1.6/ext/wddx/wddx.c 2006-05-25 12:01:30.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/ext/wddx/wddx.c 2006-09-07 19:41:16.000000000 +0200 -@@ -399,9 +399,9 @@ - break; - - default: -- if (iscntrl((int)*(unsigned char *)p)) { -+ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) { - FLUSH_BUF(); -- sprintf(control_buf, WDDX_CHAR, *p); -+ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p); - php_wddx_add_chunk(packet, control_buf); - } else - buf[l++] = *p; -diff -Nura php-5.1.6/main/fopen_wrappers.c hardening-patch-5.1.6-0.4.15/main/fopen_wrappers.c ---- php-5.1.6/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/fopen_wrappers.c 2006-09-07 19:41:16.000000000 +0200 -@@ -104,7 +104,10 @@ - } - - /* Resolve the real path into resolved_name */ -- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) { -+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { -+ return -2; -+ } -+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { - /* Handler for basedirs that end with a / */ - resolved_basedir_len = strlen(resolved_basedir); - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { -@@ -114,14 +117,20 @@ - } - } - -+ resolved_name_len = strlen(resolved_name); - if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) { -- resolved_name_len = strlen(resolved_name); - if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { - resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; - resolved_name[++resolved_name_len] = '\0'; - } - } - -+ if (resolved_name_len == resolved_basedir_len - 1) { -+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) { -+ resolved_basedir_len--; -+ } -+ } -+ - /* Check the path */ - #if defined(PHP_WIN32) || defined(NETWARE) - if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) { -@@ -135,7 +144,7 @@ - } - } else { - /* Unable to resolve the real path, return -1 */ -- return -1; -+ return -3; - } - } - /* }}} */ -@@ -154,22 +163,44 @@ - char *pathbuf; - char *ptr; - char *end; -+ char path_copy[MAXPATHLEN]; -+ int path_len; -+ -+ /* Special case path ends with a trailing slash */ -+ path_len = strlen(path); -+ if (path_len >= MAXPATHLEN) { -+ errno = EPERM; /* we deny permission to open it */ -+ return -1; -+ } -+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) { -+ memcpy(path_copy, path, path_len+1); -+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--; -+ path_copy[path_len] = '\0'; -+ path = (const char *)&path_copy; -+ } - - pathbuf = estrdup(PG(open_basedir)); - - ptr = pathbuf; - - while (ptr && *ptr) { -+ int res; - end = strchr(ptr, DEFAULT_DIR_SEPARATOR); - if (end != NULL) { - *end = '\0'; - end++; - } - -- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { -+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC); -+ if (res == 0) { - efree(pathbuf); - return 0; - } -+ if (res == -2) { -+ efree(pathbuf); -+ errno = EPERM; -+ return -1; -+ } - - ptr = end; - } -diff -Nura php-5.1.6/main/hardened_globals.h hardening-patch-5.1.6-0.4.15/main/hardened_globals.h ---- php-5.1.6/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/hardened_globals.h 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,64 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENED_GLOBALS_H -+#define HARDENED_GLOBALS_H -+ -+typedef struct _hardened_globals hardened_globals_struct; -+ -+#ifdef ZTS -+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v) -+extern int hardened_globals_id; -+#else -+# define HG(v) (hardened_globals.v) -+extern struct _hardened_globals hardened_globals; -+#endif -+ -+ -+struct _hardened_globals { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_1; -+ unsigned int canary_2; -+#endif -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_3; -+ unsigned int canary_4; -+ unsigned int ll_canary_inited; -+#endif -+ zend_bool hphp_sql_bailout_on_error; -+ zend_bool hphp_multiheader; -+ unsigned long hphp_mailprotect; -+ long hard_memory_limit; -+ HashTable *eval_whitelist; -+ HashTable *eval_blacklist; -+ HashTable *func_whitelist; -+ HashTable *func_blacklist; -+ HashTable *include_whitelist; -+ HashTable *include_blacklist; -+ unsigned int dummy; -+}; -+ -+ -+#endif /* HARDENED_GLOBALS_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-5.1.6/main/hardening_patch.c hardening-patch-5.1.6-0.4.15/main/hardening_patch.c ---- php-5.1.6/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/hardening_patch.c 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */ -+ -+#include "php.h" -+ -+#include -+#include -+ -+#if HAVE_UNISTD_H -+#include -+#endif -+#include "SAPI.h" -+#include "php_globals.h" -+ -+#if HARDENING_PATCH -+ -+#ifdef HAVE_SYS_SOCKET_H -+#include -+#endif -+ -+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE) -+#undef AF_UNIX -+#endif -+ -+#if defined(AF_UNIX) -+#include -+#endif -+ -+#define SYSLOG_PATH "/dev/log" -+ -+#include "snprintf.h" -+ -+#include "hardening_patch.h" -+ -+#ifdef ZTS -+#include "hardened_globals.h" -+int hardened_globals_id; -+#else -+struct _hardened_globals hardened_globals; -+#endif -+ -+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC) -+{ -+ memset(hardened_globals, 0, sizeof(*hardened_globals)); -+} -+ -+ -+PHPAPI void hardened_startup() -+{ -+#ifdef ZTS -+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL); -+#else -+ hardened_globals_ctor(&hardened_globals TSRMLS_CC); -+#endif -+} -+ -+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D) -+{ -+ HG(canary_1) = php_canary(); -+ HG(canary_2) = php_canary(); -+} -+ -+char *loglevel2string(int loglevel) -+{ -+ switch (loglevel) { -+ case S_FILES: -+ return "FILES"; -+ case S_INCLUDE: -+ return "INCLUDE"; -+ case S_MEMORY: -+ return "MEMORY"; -+ case S_MISC: -+ return "MISC"; -+ case S_SQL: -+ return "SQL"; -+ case S_EXECUTOR: -+ return "EXECUTOR"; -+ case S_VARS: -+ return "VARS"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+PHPAPI void php_security_log(int loglevel, char *fmt, ...) -+{ -+#if defined(AF_UNIX) -+ int s, r, i=0; -+ struct sockaddr_un saun; -+ char buf[4096+64]; -+ char error[4096+100]; -+ char *ip_address; -+ char *fname; -+ int lineno; -+ va_list ap; -+ TSRMLS_FETCH(); -+ -+ if (EG(hphp_log_use_x_forwarded_for)) { -+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "X-FORWARDED-FOR not set"; -+ } -+ } else { -+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC); -+ if (ip_address == NULL) { -+ ip_address = "REMOTE_ADDR not set"; -+ } -+ } -+ -+ -+ va_start(ap, fmt); -+ ap_php_vsnprintf(error, sizeof(error), fmt, ap); -+ va_end(ap); -+ while (error[i]) { -+ if (error[i] < 32) error[i] = '.'; -+ i++; -+ } -+ -+ if (zend_is_executing(TSRMLS_C)) { -+ lineno = zend_get_executed_lineno(TSRMLS_C); -+ fname = zend_get_executed_filename(TSRMLS_C); -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno); -+ } else { -+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); -+ if (fname==NULL) { -+ fname = "unknown"; -+ } -+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname); -+ } -+ -+ /* Syslog-Logging disabled? */ -+ if ((EG(hphp_log_syslog) & loglevel)==0) { -+ goto log_sapi; -+ } -+ -+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf); -+ -+ s = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ s = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (s == -1) { -+ goto log_sapi; -+ } -+ -+ memset(&saun, 0, sizeof(saun)); -+ saun.sun_family = AF_UNIX; -+ strcpy(saun.sun_path, SYSLOG_PATH); -+ /*saun.sun_len = sizeof(saun);*/ -+ -+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); -+ if (r) { -+ close(s); -+ goto log_sapi; -+ } -+ } -+ send(s, error, strlen(error), 0); -+ -+ close(s); -+ -+log_sapi: -+ /* SAPI Logging activated? */ -+ if ((EG(hphp_log_sapi) & loglevel)!=0) { -+ sapi_module.log_message(buf); -+ } -+ -+log_script: -+ /* script logging activaed? */ -+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) { -+ char cmd[8192], *cmdpos, *bufpos; -+ FILE *in; -+ int space; -+ -+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel)); -+ space = sizeof(cmd) - strlen(cmd); -+ cmdpos = cmd + strlen(cmd); -+ bufpos = buf; -+ if (space <= 1) return; -+ while (space > 2 && *bufpos) { -+ if (*bufpos == '\'') { -+ if (space<=5) break; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\\'; -+ *cmdpos++ = '\''; -+ *cmdpos++ = '\''; -+ bufpos++; -+ space-=4; -+ } else { -+ *cmdpos++ = *bufpos++; -+ space--; -+ } -+ } -+ *cmdpos++ = '\''; -+ *cmdpos = 0; -+ -+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) { -+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname)); -+ return; -+ } -+ /* read and forget the result */ -+ while (1) { -+ int readbytes = fread(cmd, 1, sizeof(cmd), in); -+ if (readbytes<=0) { -+ break; -+ } -+ } -+ pclose(in); -+ } -+ -+#endif -+} -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+PHPAPI unsigned int php_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+ -+PHPAPI int php_is_valid_include(zval *z) -+{ -+ char *filename; -+ int len, i; -+ TSRMLS_FETCH(); -+ -+ /* must be of type string */ -+ if (z->type != IS_STRING || z->value.str.val == NULL) { -+ return (0); -+ } -+ -+ /* short cut */ -+ filename = z->value.str.val; -+ len = z->value.str.len; -+ -+ /* 1. must be shorter than MAXPATHLEN */ -+ if (len > MAXPATHLEN) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 2. must not be cutted */ -+ if (len != strlen(filename)) { -+ char *fname = estrndup(filename, len); -+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.'; -+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */ -+ if (strstr(filename, "://")) { -+ char *fname = estrndup(filename, len); -+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.'; -+ -+ /* no black or whitelist then disallow all */ -+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname); -+ efree(fname); -+ return (0); -+ } -+ -+ /* whitelist is stronger than blacklist */ -+ if (HG(include_whitelist)) { -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ zend_bool isOk = 0; -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_whitelist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ isOk = 1; -+ break; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_whitelist)); -+ } while (1); -+ -+ /* not found in whitelist */ -+ if (!isOk) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname); -+ efree(fname); -+ return 0; -+ } -+ -+ s = h + 3; -+ } while (1); -+ } else { -+ /* okay then handle the blacklist */ -+ char *s, *t, *h, *index; -+ uint indexlen; -+ ulong numindex; -+ -+ s = filename; -+ -+ do { -+ int tlen; -+ -+ t = h = strstr(s, "://"); -+ if (h == NULL) break; -+ -+ -+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) { -+ t--; -+ } -+ -+ tlen = strlen(t); -+ -+ zend_hash_internal_pointer_reset(HG(include_blacklist)); -+ do { -+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL); -+ -+ if (r==HASH_KEY_NON_EXISTANT) { -+ break; -+ } -+ if (r==HASH_KEY_IS_STRING) { -+ if (h-t <= indexlen-1 && tlen>=indexlen-1) { -+ if (strncmp(t, index, indexlen-1)==0) { -+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname); -+ efree(fname); -+ return 0; -+ } -+ } -+ } -+ -+ zend_hash_move_forward(HG(include_blacklist)); -+ } while (1); -+ -+ s = h + 3; -+ } while (1); -+ } -+ -+ efree(fname); -+ } -+ -+ /* 4. must not be an uploaded file */ -+ if (SG(rfc1867_uploaded_files)) { -+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) { -+ php_security_log(S_INCLUDE, "Include filename is an uploaded file"); -+ return (0); -+ } -+ } -+ -+ /* passed all tests */ -+ return (1); -+} -+ -+#endif -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.6/main/hardening_patch.h hardening-patch-5.1.6-0.4.15/main/hardening_patch.h ---- php-5.1.6/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/hardening_patch.h 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,46 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+ -+#ifndef HARDENING_PATCH_H -+#define HARDENING_PATCH_H -+ -+#include "zend.h" -+ -+#if HARDENING_PATCH -+PHPAPI void php_security_log(int loglevel, char *fmt, ...); -+PHPAPI void hardened_startup(); -+#define HARDENING_PATCH_VERSION "0.4.15" -+ -+#endif -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+PHPAPI unsigned int php_canary(); -+#endif -+ -+#if HARDENING_PATCH_INC_PROTECT -+PHPAPI int php_is_valid_include(zval *z); -+#endif -+ -+#endif /* HARDENING_PATCH_H */ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ */ -diff -Nura php-5.1.6/main/hardening_patch.m4 hardening-patch-5.1.6-0.4.15/main/hardening_patch.m4 ---- php-5.1.6/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/hardening_patch.m4 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,95 @@ -+dnl -+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $ -+dnl -+dnl This file contains Hardening Patch for PHP specific autoconf functions. -+dnl -+ -+AC_ARG_ENABLE(hardening-patch-mm-protect, -+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[ -+ DO_HARDENING_PATCH_MM_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_MM_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-ll-protect, -+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[ -+ DO_HARDENING_PATCH_LL_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_LL_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-inc-protect, -+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[ -+ DO_HARDENING_PATCH_INC_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_INC_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-fmt-protect, -+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_FMT_PROTECT=yes -+]) -+ -+AC_ARG_ENABLE(hardening-patch-hash-protect, -+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval -+],[ -+ DO_HARDENING_PATCH_HASH_PROTECT=yes -+]) -+ -+AC_MSG_CHECKING(whether to protect the Zend Memory Manager) -+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the Zend Linked Lists) -+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect include/require statements) -+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect PHP Format String functions) -+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT) -+ -+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables) -+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT) -+ -+ -+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ -+ -+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection]) -+fi -+ -+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then -+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch]) -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection]) -+else -+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection]) -+fi -+ -diff -Nura php-5.1.6/main/main.c hardening-patch-5.1.6-0.4.15/main/main.c ---- php-5.1.6/main/main.c 2006-08-10 23:49:56.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/main/main.c 2006-09-07 19:41:16.000000000 +0200 -@@ -85,6 +85,10 @@ - - #include "SAPI.h" - #include "rfc1867.h" -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#endif -+ - /* }}} */ - - #ifndef ZTS -@@ -109,17 +113,39 @@ - */ - static PHP_INI_MH(OnChangeMemoryLimit) - { -+#if HARDENING_PATCH -+ long hard_memory_limit = 1<<30; -+ -+ if (stage == ZEND_INI_STAGE_RUNTIME) { -+ if (HG(hard_memory_limit) == 0) { -+ HG(hard_memory_limit) = PG(memory_limit); -+ } -+ hard_memory_limit = HG(hard_memory_limit); -+ } else { -+ HG(hard_memory_limit) = 0; -+ } -+#endif - if (new_value) { - PG(memory_limit) = zend_atoi(new_value, new_value_length); -+#if HARDENING_PATCH -+ if (PG(memory_limit) > hard_memory_limit) { -+ PG(memory_limit) = hard_memory_limit; -+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value"); -+ return FAILURE; -+ } -+#endif - } else { -+#if HARDENING_PATCH -+ PG(memory_limit) = hard_memory_limit; -+#else - PG(memory_limit) = 1<<30; /* effectively, no limit */ -+#endif - } - return zend_set_memory_limit(PG(memory_limit)); - } - /* }}} */ - #endif - -- - /* {{{ php_disable_functions - */ - static void php_disable_functions(TSRMLS_D) -@@ -1100,6 +1126,13 @@ - sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1); - } - -+ /* Disable realpath cache if safe_mode or open_basedir are set */ -+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { -+ CWDG(realpath_cache_disable) = 1; -+ } else { -+ CWDG(realpath_cache_disable) = 0; -+ } -+ - if (PG(output_handler) && PG(output_handler)[0]) { - php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); - } else if (PG(output_buffering)) { -@@ -1227,6 +1260,9 @@ - - zend_try { - shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); -+#if HARDENING_PATCH -+ hardened_clear_mm_canaries(TSRMLS_C); -+#endif - } zend_end_try(); - - zend_try { -@@ -1398,6 +1434,10 @@ - tsrm_ls = ts_resource(0); - #endif - -+#if HARDENING_PATCH -+ hardened_startup(); -+#endif -+ - module_shutdown = 0; - module_startup = 1; - sapi_initialize_empty_request(TSRMLS_C); -@@ -1411,6 +1451,12 @@ - - php_output_startup(); - -+#if HARDENING_PATCH_INC_PROTECT -+ zuf.is_valid_include = php_is_valid_include; -+#endif -+#if HARDENING_PATCH -+ zuf.security_log_function = php_security_log; -+#endif - zuf.error_function = php_error_cb; - zuf.printf_function = php_printf; - zuf.write_function = php_body_write_wrapper; -@@ -1481,7 +1527,9 @@ - - /* Disable realpath cache if safe_mode or open_basedir are set */ - if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { -- CWDG(realpath_cache_size_limit) = 0; -+ CWDG(realpath_cache_disable) = 1; -+ } else { -+ CWDG(realpath_cache_disable) = 0; - } - - /* initialize stream wrappers registry -@@ -1522,6 +1570,10 @@ - REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS); - 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); - REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS); -+#endif - REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); -diff -Nura php-5.1.6/main/php_config.h.in hardening-patch-5.1.6-0.4.15/main/php_config.h.in ---- php-5.1.6/main/php_config.h.in 2006-08-23 14:55:05.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/main/php_config.h.in 2006-09-07 19:41:16.000000000 +0200 -@@ -788,6 +788,39 @@ - /* Enabling BIND8 compatibility for Panther */ - #undef BIND_8_COMPAT - -+/* Hardening-Patch for PHP */ -+#undef HARDENING_PATCH -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Memory Manager Protection */ -+#undef HARDENING_PATCH_MM_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Linked List Protection */ -+#undef HARDENING_PATCH_LL_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Include/Require Protection */ -+#undef HARDENING_PATCH_INC_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* Fmt String Protection */ -+#undef HARDENING_PATCH_FMT_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ -+/* HashTable DTOR Protection */ -+#undef HARDENING_PATCH_HASH_PROTECT -+ - /* Whether you have AOLserver */ - #undef HAVE_AOLSERVER - -@@ -1131,6 +1164,12 @@ - /* Define if you have the getaddrinfo function */ - #undef HAVE_GETADDRINFO - -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ -+/* Whether realpath is broken */ -+#undef PHP_BROKEN_REALPATH -+ - /* Whether system headers declare timezone */ - #undef HAVE_DECLARED_TIMEZONE - -diff -Nura php-5.1.6/main/php.h hardening-patch-5.1.6-0.4.15/main/php.h ---- php-5.1.6/main/php.h 2006-03-07 23:37:53.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/php.h 2006-09-07 19:41:16.000000000 +0200 -@@ -35,11 +35,19 @@ - #include "zend_qsort.h" - #include "php_compat.h" - -+ - #include "zend_API.h" - - #undef sprintf - #define sprintf php_sprintf - -+#if HARDENING_PATCH -+#if HAVE_REALPATH -+#undef realpath -+#define realpath php_realpath -+#endif -+#endif -+ - /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */ - #undef PHP_DEBUG - #define PHP_DEBUG ZEND_DEBUG -@@ -338,6 +346,7 @@ - #define PHP_FUNCTION ZEND_FUNCTION - #define PHP_METHOD ZEND_METHOD - -+#define PHP_STATIC_FE ZEND_STATIC_FE - #define PHP_NAMED_FE ZEND_NAMED_FE - #define PHP_FE ZEND_FE - #define PHP_DEP_FE ZEND_DEP_FE -@@ -447,6 +456,10 @@ - #endif - #endif /* !XtOffsetOf */ - -+#if HARDENING_PATCH -+#include "hardening_patch.h" -+#endif -+ - #endif - - /* -diff -Nura php-5.1.6/main/php_variables.c hardening-patch-5.1.6-0.4.15/main/php_variables.c ---- php-5.1.6/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/main/php_variables.c 2006-09-07 19:41:16.000000000 +0200 -@@ -73,6 +73,10 @@ - symtable1 = Z_ARRVAL_P(track_vars_array); - } else if (PG(register_globals)) { - symtable1 = EG(active_symbol_table); -+ /* GLOBALS hijack attempt, reject parameter */ -+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) { -+ symtable1 = NULL; -+ } - } - if (!symtable1) { - /* Nothing to do */ -@@ -513,7 +517,7 @@ - */ - static inline void php_register_server_variables(TSRMLS_D) - { -- zval *array_ptr = NULL; -+ zval *array_ptr = NULL, *vptr; - /* turn off magic_quotes while importing server variables */ - int magic_quotes_gpc = PG(magic_quotes_gpc); - -diff -Nura php-5.1.6/main/rfc1867.c hardening-patch-5.1.6-0.4.15/main/rfc1867.c ---- php-5.1.6/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/rfc1867.c 2006-09-07 19:41:16.000000000 +0200 -@@ -132,6 +132,7 @@ - #define UPLOAD_ERROR_D 4 /* No file uploaded */ - #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ - #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ -+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */ - - void php_rfc1867_register_constants(TSRMLS_D) - { -@@ -142,6 +143,7 @@ - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); - REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); - } - - static void normalize_protected_variable(char *varname TSRMLS_DC) -@@ -854,6 +856,7 @@ - char buff[FILLUNIT]; - char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; - int blen=0, wlen=0; -+ unsigned long offset; - - zend_llist_clean(&header); - -@@ -970,7 +973,11 @@ - tmp++; - } - } -- -+ -+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) { -+ skip_upload = 1; -+ } -+ - total_bytes = cancel_upload = 0; - - if (!skip_upload) { -@@ -994,6 +1001,11 @@ - cancel_upload = UPLOAD_ERROR_D; - } - -+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ -+ offset = 0; - end = 0; - while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) - { -@@ -1008,6 +1020,10 @@ - #endif - cancel_upload = UPLOAD_ERROR_B; - } else if (blen > 0) { -+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - wlen = write(fd, buff, blen); - - if (wlen < blen) { -@@ -1036,6 +1052,10 @@ - } - #endif - -+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) { -+ cancel_upload = UPLOAD_ERROR_X; -+ } -+ - if (cancel_upload) { - if (temp_filename) { - if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ -diff -Nura php-5.1.6/main/SAPI.c hardening-patch-5.1.6-0.4.15/main/SAPI.c ---- php-5.1.6/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/SAPI.c 2006-09-07 19:41:16.000000000 +0200 -@@ -870,6 +870,36 @@ - post_entry->content_type_len+1); - } - -+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)) -+{ -+ sapi_module.input_filter = input_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC)) -+{ -+ sapi_module.upload_varname_filter = upload_varname_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)) -+{ -+ sapi_module.pre_upload_filter = pre_upload_filter; -+ return SUCCESS; -+} -+ -+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)) -+{ -+ sapi_module.upload_content_filter = upload_content_filter; -+ return SUCCESS; -+} -+ -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)) -+{ -+ sapi_module.post_upload_filter = post_upload_filter; -+ return SUCCESS; -+} -+ - - SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D)) - { -@@ -884,11 +914,6 @@ - return SUCCESS; - } - --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)) --{ -- sapi_module.input_filter = input_filter; -- return SUCCESS; --} - - SAPI_API int sapi_flush(TSRMLS_D) - { -diff -Nura php-5.1.6/main/SAPI.h hardening-patch-5.1.6-0.4.15/main/SAPI.h ---- php-5.1.6/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/SAPI.h 2006-09-07 19:41:16.000000000 +0200 -@@ -190,6 +190,10 @@ - SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC)); - 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)); - -+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC)); -+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)); -+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC)); -+ - SAPI_API int sapi_flush(TSRMLS_D); - SAPI_API struct stat *sapi_get_stat(TSRMLS_D); - SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC); -@@ -254,6 +258,11 @@ - int (*get_target_gid)(gid_t * TSRMLS_DC); - - unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); -+ -+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC); -+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC); -+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC); -+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC); - - void (*ini_defaults)(HashTable *configuration_hash); - int phpinfo_as_text; -@@ -279,7 +288,11 @@ - - #define SAPI_DEFAULT_MIMETYPE "text/html" - #define SAPI_DEFAULT_CHARSET "" -+#if HARDENING_PATCH -+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch" -+#else - #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION -+#endif - - #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) - #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) -@@ -287,6 +300,11 @@ - #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) - #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) - -+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC) -+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC) -+#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) -+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC) -+ - BEGIN_EXTERN_C() - SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); - SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); -diff -Nura php-5.1.6/main/snprintf.c hardening-patch-5.1.6-0.4.15/main/snprintf.c ---- php-5.1.6/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/snprintf.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1014,7 +1014,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = cc; -+#endif - goto skip_output; - - /* -diff -Nura php-5.1.6/main/spprintf.c hardening-patch-5.1.6-0.4.15/main/spprintf.c ---- php-5.1.6/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/main/spprintf.c 2006-09-07 19:41:16.000000000 +0200 -@@ -630,7 +630,11 @@ - - - case 'n': -+#if HARDENING_PATCH_FMT_PROTECT -+ php_security_log(S_MISC, "'n' specifier within format string"); -+#else - *(va_arg(ap, int *)) = xbuf->len; -+#endif - goto skip_output; - - /* -diff -Nura php-5.1.6/pear/Makefile.frag hardening-patch-5.1.6-0.4.15/pear/Makefile.frag ---- php-5.1.6/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/pear/Makefile.frag 2006-09-07 19:41:16.000000000 +0200 -@@ -3,7 +3,7 @@ - peardir=$(PEAR_INSTALLDIR) - - # Skip all php.ini files altogether --PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -+PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar - - install-pear-installer: $(SAPI_CLI_PATH) - @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" -diff -Nura php-5.1.6/php.ini-dist hardening-patch-5.1.6-0.4.15/php.ini-dist ---- php-5.1.6/php.ini-dist 2006-08-14 20:40:19.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/php.ini-dist 2006-09-07 19:41:16.000000000 +0200 -@@ -1198,6 +1198,209 @@ - ; instead of original one. - soap.wsdl_cache_ttl=86400 - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-5.1.6/php.ini-recommended hardening-patch-5.1.6-0.4.15/php.ini-recommended ---- php-5.1.6/php.ini-recommended 2006-08-14 20:40:19.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/php.ini-recommended 2006-09-07 19:41:16.000000000 +0200 -@@ -1256,6 +1256,209 @@ - ; instead of original one. - soap.wsdl_cache_ttl=86400 - -+[hardening-patch] -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's logging ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; -+; hphp.log.syslog - Configures level for alerts reported through syslog -+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog -+; hphp.log.script - Configures level for alerts reported through external script -+; -+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields. -+; Or each number up to get desired Hardening-Patch's reporting level -+; -+; S_ALL - All alerts -+; S_MEMORY - All canary violations and the safe unlink protection use this class -+; S_VARS - All variable filters trigger this class -+; S_FILES - All violation of uploaded files filter use this class -+; S_INCLUDE - The protection against malicious include filenames use this class -+; S_SQL - Failed SQL queries in MySQL are logged with this class -+; S_EXECUTOR - The execution depth protection uses this logging class -+; S_MISC - All other log messages (f.e. format string protection) use this class -+; -+; Example: -+; -+; - Report all alerts (except memory alerts) to the SAPI errorlog, -+; memory alerts through syslog and SQL+Include alerts fo the script -+; -+;hphp.log.syslog = S_MEMORY -+;hphp.log.sapi = S_ALL & ~S_MEMORY -+;hphp.log.script = S_INCLUDE | S_SQL -+; -+; Syslog logging: -+; -+; - Facility configuration: one of the following facilities -+; -+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON -+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS -+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 -+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4 -+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID -+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT -+; LOG_PERROR -+; -+; - Priority configuration: one of the followinf priorities -+; -+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING -+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR -+; -+hphp.log.syslog.priority = LOG_ALERT -+hphp.log.syslog.facility = LOG_USER -+; -+; Script logging: -+; -+;hphp.log.script.name = /home/hphp/log_script -+; -+; Alert configuration: -+; -+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR -+; -+;hphp.log.use-x-forwarded-for = On -+; -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's Executor options ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Execution depth limit -+;hphp.executor.max_depth = 8000 -+ -+; White-/blacklist for function calls during normal execution -+;hphp.executor.func.whitelist = ord,chr -+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for function calls during eval() execution -+;hphp.executor.eval.whitelist = ord,chr -+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru -+ -+; White-/blacklist for URLs allowes in include filenames -+; -+; - When both options are not set all URLs are forbidden -+; -+; - When both options are set whitelist is taken and blacklist ignored -+; -+; - An entry in the lists is either a URL sheme like: http, https -+; or the beginning of an URL like: php://input -+; -+;hphp.executor.include.whitelist = cookietest -+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's REQUEST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of REQUEST variables -+hphp.request.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.request.max_varname_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.request.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.request.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.request.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.request.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.request.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's COOKIE variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.cookie.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.cookie.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.cookie.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.cookie.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.cookie.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.cookie.max_value_length = 10000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.cookie.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's GET variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of COOKIE variables -+hphp.get.max_vars = 100 -+ -+; Limits the length of variable names (without indices) -+hphp.get.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.get.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.get.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.get.max_array_depth = 50 -+ -+; Limits the length of variable values -+hphp.get.max_value_length = 512 -+ -+; Disallow ASCII-NUL characters in input -+hphp.get.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's POST variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of POST variables -+hphp.post.max_vars = 200 -+ -+; Limits the length of variable names (without indices) -+hphp.post.max_name_length = 64 -+ -+; Limits the length of complete variable names (with indices) -+hphp.post.max_totalname_length = 256 -+ -+; Limits the length of array indices -+hphp.post.max_array_index_length = 64 -+ -+; Limits the depth of arrays -+hphp.post.max_array_depth = 100 -+ -+; Limits the length of variable values -+hphp.post.max_value_length = 65000 -+ -+; Disallow ASCII-NUL characters in input -+hphp.post.disallow_nul = 1 -+ -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+; Hardening-Patch's fileupload variable filters ; -+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -+ -+; Limits the number of uploadable files -+hphp.upload.max_uploads = 25 -+ -+; Filter out the upload of ELF executables -+hphp.upload.disallow_elf_files = On -+ -+; External filterscript for upload verification -+;hphp.upload.verification_script = /home/hphp/verify_script -+ -+ - ; Local Variables: - ; tab-width: 4 - ; End: -diff -Nura php-5.1.6/run-tests.php hardening-patch-5.1.6-0.4.15/run-tests.php ---- php-5.1.6/run-tests.php 2006-08-23 14:43:53.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/run-tests.php 2006-09-07 19:41:16.000000000 +0200 -@@ -161,6 +161,10 @@ - 'error_reporting=4095', - 'display_errors=1', - 'log_errors=0', -+ 'hphp.executor.include.whitelist=cookietest', -+ 'hphp.log.syslog=0', -+ 'hphp.log.sapi=0', -+ 'hphp.log.script=0', - 'html_errors=0', - 'track_errors=1', - 'report_memleaks=1', -diff -Nura php-5.1.6/sapi/apache/mod_php5.c hardening-patch-5.1.6-0.4.15/sapi/apache/mod_php5.c ---- php-5.1.6/sapi/apache/mod_php5.c 2006-05-14 00:03:51.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/sapi/apache/mod_php5.c 2006-09-07 19:41:16.000000000 +0200 -@@ -482,7 +482,7 @@ - sapi_apache_get_fd, - sapi_apache_force_http_10, - sapi_apache_get_target_uid, -- sapi_apache_get_target_gid -+ sapi_apache_get_target_gid, - }; - /* }}} */ - -@@ -936,7 +936,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component("PHP/" PHP_VERSION); -+#endif - } - } - #endif -diff -Nura php-5.1.6/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.6-0.4.15/sapi/apache2filter/sapi_apache2.c ---- php-5.1.6/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-07 19:41:16.000000000 +0200 -@@ -573,7 +573,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-5.1.6/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.6-0.4.15/sapi/apache2handler/sapi_apache2.c ---- php-5.1.6/sapi/apache2handler/sapi_apache2.c 2006-08-08 15:11:39.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-07 19:41:16.000000000 +0200 -@@ -341,7 +341,11 @@ - { - TSRMLS_FETCH(); - if (PG(expose_php)) { -+#if HARDENING_PATCH -+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch"); -+#else - ap_add_version_component(p, "PHP/" PHP_VERSION); -+#endif - } - } - -diff -Nura php-5.1.6/sapi/cgi/cgi_main.c hardening-patch-5.1.6-0.4.15/sapi/cgi/cgi_main.c ---- php-5.1.6/sapi/cgi/cgi_main.c 2006-05-24 09:55:38.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/sapi/cgi/cgi_main.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1448,10 +1448,18 @@ - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - } -+#if HARDENING_PATCH - #if ZEND_DEBUG -- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -+ 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()); - #else -- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); -+ 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()); -+#endif -+#else -+#if ZEND_DEBUG -+ 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()); -+#else -+ 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()); -+#endif - #endif - php_end_ob_buffers(1 TSRMLS_CC); - exit(0); -diff -Nura php-5.1.6/sapi/cli/php_cli.c hardening-patch-5.1.6-0.4.15/sapi/cli/php_cli.c ---- php-5.1.6/sapi/cli/php_cli.c 2006-05-12 00:11:17.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/sapi/cli/php_cli.c 2006-09-07 19:41:16.000000000 +0200 -@@ -754,8 +754,14 @@ - goto err; - } - -+#if HARDENING_PATCH -+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", -+ PHP_VERSION, HARDENING_PATCH_VERSION, -+#else - php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s", -- PHP_VERSION, sapi_module.name, __DATE__, __TIME__, -+ PHP_VERSION, -+#endif -+ sapi_module.name, __DATE__, __TIME__, - #if ZEND_DEBUG && defined(HAVE_GCOV) - "(DEBUG GCOV)", - #elif ZEND_DEBUG -diff -Nura php-5.1.6/TSRM/TSRM.h hardening-patch-5.1.6-0.4.15/TSRM/TSRM.h ---- php-5.1.6/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/TSRM/TSRM.h 2006-09-07 19:41:16.000000000 +0200 -@@ -33,6 +33,13 @@ - # define TSRM_API - #endif - -+#if HARDENING_PATCH -+# if HAVE_REALPATH -+# undef realpath -+# define realpath php_realpath -+# endif -+#endif -+ - /* Only compile multi-threading functions if we're in ZTS mode */ - #ifdef ZTS - -@@ -88,6 +95,7 @@ - - #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts - -+ - #ifdef __cplusplus - extern "C" { - #endif -diff -Nura php-5.1.6/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.c ---- php-5.1.6/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-07 19:41:16.000000000 +0200 -@@ -163,6 +163,7 @@ - static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) - { - CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state); -+ cwd_globals->realpath_cache_disable = 0; - cwd_globals->realpath_cache_size = 0; - cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE; - cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL; -@@ -201,6 +202,176 @@ - return p; - } - -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved) -+{ -+ struct stat sb; -+ char *p, *q, *s; -+ size_t left_len, resolved_len; -+ unsigned symlinks; -+ int serrno, slen; -+ int is_dir = 1; -+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; -+ -+ serrno = errno; -+ symlinks = 0; -+ if (path[0] == '/') { -+ resolved[0] = '/'; -+ resolved[1] = '\0'; -+ if (path[1] == '\0') -+ return (resolved); -+ resolved_len = 1; -+ left_len = strlcpy(left, path + 1, sizeof(left)); -+ } else { -+ if (getcwd(resolved, PATH_MAX) == NULL) { -+ strlcpy(resolved, ".", PATH_MAX); -+ return (NULL); -+ } -+ resolved_len = strlen(resolved); -+ left_len = strlcpy(left, path, sizeof(left)); -+ } -+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ -+ /* -+ * Iterate over path components in `left'. -+ */ -+ while (left_len != 0) { -+ /* -+ * Extract the next path component and adjust `left' -+ * and its length. -+ */ -+ p = strchr(left, '/'); -+ s = p ? p : left + left_len; -+ if (s - left >= sizeof(next_token)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ memcpy(next_token, left, s - left); -+ next_token[s - left] = '\0'; -+ left_len -= s - left; -+ if (p != NULL) -+ memmove(left, s + 1, left_len + 1); -+ if (resolved[resolved_len - 1] != '/') { -+ if (resolved_len + 1 >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ resolved[resolved_len++] = '/'; -+ resolved[resolved_len] = '\0'; -+ } -+ if (next_token[0] == '\0') -+ continue; -+ else if (strcmp(next_token, ".") == 0) -+ continue; -+ else if (strcmp(next_token, "..") == 0) { -+ /* -+ * Strip the last path component except when we have -+ * single "/" -+ */ -+ if (!is_dir) { -+ errno = ENOENT; -+ return (NULL); -+ } -+ if (resolved_len > 1) { -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ continue; -+ } -+ -+ /* -+ * Append the next path component and lstat() it. If -+ * lstat() fails we still can return successfully if -+ * there are no more path components left. -+ */ -+ resolved_len = strlcat(resolved, next_token, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ if (lstat(resolved, &sb) != 0) { -+ if (errno == ENOENT) { -+ if (p == NULL) { -+ errno = serrno; -+ return (resolved); -+ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) { -+ resolved_len = strlcat(resolved, "/", PATH_MAX); -+ resolved_len = strlcat(resolved, left, PATH_MAX); -+ if (resolved_len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ errno = serrno; -+ return (resolved); -+ } -+ } -+ return (NULL); -+ } -+ if (S_ISLNK(sb.st_mode)) { -+ if (symlinks++ > MAXSYMLINKS) { -+ errno = ELOOP; -+ return (NULL); -+ } -+ slen = readlink(resolved, symlink, sizeof(symlink) - 1); -+ if (slen < 0) -+ return (NULL); -+ symlink[slen] = '\0'; -+ if (symlink[0] == '/') { -+ resolved[1] = 0; -+ resolved_len = 1; -+ } else if (resolved_len > 1) { -+ /* Strip the last path component. */ -+ resolved[resolved_len - 1] = '\0'; -+ q = strrchr(resolved, '/'); -+ *q = '\0'; -+ resolved_len = q - resolved; -+ } -+ -+ /* -+ * If there are any path components left, then -+ * append them to symlink. The result is placed -+ * in `left'. -+ */ -+ if (p != NULL) { -+ if (symlink[slen - 1] != '/') { -+ if (slen + 1 >= sizeof(symlink)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ symlink[slen] = '/'; -+ symlink[slen + 1] = 0; -+ } -+ left_len = strlcat(symlink, left, sizeof(left)); -+ if (left_len >= sizeof(left)) { -+ errno = ENAMETOOLONG; -+ return (NULL); -+ } -+ } -+ left_len = strlcpy(left, symlink, sizeof(left)); -+ } else { -+ if (S_ISDIR(sb.st_mode)) { -+ is_dir = 1; -+ } else { -+ is_dir = 0; -+ } -+ } -+ } -+ -+ /* -+ * Remove trailing slash except when the resolved pathname -+ * is a single "/". -+ */ -+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/') -+ resolved[resolved_len - 1] = '\0'; -+ return (resolved); -+} -+#endif -+ - CWD_API void virtual_cwd_startup(void) - { - char cwd[MAXPATHLEN]; -@@ -381,22 +552,33 @@ - #endif - char orig_path[MAXPATHLEN]; - int orig_path_len = 0; -+ int use_realpath_cache = 1; - realpath_cache_bucket *bucket; - time_t t = 0; - TSRMLS_FETCH(); - - if (path_length == 0) - return (0); -- if (path_length >= MAXPATHLEN) -+ if (path_length >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return (1); -+ } -+ -+ /* Disable realpath cache if safe_mode or open_basedir are set */ -+ if (CWDG(realpath_cache_disable)) { -+ use_realpath_cache = 0; -+ } - -- if (use_realpath && CWDG(realpath_cache_size_limit)) { -+ if (use_realpath && use_realpath_cache) { - if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { - memcpy(orig_path, path, path_length+1); - orig_path_len = path_length; - } else { - orig_path_len = path_length + state->cwd_length + 1; - if (orig_path_len >= MAXPATHLEN) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(orig_path, state->cwd, state->cwd_length); -@@ -414,6 +596,8 @@ - if (verify_path && verify_path(state)) { - CWD_STATE_FREE(state); - *state = old_state; -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } else { - CWD_STATE_FREE(&old_state); -@@ -431,8 +615,9 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - } else { /* Concat current directory with relative path and then run realpath() on it */ -@@ -441,6 +626,8 @@ - - ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/")); - if (!tmp) { -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - memcpy(ptr, state->cwd, state->cwd_length); -@@ -451,6 +638,8 @@ - *ptr = '\0'; - if (strlen(tmp) >= MAXPATHLEN) { - free(tmp); -+ state->cwd[0] = 0; -+ state->cwd_length = 0; - return 1; - } - if (use_realpath) { -@@ -458,9 +647,10 @@ - path = resolved_path; - path_length = strlen(path); - } else { -- /* disable for now - free(tmp); -- return 1; */ -+ state->cwd[0] = 0; -+ state->cwd_length = 0; -+ return 1; - } - } - free(tmp); -@@ -599,7 +789,7 @@ - #endif - free(free_path); - -- if (use_realpath && CWDG(realpath_cache_size_limit)) { -+ if (use_realpath && use_realpath_cache) { - realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); - } - -diff -Nura php-5.1.6/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.h ---- php-5.1.6/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-07 19:41:16.000000000 +0200 -@@ -127,6 +127,22 @@ - - typedef int (*verify_path_func)(const cwd_state *); - -+#ifndef HAVE_STRLCPY -+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz); -+#undef strlcpy -+#define strlcpy php_strlcpy -+#endif -+ -+#ifndef HAVE_STRLCAT -+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz); -+#undef strlcat -+#define strlcat php_strlcat -+#endif -+ -+ -+#if HARDENING_PATCH -+CWD_API char *php_realpath(const char *path, char *resolved); -+#endif - CWD_API void virtual_cwd_startup(void); - CWD_API void virtual_cwd_shutdown(void); - CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); -@@ -199,6 +215,7 @@ - long realpath_cache_size_limit; - long realpath_cache_ttl; - realpath_cache_bucket *realpath_cache[1024]; -+ int realpath_cache_disable; - } virtual_cwd_globals; - - #ifdef ZTS -diff -Nura php-5.1.6/Zend/zend_alloc.c hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.c ---- php-5.1.6/Zend/zend_alloc.c 2006-08-10 19:16:24.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.c 2006-09-07 19:46:06.000000000 +0200 -@@ -64,6 +64,11 @@ - # define END_MAGIC_SIZE 0 - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+# define CANARY_SIZE sizeof(unsigned int) -+#else -+# define CANARY_SIZE 0 -+#endif - - # if MEMORY_LIMIT - # if ZEND_DEBUG -@@ -113,9 +118,17 @@ - if (p==AG(head)) { \ - AG(head) = p->pNext; \ - } else { \ -+ if (p != p->pLast->pNext) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pLast->pNext = p->pNext; \ - } \ - if (p->pNext) { \ -+ if (p != p->pNext->pLast) { \ -+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \ -+ exit(1); \ -+ } \ - p->pNext->pLast = p->pLast; \ - } - #else -@@ -154,6 +167,12 @@ - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) { -+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow"); -+ exit(1); -+ } -+#endif - CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size); - - if (size > INT_MAX || SIZE < size) { -@@ -176,6 +195,10 @@ - AG(cache_stats)[CACHE_INDEX][1]++; - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } else { -@@ -191,7 +214,7 @@ - AG(allocated_memory_peak) = AG(allocated_memory); - } - #endif -- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE); - #if !ZEND_DISABLE_MEMORY_CACHE - } - #endif -@@ -224,7 +247,10 @@ - # endif - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif -- -+#if HARDENING_PATCH_MM_PROTECT -+ p->canary = HG(canary_1); -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - HANDLE_UNBLOCK_INTERRUPTIONS(); - return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING); - } -@@ -252,6 +278,10 @@ - } - } - -+ -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()"); -+#endif - zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset); - return 0; - } -@@ -284,9 +314,25 @@ - - ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING); - DECLARE_CACHE_VARS(); - TSRMLS_FETCH(); -+ -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+efree_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected"); -+ exit(1); -+ } -+ /* to catch double efree()s */ -+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE); -+ p->canary = 0; -+#endif - - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { -@@ -327,23 +373,35 @@ - - ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -- void *p; -- int final_size = size*nmemb; -+ char *p; -+ size_t _size = nmemb * size; -+ -+ if (nmemb && (_size/nmemb!=size)) { -+#if HARDENING_PATCH -+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()"); -+#endif -+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size); -+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID -+ kill(getpid(), SIGSEGV); -+#else -+ exit(1); -+#endif -+ } - -- HANDLE_BLOCK_INTERRUPTIONS(); -- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -- if (!p) { -- HANDLE_UNBLOCK_INTERRUPTIONS(); -- return (void *) p; -+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -+ if (p) { -+ memset(p, 0, _size); - } -- memset(p, 0, final_size); -- HANDLE_UNBLOCK_INTERRUPTIONS(); -- return p; -+ -+ return ((void *)p); - } - - - ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) - { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary_2; -+#endif - zend_mem_header *p; - zend_mem_header *orig; - DECLARE_CACHE_VARS(); -@@ -355,6 +413,16 @@ - - p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING); - -+#if HARDENING_PATCH_MM_PROTECT -+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch; -+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE); -+ if (canary_2 != HG(canary_2)) { -+erealloc_canary_mismatch: -+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected"); -+ exit(1); -+ } -+#endif -+ - #if defined(ZTS) && TSRM_DEBUG - if (p->thread_id != tsrm_thread_id()) { - void *new_p; -@@ -385,7 +453,7 @@ - } - #endif - REMOVE_POINTER_FROM_LIST(p); -- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE); -+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE); - erealloc_error: - if (!p) { - if (!allow_failure) { -@@ -408,6 +476,9 @@ - memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long)); - #endif - -+#if HARDENING_PATCH_MM_PROTECT -+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE); -+#endif - p->size = size; - - HANDLE_UNBLOCK_INTERRUPTIONS(); -@@ -482,6 +553,10 @@ - { - AG(head) = NULL; - -+#if HARDENING_PATCH_MM_PROTECT -+ HG(canary_1) = zend_canary(); -+ HG(canary_2) = zend_canary(); -+#endif - #if MEMORY_LIMIT - AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */ - AG(allocated_memory) = 0; -diff -Nura php-5.1.6/Zend/zend_alloc.h hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.h ---- php-5.1.6/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_alloc.h 2006-09-07 19:41:16.000000000 +0200 -@@ -35,6 +35,9 @@ - #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL - - typedef struct _zend_mem_header { -+#if HARDENING_PATCH_MM_PROTECT -+ unsigned int canary; -+#endif - #if ZEND_DEBUG - long magic; - char *filename; -diff -Nura php-5.1.6/Zend/zend_API.h hardening-patch-5.1.6-0.4.15/Zend/zend_API.h ---- php-5.1.6/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_API.h 2006-09-07 19:41:16.000000000 +0200 -@@ -47,6 +47,7 @@ - #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) - - #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 }, -+#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 }, - - #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0) - #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0) -diff -Nura php-5.1.6/Zend/zend_builtin_functions.c hardening-patch-5.1.6-0.4.15/Zend/zend_builtin_functions.c ---- php-5.1.6/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_builtin_functions.c 2006-09-07 19:41:16.000000000 +0200 -@@ -53,6 +53,9 @@ - static ZEND_FUNCTION(crash); - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+static ZEND_FUNCTION(heap_overflow); -+#endif - static ZEND_FUNCTION(get_included_files); - static ZEND_FUNCTION(is_subclass_of); - static ZEND_FUNCTION(is_a); -@@ -113,6 +116,9 @@ - ZEND_FE(crash, NULL) - #endif - #endif -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ ZEND_FE(heap_overflow, NULL) -+#endif - ZEND_FE(get_included_files, NULL) - ZEND_FALIAS(get_required_files, get_included_files, NULL) - ZEND_FE(is_subclass_of, NULL) -@@ -1103,6 +1109,19 @@ - - #endif /* ZEND_DEBUG */ - -+ -+#if HARDENING_PATCH_MM_PROTECT_DEBUG -+ZEND_FUNCTION(heap_overflow) -+{ -+ char *nowhere = emalloc(10); -+ -+ memcpy(nowhere, "something1234567890", sizeof("something1234567890")); -+ -+ efree(nowhere); -+} -+#endif -+ -+ - /* {{{ proto array get_included_files(void) - Returns an array with the file names that were include_once()'d */ - ZEND_FUNCTION(get_included_files) -diff -Nura php-5.1.6/Zend/zend.c hardening-patch-5.1.6-0.4.15/Zend/zend.c ---- php-5.1.6/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend.c 2006-09-07 19:41:16.000000000 +0200 -@@ -55,6 +55,12 @@ - ZEND_API void (*zend_unblock_interruptions)(void); - ZEND_API void (*zend_ticks_function)(int ticks); - ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); -+#if HARDENING_PATCH -+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); - ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); - -@@ -74,9 +80,391 @@ - return SUCCESS; - } - -+#if HARDENING_PATCH -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL; -+ } else { -+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_facility) = LOG_USER; -+ } else { -+ EG(hphp_log_syslog_facility) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority) -+{ -+ if (!new_value) { -+ EG(hphp_log_syslog_priority) = LOG_ALERT; -+ } else { -+ EG(hphp_log_syslog_priority) = atoi(new_value); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_sapi) -+{ -+ if (!new_value) { -+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL; -+ } else { -+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL; -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_script) -+{ -+ if (!new_value) { -+ EG(hphp_log_script) = S_ALL & ~S_MEMORY; -+ } else { -+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL); -+ } -+ return SUCCESS; -+} -+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname) -+{ -+ if (EG(hphp_log_scriptname)) { -+ pefree(EG(hphp_log_scriptname),1); -+ } -+ EG(hphp_log_scriptname) = NULL; -+ if (new_value) { -+ EG(hphp_log_scriptname) = pestrdup(new_value,1); -+ } -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_whitelist_destroy: -+ if (HG(include_whitelist)) { -+ zend_hash_destroy(HG(include_whitelist)); -+ pefree(HG(include_whitelist),1); -+ } -+ HG(include_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_whitelist_destroy; -+ } -+ -+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+include_blacklist_destroy: -+ if (HG(include_blacklist)) { -+ zend_hash_destroy(HG(include_blacklist)); -+ pefree(HG(include_blacklist),1); -+ } -+ HG(include_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto include_blacklist_destroy; -+ } -+ -+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_whitelist_destroy: -+ if (HG(eval_whitelist)) { -+ zend_hash_destroy(HG(eval_whitelist)); -+ pefree(HG(eval_whitelist),1); -+ } -+ HG(eval_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_whitelist_destroy; -+ } -+ -+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+eval_blacklist_destroy: -+ if (HG(eval_blacklist)) { -+ zend_hash_destroy(HG(eval_blacklist)); -+ pefree(HG(eval_blacklist), 1); -+ } -+ HG(eval_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto eval_blacklist_destroy; -+ } -+ -+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_whitelist_destroy: -+ if (HG(func_whitelist)) { -+ zend_hash_destroy(HG(func_whitelist)); -+ pefree(HG(func_whitelist),1); -+ } -+ HG(func_whitelist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_whitelist_destroy; -+ } -+ -+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ return SUCCESS; -+} -+ -+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist) -+{ -+ char *s = NULL, *e, *val; -+ unsigned long dummy = 1; -+ -+ if (!new_value) { -+func_blacklist_destroy: -+ if (HG(func_blacklist)) { -+ zend_hash_destroy(HG(func_blacklist)); -+ pefree(HG(func_blacklist),1); -+ } -+ HG(func_blacklist) = NULL; -+ return SUCCESS; -+ } -+ if (!(*new_value)) { -+ goto func_blacklist_destroy; -+ } -+ -+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1); -+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1); -+ -+ val = zend_str_tolower_dup(new_value, strlen(new_value)); -+ e = val; -+ -+ while (*e) { -+ switch (*e) { -+ case ' ': -+ case ',': -+ if (s) { -+ *e = '\0'; -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ s = NULL; -+ } -+ break; -+ default: -+ if (!s) { -+ s = e; -+ } -+ break; -+ } -+ e++; -+ } -+ if (s) { -+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL); -+ } -+ efree(val); -+ -+ -+ return SUCCESS; -+} -+ -+#endif - - ZEND_INI_BEGIN() - ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) -+#if HARDENING_PATCH -+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog) -+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility) -+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority) -+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi) -+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script) -+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname) -+ 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) -+ -+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist) -+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist) -+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist) -+ -+ 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) -+ 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) -+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals) -+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals) -+#endif - STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals) - #ifdef ZEND_MULTIBYTE - STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) -@@ -501,9 +889,13 @@ - EG(user_error_handler) = NULL; - EG(user_exception_handler) = NULL; - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(in_autoload) = NULL; - EG(current_execute_data) = NULL; - EG(current_module) = NULL; -+#if HARDENING_PATCH -+ EG(hphp_log_scriptname) = NULL; -+#endif - } - - -@@ -574,6 +966,14 @@ - extern zend_scanner_globals language_scanner_globals; - #endif - -+ /* Set up Hardening-Patch utility functions first */ -+#if HARDENING_PATCH -+ zend_security_log = utility_functions->security_log_function; -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ zend_is_valid_include = utility_functions->is_valid_include; -+#endif -+ - #ifdef ZTS - ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); - #else -@@ -777,6 +1177,7 @@ - } - CG(unclean_shutdown) = 1; - CG(in_compilation) = EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(current_execute_data) = NULL; - longjmp(EG(bailout), FAILURE); - } -diff -Nura php-5.1.6/Zend/zend_canary.c hardening-patch-5.1.6-0.4.15/Zend/zend_canary.c ---- php-5.1.6/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_canary.c 2006-09-07 19:41:16.000000000 +0200 -@@ -0,0 +1,58 @@ -+/* -+ +----------------------------------------------------------------------+ -+ | Hardening-Patch for PHP | -+ +----------------------------------------------------------------------+ -+ | Copyright (c) 2004-2005 Stefan Esser | -+ +----------------------------------------------------------------------+ -+ | This source file is subject to version 2.02 of the PHP license, | -+ | that is bundled with this package in the file LICENSE, and is | -+ | available at through the world-wide-web at | -+ | http://www.php.net/license/2_02.txt. | -+ | If you did not receive a copy of the PHP license and are unable to | -+ | obtain it through the world-wide-web, please send a note to | -+ | license@php.net so we can mail you a copy immediately. | -+ +----------------------------------------------------------------------+ -+ | Author: Stefan Esser | -+ +----------------------------------------------------------------------+ -+ */ -+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */ -+ -+#include "zend.h" -+ -+#include -+#include -+ -+ -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ -+/* will be replaced later with more compatible method */ -+ZEND_API unsigned int zend_canary() -+{ -+ time_t t; -+ unsigned int canary; -+ int fd; -+ -+ fd = open("/dev/urandom", 0); -+ if (fd != -1) { -+ int r = read(fd, &canary, sizeof(canary)); -+ close(fd); -+ if (r == sizeof(canary)) { -+ return (canary); -+ } -+ } -+ /* not good but we never want to do this */ -+ time(&t); -+ canary = *(unsigned int *)&t + getpid() << 16; -+ return (canary); -+} -+#endif -+ -+ -+/* -+ * Local variables: -+ * tab-width: 4 -+ * c-basic-offset: 4 -+ * End: -+ * vim600: sw=4 ts=4 fdm=marker -+ * vim<600: sw=4 ts=4 -+ */ -diff -Nura php-5.1.6/Zend/zend_compile.c hardening-patch-5.1.6-0.4.15/Zend/zend_compile.c ---- php-5.1.6/Zend/zend_compile.c 2006-05-02 17:49:26.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_compile.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1093,6 +1093,13 @@ - op_array.prototype = NULL; - - op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array.created_by_eval = 1; -+ } else { -+ op_array.created_by_eval = 0; -+ } -+#endif - - if (is_method) { - char *short_class_name = CG(active_class_entry)->name; -diff -Nura php-5.1.6/Zend/zend_compile.h hardening-patch-5.1.6-0.4.15/Zend/zend_compile.h ---- php-5.1.6/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_compile.h 2006-09-07 19:41:16.000000000 +0200 -@@ -217,6 +217,9 @@ - zend_uint doc_comment_len; - - void *reserved[ZEND_MAX_RESERVED_RESOURCES]; -+#if HARDENING_PATCH -+ zend_bool created_by_eval; -+#endif - }; - - -@@ -295,6 +298,8 @@ - zval ***CVs; - zend_bool original_in_execution; - HashTable *symbol_table; -+ zend_uint original_in_code_type; -+ zend_uint execute_depth; - struct _zend_execute_data *prev_execute_data; - zval *old_error_reporting; - }; -@@ -617,6 +622,7 @@ - #define ZEND_OVERLOADED_FUNCTION 3 - #define ZEND_EVAL_CODE 4 - #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5 -+#define ZEND_SANDBOX_CODE 6 - - #define ZEND_INTERNAL_CLASS 1 - #define ZEND_USER_CLASS 2 -diff -Nura php-5.1.6/Zend/zend_constants.c hardening-patch-5.1.6-0.4.15/Zend/zend_constants.c ---- php-5.1.6/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_constants.c 2006-09-07 19:41:16.000000000 +0200 -@@ -109,6 +109,74 @@ - REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS); - - REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS); -+#if HARDENING_PATCH -+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS); -+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS); -+ -+ /* error levels */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT); -+ /* facility: type of program logging the message */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NEWS -+ /* No LOG_NEWS on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */ -+#endif -+#ifdef LOG_UUCP -+ /* No LOG_UUCP on HP-UX */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_CRON -+ /* apparently some systems don't have this one */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_AUTHPRIV -+ /* AIX doesn't have LOG_AUTHPRIV */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT); -+#endif -+#if !defined(PHP_WIN32) && !defined(NETWARE) -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT); -+#endif -+ /* options */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT); -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT); -+#ifdef LOG_NOWAIT -+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT); -+#endif -+#ifdef LOG_PERROR -+ /* AIX doesn't have LOG_PERROR */ -+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ -+#endif -+#endif - - /* true/false constants */ - { -diff -Nura php-5.1.6/Zend/zend_errors.h hardening-patch-5.1.6-0.4.15/Zend/zend_errors.h ---- php-5.1.6/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_errors.h 2006-09-07 19:41:16.000000000 +0200 -@@ -38,6 +38,19 @@ - #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) - #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) - -+#if HARDENING_PATCH -+#define S_MEMORY (1<<0L) -+#define S_VARS (1<<1L) -+#define S_FILES (1<<2L) -+#define S_INCLUDE (1<<3L) -+#define S_SQL (1<<4L) -+#define S_EXECUTOR (1<<5L) -+#define S_MAIL (1<<6L) -+#define S_MISC (1<<30L) -+#define S_INTERNAL (1<<29L) -+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR) -+#endif -+ - #endif /* ZEND_ERRORS_H */ - - /* -diff -Nura php-5.1.6/Zend/zend_execute_API.c hardening-patch-5.1.6-0.4.15/Zend/zend_execute_API.c ---- php-5.1.6/Zend/zend_execute_API.c 2006-04-21 00:49:20.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_execute_API.c 2006-09-07 19:41:16.000000000 +0200 -@@ -142,6 +142,7 @@ - EG(class_table) = CG(class_table); - - EG(in_execution) = 0; -+ EG(in_code_type) = 0; - EG(in_autoload) = NULL; - EG(autoload_func) = NULL; - -@@ -784,6 +785,39 @@ - if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) { - EX(function_state).function = NULL; - } -+#if HARDENING_PATCH -+ else { -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc); -+ efree(function_name_lc); -+ zend_bailout(); -+ } -+ } -+ } -+#endif - efree(function_name_lc); - } - -@@ -1076,7 +1110,7 @@ - return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC); - } - --ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC) - { - zval pv; - zend_op_array *new_op_array; -@@ -1109,6 +1143,7 @@ - zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); - zend_op **original_opline_ptr = EG(opline_ptr); - -+ new_op_array->type = type; - EG(return_value_ptr_ptr) = &local_retval_ptr; - EG(active_op_array) = new_op_array; - EG(no_extensions)=1; -@@ -1143,6 +1178,12 @@ - } - - -+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) -+{ -+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC)); -+} -+ -+ - ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) - { - int result; -diff -Nura php-5.1.6/Zend/zend_execute.c hardening-patch-5.1.6-0.4.15/Zend/zend_execute.c ---- php-5.1.6/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_execute.c 2006-09-07 19:41:16.000000000 +0200 -@@ -1351,6 +1351,37 @@ - /* OBJ-TBI - doesn't support new object model! */ - zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - return 0; - } -@@ -1396,6 +1427,7 @@ - efree(EX(Ts)); \ - } \ - EG(in_execution) = EX(original_in_execution); \ -+ EG(in_code_type) = EX(original_in_code_type); \ - EG(current_execute_data) = EX(prev_execute_data); \ - ZEND_VM_RETURN() - -diff -Nura php-5.1.6/Zend/zend_extensions.c hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.c ---- php-5.1.6/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.c 2006-09-07 19:41:16.000000000 +0200 -@@ -55,23 +55,44 @@ - return FAILURE; - } - -+ /* check if module is compiled against Hardening-Patch */ -+ if (extension_version_info->zend_extension_api_no < 1000000000) { -+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } -+ -+ -+ /* check if module is compiled against correct Hardening-Patch version */ -+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) { -+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n" -+ "The Hardening-Patch version %d is installed.\n\n", -+ new_extension->name, -+ extension_version_info->zend_extension_api_no, -+ HARDENING_PATCH_ZEND_EXTENSION_API_NO); -+ DL_UNLOAD(handle); -+ return FAILURE; -+ } - - /* allow extension to proclaim compatibility with any Zend version */ -- 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)) { -- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) { -+ 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)) { -+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is outdated.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO); - DL_UNLOAD(handle); - return FAILURE; -- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) { -+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) { - fprintf(stderr, "%s requires Zend Engine API version %d.\n" - "The Zend Engine API version %d which is installed, is newer.\n" - "Contact %s at %s for a later version of %s.\n\n", - new_extension->name, -- extension_version_info->zend_extension_api_no, -+ extension_version_info->real_zend_extension_api_no, - ZEND_EXTENSION_API_NO, - new_extension->author, - new_extension->URL, -diff -Nura php-5.1.6/Zend/zend_extensions.h hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.h ---- php-5.1.6/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_extensions.h 2006-09-07 19:41:16.000000000 +0200 -@@ -24,9 +24,11 @@ - - #include "zend_compile.h" - --/* The first number is the engine version and the rest is the date. -+/* The first API number is a flag saying that Hardening-Patch is used. -+ * The second number is the engine version and the date. - * This way engine 2 API no. is always greater than engine 1 API no.. - */ -+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106 - #define ZEND_EXTENSION_API_NO 220051025 - - typedef struct _zend_extension_version_info { -@@ -34,6 +36,7 @@ - char *required_zend_version; - unsigned char thread_safe; - unsigned char debug; -+ int real_zend_extension_api_no; - } zend_extension_version_info; - - -@@ -101,7 +104,7 @@ - - - #define ZEND_EXTENSION() \ -- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG } -+ 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 } - - #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 - #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1 -diff -Nura php-5.1.6/Zend/zend_globals.h hardening-patch-5.1.6-0.4.15/Zend/zend_globals.h ---- php-5.1.6/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_globals.h 2006-09-07 19:41:16.000000000 +0200 -@@ -180,6 +180,16 @@ - - int error_reporting; - int orig_error_reporting; -+#if HARDENING_PATCH -+ int hphp_log_syslog; -+ int hphp_log_syslog_facility; -+ int hphp_log_syslog_priority; -+ int hphp_log_sapi; -+ int hphp_log_script; -+ char *hphp_log_scriptname; -+ zend_bool hphp_log_use_x_forwarded_for; -+ long hphp_executor_max_depth; -+#endif - int exit_status; - - zend_op_array *active_op_array; -@@ -197,6 +207,7 @@ - int ticks_count; - - zend_bool in_execution; -+ zend_uint in_code_type; - HashTable *in_autoload; - zend_function *autoload_func; - zend_bool bailout_set; -diff -Nura php-5.1.6/Zend/zend.h hardening-patch-5.1.6-0.4.15/Zend/zend.h ---- php-5.1.6/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend.h 2006-09-07 19:41:16.000000000 +0200 -@@ -297,6 +297,7 @@ - /* Variable information */ - zvalue_value value; /* value */ - zend_uint refcount; -+ zend_ushort flags; - zend_uchar type; /* active type */ - zend_uchar is_ref; - }; -@@ -382,6 +383,12 @@ - int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); - int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); - char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); -+#if HARDENING_PATCH -+ void (*security_log_function)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+ int (*is_valid_include)(zval *z); -+#endif - } zend_utility_functions; - - -@@ -519,7 +526,16 @@ - extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); - extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); - extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); -+#if HARDENING_PATCH -+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...); -+#endif -+#if HARDENING_PATCH_INC_PROTECT -+extern ZEND_API int (*zend_is_valid_include)(zval *z); -+#endif - -+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT -+ZEND_API unsigned int zend_canary(void); -+#endif - - ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); - -@@ -644,6 +660,11 @@ - - #include "zend_variables.h" - -+#if HARDENING_PATCH -+#include "hardened_globals.h" -+#include "php_syslog.h" -+#endif -+ - #endif /* ZEND_H */ - - /* -diff -Nura php-5.1.6/Zend/zend_hash.c hardening-patch-5.1.6-0.4.15/Zend/zend_hash.c ---- php-5.1.6/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_hash.c 2006-09-07 19:41:16.000000000 +0200 -@@ -21,6 +21,18 @@ - - #include "zend.h" - -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int zend_hash_canary = 0x1234567; -+ zend_bool zend_hash_canary_inited = 0; -+#endif -+ -+#define CHECK_HASH_CANARY(hash) \ -+ if (zend_hash_canary != (hash)->canary) { \ -+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+ - #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ - (element)->pNext = (list_head); \ - (element)->pLast = NULL; \ -@@ -138,6 +150,9 @@ - { - uint i = 3; - Bucket **tmp; -+#if HARDENING_PATCH_HASH_PROTECT -+ TSRMLS_FETCH(); -+#endif - - SET_INCONSISTENT(HT_OK); - -@@ -147,6 +162,13 @@ - - ht->nTableSize = 1 << i; - ht->nTableMask = ht->nTableSize - 1; -+#if HARDENING_PATCH_HASH_PROTECT -+ if (zend_hash_canary_inited==0) { -+ zend_hash_canary = zend_canary(); -+ zend_hash_canary_inited = 1; -+ } -+ ht->canary = zend_hash_canary; -+#endif - ht->pDestructor = pDestructor; - ht->arBuckets = NULL; - ht->pListHead = NULL; -@@ -226,6 +248,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -291,6 +316,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -366,6 +394,9 @@ - } - #endif - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - UPDATE_DATA(ht, p, pData, nDataSize); -@@ -414,7 +445,7 @@ - IS_CONSISTENT(ht); - - if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ -- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); -+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); - if (t) { - HANDLE_BLOCK_INTERRUPTIONS(); - ht->arBuckets = t; -@@ -424,6 +455,7 @@ - HANDLE_UNBLOCK_INTERRUPTIONS(); - return SUCCESS; - } -+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory"); - return FAILURE; - } - return SUCCESS; -@@ -489,6 +521,9 @@ - ht->pInternalPointer = p->pListNext; - } - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (p->pData != &p->pDataPtr) { -@@ -513,6 +548,11 @@ - - SET_INCONSISTENT(HT_IS_DESTROYING); - -+#if HARDENING_PATCH_HASH_PROTECT -+ if (ht->pDestructor) { -+ CHECK_HASH_CANARY(ht); -+ } -+#endif - p = ht->pListHead; - while (p != NULL) { - q = p; -@@ -539,6 +579,11 @@ - - SET_INCONSISTENT(HT_CLEANING); - -+#if HARDENING_PATCH_HASH_PROTECT -+ if (ht->pDestructor) { -+ CHECK_HASH_CANARY(ht); -+ } -+#endif - p = ht->pListHead; - while (p != NULL) { - q = p; -@@ -573,6 +618,9 @@ - HANDLE_BLOCK_INTERRUPTIONS(); - - if (ht->pDestructor) { -+#if HARDENING_PATCH_HASH_PROTECT -+ CHECK_HASH_CANARY(ht); -+#endif - ht->pDestructor(p->pData); - } - if (p->pData != &p->pDataPtr) { -diff -Nura php-5.1.6/Zend/zend_hash.h hardening-patch-5.1.6-0.4.15/Zend/zend_hash.h ---- php-5.1.6/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_hash.h 2006-09-07 19:41:16.000000000 +0200 -@@ -58,6 +58,9 @@ - } Bucket; - - typedef struct _hashtable { -+#if HARDENING_PATCH_HASH_PROTECT -+ unsigned int canary; -+#endif - uint nTableSize; - uint nTableMask; - uint nNumOfElements; -diff -Nura php-5.1.6/Zend/zend_ini.c hardening-patch-5.1.6-0.4.15/Zend/zend_ini.c ---- php-5.1.6/Zend/zend_ini.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_ini.c 2006-09-07 19:41:16.000000000 +0200 -@@ -256,7 +256,8 @@ - zend_ini_entry *ini_entry; - TSRMLS_FETCH(); - -- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) { -+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE || -+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) { - return FAILURE; - } - -diff -Nura php-5.1.6/Zend/zend_language_scanner.l hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.l ---- php-5.1.6/Zend/zend_language_scanner.l 2006-04-13 15:48:28.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.l 2006-09-07 19:41:16.000000000 +0200 -@@ -389,6 +389,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-5.1.6/Zend/zend_language_scanner.c hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.c ---- php-5.1.6/Zend/zend_language_scanner.c 2006-08-23 14:55:05.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_language_scanner.c 2006-09-07 19:41:16.000000000 +0200 -@@ -3075,6 +3075,13 @@ - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); -+#if HARDENING_PATCH -+ if (EG(in_code_type)==ZEND_EVAL_CODE) { -+ op_array->created_by_eval = 1; -+ } else { -+ op_array->created_by_eval = 0; -+ } -+#endif - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - compiler_result = zendparse(TSRMLS_C); -diff -Nura php-5.1.6/Zend/zend_llist.c hardening-patch-5.1.6-0.4.15/Zend/zend_llist.c ---- php-5.1.6/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_llist.c 2006-09-07 19:41:16.000000000 +0200 -@@ -22,9 +22,49 @@ - #include "zend.h" - #include "zend_llist.h" - #include "zend_qsort.h" -+#include "zend_globals.h" -+ -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int zend_llist_canary_1 = 0x1234567; -+ unsigned int zend_llist_canary_2 = 0x1553425; -+ zend_bool zend_llist_canary_inited = 0; -+#endif -+ -+#define CHECK_LIST_CANARY(list) \ -+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \ -+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \ -+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \ -+ exit(1); \ -+ } -+ -+#define CHECK_LISTELEMENT_CANARY(elem, list) \ -+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \ -+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \ -+ exit(1); \ -+ } -+ - - ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ -+ if (persistent) { -+ if (!zend_llist_canary_inited) { -+ /* do not change order to ensure thread safety */ -+ zend_llist_canary_1 = zend_canary(); -+ zend_llist_canary_2 = zend_canary(); -+ zend_llist_canary_inited = 1; -+ } -+ } else -+ if (!HG(ll_canary_inited)) { -+ HG(canary_3) = zend_canary(); -+ HG(canary_4) = zend_canary(); -+ HG(ll_canary_inited) = 1; -+ } -+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3); -+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4); -+#endif - l->head = NULL; - l->tail = NULL; - l->count = 0; -@@ -38,6 +78,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->prev = l->tail; - tmp->next = NULL; - if (l->tail) { -@@ -56,6 +101,11 @@ - { - zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent); - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3); -+#endif - tmp->next = l->head; - tmp->prev = NULL; - if (l->head) { -@@ -93,10 +143,20 @@ - zend_llist_element *current=l->head; - zend_llist_element *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (compare(current->data, element)) { - DEL_LLIST_ELEMENT(current, l); -+#if HARDENING_PATCH_LL_PROTECT -+ current->canary = 0; -+#endif - break; - } - current = next; -@@ -108,7 +168,14 @@ - { - zend_llist_element *current=l->head, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - while (current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(current, l) -+#endif - next = current->next; - if (l->dtor) { - l->dtor(current->data); -@@ -133,7 +200,14 @@ - zend_llist_element *old_tail; - void *data; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if ((old_tail = l->tail)) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(old_tail, l) -+#endif - if (l->tail->prev) { - l->tail->prev->next = NULL; - } -@@ -159,9 +233,16 @@ - { - zend_llist_element *ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(src) -+#endif - zend_llist_init(dst, src->size, src->dtor, src->persistent); - ptr = src->head; - while (ptr) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(ptr, src) -+#endif - zend_llist_add_element(dst, ptr->data); - ptr = ptr->next; - } -@@ -172,11 +253,21 @@ - { - zend_llist_element *element, *next; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - element=l->head; - while (element) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - next = element->next; - if (func(element->data)) { - DEL_LLIST_ELEMENT(element, l); -+#if HARDENING_PATCH_LL_PROTECT -+ element->canary = 0; -+#endif - } - element = next; - } -@@ -187,7 +278,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data TSRMLS_CC); - } - } -@@ -199,6 +296,9 @@ - zend_llist_element **elements; - zend_llist_element *element, **ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - if (l->count <= 0) { - return; - } -@@ -208,6 +308,9 @@ - ptr = &elements[0]; - - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - *ptr++ = element; - } - -@@ -230,7 +333,13 @@ - { - zend_llist_element *element; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, arg TSRMLS_CC); - } - } -@@ -241,8 +350,14 @@ - zend_llist_element *element; - va_list args; - -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LIST_CANARY(l) -+#endif - va_start(args, num_args); - for (element=l->head; element; element=element->next) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(element, l) -+#endif - func(element->data, num_args, args TSRMLS_CC); - } - va_end(args); -@@ -251,6 +366,10 @@ - - ZEND_API int zend_llist_count(zend_llist *l) - { -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - return l->count; - } - -@@ -259,8 +378,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->head; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -272,8 +398,15 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - *current = l->tail; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } else { - return NULL; -@@ -285,9 +418,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->next; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -@@ -299,9 +442,19 @@ - { - zend_llist_position *current = pos ? pos : &l->traverse_ptr; - -+#if HARDENING_PATCH_LL_PROTECT -+ TSRMLS_FETCH(); -+ CHECK_LIST_CANARY(l) -+#endif - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - *current = (*current)->prev; - if (*current) { -+#if HARDENING_PATCH_LL_PROTECT -+ CHECK_LISTELEMENT_CANARY(*current, l) -+#endif - return (*current)->data; - } - } -diff -Nura php-5.1.6/Zend/zend_llist.h hardening-patch-5.1.6-0.4.15/Zend/zend_llist.h ---- php-5.1.6/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_llist.h 2006-09-07 19:41:16.000000000 +0200 -@@ -23,6 +23,9 @@ - #define ZEND_LLIST_H - - typedef struct _zend_llist_element { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary, padding; -+#endif - struct _zend_llist_element *next; - struct _zend_llist_element *prev; - char data[1]; /* Needs to always be last in the struct */ -@@ -35,6 +38,9 @@ - typedef void (*llist_apply_func_t)(void * TSRMLS_DC); - - typedef struct _zend_llist { -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_h; /* head */ -+#endif - zend_llist_element *head; - zend_llist_element *tail; - size_t count; -@@ -42,6 +48,9 @@ - llist_dtor_func_t dtor; - unsigned char persistent; - zend_llist_element *traverse_ptr; -+#if HARDENING_PATCH_LL_PROTECT -+ unsigned int canary_t; /* tail */ -+#endif - } zend_llist; - - typedef zend_llist_element* zend_llist_position; -diff -Nura php-5.1.6/Zend/zend_modules.h hardening-patch-5.1.6-0.4.15/Zend/zend_modules.h ---- php-5.1.6/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_modules.h 2006-09-07 19:41:16.000000000 +0200 -@@ -39,6 +39,7 @@ - extern struct _zend_arg_info fifth_arg_force_ref[6]; - extern struct _zend_arg_info all_args_by_ref[1]; - -+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106 - #define ZEND_MODULE_API_NO 20050922 - #ifdef ZTS - #define USING_ZTS 1 -@@ -46,13 +47,13 @@ - #define USING_ZTS 0 - #endif - --#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS -+#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS - #define STANDARD_MODULE_HEADER \ - STANDARD_MODULE_HEADER_EX, NULL, NULL - #define ZE2_STANDARD_MODULE_HEADER \ - STANDARD_MODULE_HEADER_EX, ini_entries, NULL - --#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 -+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO - - #define STANDARD_MODULE_PROPERTIES \ - NULL, STANDARD_MODULE_PROPERTIES_EX -@@ -87,6 +88,7 @@ - unsigned char type; - void *handle; - int module_number; -+ unsigned int real_zend_api; - }; - - #define MODULE_DEP_REQUIRED 1 -diff -Nura php-5.1.6/Zend/zend_opcode.c hardening-patch-5.1.6-0.4.15/Zend/zend_opcode.c ---- php-5.1.6/Zend/zend_opcode.c 2006-04-10 14:26:53.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_opcode.c 2006-09-07 19:41:16.000000000 +0200 -@@ -98,6 +98,9 @@ - op_array->uses_this = 0; - - op_array->start_op = NULL; -+#if HARDENING_PATCH -+ op_array->created_by_eval = 0; -+#endif - - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); - } -diff -Nura php-5.1.6/Zend/zend_vm_def.h hardening-patch-5.1.6-0.4.15/Zend/zend_vm_def.h ---- php-5.1.6/Zend/zend_vm_def.h 2006-07-06 17:39:23.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_vm_def.h 2006-09-07 19:41:16.000000000 +0200 -@@ -1771,6 +1771,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (OP2_TYPE != IS_CONST) { -@@ -1996,6 +2027,34 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+#endif -+ - EX(object) = NULL; - - FREE_OP1(); -@@ -2711,7 +2770,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -2736,6 +2800,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -diff -Nura php-5.1.6/Zend/zend_vm_execute.h hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.h ---- php-5.1.6/Zend/zend_vm_execute.h 2006-07-06 17:39:23.000000000 +0200 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.h 2006-09-07 19:42:45.000000000 +0200 -@@ -56,6 +56,16 @@ - EX(symbol_table) = EG(active_symbol_table); - EX(prev_execute_data) = EG(current_execute_data); - EG(current_execute_data) = &execute_data; -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif - - EG(in_execution) = 1; - if (op_array->start_op) { -@@ -81,6 +91,18 @@ - */ - EX(function_state).function_symbol_table = NULL; - #endif -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif - - while (1) { - #ifdef ZEND_WIN32 -@@ -724,6 +746,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_CONST != IS_CONST) { -@@ -925,6 +978,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_TMP_VAR != IS_CONST) { -@@ -1083,6 +1167,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_VAR != IS_CONST) { -@@ -1330,6 +1445,37 @@ - efree(lcname); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname); -+ efree(lcname); -+ zend_bailout(); -+ } -+ } -+#endif - - efree(lcname); - if (IS_CV != IS_CONST) { -@@ -1635,6 +1781,34 @@ - if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { - zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val); - } -+#if HARDENING_PATCH -+ if (EG(in_code_type) == ZEND_EVAL_CODE) { -+ if (HG(eval_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(eval_blacklist) != NULL) { -+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+ } -+ -+ if (HG(func_whitelist) != NULL) { -+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } else if (HG(func_blacklist) != NULL) { -+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) { -+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val); -+ zend_bailout(); -+ } -+ } -+#endif -+ - EX(object) = NULL; - - return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); -@@ -1914,7 +2088,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -1939,6 +2118,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -4345,7 +4529,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -4370,6 +4559,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -7358,7 +7552,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -7383,6 +7582,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -@@ -19486,7 +19690,12 @@ - int dummy = 1; - zend_file_handle file_handle; - -- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#if HARDENING_PATCH_INC_PROTECT -+ if (zend_is_valid_include(inc_filename) -+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) { -+#else -+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { -+#endif - - if (!file_handle.opened_path) { - file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); -@@ -19511,6 +19720,11 @@ - break; - case ZEND_INCLUDE: - case ZEND_REQUIRE: -+#if HARDENING_PATCH_INC_PROTECT -+ if (!zend_is_valid_include(inc_filename)) { -+ break; -+ } -+#endif - new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC); - break; - case ZEND_EVAL: { -diff -Nura php-5.1.6/Zend/zend_vm_execute.skl hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.skl ---- php-5.1.6/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100 -+++ hardening-patch-5.1.6-0.4.15/Zend/zend_vm_execute.skl 2006-09-07 19:41:16.000000000 +0200 -@@ -27,6 +27,16 @@ - EX(symbol_table) = EG(active_symbol_table); - EX(prev_execute_data) = EG(current_execute_data); - EG(current_execute_data) = &execute_data; -+#if HARDENING_PATCH -+ EX(execute_depth) = 0; -+ -+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_EVAL_CODE; -+ } else if (op_array->type == ZEND_SANDBOX_CODE) { -+ EG(in_code_type) = ZEND_SANDBOX_CODE; -+ op_array->type = ZEND_EVAL_CODE; -+ } -+#endif - - EG(in_execution) = 1; - if (op_array->start_op) { -@@ -52,6 +62,18 @@ - */ - EX(function_state).function_symbol_table = NULL; - #endif -+#if HARDENING_PATCH -+ if (EX(prev_execute_data) == NULL) { -+ EX(execute_depth) = 0; -+ } else { -+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1; -+ } -+ -+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) { -+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth)); -+ zend_bailout(); -+ } -+#endif - - while (1) { - {%ZEND_VM_CONTINUE_LABEL%} -- cgit v1.3