1 /* Stack overflow handling. 2 3 Copyright (C) 2002, 2004, 2006, 2008-2018 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 3 of the License, or 8 (at your option) 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, see <https://www.gnu.org/licenses/>. */ 17 18 /* Written by Paul Eggert. */ 19 20 /* NOTES: 21 22 A program that uses alloca, dynamic arrays, or large local 23 variables may extend the stack by more than a page at a time. If 24 so, when the stack overflows the operating system may not detect 25 the overflow until the program uses the array, and this module may 26 incorrectly report a program error instead of a stack overflow. 27 28 To avoid this problem, allocate only small objects on the stack; a 29 program should be OK if it limits single allocations to a page or 30 less. Allocate larger arrays in static storage, or on the heap 31 (e.g., with malloc). Yes, this is a pain, but we don't know of any 32 better solution that is portable. 33 34 No attempt has been made to deal with multithreaded applications. */ 35 36 #include <config.h> 37 38 #ifndef __attribute__ 39 # if __GNUC__ < 3 40 # define __attribute__(x) 41 # endif 42 #endif 43 44 #include "gettext.h" 45 #define _(msgid) gettext (msgid) 46 47 #include <errno.h> 48 49 #include <signal.h> 50 #if ! HAVE_STACK_T && ! defined stack_t 51 typedef struct sigaltstack stack_t; 52 #endif 53 #ifndef SIGSTKSZ 54 # define SIGSTKSZ 16384 55 #elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384 56 /* libsigsegv 2.6 through 2.8 have a bug where some architectures use 57 more than the Linux default of an 8k alternate stack when deciding 58 if a fault was caused by stack overflow. */ 59 # undef SIGSTKSZ 60 # define SIGSTKSZ 16384 61 #endif 62 63 #include <stdlib.h> 64 #include <string.h> 65 66 /* Posix 2001 declares ucontext_t in <ucontext.h>, Posix 200x in 67 <signal.h>. */ 68 #if HAVE_UCONTEXT_H 69 # include <ucontext.h> 70 #endif 71 72 #include <unistd.h> 73 74 #if HAVE_LIBSIGSEGV 75 # include <sigsegv.h> 76 #endif 77 78 #include "c-stack.h" 79 #include "exitfail.h" 80 #include "ignore-value.h" 81 #include "getprogname.h" 82 83 #if defined SA_ONSTACK && defined SA_SIGINFO 84 # define SIGINFO_WORKS 1 85 #else 86 # define SIGINFO_WORKS 0 87 # ifndef SA_ONSTACK 88 # define SA_ONSTACK 0 89 # endif 90 #endif 91 92 /* The user-specified action to take when a SEGV-related program error 93 or stack overflow occurs. */ 94 static void (* volatile segv_action) (int); 95 96 /* Translated messages for program errors and stack overflow. Do not 97 translate them in the signal handler, since gettext is not 98 async-signal-safe. */ 99 static char const * volatile program_error_message; 100 static char const * volatile stack_overflow_message; 101 102 #if ((HAVE_LIBSIGSEGV && ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC) \ 103 || (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK \ 104 && HAVE_STACK_OVERFLOW_HANDLING)) 105 106 /* Output an error message, then exit with status EXIT_FAILURE if it 107 appears to have been a stack overflow, or with a core dump 108 otherwise. This function is async-signal-safe. */ 109 110 static _Noreturn void 111 die (int signo) 112 { 113 char const *message; 114 #if !SIGINFO_WORKS && !HAVE_LIBSIGSEGV 115 /* We can't easily determine whether it is a stack overflow; so 116 assume that the rest of our program is perfect (!) and that 117 this segmentation violation is a stack overflow. */ 118 signo = 0; 119 #endif /* !SIGINFO_WORKS && !HAVE_LIBSIGSEGV */ 120 segv_action (signo); 121 message = signo ? program_error_message : stack_overflow_message; 122 ignore_value (write (STDERR_FILENO, getprogname (), strlen (getprogname ()))); 123 ignore_value (write (STDERR_FILENO, ": ", 2)); 124 ignore_value (write (STDERR_FILENO, message, strlen (message))); 125 ignore_value (write (STDERR_FILENO, "\n", 1)); 126 if (! signo) 127 _exit (exit_failure); 128 raise (signo); 129 abort (); 130 } 131 #endif 132 133 #if (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK \ 134 && HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV 135 136 /* Storage for the alternate signal stack. */ 137 static union 138 { 139 char buffer[SIGSTKSZ]; 140 141 /* These other members are for proper alignment. There's no 142 standard way to guarantee stack alignment, but this seems enough 143 in practice. */ 144 long double ld; 145 long l; 146 void *p; 147 } alternate_signal_stack; 148 149 static void 150 null_action (int signo __attribute__ ((unused))) 151 { 152 } 153 154 #endif /* SIGALTSTACK || LIBSIGSEGV */ 155 156 /* Only use libsigsegv if we need it; platforms like Solaris can 157 detect stack overflow without the overhead of an external 158 library. */ 159 #if HAVE_LIBSIGSEGV && ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC 160 161 /* Nonzero if general segv handler could not be installed. */ 162 static volatile int segv_handler_missing; 163 164 /* Handle a segmentation violation and exit if it cannot be stack 165 overflow. This function is async-signal-safe. */ 166 167 static int segv_handler (void *address __attribute__ ((unused)), 168 int serious) 169 { 170 # if DEBUG 171 { 172 char buf[1024]; 173 sprintf (buf, "segv_handler serious=%d\n", serious); 174 write (STDERR_FILENO, buf, strlen (buf)); 175 } 176 # endif 177 178 /* If this fault is not serious, return 0 to let the stack overflow 179 handler take a shot at it. */ 180 if (!serious) 181 return 0; 182 die (SIGSEGV); 183 } 184 185 /* Handle a segmentation violation that is likely to be a stack 186 overflow and exit. This function is async-signal-safe. */ 187 188 static _Noreturn void 189 overflow_handler (int emergency, 190 stackoverflow_context_t context __attribute__ ((unused))) 191 { 192 # if DEBUG 193 { 194 char buf[1024]; 195 sprintf (buf, "overflow_handler emergency=%d segv_handler_missing=%d\n", 196 emergency, segv_handler_missing); 197 write (STDERR_FILENO, buf, strlen (buf)); 198 } 199 # endif 200 201 die ((!emergency || segv_handler_missing) ? 0 : SIGSEGV); 202 } 203 204 int 205 c_stack_action (void (*action) (int)) 206 { 207 segv_action = action ? action : null_action; 208 program_error_message = _("program error"); 209 stack_overflow_message = _("stack overflow"); 210 211 /* Always install the overflow handler. */ 212 if (stackoverflow_install_handler (overflow_handler, 213 alternate_signal_stack.buffer, 214 sizeof alternate_signal_stack.buffer)) 215 { 216 errno = ENOTSUP; 217 return -1; 218 } 219 /* Try installing a general handler; if it fails, then treat all 220 segv as stack overflow. */ 221 segv_handler_missing = sigsegv_install_handler (segv_handler); 222 return 0; 223 } 224 225 #elif HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING 226 227 # if SIGINFO_WORKS 228 229 /* Handle a segmentation violation and exit. This function is 230 async-signal-safe. */ 231 232 static _Noreturn void 233 segv_handler (int signo, siginfo_t *info, 234 void *context __attribute__ ((unused))) 235 { 236 /* Clear SIGNO if it seems to have been a stack overflow. */ 237 # if ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC 238 /* We can't easily determine whether it is a stack overflow; so 239 assume that the rest of our program is perfect (!) and that 240 this segmentation violation is a stack overflow. 241 242 Note that although both Linux and Solaris provide 243 sigaltstack, SA_ONSTACK, and SA_SIGINFO, currently only 244 Solaris satisfies the XSI heuristic. This is because 245 Solaris populates uc_stack with the details of the 246 interrupted stack, while Linux populates it with the details 247 of the current stack. */ 248 signo = 0; 249 # else 250 if (0 < info->si_code) 251 { 252 /* If the faulting address is within the stack, or within one 253 page of the stack, assume that it is a stack overflow. */ 254 ucontext_t const *user_context = context; 255 char const *stack_base = user_context->uc_stack.ss_sp; 256 size_t stack_size = user_context->uc_stack.ss_size; 257 char const *faulting_address = info->si_addr; 258 size_t page_size = sysconf (_SC_PAGESIZE); 259 size_t s = faulting_address - stack_base + page_size; 260 if (s < stack_size + 2 * page_size) 261 signo = 0; 262 263 # if DEBUG 264 { 265 char buf[1024]; 266 sprintf (buf, 267 "segv_handler fault=%p base=%p size=%lx page=%lx signo=%d\n", 268 faulting_address, stack_base, (unsigned long) stack_size, 269 (unsigned long) page_size, signo); 270 write (STDERR_FILENO, buf, strlen (buf)); 271 } 272 # endif 273 } 274 # endif 275 276 die (signo); 277 } 278 # endif 279 280 int 281 c_stack_action (void (*action) (int)) 282 { 283 int r; 284 stack_t st; 285 struct sigaction act; 286 st.ss_flags = 0; 287 # if SIGALTSTACK_SS_REVERSED 288 /* Irix mistakenly treats ss_sp as the upper bound, rather than 289 lower bound, of the alternate stack. */ 290 st.ss_sp = alternate_signal_stack.buffer + SIGSTKSZ - sizeof (void *); 291 st.ss_size = sizeof alternate_signal_stack.buffer - sizeof (void *); 292 # else 293 st.ss_sp = alternate_signal_stack.buffer; 294 st.ss_size = sizeof alternate_signal_stack.buffer; 295 # endif 296 r = sigaltstack (&st, NULL); 297 if (r != 0) 298 return r; 299 300 segv_action = action ? action : null_action; 301 program_error_message = _("program error"); 302 stack_overflow_message = _("stack overflow"); 303 304 sigemptyset (&act.sa_mask); 305 306 # if SIGINFO_WORKS 307 /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but 308 this is not true on Solaris 8 at least. It doesn't hurt to use 309 SA_NODEFER here, so leave it in. */ 310 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO; 311 act.sa_sigaction = segv_handler; 312 # else 313 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; 314 act.sa_handler = die; 315 # endif 316 317 # if FAULT_YIELDS_SIGBUS 318 if (sigaction (SIGBUS, &act, NULL) < 0) 319 return -1; 320 # endif 321 return sigaction (SIGSEGV, &act, NULL); 322 } 323 324 #else /* ! ((HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK 325 && HAVE_STACK_OVERFLOW_HANDLING) || HAVE_LIBSIGSEGV) */ 326 327 int 328 c_stack_action (void (*action) (int) __attribute__ ((unused))) 329 { 330 errno = ENOTSUP; 331 return -1; 332 } 333 334 #endif 335