diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp --- a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp @@ -77,10 +77,13 @@ return; } - sigact = {}; - sigact.sa_flags = SA_SIGINFO; - sigact.sa_sigaction = callback; - if (sigaction(signum, &sigact, 0)) { + struct sigaction new_sigact = {}; + // Address sanitizer needs SA_ONSTACK (causing the signal handler to run on a + // dedicated stack) in order to be able to detect stack overflows; keep the + // flag if it's set. + new_sigact.sa_flags = SA_SIGINFO | (sigact.sa_flags & SA_ONSTACK); + new_sigact.sa_sigaction = callback; + if (sigaction(signum, &new_sigact, nullptr)) { Printf("libFuzzer: sigaction failed with %d\n", errno); exit(1); } diff --git a/compiler-rt/test/fuzzer/StackOverflowTest.cpp b/compiler-rt/test/fuzzer/StackOverflowTest.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/fuzzer/StackOverflowTest.cpp @@ -0,0 +1,26 @@ +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Stack overflow test for a fuzzer. The fuzzer must find the string "Hi" and +// cause a stack overflow. +#include +#include + +volatile int x; +volatile int y = 1; + +int infinite_recursion(char *p) { + char *buf = nullptr; + + if (y) + infinite_recursion(buf); + + x = 1; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size >= 2 && Data[0] == 'H' && Data[1] == 'i') + infinite_recursion(nullptr); + return 0; +} diff --git a/compiler-rt/test/fuzzer/stack-overflow-with-asan.test b/compiler-rt/test/fuzzer/stack-overflow-with-asan.test new file mode 100644 --- /dev/null +++ b/compiler-rt/test/fuzzer/stack-overflow-with-asan.test @@ -0,0 +1,3 @@ +CHECK: SUMMARY: AddressSanitizer: stack-overflow +RUN: %cpp_compiler %S/StackOverflowTest.cpp -o %t-StackOverflowTest +RUN: not %run %t-StackOverflowTest 2>&1 | FileCheck %s