AFLplusplus / AFLplusplus/LibAFL

Full system qemu baremetal for riscv

Đang mở
#3,100 4 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Rust
Star
2.6k
Fork
481
Merge trung bình
2 ngày 30 phút
Pull request đã merge (30 ngày)
16

Mô tả

# Description
I am trying to fuzz the riscv32 baremetal program in qemu full system emulation mode in LibAFL. Currently, I have made following changes to the given Arm example accordingly to match with riscv.
- Changed the `Cargo.toml` file to install qemu riscv32 version.
- Changed the `Justfile` to modify the gcc toolchain for riscv32 and to modify the qemu machine to `sifive_e`
- Then I made changes to the linker file according to `sifive_e` machine.

I was able to successfully build the environment (`just build`). However, when running the fuzzer(`just run`), I am getting following error.
```afluser@860c6ff8fa77:/workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32$ just run
mkdir -p "/workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target"
qemu-img create -f qcow2 /workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target/dummy.qcow2 32M
Formatting '/workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target/dummy.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=33554432 lazy_refcounts=off refcount_bits=16
riscv32-unknown-elf-gcc -ggdb -ffreestanding -nostartfiles -lgcc -T example/sifive_e.ld -D "TARGET_BREAKPOINT" -I /workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target/release/include example/main.c example/startup.c -o /workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target/example.elf
cargo build --profile release --no-default-features --features std,breakpoint --target-dir /workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target
Finished `release` profile [optimized + debuginfo] target(s) in 0.11s
/workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target/release/qemu_baremetal -icount shift=auto,align=off,sleep=off -machine sifive_e -monitor null -kernel /workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target/example.elf -drive if=none,format=qcow2,file=/workspaces/wolfboot-fuzzer/LibAFL/fuzzers/full_system/qemu_riscv32/target/dummy.qcow2 -serial null -nographic -snapshot -S
FUZZ_INPUT @ 0x80000000
main address = 0x20010306
Breakpoint address = 0x20010200
Devices = ["timer", "cpu_common", "cpu", "riscv_sifive_plic", "riscv_mtimer", "sifive_soc.gpio", "riscv.sifive.uart", "riscv.sifive.uart"]
[Objective #1] (GLOBAL) run time: 0h-0m-3s, clients: 1, corpus: 0, objectives: 1, executions: 0, exec/sec: 0.000
(CLIENT) corpus: 0, objectives: 1, executions: 0, exec/sec: 0.000
We imported 0 inputs from disk.

thread 'main' panicked at src/fuzzer_breakpoint.rs:217:14:
called `Result::unwrap()` on an `Err` value: Empty("No entries in corpus. This often implies the target is not properly instrumented.", ErrorBacktrace)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
[Objective #1] (GLOBAL) run time: 0h-0m-6s, clients: 1, corpus: 0, objectives: 2, executions: 0, exec/sec: 0.000
(CLIENT) corpus: 0, objectives: 2, executions: 0, exec/sec: 0.000

thread 'main' panicked at /workspaces/wolfboot-fuzzer/LibAFL/libafl/src/events/llmp/restarting.rs:886:21:
Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client! This can happen if the child calls `exit()`, in that case make sure it uses `abort()`, if it got killed unrecoverable (OOM), or if there is a bug in the fuzzer itself. (Child exited with: 101)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Fuzzing stopped by user. Good bye.
```
## Questions
1. It seems like the problem is with the initial corpus. As stated in the above output, it could not import corpus. I copied the corpus directory from the qemu_baremetal example. I am having a problem understanding the corpus directory. Do I need to create a new corpus for my version?
2. I have gone through the README file in the example directory to understand the fuzzing flow. However, I still do not have an idea of how exactly full system fuzzing is achieved in LibAFL. Can you give me a brief explanation on this work?

## Modified files
`Cargo.toml`
```
[package]
name = "qemu_baremetal"
version = "0.15.1"
authors = [
"Andrea Fioraldi ",
"Dominik Maier ",
"Romain Malmain ",
]
edition = "2021"

[features]
default = ["std", "low_level"]
std = []

low_level = [
] # The low-level way to interact with LibAFL QEMU, with direct calls to QEMU's functions
breakpoint = [] # Uses the command system, with breakpoints
sync_exit = [] # Uses the command system, with sync exit.

shared = ["libafl_qemu/shared"]

[profile.release]
incremental = true
debug = true
lto = "fat"
codegen-units = 1

[dependencies]
libafl = { path = "../../../libafl" }
libafl_bolts = { path = "../../../libafl_bolts" }
libafl_targets = { path = "../../../libafl_targets" }
libafl_qemu = { path = "../../../libafl_qemu", features = [
"riscv32",
"systemmode",
], default-features = false }
env_logger = "0.11.5"
log = { version = "0.4.22", features = ["release_max_level_info"] }

[build-dependencies]
libafl_qemu_build = { path = "../../../libafl_qemu/libafl_qemu_build" }
```

`Justfile`
```import "../../../just/libafl-qemu.just"
FUZZER_NAME := "qemu_baremetal"

KERNEL := TARGET_DIR / "example.elf"
DUMMY_IMG := TARGET_DIR / "dummy.qcow2"

target_dir:
mkdir -p "{{TARGET_DIR}}"

image: target_dir
qemu-img create -f qcow2 {{DUMMY_IMG}} 32M

target flavor: image target_dir
riscv32-unknown-elf-gcc -ggdb -ffreestanding -nostartfiles -lgcc \
-T example/sifive_e.ld \
-D "TARGET_{{ uppercase(flavor) }}" \
-I {{BUILD_DIR / "include"}} \
example/main.c \
example/startup.c \
-o {{TARGET_DIR}}/example.elf

build flavor="breakpoint": target_dir
cargo build \
--profile {{PROFILE}} \
--no-default-features \
--features std,{{flavor}} \
--target-dir {{TARGET_DIR}}

run flavor="breakpoint": (target flavor) (build flavor)
{{BUILD_DIR / "qemu_baremetal"}} \
-icount shift=auto,align=off,sleep=off \
-machine sifive_e \
-monitor null \
-kernel {{KERNEL}} \
-drive if=none,format=qcow2,file={{DUMMY_IMG}} \
-serial null \
-nographic \
-snapshot \
-S

test_flavor flavor: (target flavor) (build flavor)
#!/bin/bash
export KERNEL={{ KERNEL }}
export TARGET_DIR={{ TARGET_DIR }}

TMP_DIR=$(mktemp -d)

timeout 20s {{ FUZZER }} \
-icount shift=auto,align=off,sleep=off \
-machine sifive_e \
-monitor null \
-kernel {{ KERNEL }} -serial null \
-drive if=none,format=qcow2,file={{ DUMMY_IMG }} \
-nographic \
-snapshot \
-S | tee "$TMP_DIR/fuzz.log" 2>&1 || true

if [ -z "$(grep 'Objective' $TMP_DIR/fuzz.log)" ]; then
echo "qemu_baremetal ${FEATURE}: Fuzzer did not find the objective in $TMP_DIR/fuzz.log"
exit 1
else
echo "qemu_baremetal ${FEATURE}: Objective found."
fi

test: (test_flavor "low_level") (test_flavor "breakpoint") (test_flavor "sync_exit")

clean:
cargo clean
```
Linker File
```
OUTPUT_ARCH( "riscv" )

ENTRY( _reset )

MEMORY
{
FLASH(rxai!w) : ORIGIN = 0x20010000, LENGTH = 65536
RAM(wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K
}

SECTIONS
{
.text :
{
_start_text = .;
KEEP(*(.init)) /* Only for _reset, relocates IV to 0x200 */
. = ORIGIN(FLASH) + 0x200;
_start_vector = .;
KEEP(*(.isr_vector))
*(.text*)
*(.rodata*)
*(.srodata*)
. = ALIGN(4);
_end_text = .;
} > FLASH

_stored_data = .;

.data : AT (_stored_data)
{
. = ALIGN(4096);
_start_data = .;
KEEP(*(.ramcode*))
. = ALIGN(4);
*(.data*)
. = ALIGN(4);
_global_pointer = . + 0x800;
*(.sdata*)
. = ALIGN(4);
_end_data = .;
} > RAM

.bss (NOLOAD) :
{
_start_bss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_end_bss = .;
_end = .;
} > RAM

}

PROVIDE(_start_heap = _end);
PROVIDE(_end_stack = ORIGIN(RAM) + (LENGTH(RAM)) );
```
`startup.c`
```c
extern void main(void);
typedef unsigned int uint32_t;
extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss;
__attribute__((optimize("O0"))) __attribute__((naked)) void _reset(void) {
/* jump to board initialisation */
void _start(void);
_start();
}

void _start(void) {
main();
}
```

Thank you for your time.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.