forked from OSchip/llvm-project
[fuzzer] Add Windows Visual C++ exception intercept
Adds a new option, `handle_winexcept` to try to intercept uncaught Visual C++ exceptions on Windows. On Linux, such exceptions are handled implicitly by `std::terminate()` raising `SIBABRT`. This option brings the Windows behavior in line with Linux. Unfortunately this exception code is intentionally undocumented, however has remained stable for the last decade. More information can be found here: https://devblogs.microsoft.com/oldnewthing/20100730-00/?p=13273 Reviewed By: morehouse, metzman Differential Revision: https://reviews.llvm.org/D89755
This commit is contained in:
parent
6c516cda39
commit
f897e82bfd
|
@ -829,6 +829,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||
Options.HandleXfsz = Flags.handle_xfsz;
|
||||
Options.HandleUsr1 = Flags.handle_usr1;
|
||||
Options.HandleUsr2 = Flags.handle_usr2;
|
||||
Options.HandleWinExcept = Flags.handle_winexcept;
|
||||
|
||||
SetSignalHandler(Options);
|
||||
|
||||
std::atexit(Fuzzer::StaticExitCallback);
|
||||
|
|
|
@ -145,6 +145,8 @@ FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.")
|
|||
FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
|
||||
FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
|
||||
FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")
|
||||
FUZZER_FLAG_INT(handle_winexcept, 1, "If 1, try to intercept uncaught Windows "
|
||||
"Visual C++ Exceptions.")
|
||||
FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; "
|
||||
"if 2, close stderr; if 3, close both. "
|
||||
"Be careful, this will also close e.g. stderr of asan.")
|
||||
|
|
|
@ -84,6 +84,7 @@ struct FuzzingOptions {
|
|||
bool HandleXfsz = false;
|
||||
bool HandleUsr1 = false;
|
||||
bool HandleUsr2 = false;
|
||||
bool HandleWinExcept = false;
|
||||
};
|
||||
|
||||
} // namespace fuzzer
|
||||
|
|
|
@ -60,7 +60,15 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
|
|||
if (HandlerOpt->HandleFpe)
|
||||
Fuzzer::StaticCrashSignalCallback();
|
||||
break;
|
||||
// TODO: handle (Options.HandleXfsz)
|
||||
// This is an undocumented exception code corresponding to a Visual C++
|
||||
// Exception.
|
||||
//
|
||||
// See: https://devblogs.microsoft.com/oldnewthing/20100730-00/?p=13273
|
||||
case 0xE06D7363:
|
||||
if (HandlerOpt->HandleWinExcept)
|
||||
Fuzzer::StaticCrashSignalCallback();
|
||||
break;
|
||||
// TODO: Handle (Options.HandleXfsz)
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
@ -127,7 +135,7 @@ void SetSignalHandler(const FuzzingOptions& Options) {
|
|||
}
|
||||
|
||||
if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||
|
||||
Options.HandleFpe)
|
||||
Options.HandleFpe || Options.HandleWinExcept)
|
||||
SetUnhandledExceptionFilter(ExceptionHandler);
|
||||
|
||||
if (Options.HandleAbrt)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, size_t size) {
|
||||
std::vector<uint8_t> v;
|
||||
// Intentionally throw std::length_error
|
||||
v.reserve(static_cast<uint64_t>(-1));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# Test that throws a C++ exception and doesn't catch it. Should result in a
|
||||
# crash
|
||||
RUN: %cpp_compiler %S/UncaughtException.cpp -o %t-UncaughtException
|
||||
|
||||
RUN: not %run %t-UncaughtException 2>&1 | FileCheck %s
|
||||
|
||||
CHECK: ERROR: libFuzzer: deadly signal
|
||||
CHECK: Test unit written to ./crash
|
Loading…
Reference in New Issue