Mercurial > hg > octave-lyh > gnulib-hg
changeset 10358:37fd490ee38d
c-stack: test that stack overflow can be caught
* m4/c-stack.m4 (AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC): Also check
that platform allows handling stack overflow; at least OS/2 EMX
has sigaltstack, but crashes before transferring control to
handler on stack overflow.
* lib/c-stack.c [HAVE_SIGALTSTACK]: Adjust conditions to also
check for HAVE_STACK_OVERFLOW_HANDLING.
Reported by Elbert Pol.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Mon, 25 Aug 2008 06:26:56 -0600 |
parents | ae4cf624bf35 |
children | 20375c619b75 |
files | ChangeLog lib/c-stack.c m4/c-stack.m4 |
diffstat | 3 files changed, 106 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-08-25 Eric Blake <ebb9@byu.net> + + c-stack: test that stack overflow can be caught + * m4/c-stack.m4 (AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC): Also check + that platform allows handling stack overflow; at least OS/2 EMX + has sigaltstack, but crashes before transferring control to + handler on stack overflow. + * lib/c-stack.c [HAVE_SIGALTSTACK]: Adjust conditions to also + check for HAVE_STACK_OVERFLOW_HANDLING. + Reported by Elbert Pol. + 2008-08-25 Bruno Haible <bruno@clisp.org> * doc/posix-functions/strftime.texi: Fix description of strftime
--- a/lib/c-stack.c +++ b/lib/c-stack.c @@ -117,7 +117,8 @@ abort (); } -#if (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) || HAVE_LIBSIGSEGV +#if (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK \ + && HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV /* Storage for the alternate signal stack. */ static union @@ -210,7 +211,7 @@ return 0; } -#elif HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK +#elif HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING /* Direction of the C runtime stack. This function is async-signal-safe. */ @@ -316,7 +317,8 @@ return sigaction (SIGSEGV, &act, NULL); } -#else /* ! ((HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) || HAVE_LIBSIGSEGV) */ +#else /* ! ((HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK + && HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV) */ int c_stack_action (void (*action) (int) __attribute__ ((unused)))
--- a/m4/c-stack.m4 +++ b/m4/c-stack.m4 @@ -7,7 +7,7 @@ # Written by Paul Eggert. -# serial 4 +# serial 5 AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], [# for STACK_DIRECTION @@ -16,6 +16,90 @@ AC_CHECK_HEADERS_ONCE([ucontext.h]) AC_CACHE_CHECK([for working C stack overflow detection], + [ac_cv_sys_stack_overflow_works], + [AC_TRY_RUN( + [ + #include <unistd.h> + #include <signal.h> + #if HAVE_SETRLIMIT + # include <sys/types.h> + # include <sys/time.h> + # include <sys/resource.h> + #endif + #ifndef SIGSTKSZ + # define SIGSTKSZ 16384 + #endif + + static union + { + char buffer[SIGSTKSZ]; + long double ld; + long u; + void *p; + } alternate_signal_stack; + + static void + segv_handler (int signo) + { + _exit (0); + } + + static int + c_stack_action () + { + stack_t st; + struct sigaction act; + int r; + + st.ss_flags = 0; + st.ss_sp = alternate_signal_stack.buffer; + st.ss_size = sizeof alternate_signal_stack.buffer; + r = sigaltstack (&st, 0); + if (r != 0) + return r; + + sigemptyset (&act.sa_mask); + act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; + act.sa_handler = segv_handler; + return sigaction (SIGSEGV, &act, 0); + } + + static int + recurse (char *p) + { + char array[500]; + array[0] = 1; + return *p + recurse (array); + } + + int + main () + { + #if HAVE_SETRLIMIT && defined RLIMIT_STACK + /* Before starting the endless recursion, try to be friendly + to the user's machine. On some Linux 2.2.x systems, there + is no stack limit for user processes at all. We don't want + to kill such systems. */ + struct rlimit rl; + rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */ + setrlimit (RLIMIT_STACK, &rl); + #endif + + c_stack_action (); + return recurse ("\1"); + } + ], + [ac_cv_sys_stack_overflow_works=yes], + [ac_cv_sys_stack_overflow_works=no], + [ac_cv_sys_stack_overflow_works=cross-compiling])]) + + if test $ac_cv_sys_stack_overflow_works = yes; then + AC_DEFINE([HAVE_STACK_OVERFLOW_HANDLING], [1], + [Define to 1 if extending the stack slightly past the limit causes + a SIGSEGV which can be handled on an alternate stack established + with sigaltstack.]) + + AC_CACHE_CHECK([for precise C stack overflow detection], ac_cv_sys_xsi_stack_overflow_heuristic, [AC_TRY_RUN( [ @@ -29,6 +113,9 @@ # include <sys/time.h> # include <sys/resource.h> #endif + #ifndef SIGSTKSZ + # define SIGSTKSZ 16384 + #endif static union { @@ -131,7 +218,8 @@ with the X/Open System Interface (XSI) option and is a standardized way to implement a SEGV-based stack overflow detection heuristic.]) - fi]) + fi + fi]) AC_DEFUN([gl_PREREQ_C_STACK],