-
-
Save krakjoe/b89a62ca7ad4dfb116c97da1dcff9d56 to your computer and use it in GitHub Desktop.
overflow patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 | |
index ad8c296cdf..b82f7aa7cd 100644 | |
--- a/Zend/Zend.m4 | |
+++ b/Zend/Zend.m4 | |
@@ -91,6 +91,12 @@ AC_ARG_ENABLE([inline-optimization], | |
[ZEND_INLINE_OPTIMIZATION=$enableval], | |
[ZEND_INLINE_OPTIMIZATION=yes]) | |
+AC_ARG_ENABLE([overflow-handler], | |
+ [AS_HELP_STRING([--enable-overflow-handler], | |
+ [Enable overflow handling])], | |
+ [ZEND_OVERFLOW_HANDLER=$enableval], | |
+ [ZEND_OVERFLOW_HANDLER=no]) | |
+ | |
AC_MSG_CHECKING(whether to enable thread-safety) | |
AC_MSG_RESULT($ZEND_MAINTAINER_ZTS) | |
@@ -99,6 +105,9 @@ AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION) | |
AC_MSG_CHECKING(whether to enable Zend debugging) | |
AC_MSG_RESULT($ZEND_DEBUG) | |
+ | |
+AC_MSG_CHECKING(whether to enable Zend overflow handler) | |
+AC_MSG_RESULT($ZEND_OVERFLOW_HANDLER) | |
if test "$ZEND_DEBUG" = "yes"; then | |
AC_DEFINE(ZEND_DEBUG,1,[ ]) | |
@@ -120,6 +129,13 @@ if test "$ZEND_MAINTAINER_ZTS" = "yes"; then | |
CFLAGS="$CFLAGS -DZTS" | |
fi | |
+if test "$ZEND_OVERFLOW_HANDLER" = "yes"; then | |
+ AC_DEFINE(ZEND_OVERFLOW_HANDLER,1,[ ]) | |
+ EXTRA_LIBS="$EXTRA_LIBS -lpthread" | |
+ CFLAGS="$CFLAGS -DZEND_OVERFLOW_HANDLER" | |
+ PHP_SUBST(EXTRA_LIBS) | |
+fi | |
+ | |
changequote({,}) | |
if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then | |
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//` | |
diff --git a/Zend/zend.c b/Zend/zend.c | |
index 2c2bd09081..1cf070354e 100644 | |
--- a/Zend/zend.c | |
+++ b/Zend/zend.c | |
@@ -33,6 +33,10 @@ | |
#include "zend_smart_string.h" | |
#include "zend_cpuinfo.h" | |
+#ifdef ZEND_OVERFLOW_HANDLER | |
+#include <pthread.h> | |
+#endif | |
+ | |
static size_t global_map_ptr_last = 0; | |
#ifdef ZTS | |
@@ -773,6 +777,101 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */ | |
} | |
/* }}} */ | |
+#ifdef ZEND_OVERFLOW_HANDLER | |
+/* {{{ */ | |
+static void* zend_stack_address; | |
+static size_t zend_stack_size; | |
+static size_t zend_page_size; /* }}} */ | |
+ | |
+static void zend_overflow_handler(int signo, siginfo_t *info, void *ucontext) { /* {{{ */ | |
+ struct sigaction sa; | |
+ void *address = info->si_addr; | |
+ | |
+ if (address < (zend_stack_address + zend_page_size)) { | |
+ zend_execute_data *execute_data = EG(current_execute_data); | |
+ | |
+ while (!EX(func) && execute_data) { | |
+ execute_data = EX(prev_execute_data); | |
+ } | |
+ | |
+ if (execute_data && EX(func)) { | |
+ if (EX(func)->common.scope) { | |
+ fprintf(stderr, "overflow at %s::%s", | |
+ ZSTR_VAL(EX(func)->common.scope->name), | |
+ ZSTR_VAL(EX(func)->common.function_name)); | |
+ } else { | |
+ fprintf(stderr, "overflow at %s", | |
+ ZSTR_VAL(EX(func)->common.function_name)); | |
+ } | |
+ if (ZEND_USER_CODE(EX(func)->type)) { | |
+ fprintf(stderr, " in %s on line %d\n", | |
+ ZSTR_VAL(EX(func)->op_array.filename), | |
+ EX(opline)->lineno); | |
+ } else { | |
+ fprintf(stderr, " in <internal>\n"); | |
+ } | |
+ } else { | |
+ fprintf(stderr, "overflow at %p\n", address); | |
+ } | |
+ | |
+ memset(&sa, 0, sizeof(sa)); | |
+ sa.sa_sigaction = SIG_DFL; | |
+ sigaction(signo, &sa, NULL); | |
+ | |
+ abort(); | |
+ } | |
+} /* }}} */ | |
+ | |
+/* {{{ */ | |
+static void zend_overflow_startup(void) { | |
+ pthread_attr_t attr; | |
+ struct sigaction sa; | |
+ stack_t st; | |
+ | |
+ if (pthread_attr_init(&attr) != SUCCESS) { | |
+ return; | |
+ } | |
+ | |
+#ifdef __FreeBSD__ | |
+ if (pthread_attr_get_np(pthread_self(), &attr) != SUCCESS) { | |
+#else | |
+ if (pthread_getattr_np(pthread_self(), &attr) != SUCCESS) { | |
+#endif | |
+ pthread_attr_destroy(&attr); | |
+ return; | |
+ } | |
+ | |
+ if (pthread_attr_getstack(&attr, &zend_stack_address, &zend_stack_size) != SUCCESS) { | |
+ pthread_attr_destroy(&attr); | |
+ return; | |
+ } | |
+ | |
+ pthread_attr_destroy(&attr); | |
+ | |
+ zend_page_size = sysconf(_SC_PAGESIZE); | |
+ | |
+ st.ss_sp = malloc(SIGSTKSZ); | |
+ if (st.ss_sp == NULL) { | |
+ return; | |
+ } | |
+ st.ss_size = SIGSTKSZ; | |
+ st.ss_flags = 0; | |
+ | |
+ if (sigaltstack(&st, NULL) != SUCCESS) { | |
+ free(st.ss_sp); | |
+ return; | |
+ } | |
+ | |
+ sa.sa_flags = SA_SIGINFO | SA_ONSTACK; | |
+ sa.sa_handler = zend_overflow_handler; | |
+ sigemptyset(&sa.sa_mask); | |
+ | |
+ if (sigaction(SIGSEGV, &sa, NULL) != SUCCESS) { | |
+ perror("failed to setup overflow handler"); | |
+ } | |
+} /* }}} */ | |
+#endif | |
+ | |
int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ | |
{ | |
#ifdef ZTS | |
@@ -786,6 +885,10 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ | |
#endif | |
zend_cpu_startup(); | |
+ | |
+#ifdef ZEND_OVERFLOW_HANDLER | |
+ zend_overflow_startup(); | |
+#endif | |
#ifdef ZEND_WIN32 | |
php_win32_cp_set_by_id(65001); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment