From 97b0d8ad7078daafc1911ada2a53bf3d642a6cde Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 21 May 2021 14:41:42 -0700 Subject: [PATCH 1/2] =?UTF-8?q?sigsegv:=20don=E2=80=99t=20assume=20SIGSTKS?= =?UTF-8?q?Z=20is=20a=20constant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * m4/sigaltstack.m4 (SV_SIGALTSTACK): Don’t attempt to override SIGSTKSZ. Instead, use an array that is plenty large, while checking that it’s large enough. Also, be consistent about putting that array in static storage rather than on the stack. * tests/altstack-util.h (SIGSTKSZ): Don’t define. (MYSTACK_SIZE): New macro, used consistently instead of SIGSTKSZ. (mystack_storage, mystack): Now static. (prepare_alternate_stack) [defined SIGSTKSZ]: Check that MYSTACK_SIZE is large enough. --- ChangeLog | 13 +++++++ m4/sigaltstack.m4 | 44 ++++++----------------- tests/altstack-util.h | 18 ++++++---- tests/test-sigsegv-catch-stackoverflow1.c | 4 +-- tests/test-sigsegv-catch-stackoverflow2.c | 2 +- 5 files changed, 39 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index fc67bc69a..50e376176 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2021-05-21 Paul Eggert + + sigsegv: don’t assume SIGSTKSZ is a constant + * m4/sigaltstack.m4 (SV_SIGALTSTACK): Don’t attempt to override + SIGSTKSZ. Instead, use an array that is plenty large, while + checking that it’s large enough. Also, be consistent about + putting that array in static storage rather than on the stack. + * tests/altstack-util.h (SIGSTKSZ): Don’t define. + (MYSTACK_SIZE): New macro, used instead of SIGSTKSZ. + (mystack_storage, mystack): Now static. + (prepare_alternate_stack) [SIGSTKSZ]: + Check that MYSTACK_SIZE is large enough. + 2021-05-20 Paul Eggert fstatat: doc improvement diff --git a/m4/sigaltstack.m4 b/m4/sigaltstack.m4 index 837191e5f..47e900079 100644 --- a/m4/sigaltstack.m4 +++ b/m4/sigaltstack.m4 @@ -1,4 +1,4 @@ -# sigaltstack.m4 serial 13 +# sigaltstack.m4 serial 14 dnl Copyright (C) 2002-2021 Bruno Haible dnl Copyright (C) 2008 Eric Blake dnl This file is free software, distributed under the terms of the GNU @@ -53,19 +53,6 @@ AC_DEFUN([SV_SIGALTSTACK], # include # include #endif -/* In glibc >= 2.34, when _GNU_SOURCE is defined, SIGSTKSZ is no longer a - compile-time constant. But we need a simple constant here. */ -#if __GLIBC__ >= 2 -# undef SIGSTKSZ -# if defined __ia64__ -# define SIGSTKSZ 262144 -# else -# define SIGSTKSZ 16384 -# endif -#endif -#ifndef SIGSTKSZ -# define SIGSTKSZ 16384 -#endif void stackoverflow_handler (int sig) { /* If we get here, the stack overflow was caught. */ @@ -82,7 +69,7 @@ int recurse (volatile int n) int sum = 0; return *recurse_1 (n, &sum); } -char mystack[2 * SIGSTKSZ]; +char mystack[2 * (1 << 24)]; int main () { stack_t altstack; @@ -97,8 +84,12 @@ int main () #endif /* Install the alternate stack. Use the midpoint of mystack, to guard against a buggy interpretation of ss_sp on IRIX. */ - altstack.ss_sp = mystack + SIGSTKSZ; - altstack.ss_size = SIGSTKSZ; +#ifdef SIGSTKSZ + if (sizeof mystack / 2 < SIGSTKSZ) + exit (3); +#endif + altstack.ss_sp = mystack + sizeof mystack / 2; + altstack.ss_size = sizeof mystack / 2; altstack.ss_flags = 0; /* no SS_DISABLE */ if (sigaltstack (&altstack, NULL) < 0) exit (1); @@ -148,19 +139,6 @@ int main () #if HAVE_SYS_SIGNAL_H # include #endif -/* In glibc >= 2.34, when _GNU_SOURCE is defined, SIGSTKSZ is no longer a - compile-time constant. But we need a simple constant here. */ -#if __GLIBC__ >= 2 -# undef SIGSTKSZ -# if defined __ia64__ -# define SIGSTKSZ 262144 -# else -# define SIGSTKSZ 16384 -# endif -#endif -#ifndef SIGSTKSZ -# define SIGSTKSZ 16384 -#endif volatile char *stack_lower_bound; volatile char *stack_upper_bound; static void check_stack_location (volatile char *addr) @@ -175,14 +153,14 @@ static void stackoverflow_handler (int sig) char dummy; check_stack_location (&dummy); } +char mystack[2 * (1 << 24)]; int main () { - char mystack[2 * SIGSTKSZ]; stack_t altstack; struct sigaction action; /* Install the alternate stack. */ - altstack.ss_sp = mystack + SIGSTKSZ; - altstack.ss_size = SIGSTKSZ; + altstack.ss_sp = mystack + sizeof mystack / 2; + altstack.ss_size = sizeof mystack / 2; stack_lower_bound = (char *) altstack.ss_sp; stack_upper_bound = (char *) altstack.ss_sp + altstack.ss_size - 1; altstack.ss_flags = 0; /* no SS_DISABLE */ diff --git a/tests/altstack-util.h b/tests/altstack-util.h index 513064506..f91072611 100644 --- a/tests/altstack-util.h +++ b/tests/altstack-util.h @@ -18,9 +18,7 @@ #include /* uintptr_t */ #include /* for memset */ -#ifndef SIGSTKSZ -# define SIGSTKSZ 16384 -#endif +#define MYSTACK_SIZE (1 << 24) /* glibc says: Users should use SIGSTKSZ as the size of user-supplied buffers. We want to detect stack overflow of the alternate stack @@ -29,12 +27,20 @@ an unaligned pointer, to ensure the alternate stack still ends up aligned. */ #define MYSTACK_CRUMPLE_ZONE 8192 -char mystack_storage[SIGSTKSZ + 2 * MYSTACK_CRUMPLE_ZONE + 31]; -char *mystack; /* SIGSTKSZ bytes in the middle of storage. */ +static char mystack_storage[MYSTACK_SIZE + 2 * MYSTACK_CRUMPLE_ZONE + 31]; +static char *mystack; /* MYSTACK_SIZE bytes in the middle of storage. */ static void prepare_alternate_stack (void) { +#ifdef SIGSTKSZ + if (MYSTACK_SIZE < SIGSTKSZ) + { + size_t size = SIGSTKSZ; + printf ("SIGSTKSZ=%zu exceeds MYSTACK_SIZE=%d\n", size, MYSTACK_SIZE); + exit (1); + } +#endif memset (mystack_storage, 's', sizeof mystack_storage); mystack = (char *) ((uintptr_t) (mystack_storage + MYSTACK_CRUMPLE_ZONE) | 31); } @@ -51,7 +57,7 @@ check_alternate_stack_no_overflow (void) exit (1); } for (i = MYSTACK_CRUMPLE_ZONE; i > 0; i--) - if (*(mystack + SIGSTKSZ - 1 + i) != 's') + if (*(mystack + MYSTACK_SIZE - 1 + i) != 's') { printf ("Alternate stack was exceeded by %u bytes!!\n", i); exit (1); diff --git a/tests/test-sigsegv-catch-stackoverflow1.c b/tests/test-sigsegv-catch-stackoverflow1.c index 141dfd44d..c828ed282 100644 --- a/tests/test-sigsegv-catch-stackoverflow1.c +++ b/tests/test-sigsegv-catch-stackoverflow1.c @@ -105,11 +105,11 @@ main () /* Install the stack overflow handler. */ if (stackoverflow_install_handler (&stackoverflow_handler, - mystack, SIGSTKSZ) + mystack, MYSTACK_SIZE) < 0) exit (2); stack_lower_bound = mystack; - stack_upper_bound = mystack + SIGSTKSZ - 1; + stack_upper_bound = mystack + MYSTACK_SIZE - 1; /* Save the current signal mask. */ sigemptyset (&emptyset); diff --git a/tests/test-sigsegv-catch-stackoverflow2.c b/tests/test-sigsegv-catch-stackoverflow2.c index 1db2d44fc..b94d1310b 100644 --- a/tests/test-sigsegv-catch-stackoverflow2.c +++ b/tests/test-sigsegv-catch-stackoverflow2.c @@ -129,7 +129,7 @@ main () /* Install the stack overflow handler. */ if (stackoverflow_install_handler (&stackoverflow_handler, - mystack, SIGSTKSZ) + mystack, MYSTACK_SIZE) < 0) exit (2); -- 2.27.0