1# Check prerequisites for compiling lib/c-stack.c. 2 3# Copyright (C) 2002 Free Software Foundation, Inc. 4 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2, or (at your option) 8# any later version. 9 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 18# 02111-1307, USA. 19 20AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], 21 [# for STACK_DIRECTION 22 AC_REQUIRE([AC_FUNC_ALLOCA]) 23 24 AC_CACHE_CHECK([for working C stack overflow detection], 25 ac_cv_sys_xsi_stack_overflow_heuristic, 26 [AC_TRY_RUN( 27 [ 28 #include <signal.h> 29 #include <ucontext.h> 30 31 static union 32 { 33 char buffer[SIGSTKSZ]; 34 long double ld; 35 uintmax_t u; 36 void *p; 37 } alternate_signal_stack; 38 39 #if STACK_DIRECTION 40 # define find_stack_direction(ptr) STACK_DIRECTION 41 #else 42 static int 43 find_stack_direction (char const *addr) 44 { 45 char dummy; 46 return (! addr ? find_stack_direction (&dummy) 47 : addr < &dummy ? 1 : -1); 48 } 49 #endif 50 51 static void 52 segv_handler (int signo, siginfo_t *info, void *context) 53 { 54 if (0 < info->si_code) 55 { 56 ucontext_t const *user_context = context; 57 char const *stack_min = user_context->uc_stack.ss_sp; 58 size_t stack_size = user_context->uc_stack.ss_size; 59 char const *faulting_address = info->si_addr; 60 size_t s = faulting_address - stack_min; 61 size_t page_size = sysconf (_SC_PAGESIZE); 62 if (find_stack_direction (0) < 0) 63 s += page_size; 64 if (s < stack_size + page_size) 65 _exit (0); 66 } 67 68 _exit (1); 69 } 70 71 static int 72 c_stack_action (void) 73 { 74 stack_t st; 75 struct sigaction act; 76 int r; 77 78 st.ss_flags = 0; 79 st.ss_sp = alternate_signal_stack.buffer; 80 st.ss_size = sizeof alternate_signal_stack.buffer; 81 r = sigaltstack (&st, 0); 82 if (r != 0) 83 return r; 84 85 sigemptyset (&act.sa_mask); 86 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO; 87 act.sa_sigaction = segv_handler; 88 return sigaction (SIGSEGV, &act, 0); 89 } 90 91 static int 92 recurse (char *p) 93 { 94 char array[500]; 95 array[0] = 1; 96 return *p + recurse (array); 97 } 98 99 int 100 main (void) 101 { 102 c_stack_action (); 103 return recurse ("\1"); 104 } 105 ], 106 [ac_cv_sys_xsi_stack_overflow_heuristic=yes], 107 [ac_cv_sys_xsi_stack_overflow_heuristic=no], 108 [ac_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])]) 109 110 if test $ac_cv_sys_xsi_stack_overflow_heuristic = yes; then 111 AC_DEFINE(HAVE_XSI_STACK_OVERFLOW_HEURISTIC, 1, 112 [Define to 1 if extending the stack slightly past the limit causes 113 a SIGSEGV, and an alternate stack can be established with sigaltstack, 114 and the signal handler is passed a context that specifies the 115 run time stack. This behavior is defined by POSIX 1003.1-2001 116 with the X/Open System Interface (XSI) option 117 and is a standardized way to implement a SEGV-based stack 118 overflow detection heuristic.]) 119 fi]) 120 121 122AC_DEFUN([jm_PREREQ_C_STACK], 123 [AC_REQUIRE([jm_AC_TYPE_UINTMAX_T]) 124 AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC]) 125 126 # for STACK_DIRECTION 127 AC_REQUIRE([AC_FUNC_ALLOCA]) 128 129 AC_CHECK_HEADERS(unistd.h) 130 131 AC_CHECK_TYPES([siginfo_t, stack_t], , , [#include <signal.h>])]) 132