LibAFL
LibAFL copied to clipboard
LibAFL Incorrectly classifying crashes on MSVC
Describe the bug LibAFL on MSVC is marking discovered crashes as fuzzer crashes instead of target crashes.
To Reproduce Steps to reproduce the behavior:
- Download the included project file
- Open it with your MSVC developer powershell
- run
./build_libafl.ps1
- optionally changing the position of sancov.lib within -
cd fuzzer_rust
-
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
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.
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
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
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?
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).
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
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,
- 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.
- 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.)
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
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.
Can't we hook ASans exception behavior, maybe?
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?
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?
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
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
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 :)
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.
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.
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
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.
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
I think now I understand why all these problems are happening. I think I got the solution.
So, actually we have 2 separate problems.
-
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 canAddVectoredExceptionHandler(0, ..)
-
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 tovoid 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 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.
#908 fixes this issue
@tokatoka thanks so much for the hard work put in here ❤️ much appreciated