Skip to content

Commit

Permalink
Add initial honggfuzz fuzzing infrastructure
Browse files Browse the repository at this point in the history
This initially includes fuzzers for the AVB and boot image parsers. The
initial input corpus are the same test files we use for the round trip
tests.

Issue: #160

Signed-off-by: Andrew Gunnerson <[email protected]>
  • Loading branch information
chenxiaolong committed Sep 27, 2023
1 parent 11d19de commit de9b70f
Show file tree
Hide file tree
Showing 18 changed files with 158 additions and 1 deletion.
50 changes: 50 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
default-members = ["avbroot"]
members = ["avbroot", "e2e", "xtask"]
members = ["avbroot", "e2e", "fuzz", "xtask"]
resolver = "2"

[workspace.package]
Expand Down
4 changes: 4 additions & 0 deletions fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/hfuzz_target/
HONGGFUZZ.REPORT.TXT
*.honggfuzz.cov
*.fuzz
13 changes: 13 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "fuzz"
version.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
avbroot = { path = "../avbroot" }
honggfuzz = "0.5.55"
53 changes: 53 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Fuzzing

While avbroot's parsers are all memory-safe, it is still possible for panics or crashes to occur, for example due to excessive memory allocation, integer overflow, or division by zero. Fuzzing helps to identify these issues by randomizing inputs in a way that tries to increase code coverage.

## Running the fuzzers

1. Install the cargo honggfuzz commands.

```bash
cargo install honggfuzz
```

2. Pick a fuzz target to run. A fuzz target is the name of the source file in [`src/bin/`](./src/bin) without the `.rs` extension.

The list of targets can be queried programmatically with:

```bash
cargo read-manifest | jq -r '.targets[].name'
```

3. Run the fuzzer.

```bash
cargo hfuzz run <fuzz target>
```

This will run forever until it is manually killed. At the top of the screen, a summary section like the following is shown:

```
Iterations : 31,243 [31.24k]
Mode [1/3] : Feedback Driven Dry Run [2486/4085]
Target : hfuzz_target/x86_64-unknown-linux-gnu/release/bootimage
Threads : 8, CPUs: 16, CPU%: 800% [50%/CPU]
Speed : 36,126/sec [avg: 31,243]
Crashes : 53 [unique: 1, blocklist: 0, verified: 0]
Timeouts : 0 [1 sec]
Corpus Size : 1,424, max: 24,576 bytes, init: 4,085 files
Cov Update : 0 days 00 hrs 00 mins 00 secs ago
Coverage : edge: 897/224,621 [0%] pc: 2 cmp: 34,736
```

When a crash occurs, the `Crashes` counter will increment and the input data that triggered the crash will be written to `hfuzz_workspace/<fuzz target>/*.fuzz`. New files are only written for unique crashes.

4. If a crash occurs, run the following command to trigger the crash in a debugger.

```bash
cargo hfuzz run-debug <fuzz target> \
hfuzz_workspace/<fuzz_target>/<input file>.fuzz
```

This defaults to using `rust-lldb`. To use `rust-gdb` instead, set the `HFUZZ_DEBUGGER` environment variable to `rust-gdb`.

Alternatively, just feed the input file to the appropriate avbroot command directly (eg. `avbroot boot info -i hfuzz_workspace/<fuzz_target>/<input file>.fuzz` for boot images).
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/avb/input/vbmeta_appended_hash.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/avb/input/vbmeta_root.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/boot_v0.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/boot_v1.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/boot_v2.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/boot_v3.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/boot_v4.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/boot_v4_vts.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/vendor_v3.img
1 change: 1 addition & 0 deletions fuzz/hfuzz_workspace/bootimage/input/vendor_v4.img
13 changes: 13 additions & 0 deletions fuzz/src/bin/avb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::io::Cursor;

use avbroot::format::avb;
use honggfuzz::fuzz;

fn main() {
loop {
fuzz!(|data: &[u8]| {
let reader = Cursor::new(data);
let _ = avb::load_image(reader);
});
}
}
13 changes: 13 additions & 0 deletions fuzz/src/bin/bootimage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::io::Cursor;

use avbroot::{format::bootimage::BootImage, stream::FromReader};
use honggfuzz::fuzz;

fn main() {
loop {
fuzz!(|data: &[u8]| {
let reader = Cursor::new(data);
let _ = BootImage::from_reader(reader);
});
}
}

0 comments on commit de9b70f

Please sign in to comment.