Skip to content

Instantly share code, notes, and snippets.

@krakjoe
Created March 21, 2019 08:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krakjoe/b89a62ca7ad4dfb116c97da1dcff9d56 to your computer and use it in GitHub Desktop.
Save krakjoe/b89a62ca7ad4dfb116c97da1dcff9d56 to your computer and use it in GitHub Desktop.
overflow patch
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