LibAFL icon indicating copy to clipboard operation
LibAFL copied to clipboard

LibAFL Incorrectly classifying crashes on MSVC

Open Ben-Lichtman opened this issue 2 years ago • 4 comments

Describe the bug LibAFL on MSVC is marking discovered crashes as fuzzer crashes instead of target crashes.

To Reproduce Steps to reproduce the behavior:

  1. Download the included project file
  2. Open it with your MSVC developer powershell
  3. run ./build_libafl.ps1 - optionally changing the position of sancov.lib within
  4. cd fuzzer_rust
  5. cargo run - you should get crash marked as occurring outside of the target

Expected behavior The crash should be classified as occurring inside the target

Screen output/Screenshots image

Additional context fuzz_target.zip

Note Changing the VEH installed at https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/bolts/os/windows_exceptions.rs#L367 from 1 to 0 seemed to fix the problem here, but I'm not sure if this may have broken anything else / things in other scenarios.

Ben-Lichtman avatar Sep 06 '22 19:09 Ben-Lichtman

Hi, thanks for opening this issue.

Does this problem happens when you are not using ASAN too? Does your fuzzer get objectives without crashing itself when you are not using ASAN?

Yes it could be that their VEH interferes with ours https://github.com/llvm/llvm-project/blob/c93e4b6b2c497aecda82029d6f161bd81da26dab/compiler-rt/lib/asan/asan_win.cpp#L321 They install their VEH with 1 too

tokatoka avatar Sep 10 '22 13:09 tokatoka

Hmm, I think I have a theory about why this problem happens

 # Child-SP          RetAddr               Call Site
00 (Inline Function) --------`--------     clang_rt_asan_dynamic_x86_64!__asan::AddressIsPoisoned+0x11 [D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_mapping.h @ 386] 
01 00000070`ba15b690 00007fff`a1bd4417     clang_rt_asan_dynamic_x86_64!__asan_region_is_poisoned+0x90 [D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_poisoning.cpp @ 219] 
02 00000070`ba15b6d0 00007ff8`4a026722     clang_rt_asan_dynamic_x86_64!__asan_wrap_memset+0xf7 [D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\sanitizer_common\sanitizer_common_interceptors.inc @ 783] 
03 00000070`ba15bf80 00007ff8`4a0266cb     ntdll!EtwpFreeRegistration+0x1a [minkernel\etw\ntdll\evntsup.c @ 580] 
04 00000070`ba15bfb0 00007ff8`46b7392f     ntdll!EtwNotificationUnregister+0xdb [minkernel\etw\ntdll\evntapi.c @ 1107] 
05 00000070`ba15bff0 00007ff8`46b7689b     userenv!McGenEventUnregister_EtwEventUnregister+0x17 [onecore\ds\security\gina\profile\userenv\dll\objfre\amd64\userenvevents.h @ 640] 
06 00000070`ba15c020 00007ff8`46b75065     userenv!DllMain+0x43 [onecore\ds\security\gina\profile\userenv\dll\userenv.cpp @ 131] 
07 00000070`ba15c050 00007ff8`4a060277     userenv!dllmain_dispatch+0x99 [VCCRT\vcstartup\src\startup\dll_dllmain.cpp @ 281] 
08 00000070`ba15c0b0 00007ff8`4a07486c     ntdll!LdrpCallInitRoutine+0x6b [minkernel\ntdll\ldr.c @ 231] 
09 00000070`ba15c120 00007ff8`4a07465d     ntdll!LdrShutdownProcess+0x1ec [minkernel\ntdll\ldrinit.c @ 7359] 
0a 00000070`ba15c230 00007ff8`4982c66b     ntdll!RtlExitUserProcess+0xad [minkernel\ntdll\rtlstrt.c @ 1570] 
0b 00000070`ba15c260 00007ff7`e7ea7131     KERNEL32!ExitProcessImplementation+0xb [clientcore\base\win32\client\process.c @ 2522] 
0c 00000070`ba15c290 00007ff7`e7ec33f8     fuzzer_rust!windows::Windows::Win32::System::Threading::ExitProcess+0x11 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\windows-0.39.0\src\Windows\Win32\System\Threading\mod.rs @ 1278] 
0d 00000070`ba15c2c0 00007ff7`e7f9a1b0     fuzzer_rust!libafl::executors::inprocess::windows_exception_handler::inproc_crash_handler<libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::feedbacks::CrashFeedback,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,libafl::fuzzer::StdFuzzer<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondis+0x348 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\executors\inprocess.rs @ 1242] 
0e 00000070`ba15c900 00007ff7`e7f78fe8     fuzzer_rust!libafl::executors::inprocess::windows_exception_handler::impl$0::handle+0x70 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\executors\inprocess.rs @ 906] 
0f 00000070`ba15c970 00007ff7`e7f790e8     fuzzer_rust!libafl::bolts::os::windows_exceptions::internal_handle_exception+0x118 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\bolts\os\windows_exceptions.rs @ 309] 
10 00000070`ba15ca20 00007ff8`4a09c89a     fuzzer_rust!libafl::bolts::os::windows_exceptions::handle_exception+0x98 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\bolts\os\windows_exceptions.rs @ 326] 
11 00000070`ba15ca90 00007ff8`4a055ca2     ntdll!RtlpCallVectoredHandlers+0x112 [minkernel\ntdll\vectxcpt.c @ 204] 
12 (Inline Function) --------`--------     ntdll!RtlCallVectoredExceptionHandlers+0xe [minkernel\ntdll\vectxcpt.c @ 358] 
13 00000070`ba15cb30 00007ff8`4a0c7fde     ntdll!RtlDispatchException+0x62 [minkernel\ntos\rtl\amd64\exdsptch.c @ 390] 
14 00000070`ba15cd80 00007ff7`e876a015     ntdll!KiUserExceptionDispatch+0x2e [minkernel\ntos\rtl\amd64\trampoln.asm @ 751] 
15 00000070`ba15d520 00007ff7`e7ecf8b8     fuzzer_rust!fuzz_function+0x265 [C:\Users\benlichtman\OneDrive - Microsoft\dev\other\fuzz_target\boom.cpp @ 18] 
16 00000070`ba15d5b0 00007ff7`e7ed4308     fuzzer_rust!fuzzer_rust::harness+0x88 [C:\Users\benlichtman\OneDrive - Microsoft\dev\other\fuzz_target\fuzzer_rust\src\main.rs @ 13] 
17 00000070`ba15d660 00007ff7`e7eaa40b     fuzzer_rust!core::ops::function::FnMut::call_mut<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),tuple$<ref$<libafl::inputs::bytes::BytesInput> > >+0x18 [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a\library\core\src\ops\function.rs @ 164] 
18 00000070`ba15d6a0 00007ff7`e7ea4c9c     fuzzer_rust!libafl::executors::inprocess::impl$1::run_target<libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,libafl::fuzzer::StdFuzzer<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::MultiMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedback+0x7b [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\executors\inprocess.rs @ 110] 
19 00000070`ba15d730 00007ff7`e7ea345e     fuzzer_rust!libafl::fuzzer::StdFuzzer<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::MultiMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::LogicEagerOr,libafl::inputs::bytes::BytesInput,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::feedbacks::CrashFeedback,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >::execute_input<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReduc+0x1cc [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\fuzzer\mod.rs @ 603] 
1a 00000070`ba15d990 00007ff7`e7ea2636     fuzzer_rust!libafl::fuzzer::impl$4::evaluate_input_with_observers<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::MultiMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::LogicEagerOr,libafl::inputs::bytes::BytesInput,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::feedbacks::CrashFeedback,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::Byt+0x8e [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\fuzzer\mod.rs @ 444] 
1b 00000070`ba15db20 00007ff7`e7ea5271     fuzzer_rust!libafl::fuzzer::impl$5::evaluate_input_events<libafl::schedulers::queue::QueueScheduler,libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::MultiMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesI+0x76 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\fuzzer\mod.rs @ 472] 
1c 00000070`ba15dbb0 00007ff7`e7ebc90a     fuzzer_rust!libafl::fuzzer::Evaluator::evaluate_input<libafl::fuzzer::StdFuzzer<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::MultiMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::LogicEagerOr,libafl::inputs::bytes::BytesInput,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::feedbacks::CrashFeedback,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::in+0x61 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\fuzzer\mod.rs @ 121] 
1d 00000070`ba15dc30 00007ff7`e7ebc3e7     fuzzer_rust!libafl::stages::mutational::MutationalStage::perform_mutational<libafl::stages::mutational::StdMutationalStage<libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::mutators::scheduled::StdScheduledMutator<libafl::inputs::bytes::BytesInput,tuple$<libafl::mutators::mutations::BitFlipMutator,tuple$<libafl::mutators::mutations::ByteFlipMutator,tuple$<libafl::mutators::mutations::ByteIncMutator,tuple$<libafl::mutators::mutations::ByteDecMutator,tuple$<libafl::mutators::mutations::ByteNegMutator,tuple$<libafl::mutators::mutations::ByteRandMutator,tuple$<libafl::mutators::mutations::ByteAddMutator,tuple$<libafl::mutators::mutations::WordAddMutator,tuple$<libafl::mutators::mutations::DwordAddMutator,tuple$<libafl::mutators::mutations::QwordAddMutator,tuple$<libafl::mutators::mutations::ByteInterestingMutator,tuple$<libafl::mutators::mutations::WordInterestingMutator,tuple$<libafl::mutators::mutations::DwordInterestingMutator,tuple$<libafl::mutators::mutations::BytesDeleteMutator,tuple$<libafl+0x45a [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\stages\mutational.rs @ 69] 
1e 00000070`ba15e170 00007ff7`e7ebcd2b     fuzzer_rust!libafl::stages::mutational::impl$1::perform<libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::mutators::scheduled::StdScheduledMutator<libafl::inputs::bytes::BytesInput,tuple$<libafl::mutators::mutations::BitFlipMutator,tuple$<libafl::mutators::mutations::ByteFlipMutator,tuple$<libafl::mutators::mutations::ByteIncMutator,tuple$<libafl::mutators::mutations::ByteDecMutator,tuple$<libafl::mutators::mutations::ByteNegMutator,tuple$<libafl::mutators::mutations::ByteRandMutator,tuple$<libafl::mutators::mutations::ByteAddMutator,tuple$<libafl::mutators::mutations::WordAddMutator,tuple$<libafl::mutators::mutations::DwordAddMutator,tuple$<libafl::mutators::mutations::QwordAddMutator,tuple$<libafl::mutators::mutations::ByteInterestingMutator,tuple$<libafl::mutators::mutations::WordInterestingMutator,tuple$<libafl::mutators::mutations::DwordInterestingMutator,tuple$<libafl::mutators::mutations::BytesDeleteMutator,tuple$<libafl::mutators::mutations::BytesDeleteMutator,tuple$<libafl::mutators::+0x47 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\stages\mutational.rs @ 145] 
1f 00000070`ba15e1d0 00007ff7`e7ea312c     fuzzer_rust!libafl::stages::impl$1::perform_all<libafl::stages::mutational::StdMutationalStage<libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::mutators::scheduled::StdScheduledMutator<libafl::inputs::bytes::BytesInput,tuple$<libafl::mutators::mutations::BitFlipMutator,tuple$<libafl::mutators::mutations::ByteFlipMutator,tuple$<libafl::mutators::mutations::ByteIncMutator,tuple$<libafl::mutators::mutations::ByteDecMutator,tuple$<libafl::mutators::mutations::ByteNegMutator,tuple$<libafl::mutators::mutations::ByteRandMutator,tuple$<libafl::mutators::mutations::ByteAddMutator,tuple$<libafl::mutators::mutations::WordAddMutator,tuple$<libafl::mutators::mutations::DwordAddMutator,tuple$<libafl::mutators::mutations::QwordAddMutator,tuple$<libafl::mutators::mutations::ByteInterestingMutator,tuple$<libafl::mutators::mutations::WordInterestingMutator,tuple$<libafl::mutators::mutations::DwordInterestingMutator,tuple$<libafl::mutators::mutations::BytesDeleteMutator,tuple$<libafl::mutators::mutations::Bytes+0x7b [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\stages\mod.rs @ 107] 
20 00000070`ba15e2f0 00007ff7`e7ea4ff1     fuzzer_rust!libafl::fuzzer::impl$6::fuzz_one<libafl::schedulers::queue::QueueScheduler,libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::MultiMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,l+0xdc [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\fuzzer\mod.rs @ 549] 
21 00000070`ba15e550 00007ff7`e7ed0316     fuzzer_rust!libafl::fuzzer::Fuzzer::fuzz_loop<libafl::fuzzer::StdFuzzer<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::MultiMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,u8>,libafl::feedbacks::LogicEagerOr,libafl::inputs::bytes::BytesInput,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::feedbacks::CrashFeedback,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::by+0xc1 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\fuzzer\mod.rs @ 183] 
22 00000070`ba15e750 00007ff7`e7ecfa72     fuzzer_rust!fuzzer_rust::fuzz+0x786 [C:\Users\benlichtman\OneDrive - Microsoft\dev\other\fuzz_target\fuzzer_rust\src\main.rs @ 112] 
23 00000070`ba15f600 00007ff7`e7ed43bb     fuzzer_rust!fuzzer_rust::main+0x162 [C:\Users\benlichtman\OneDrive - Microsoft\dev\other\fuzz_target\fuzzer_rust\src\main.rs @ 25] 
24 00000070`ba15f7c0 00007ff7`e7ed6bee     fuzzer_rust!core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >+0xb [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a\library\core\src\ops\function.rs @ 248] 
25 00000070`ba15f800 00007ff7`e7eaf6b1     fuzzer_rust!std::sys_common::backtrace::__rust_begin_short_backtrace<void (*)(),tuple$<> >+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a\library\std\src\sys_common\backtrace.rs @ 125] 
26 00000070`ba15f830 00007ff7`e86f9d10     fuzzer_rust!std::rt::lang_start::closure$0<tuple$<> >+0x11 [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a\library\std\src\rt.rs @ 145] 
27 (Inline Function) --------`--------     fuzzer_rust!core::ops::function::impls::impl$2::call_once+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\core\src\ops\function.rs @ 280] 
28 (Inline Function) --------`--------     fuzzer_rust!std::panicking::try::do_call+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\panicking.rs @ 492] 
29 (Inline Function) --------`--------     fuzzer_rust!std::panicking::try+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\panicking.rs @ 456] 
2a (Inline Function) --------`--------     fuzzer_rust!std::panic::catch_unwind+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\panic.rs @ 137] 
2b (Inline Function) --------`--------     fuzzer_rust!std::rt::lang_start_internal::closure$2+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\rt.rs @ 128] 
2c (Inline Function) --------`--------     fuzzer_rust!std::panicking::try::do_call+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\panicking.rs @ 492] 
2d (Inline Function) --------`--------     fuzzer_rust!std::panicking::try+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\panicking.rs @ 456] 
2e (Inline Function) --------`--------     fuzzer_rust!std::panic::catch_unwind+0xe [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\panic.rs @ 137] 
2f 00000070`ba15f870 00007ff7`e7eaf67f     fuzzer_rust!std::rt::lang_start_internal+0xc0 [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a/library\std\src\rt.rs @ 128] 
30 00000070`ba15f9c0 00007ff7`e7ed0636     fuzzer_rust!std::rt::lang_start<tuple$<> >+0x2f [/rustc/c07a8b4e09f356c7468b69c50cac7fc5b5000b8a\library\std\src\rt.rs @ 144] 
31 00000070`ba15fa20 00007ff7`e876ab7c     fuzzer_rust!main+0x16
32 (Inline Function) --------`--------     fuzzer_rust!invoke_main+0x22 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 
33 00000070`ba15fa50 00007ff8`498254e0     fuzzer_rust!__scrt_common_main_seh+0x10c [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 
34 00000070`ba15fa90 00007ff8`4a02485b     KERNEL32!BaseThreadInitThunk+0x10 [clientcore\base\win32\client\thread.c @ 75] 
35 00000070`ba15fac0 00000000`00000000     ntdll!RtlUserThreadStart+0x2b [minkernel\ntdll\rtlstrt.c @ 1152] 

This is the backtrace you showed on discord,

At frame 0x0d, we are trying to exit the process

00000070`ba15c2c0 00007ff7`e7f9a1b0     fuzzer_rust!libafl::executors::inprocess::windows_exception_handler::inproc_crash_handler<libafl::executors::inprocess::GenericInProcessExecutor<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>),ref_mut$<enum2$<libafl::executors::ExitKind> (*)(ref$<libafl::inputs::bytes::BytesInput>)>,libafl::inputs::bytes::BytesInput,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::events::simple::SimpleEventManager<libafl::inputs::bytes::BytesInput,libafl::monitors::SimpleMonitor<fuzzer_rust::fuzz::closure_env$0>,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> > >,libafl::inputs::bytes::BytesInput,libafl::feedbacks::CrashFeedback,tuple$<libafl::observers::map::StdMapObserver<u8>,tuple$<libafl::observers::map::MultiMapObserver<u8>,tuple$<> > >,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondisk::OnDiskCorpus<libafl::inputs::bytes::BytesInput> >,libafl::fuzzer::StdFuzzer<libafl::schedulers::queue::QueueScheduler,libafl::feedbacks::CombinedFeedback<libafl::feedbacks::map::MapFeedback<libafl::inputs::bytes::BytesInput,libafl::feedbacks::map::DifferentIsNovel,libafl::observers::map::StdMapObserver<u8>,libafl::feedbacks::map::MaxReducer,libafl::state::StdState<libafl::corpus::inmemory::InMemoryCorpus<libafl::inputs::bytes::BytesInput>,libafl::inputs::bytes::BytesInput,libafl::bolts::rands::RomuDuoJrRand,libafl::corpus::ondis+0x348 [C:\Users\benlichtman\.cargo\registry\src\github.com-1ecc6299db9ec823\libafl-0.8.1\src\executors\inprocess.rs @ 1242] 

https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/executors/inprocess.rs#L1242

And by that time, we already have the global variable data.current_input_ptr() cleared with null in this function call https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/executors/inprocess.rs#L1196

then after we call ExitProcess(1), the ASAN starts working (This is the problem, why..?) and raises the exception again at frames upper than 0x0d, which calles again our crash exception handler, but this time the pointer to the data.current_input_ptr() is null, so it is classified with A crash outside the harness

tokatoka avatar Sep 10 '22 14:09 tokatoka

I'm not sure if changing AddVectoredExceptionHandler(1, handler) to AddVectoredExceptionHandler(0, handler) is right...

If ASAN's exception handler is prioritized over ours, could the exception still be passed to our exception handlers? I wonder what will happen if you changed

        *(char *)0x41414141 = 'A';

to something like a off-by-one overflow and compile it with ASAN (so only with asan's exception handler we can catch this bug) and also use AddVectoredExceptionHandler(0, handler) together

does libafl still catch the objective in this case if ASAN's handler is prioritized?

tokatoka avatar Sep 10 '22 14:09 tokatoka

I feel like it's some sort of asan for windows misconfiguration/misuse. I'm facing the asan for windows the second time (so I'm not an expert here, perhaps someone can explain why am I seeing next exceptions?), and it looks like windows is just not ready for such drastic sanitizer or perhaps it's buggy itself. Here are some examples of which I'm getting even before the harness hits the *(char *)0x41414141 = 'A'; path. (in the stack call mentioned by @tokatoka we see the same _asan_wrap_memset).

(2e40.15f0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
clang_rt_asan_dynamic_x86_64!_asan_region_is_poisoned+0x90:
00007ffc`05a36ce0 420fb60401      movzx   eax,byte ptr [rcx+r8] ds:0000029c`658cc62e=??
0:000> k
 # Child-SP          RetAddr               Call Site
00 000000e5`a78fcd10 00007ffc`05a24417     clang_rt_asan_dynamic_x86_64!_asan_region_is_poisoned+0x90
01 000000e5`a78fcd50 00007ffc`7910bbcc     clang_rt_asan_dynamic_x86_64!_asan_wrap_memset+0xf7
02 000000e5`a78fd600 00007ffc`7910929c     ntdll!RtlpAllocateHeap+0xa6c
03 000000e5`a78fd860 00007ffc`05a2f911     ntdll!RtlpAllocateHeapInternal+0x6ac
04 000000e5`a78fd960 00007ffc`791e46c6     clang_rt_asan_dynamic_x86_64!_asan_wrap_RtlAllocateHeap+0x141
05 000000e5`a78fe280 00007ffc`7919dc72     ntdll!RtlDebugAllocateHeap+0x102
06 000000e5`a78fe320 00007ffc`7910929c     ntdll!RtlpAllocateHeap+0x92b12
07 000000e5`a78fe580 00007ffc`05a2f911     ntdll!RtlpAllocateHeapInternal+0x6ac
08 000000e5`a78fe680 00007ffc`7912dd82     clang_rt_asan_dynamic_x86_64!_asan_wrap_RtlAllocateHeap+0x141
09 000000e5`a78fefa0 00007ffc`7912dccc     ntdll!LdrpAllocatePlaceHolder+0x5a
0a 000000e5`a78fefe0 00007ffc`7911ba75     ntdll!LdrpFindOrPrepareLoadingModule+0x98
0b 000000e5`a78ff050 00007ffc`79124dfc     ntdll!LdrpLoadDllInternal+0x185
0c 000000e5`a78ff0f0 00007ffc`7911aeb6     ntdll!LdrpLoadDll+0xb0
0d 000000e5`a78ff2b0 00007ffc`769d3ec2     ntdll!LdrLoadDll+0x106
0e 000000e5`a78ff3a0 00007ffc`75e924c1     KERNELBASE!LoadLibraryExW+0x172

(2e40.15f0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
clang_rt_asan_dynamic_x86_64!__asan::QuickCheckForUnpoisonedRegion+0x8e:
00007ffc`05a2147e 460fb61408      movzx   r10d,byte ptr [rax+r9] ds:00001250`b9190238=??
0:000> k
 # Child-SP          RetAddr               Call Site
00 000000e5`a78fead8 00007ffc`05a23fcc     clang_rt_asan_dynamic_x86_64!__asan::QuickCheckForUnpoisonedRegion+0x8e
01 000000e5`a78feae0 00007ffc`769fdb58     clang_rt_asan_dynamic_x86_64!_asan_wrap_memmove+0xec
02 000000e5`a78ff3a0 00007ffc`75e925bb     KERNELBASE!GetSystemDirectoryW+0x28
03 000000e5`a78ff3d0 00007ffc`75e92478     bcrypt!_GetImagePath+0x83
04 000000e5`a78ff410 00007ffc`75e92114     bcrypt!_LoadImage+0x58
05 000000e5`a78ff470 00007ffc`75e960c6     bcrypt!LoadProviderEx+0x364
06 000000e5`a78ff510 00007ffc`75e93a12     bcrypt!BCryptOpenAlgorithmProvider+0x696
07 000000e5`a78ff8f0 00007ffc`75e9390d     bcrypt!OpenSystemPreferredAlgorithmProvider+0x9a
08 000000e5`a78ff950 00007ff6`15cb98a1     bcrypt!BCryptGenRandom+0x1ad

(2e40.15f0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
clang_rt_asan_dynamic_x86_64!__asan::QuickCheckForUnpoisonedRegion+0x1f:
00007ffc`05a2140f 460fb61408      movzx   r10d,byte ptr [rax+r9] ds:00001251`b08c30c5=??
0:000> k
 # Child-SP          RetAddr               Call Site
00 000000e5`a78fe848 00007ffc`05a23fcc     clang_rt_asan_dynamic_x86_64!__asan::QuickCheckForUnpoisonedRegion+0x1f
01 000000e5`a78fe850 00007ffc`79154db1     clang_rt_asan_dynamic_x86_64!_asan_wrap_memmove+0xec
02 000000e5`a78ff110 00007ffc`79125620     ntdll!RtlMultiAppendUnicodeStringBuffer+0xb1
03 000000e5`a78ff160 00007ffc`79124b41     ntdll!RtlDosApplyFileIsolationRedirection_Ustr+0x440
04 000000e5`a78ff3b0 00007ffc`79124888     ntdll!LdrpApplyFileNameRedirection+0xfd
05 000000e5`a78ff450 00007ffc`79124dc0     ntdll!LdrpPreprocessDllName+0x4c
06 000000e5`a78ff4c0 00007ffc`7911aeb6     ntdll!LdrpLoadDll+0x74
07 000000e5`a78ff680 00007ffc`769d3ec2     ntdll!LdrLoadDll+0x106
08 000000e5`a78ff770 00007ffc`7672fe22     KERNELBASE!LoadLibraryExW+0x172
09 000000e5`a78ff7e0 00007ffc`7673052c     ucrtbase!try_get_module+0x4a
0a 000000e5`a78ff810 00007ffc`767304a4     ucrtbase!__acrt_AreFileApisANSI+0x60
0b 000000e5`a78ff840 00007ffc`7673038c     ucrtbase!__acrt_get_utf8_acp_compatibility_codepage+0x24
0c 000000e5`a78ff890 00007ffc`76733014     ucrtbase!__acrt_GetModuleFileNameA+0x64
0d 000000e5`a78ffb10 00007ff6`15d988a1     ucrtbase!common_configure_argv<char>+0x48
0e (Inline Function) --------`--------     frida_gdiplus!__scrt_narrow_argv_policy::configure_argv+0xc [D:\a\_work\1\s\src\vctools\crt\vcstartup\inc\vcstartup_internal.h @ 418] 
0f 000000e5`a78ffb70 00007ffc`76732dad     frida_gdiplus!pre_c_initialization+0x55 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 167] 
10 000000e5`a78ffba0 00007ff6`15d98990     ucrtbase!initterm_e+0x2d
...

So, I'd say for some reason, legit or not, asan itself is generating too much exceptions. Although these are first chance exceptions and they are handled by asan internal handler, never the less it's not a good companion for fuzzing, because it's impossible to distinguish if these access violations are valid or not (from the perspective of vulnerability research).

expend20 avatar Sep 19 '22 20:09 expend20

ok I reproduced the issue and

Changing the VEH installed at https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/bolts/os/windows_exceptions.rs#L367 from 1 to 0 seemed to fix the problem here, but I'm not sure if this may have broken anything else / things in other scenarios.

it seems this does not work if asan's exception handler is triggered first and then our fuzzer process dies

tokatoka avatar Oct 17 '22 01:10 tokatoka

my binary does not even start fuzzing when I execute fuzz_target.exe, it will immediately crash on some asan startup functions and I see the same call stack by expend20

the problem is asan emits many exceptions,

  1. but if we get our exception handler prioritized over asans exception handler (AddVectoredExceptionHandler(1, ...) ) , then we'll get many exceptions from asan internals, leading to double crashes error.
  2. if we get asan's exception handler prioritized over ours exception handler (AddVectoredExceptionHandler(0, ...) ) then our exception handler will never get executed and the fuzzer has no way to know if the harness has crashed

I don't think there's a solution for this for now, Asan's exception handler keeps interfering with ours. (you know, windows + asan on libfuzzer does not work either.)

tokatoka avatar Oct 17 '22 03:10 tokatoka

I'm happy that I finally stumbled upon this issue. That confirms that something is off with LibAFL+ASAN instead of my linking procedure is wrong.

I experimented with quite a few configuration of linking ASAN and the Program Under Test with LibAFL, e.g -crt-static, +crt-static, /MD, /MT.

In fact changing this to 0 works: https://github.com/AFLplusplus/LibAFL/blob/f7f6392a4be79e866cd77c408fe7501388470b5a/libafl/src/bolts/os/windows_exceptions.rs#L379

maxammann avatar Nov 18 '22 16:11 maxammann

hello, Max Changing that value to 0 brings another issue. When the error is detectable only with ASAN (, like off-byte-one overflow), then the ASAN exception handler is called and the process exits. but our exception handler is not called.

tokatoka avatar Nov 18 '22 19:11 tokatoka

Can't we hook ASans exception behavior, maybe?

domenukk avatar Nov 18 '22 20:11 domenukk

Would that also happen if I set the ASAN_OPTION abort_on_error?

Do you have some solution in your mind how we can fix this problem?

An another question: Do you have more information why libfuzzer(clang or msvc) does not work with ASAN on windows?

maxammann avatar Nov 18 '22 20:11 maxammann

When the error is detectable only with ASAN (, like off-byte-one overflow), then the ASAN exception handler is called and the process exits. but our exception handler is not called.

True I just observed that ASAN detected an issue, but the test input was not recorded as an objective.

Can we maybe ignore some exceptions with AddVectoredExceptionHandler(1, ...) and avoid the double crash?

maxammann avatar Nov 18 '22 21:11 maxammann

Just stumbled upon this thing: https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/gwp_asan.md#crash-handler

The crashpad tool in chromium seems to be able to catch ASAN exceptions on Windows and detect them as being ASAN related. Maybe crashpad has some code we need?

Quick search in Chromium's source:

  • https://source.chromium.org/search?q=AddVectoredExceptionHandler
  • https://source.chromium.org/chromium/chromium/src/+/main:components/browser_watcher/extended_crash_reporting.cc;l=149?q=AddVectoredExceptionHandler
  • https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/llvm-project/compiler-rt/lib/asan/asan_win.cpp;l=279?q=AddVectoredExceptionHandler

maxammann avatar Nov 19 '22 21:11 maxammann

Hello, sorry for the late response

Do you have some solution in your mind how we can fix this problem? Can we maybe ignore some exceptions with AddVectoredExceptionHandler(1, ...) and avoid the double crash? The reason the fuzzer double crashes is because it fails at this check: https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/executors/inprocess.rs#L1170

This is because the first crash handler cleared this already, but then asan runtime emits another exception, calling our crash handler again. but this time input == NULL. So it is a double crash.

Just an Idea, but I think something we could try is to check the crashing address in the exception handler, and if it's in asan's region, then simply skip it in the exception handler. This way, we could avoid the double crash.

(PRs are welcome 😁 )

An another question: Do you have more information why libfuzzer(clang or msvc) does not work with ASAN on windows?

Not sure... I don't know much about libfuzzer internals 😔 . but I just read it here saying it's unsupported. https://llvm.org/docs/LibFuzzer.html#q-does-libfuzzer-support-windows

tokatoka avatar Nov 21 '22 00:11 tokatoka

Not sure... I don't know much about libfuzzer internals pensive . but I just read it here saying it's unsupported. https://llvm.org/docs/LibFuzzer.html#q-does-libfuzzer-support-windows

Actually it is saying that the opposite is not possible. Fuzzing without ASAN is unsupported :D

Just an Idea, but I think something we could try is to check the crashing address in the exception handler, and if it's in asan's region, then simply skip it in the exception handler. This way, we could avoid the double crash.

That sound like an idea! Isn't that what Chromium is doing here maybe? https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/llvm-project/compiler-rt/lib/asan/asan_win.cpp;l=293-297?q=AddVectoredExceptionHandler

(PRs are welcome grin )

Depending on whether we choose LibAFL or libfuzzer I will give my best to fix this issue and create a PR :)

maxammann avatar Nov 21 '22 07:11 maxammann

Actually it is saying that the opposite is not possible. Fuzzing without ASAN is unsupported :D

😁 I read it wrong. haha then probably libfuzzer has the solution for this...

That sound like an idea! Isn't that what Chromium is doing here maybe? https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/llvm-project/compiler-rt/lib/asan/asan_win.cpp;l=293-297?q=AddVectoredExceptionHandler

This handler here is checking if the accessed ptr is in shadow region for ASAN. (as the function name suggests) Yes, we can do similar things, if the crash seems to be raised from asan runtime, then just return exception_continue_search.

tokatoka avatar Nov 21 '22 08:11 tokatoka

2. if we get asan's exception handler prioritized over ours exception handler (AddVectoredExceptionHandler(0, ...) ) then our exception handler will never get executed and the fuzzer has no way to know if the harness has crashed

I'm not entirely sure if that is the case.

EXCEPTION_CONTINUE_EXECUTION means: return control to the point at which the exception occurred EXCEPTION_CONTINUE_SEARCH means: continue the handler search

That means if ASAN returns EXCEPTION_CONTINUE_SEARCH in fact the LibAFL handler should be called (https://github.com/llvm/llvm-project/blob/535c2da58dd2469dc8b8610443b51e5b10867074/compiler-rt/lib/asan/asan_win.cpp#L286).

Actually the return value EXCEPTION_EXECUTE_HANDLER which is used in LibAFL is not valid (https://learn.microsoft.com/en-us/windows/win32/api/winnt/nc-winnt-pvectored_exception_handler).


If I set abort_on_error=1 then the child crashes with exit code 3. If I set it to 0 then the child crashes with exit code 1. Maybe we somehow have to catch the abort() issued by ASAN better. Maybe in that case we can actually avoid using a vectored exception handler all together when using ASAN.

maxammann avatar Nov 21 '22 20:11 maxammann

We might be able to use Vectored Continue Händlers, which get called when EXCEPTION_CONTINUE_EXECUTION is returned from a VEH: https://reverseengineering.stackexchange.com/questions/14992/what-are-the-vectored-continue-handlers

maxammann avatar Nov 21 '22 20:11 maxammann

That means if ASAN returns EXCEPTION_CONTINUE_SEARCH in fact the LibAFL handler should be called (https://github.com/llvm/llvm-project/blob/535c2da58dd2469dc8b8610443b51e5b10867074/compiler-rt/lib/asan/asan_win.cpp#L286).

True., but then I'm not sure why our exception handler is ignored when I used AddVectoredHandler(0, ..)

Actually the return value EXCEPTION_EXECUTE_HANDLER which is used in LibAFL is not valid (https://learn.microsoft.com/en-us/windows/win32/api/winnt/nc-winnt-pvectored_exception_handler).

Yes this is a mistake. Before we use this vectored exception handler we were using SEH and this EXCEPTION_EXECUTE_HANDLER seems to be the return value for SEH, and I forgot to change this value.

tokatoka avatar Nov 21 '22 21:11 tokatoka

EXCEPTION_CONTINUE_EXECUTION means: return control to the point at which the exception occurred EXCEPTION_CONTINUE_SEARCH means: continue the handler search

This is the stacktrace right before the process exits

0:000> k
 # Child-SP          RetAddr               Call Site
00 0000003f`6b34e060 00007ffa`160a9496     clang_rt_asan_dynamic_x86_64!__sanitizer::internal__exit+0x1e
01 0000003f`6b34e090 00007ffa`160e3997     clang_rt_asan_dynamic_x86_64!__sanitizer::Die+0x56
02 0000003f`6b34e0c0 00007ffa`160e5012     clang_rt_asan_dynamic_x86_64!__asan::ScopedInErrorReport::~ScopedInErrorReport+0x247
03 0000003f`6b34e0f0 00007ffa`160e945a     clang_rt_asan_dynamic_x86_64!__asan::ReportGenericError+0x122
*** WARNING: Unable to verify checksum for fuzzer_rust.exe
04 0000003f`6b34ed50 00007ff6`a06fac43     clang_rt_asan_dynamic_x86_64!_asan_report_store1+0x3a
05 0000003f`6b34eda0 00007ff6`a0329842     fuzzer_rust!fuzz_function+0x3d3 [C:\Users\toka\LibAFL\fuzzers\fuzz_target\boom.cpp @ 20] 
06 0000003f`6b34eea0 00007ff6`a0324563     fuzzer_rust!ZN6libafl6fuzzer9Evaluator14evaluate_input17he33fd16bb6ae3713E+0x182
07 0000003f`6b34f140 00007ff6`a032950b     fuzzer_rust!ZN143_$LT$$LP$Head$C$Tail$RP$$u20$as$u20$libafl..stages..StagesTuple$LT$E$C$EM$C$$LT$Head$u20$as$u20$libafl..state..UsesState$GT$..State$C$Z$GT$$GT$11perform_all17hdb75051193a69926E+0x1a3
08 0000003f`6b34f260 00007ff6`a033ebad     fuzzer_rust!ZN6libafl6fuzzer6Fuzzer9fuzz_loop17h09ad24f54a71ddbdE+0xdb
09 0000003f`6b34f340 00007ff6`a0339396     fuzzer_rust!ZN11fuzzer_rust7harness17h2eb8ce20aca05dbeE+0xb5d
0a 0000003f`6b34fa80 00007ff6`a03492ac     fuzzer_rust!ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h2ffa826a2ea57294E+0x6
0b 0000003f`6b34fab0 00007ff6`a068913e     fuzzer_rust!ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h2be16d2a34723d73E.llvm.10830847702297512092+0xc
0c (Inline Function) --------`--------     fuzzer_rust!core::ops::function::impls::impl$2::call_once+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\core\src\ops\function.rs @ 286] 
0d (Inline Function) --------`--------     fuzzer_rust!std::panicking::try::do_call+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\panicking.rs @ 483] 
0e (Inline Function) --------`--------     fuzzer_rust!std::panicking::try+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\panicking.rs @ 447] 
0f (Inline Function) --------`--------     fuzzer_rust!std::panic::catch_unwind+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\panic.rs @ 137] 
10 (Inline Function) --------`--------     fuzzer_rust!std::rt::lang_start_internal::closure$2+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\rt.rs @ 148] 
11 (Inline Function) --------`--------     fuzzer_rust!std::panicking::try::do_call+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\panicking.rs @ 483] 
12 (Inline Function) --------`--------     fuzzer_rust!std::panicking::try+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\panicking.rs @ 447] 
13 (Inline Function) --------`--------     fuzzer_rust!std::panic::catch_unwind+0xb [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\panic.rs @ 137] 
14 0000003f`6b34fae0 00007ff6`a033f85c     fuzzer_rust!std::rt::lang_start_internal+0xbe [/rustc/b8b5caee04116c7383eb1c6470fcf15c437a60d4/library\std\src\rt.rs @ 148] 
15 0000003f`6b34fc30 00007ff6`a06fb7c8     fuzzer_rust!main+0x2c
16 (Inline Function) --------`--------     fuzzer_rust!invoke_main+0x22 [d:\a01\_work\20\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 
17 0000003f`6b34fc70 00007ffa`85d474b4     fuzzer_rust!__scrt_common_main_seh+0x10c [d:\a01\_work\20\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 
18 0000003f`6b34fcb0 00007ffa`860a26a1     KERNEL32!BaseThreadInitThunk+0x14
19 0000003f`6b34fce0 00000000`00000000     ntdll!RtlUserThreadStart+0x21

tokatoka avatar Nov 22 '22 05:11 tokatoka

I think now I understand why all these problems are happening. I think I got the solution.

So, actually we have 2 separate problems.

  1. windows asan uses access violation exception and exception handler to manage shadow memory (https://github.com/llvm/llvm-project/blob/535c2da58dd2469dc8b8610443b51e5b10867074/compiler-rt/lib/asan/asan_win.cpp#L279) This is why the program built with asan enabled emits many exceptions. But this is not good if we install our exception handler with AddVectoredExceptionHandler(1, ..) because it'll get called twice and our exception handler regards it as "double crash". To fix this, we can AddVectoredExceptionHandler(0, ..)

  2. The process dies after asan prints out the error log, but our crash handler is never called. At first, I thought for some odd reason, our exception handler is not registered. but it turns out the problem is in how asan exits the process after it detects errors. In libafl, when the platform is linux, we use abort_on_error option. This way, asan runtime calls void Abort() (I mean the function from asan runtime). On linux, it simply calls abort() (the libc function), and we can catch sigabrt in our signal handler. Only with this call to void Abort(), can we transfer the execution the fuzzer's signal handler https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp#L131 but on windows, this is simply an TerminateProcess(GetCurrentProcess(), 3) ,so no sigabrt signal, thus we can't really catch this and transfer the rip to the exception handler https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp#L591 https://github.com/llvm/llvm-project/blob/2e999b7dd1934a44d38c3a753460f1e5a217e9a5/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp#L824

So I guess the solution here would be to use this UserDieCallback https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/sanitizer_common/sanitizer_termination.cpp#L52 we can use __sanitizer_set_death_callback to set it. and libfuzzer is using it too https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/fuzzer/FuzzerLoop.cpp#L142

tokatoka avatar Nov 22 '22 08:11 tokatoka

@tokatoka Thank you very much! I will test this asap. That there are 2 issues definitely confirms with my observations! I was slightly confused why the handlers would conflict with each other.

maxammann avatar Nov 22 '22 12:11 maxammann

#908 fixes this issue

tokatoka avatar Nov 25 '22 11:11 tokatoka

@tokatoka thanks so much for the hard work put in here ❤️ much appreciated

Ben-Lichtman avatar Nov 25 '22 18:11 Ben-Lichtman