+2021-05-14 Paul Eggert <eggert@cs.ucla.edu>
+
+ c-stack: work around Solaris 11 bugs
+ Problem reported by Bruno Haible in:
+ https://lists.gnu.org/r/bug-gnulib/2021-05/msg00062.html
+ * lib/c-stack.c: Always include sigsegv.h if HAVE_LIBSIGSEGV.
+ (USE_LIBSIGSEGV): Do not use libsigsegv if the kernel
+ has the si_addr bug and libsigsegv is too old to work
+ around it.
+ (segv_handler) [!USE_LIBSIGSEGV]: Do not trust si_addr
+ if BOGUS_SI_ADDR_UPON_STACK_OVERFLOW.
+ * m4/c-stack.m4 (AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC):
+ Define BOGUS_SI_ADDR_UPON_STACK_OVERFLOW on Solaris 2.11 SPARC.
+ And do not define HAVE_XSI_STACK_OVERFLOW_HEURISTIC.
+
2021-05-14 Bruno Haible <bruno@clisp.org>
fcntl tests: Avoid failure in MacPorts.
#include "gettext.h"
#define _(msgid) gettext (msgid)
-/* Use libsigsegv only if needed; kernels like Solaris can detect
- stack overflow without the overhead of an external library. */
-#define USE_LIBSIGSEGV (!HAVE_XSI_STACK_OVERFLOW_HEURISTIC && HAVE_LIBSIGSEGV)
-
-#if USE_LIBSIGSEGV
+#if HAVE_LIBSIGSEGV
# include <sigsegv.h>
#endif
+/* Use libsigsegv only if needed; kernels like Solaris can detect
+ stack overflow without the overhead of an external library.
+ However, BOGUS_SI_ADDR_ON_STACK_OVERFLOW indicates a buggy
+ Solaris kernel, and a too-small LIBSIGSEGV_VERSION indicates a
+ libsigsegv so old that it does not work around the bug. */
+#define USE_LIBSIGSEGV (!HAVE_XSI_STACK_OVERFLOW_HEURISTIC && HAVE_LIBSIGSEGV \
+ && ! (BOGUS_SI_ADDR_UPON_STACK_OVERFLOW \
+ && LIBSIGSEGV_VERSION < 0x020D))
+
#include "exitfail.h"
#include "ignore-value.h"
#include "intprops.h"
of the current stack. */
if (!cannot_be_stack_overflow)
{
+# if BOGUS_SI_ADDR_UPON_STACK_OVERFLOW
+ signo = 0;
+# else
/* If the faulting address is within the stack, or within one
page of the stack, assume that it is a stack overflow. */
uintptr_t faulting_address = (uintptr_t) info->si_addr;
pages might be in the stack. */
void *stack_base = (void *) (uintptr_t) page_size;
uintptr_t stack_size = 0; stack_size -= page_size;
-# if HAVE_XSI_STACK_OVERFLOW_HEURISTIC
+# if HAVE_XSI_STACK_OVERFLOW_HEURISTIC
/* Tighten the stack bounds via the XSI heuristic. */
ucontext_t const *user_context = context;
stack_base = user_context->uc_stack.ss_sp;
stack_size = user_context->uc_stack.ss_size;
-# endif
+# endif
uintptr_t base = (uintptr_t) stack_base,
lo = (INT_SUBTRACT_WRAPV (base, page_size, &lo) || lo < page_size
? page_size : lo),
? UINTPTR_MAX : hi);
if (lo <= faulting_address && faulting_address <= hi)
signo = 0;
+# endif
-# if DEBUG
+# if DEBUG
{
char buf[1024];
ignore_value (write (STDERR_FILENO, buf,
rather than as the lowest address.])
fi
+ case $host_os--$host_cpu in
+ solaris2.11--sparc*)
+ AC_DEFINE([BOGUS_SI_ADDR_UPON_STACK_OVERFLOW], [1],
+ [Define to 1 if the faulting address (info->si_addr)
+ might be incorrect on stack overflow.])
+ gl_bogus_si_addr=1;;
+ *) gl_bogus_si_addr=0;;
+ esac
+
AC_CACHE_CHECK([for precise C stack overflow detection],
[gl_cv_sys_xsi_stack_overflow_heuristic],
[dnl On Linux/sparc64 (both in 32-bit and 64-bit mode), it would be wrong
dnl to set HAVE_XSI_STACK_OVERFLOW_HEURISTIC to 1, because the third
dnl argument passed to the segv_handler is a 'struct sigcontext *', not
dnl an 'ucontext_t *'. It would lead to a failure of test-c-stack2.sh.
- case "${host_os}--${host_cpu}" in
- linux*--sparc*)
+ dnl If $gl_bogus_si_addr is 1, there is no point to the heuristic.
+ case "${host_os}--${host_cpu}--${gl_bogus_si_addr}" in
+ linux*--sparc* | *--1)
gl_cv_sys_xsi_stack_overflow_heuristic=no
;;
*)