BIOS path specification and fast snapshot crash in QEMU system mode
I'm learning kernel fuzzing, and I'm writing a simple fuzzer using libafl_qemu under system mode. It's based on the examples in fuzzers/qemu_systemmode, but uses my x86_64 kernel. There are mainly two problems bothering me a lot:
-
I find it difficult to start QEMU. It can't work unless I use
-Loption to specify the path of BIOS files like:bios-256k.bin efi-e1000e.rom kvmvapic.bin multiboot_dma.bin vgabios-stdvga.binIf running with
-L help, it prints:<project_dir>/target/classic/release/../share/qemu-firmware <project_dir>/target/classic/release/../share/qemuBoth of the directories are missing. I wonder if it's expected and I should put the files there, or something goes wrong.
-
If I use fast snapshot in my harness function, QEMU simply crashes due to a failed assertion when processing memory regions. Here's detailed message:
x86-qemu-fuzzer: ../system/memory.c:2639: memory_region_add_subregion_common: Assertion `!subregion->container' failed. [2024-04-14T06:56:22Z ERROR libafl::executors::hooks::unix::unix_signal_handler] Crashed with SIGABRT [2024-04-14T06:56:22Z ERROR libafl::executors::hooks::unix::unix_signal_handler] Child crashed! [2024-04-14T06:56:22Z ERROR libafl::executors::hooks::unix::unix_signal_handler] input: "c8d7426a9255f45b" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CRASH ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Received signal SIGABRT at 0x007f51f12aa00b, fault address: 0x00000000000000 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ REGISTERS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ r8 : 0x00000000000000, r9 : 0x007ffd21062270, r10: 0x00000000000008, r11: 0x00000000000246, r12: 0x0055f517b3ff6c, r13: 0x00000000000a4f, r14: 0x0055f517b4009b, r15: 0x0055f51a5a9000, rdi: 0x00000000000002, rsi: 0x007ffd21062270, rbp: 0x007f51f141f588, rbx: 0x007f51f11efc40, rdx: 0x00000000000000, rax: 0x00000000000000, rcx: 0x007f51f12aa00b, rsp: 0x007ffd21062270, rip: 0x007f51f12aa00b, efl: 0x00000000000246, ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0: libafl_bolts::minibsod::generate_minibsod at /home/patrickli/os/LibAFL/libafl_bolts/src/minibsod.rs:1005:30 1: libafl::executors::hooks::unix::unix_signal_handler::inproc_crash_handler at /home/patrickli/os/LibAFL/libafl/src/executors/hooks/unix.rs:208:32 2: libafl::executors::hooks::unix::unix_signal_handler::<impl libafl_bolts::os::unix_signals::Handler for libafl::executors::hooks::inprocess::InProcessExecutorHandlerData>::handle 3: libafl_bolts::os::unix_signals::handle_signal at /home/patrickli/os/LibAFL/libafl_bolts/src/os/unix_signals.rs:418:5 4: <unknown> 5: __libc_signal_restore_set at /build/glibc-wuryBv/glibc-2.31/signal/../sysdeps/unix/sysv/linux/internal-signals.h:86:3 __GI_raise at /build/glibc-wuryBv/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:48:3 6: __GI_abort at /build/glibc-wuryBv/glibc-2.31/stdlib/abort.c:79:7 7: __assert_fail_base at /build/glibc-wuryBv/glibc-2.31/assert/assert.c:92:3 8: __GI___assert_fail at /build/glibc-wuryBv/glibc-2.31/assert/assert.c:101:3 9: memory_region_add_subregion_common at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../system/memory.c:2639:5 memory_region_add_subregion_common at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../system/memory.c:2633:13 10: ich9_lpc_rcba_update at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../hw/isa/lpc_ich9.c:522:9 ich9_lpc_post_load at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../hw/isa/lpc_ich9.c:548:5 11: vmstate_load_state at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../migration/vmstate.c:186:15 12: qemu_loadvm_section_start_full at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../migration/savevm.c:2592:11 13: qemu_loadvm_state_main at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../migration/savevm.c:2847:19 14: qemu_load_device_state at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../migration/savevm.c:2991:11 15: device_restore_all at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../libafl/syx-snapshot/device-save.c:98:5 16: syx_snapshot_root_restore at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/target/classic/release/qemu-libafl-bridge/build/../libafl/syx-snapshot/syx-snapshot.c:636:5 17: libafl_qemu::emu::systemmode::<impl libafl_qemu::emu::Qemu>::restore_fast_snapshot at /home/patrickli/os/LibAFL/libafl_qemu/src/emu/systemmode.rs:372:18 x86_qemu_fuzzer::fuzzer_classic::fuzz::{{closure}}::{{closure}} at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/src/fuzzer_classic.rs:154:17 18: <libafl::executors::inprocess::GenericInProcessExecutor<H,HB,HT,OT,S> as libafl::executors::Executor<EM,Z>>::run_target at /home/patrickli/os/LibAFL/libafl/src/executors/inprocess/mod.rs:137:19 <libafl_qemu::executor::QemuExecutor<H,OT,QT,S> as libafl::executors::Executor<EM,Z>>::run_target at /home/patrickli/os/LibAFL/libafl_qemu/src/executor/mod.rs:307:29 libafl::fuzzer::StdFuzzer<CS,F,OF,OT>::execute_input at /home/patrickli/os/LibAFL/libafl/src/fuzzer/mod.rs:775:25 <libafl::fuzzer::StdFuzzer<CS,F,OF,OT> as libafl::fuzzer::EvaluatorObservers<OT>>::evaluate_input_with_observers at /home/patrickli/os/LibAFL/libafl/src/fuzzer/mod.rs:541:25 <libafl::fuzzer::StdFuzzer<CS,F,OF,OT> as libafl::fuzzer::Evaluator<E,EM>>::evaluate_input_events at /home/patrickli/os/LibAFL/libafl/src/fuzzer/mod.rs:570:9 libafl::fuzzer::Evaluator::evaluate_input at /home/patrickli/os/LibAFL/libafl/src/fuzzer/mod.rs:144:9 19: libafl::state::StdState<I,C,R,SC>::load_file at /home/patrickli/os/LibAFL/libafl/src/state/mod.rs:688:28 libafl::state::StdState<I,C,R,SC>::continue_loading_initial_inputs_custom at /home/patrickli/os/LibAFL/libafl/src/state/mod.rs:715:21 libafl::state::StdState<I,C,R,SC>::load_initial_inputs at /home/patrickli/os/LibAFL/libafl/src/state/mod.rs:822:9 x86_qemu_fuzzer::fuzzer_classic::fuzz::{{closure}} at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/src/fuzzer_classic.rs:228:13 20: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once at /rustc/2f090c30ddd6b3bbe5c81c087579a5166e7c7278/library/core/src/ops/function.rs:305:13 libafl::events::launcher::Launcher<CF,EMH,MT,S,SP>::launch_with_hooks at /home/patrickli/os/LibAFL/libafl/src/events/launcher.rs:265:32 libafl::events::launcher::Launcher<CF,(),MT,S,SP>::launch at /home/patrickli/os/LibAFL/libafl/src/events/launcher.rs:163:9 x86_qemu_fuzzer::fuzzer_classic::fuzz at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/src/fuzzer_classic.rs:258:11 x86_qemu_fuzzer::main at /home/patrickli/program/fuzzing/x86-qemu-fuzzer/src/main.rs:13:5 21: core::ops::function::FnOnce::call_once at /rustc/2f090c30ddd6b3bbe5c81c087579a5166e7c7278/library/core/src/ops/function.rs:250:5 std::sys_common::backtrace::__rust_begin_short_backtrace at /rustc/2f090c30ddd6b3bbe5c81c087579a5166e7c7278/library/std/src/sys_common/backtrace.rs:155:18 22: main 23: __libc_start_main at /build/glibc-wuryBv/glibc-2.31/csu/../csu/libc-start.c:308:16 24: _startHowever, QEMU vanilla snapshot works fine.
Any help would be greatly appreciated!
I've just tried to use fast snapshotting in a fuzzing context and have encountered nearly the same assertion error: ../system/memory.c:2655: memory_region_add_subregion_common: Assertion `!subregion->container' failed. @nine-point-eight-p, did you ever figure out what was wrong with fast snapshotting, and/or how to fix it?
Also, in case it's useful, there does exist a different system-mode snapshotting mechanism: Qemu::{save,load}_snapshot.