-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial honggfuzz fuzzing infrastructure
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
1 parent
11d19de
commit 7f5c043
Showing
22 changed files
with
256 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/hfuzz_target/ | ||
HONGGFUZZ.REPORT.TXT | ||
*.honggfuzz.cov | ||
*.fuzz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/vbmeta_appended_hash.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/vbmeta_appended_hash_tree.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/vbmeta_root.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/boot_v0.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/boot_v1.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/boot_v2.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/boot_v3.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/boot_v4.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/boot_v4_vts.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/vendor_v3.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../avbroot/tests/data/vendor_v4.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 Andrew Gunnerson | ||
* SPDX-License-Identifier: GPL-3.0-only | ||
*/ | ||
|
||
use std::{env, fs, path::Path, process::Command}; | ||
|
||
use anyhow::{anyhow, bail, Result}; | ||
use clap::Parser; | ||
use toml_edit::Document; | ||
|
||
use crate::WORKSPACE_DIR; | ||
|
||
fn get_members() -> Result<Vec<String>> { | ||
let path = Path::new(WORKSPACE_DIR).join("Cargo.toml"); | ||
let data = fs::read_to_string(&path)?; | ||
|
||
let document: Document = data.parse()?; | ||
let members = document["workspace"]["members"] | ||
.as_array() | ||
.ok_or_else(|| anyhow!("Cargo.toml has no workspace members"))?; | ||
|
||
let mut result = vec![]; | ||
|
||
for member in members { | ||
let member = member | ||
.as_str() | ||
.ok_or_else(|| anyhow!("Member is not a string: {member:?}"))?; | ||
|
||
result.push(member.to_owned()); | ||
} | ||
|
||
Ok(result) | ||
} | ||
|
||
pub fn wswrap_subcommand(cli: &WswrapCli) -> Result<()> { | ||
let cargo = env::var_os("CARGO").ok_or_else(|| anyhow!("CARGO is not set"))?; | ||
let members = get_members()?; | ||
|
||
let mut command = Command::new(cargo); | ||
command.args(&cli.args); | ||
|
||
for member in members { | ||
#[cfg(windows)] | ||
if member == "fuzz" { | ||
continue; | ||
} | ||
|
||
command.arg("-p"); | ||
command.arg(member); | ||
} | ||
|
||
if cli.verbose { | ||
eprintln!("Running: {command:?}"); | ||
} | ||
|
||
let mut child = command.spawn()?; | ||
let status = child.wait()?; | ||
|
||
if !status.success() { | ||
bail!("{command:?} failed with {status}"); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Run a Cargo command against all workspace members compatible with the target | ||
/// platform. | ||
/// | ||
/// This is meant to replace the use of `cargo <subcommand> --workspace`. This | ||
/// currently only filters out the `fuzz` member on Windows. | ||
#[derive(Debug, Parser)] | ||
pub struct WswrapCli { | ||
/// Display command before running. | ||
#[arg(short, long)] | ||
verbose: bool, | ||
|
||
/// Full Cargo command. | ||
args: Vec<String>, | ||
} |