Skip to content

Commit f897e82

Browse files
jopletch-MSFTjonathanmetzman
authored andcommitted
[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
1 parent 6c516cd commit f897e82

File tree

6 files changed

+33
-2
lines changed

6 files changed

+33
-2
lines changed

compiler-rt/lib/fuzzer/FuzzerDriver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
829829
Options.HandleXfsz = Flags.handle_xfsz;
830830
Options.HandleUsr1 = Flags.handle_usr1;
831831
Options.HandleUsr2 = Flags.handle_usr2;
832+
Options.HandleWinExcept = Flags.handle_winexcept;
833+
832834
SetSignalHandler(Options);
833835

834836
std::atexit(Fuzzer::StaticExitCallback);

compiler-rt/lib/fuzzer/FuzzerFlags.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.")
145145
FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
146146
FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
147147
FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")
148+
FUZZER_FLAG_INT(handle_winexcept, 1, "If 1, try to intercept uncaught Windows "
149+
"Visual C++ Exceptions.")
148150
FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; "
149151
"if 2, close stderr; if 3, close both. "
150152
"Be careful, this will also close e.g. stderr of asan.")

compiler-rt/lib/fuzzer/FuzzerOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct FuzzingOptions {
8484
bool HandleXfsz = false;
8585
bool HandleUsr1 = false;
8686
bool HandleUsr2 = false;
87+
bool HandleWinExcept = false;
8788
};
8889

8990
} // namespace fuzzer

compiler-rt/lib/fuzzer/FuzzerUtilWindows.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,15 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
6060
if (HandlerOpt->HandleFpe)
6161
Fuzzer::StaticCrashSignalCallback();
6262
break;
63-
// TODO: handle (Options.HandleXfsz)
63+
// This is an undocumented exception code corresponding to a Visual C++
64+
// Exception.
65+
//
66+
// See: https://devblogs.microsoft.com/oldnewthing/20100730-00/?p=13273
67+
case 0xE06D7363:
68+
if (HandlerOpt->HandleWinExcept)
69+
Fuzzer::StaticCrashSignalCallback();
70+
break;
71+
// TODO: Handle (Options.HandleXfsz)
6472
}
6573
return EXCEPTION_CONTINUE_SEARCH;
6674
}
@@ -127,7 +135,7 @@ void SetSignalHandler(const FuzzingOptions& Options) {
127135
}
128136

129137
if (Options.HandleSegv || Options.HandleBus || Options.HandleIll ||
130-
Options.HandleFpe)
138+
Options.HandleFpe || Options.HandleWinExcept)
131139
SetUnhandledExceptionFilter(ExceptionHandler);
132140

133141
if (Options.HandleAbrt)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <cstdint>
2+
#include <vector>
3+
4+
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, size_t size) {
5+
std::vector<uint8_t> v;
6+
// Intentionally throw std::length_error
7+
v.reserve(static_cast<uint64_t>(-1));
8+
9+
return 0;
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Test that throws a C++ exception and doesn't catch it. Should result in a
2+
# crash
3+
RUN: %cpp_compiler %S/UncaughtException.cpp -o %t-UncaughtException
4+
5+
RUN: not %run %t-UncaughtException 2>&1 | FileCheck %s
6+
7+
CHECK: ERROR: libFuzzer: deadly signal
8+
CHECK: Test unit written to ./crash

0 commit comments

Comments
 (0)