LibAFL icon indicating copy to clipboard operation
LibAFL copied to clipboard

BIOS path specification and fast snapshot crash in QEMU system mode

Open nine-point-eight-p opened this issue 1 year ago • 1 comments

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:

  1. I find it difficult to start QEMU. It can't work unless I use -L option to specify the path of BIOS files like:

    bios-256k.bin
    efi-e1000e.rom
    kvmvapic.bin
    multiboot_dma.bin
    vgabios-stdvga.bin
    

    If running with -L help, it prints:

    <project_dir>/target/classic/release/../share/qemu-firmware
    <project_dir>/target/classic/release/../share/qemu
    

    Both of the directories are missing. I wonder if it's expected and I should put the files there, or something goes wrong.

  2. 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: _start
    

    However, QEMU vanilla snapshot works fine.

Any help would be greatly appreciated!

nine-point-eight-p avatar Apr 14 '24 07:04 nine-point-eight-p

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.

samcowger avatar Oct 18 '24 21:10 samcowger