From 73fb9698c0573778787e77a8ffa57e7fa3caebd4 Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Wed, 30 Sep 2020 18:56:52 +0200 Subject: [PATCH] [asan][test] Several Posix/unpoison-alternate-stack.cpp fixes `Posix/unpoison-alternate-stack.cpp` currently `FAIL`s on Solaris/i386. Some of the problems are generic: - `clang` warns compiling the testcase: compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp:83:7: warning: nested designators are a C99 extension [-Wc99-designator] .sa_sigaction = signalHandler, ^~~~~~~~~~~~~ compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp:84:7: warning: ISO C++ requires field designators to be specified in declaration order; field '_funcptr' will be initialized after field 'sa_flags' [-Wreorder-init-list] .sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and some more instances. This can all easily be avoided by initializing each field separately. - The test `SEGV`s in `__asan_memcpy`. The default Solaris/i386 stack size is only 4 kB, while `__asan_memcpy` tries to allocate either 5436 (32-bit) or 10688 bytes (64-bit) on the stack. This patch avoids this by requiring at least 16 kB stack size. - Even without `-fsanitize=address` I get an assertion failure: Assertion failed: !isOnSignalStack(), file compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp, line 117 The fundamental problem with this testcase is that `longjmp` from a signal handler is highly unportable; XPG7 strongly warns against it and it is thus unspecified which stack is used when `longjmp`ing from a signal handler running on an alternative stack. So I'm `XFAIL`ing this testcase on Solaris. Tested on `amd64-pc-solaris2.11` and `x86_64-pc-linux-gnu`. Differential Revision: https://reviews.llvm.org/D88501 --- .../TestCases/Posix/unpoison-alternate-stack.cpp | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp b/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp index d684810..4774993 100644 --- a/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp @@ -7,7 +7,10 @@ // RUN: %run %t // XFAIL: ios && !iossim +// longjmp from signal handler is unportable. +// XFAIL: solaris +#include #include #include #include @@ -83,10 +86,9 @@ void signalHandler(int, siginfo_t *, void *) { void setSignalAlternateStack(void *AltStack) { sigaltstack((stack_t const *)AltStack, nullptr); - struct sigaction Action = { - .sa_sigaction = signalHandler, - .sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK, - }; + struct sigaction Action = {}; + Action.sa_sigaction = signalHandler; + Action.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK; sigemptyset(&Action.sa_mask); sigaction(SIGUSR1, &Action, nullptr); @@ -137,9 +139,11 @@ void *threadFun(void *AltStack) { // reports when the stack is reused. int main() { size_t const PageSize = sysconf(_SC_PAGESIZE); + // The Solaris defaults of 4k (32-bit) and 8k (64-bit) are too small. + size_t const MinStackSize = std::max(PTHREAD_STACK_MIN, 16 * 1024); // To align the alternate stack, we round this up to page_size. size_t const DefaultStackSize = - (PTHREAD_STACK_MIN - 1 + PageSize) & ~(PageSize - 1); + (MinStackSize - 1 + PageSize) & ~(PageSize - 1); // The alternate stack needs a certain size, or the signal handler segfaults. size_t const AltStackSize = 10 * PageSize; size_t const MappingSize = DefaultStackSize + AltStackSize; @@ -149,11 +153,10 @@ int main() { MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - stack_t const AltStack = { - .ss_sp = (char *)Mapping + DefaultStackSize, - .ss_flags = 0, - .ss_size = AltStackSize, - }; + stack_t AltStack = {}; + AltStack.ss_sp = (char *)Mapping + DefaultStackSize; + AltStack.ss_flags = 0; + AltStack.ss_size = AltStackSize; pthread_t Thread; pthread_attr_t ThreadAttr; -- 2.7.4