Skip to content

Commit 89876f2

Browse files
authored
Use listings for baby_fuzzer book chapter (#1289)
* Clarify setup steps for the baby fuzzer Specifically: - Explicitly mention that the dependency path must point to a specific directory in the cloned repo (and not the root directory) - Explicitly mention how to manually trigger the panic in the harness for testing purposes * Clean up documentation on the baby fuzzer Since the baby fuzzer chapter of the documentation is done in a "tutorial", step-by-step fashion, it would be nice to be able to see where exactly new lines have to be placed in the existing code. To that end, the code used in the tutorial is moved to snippets (as is done in the Rust Book), as it allows for much more convenient maintenance of the snippets, as well as easy hiding of the non-important code on any given snippet. Furthermore, a few minor fixes are applied; a typo on a comment and a missing unsafe block. * Fix code snippet attributes for baby fuzzer Specifically: - Remove unnecessary `compile_fail` attribute - Add `ignore` attribute to the snippets of the complete baby fuzzer. As explained in [#1290], it is expected for the baby fuzzer to return a non-0 exit code, so this should not trigger a failure during `mdbook test`. * Fix CLI snippet language For CLI snippets, the "language" should be set to `console`. * Remove nested safe block in baby_fuzzer listings
1 parent 5a6d683 commit 89876f2

File tree

14 files changed

+522
-210
lines changed

14 files changed

+522
-210
lines changed

docs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
book
2+
!listings/**/*
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "baby_fuzzer"
3+
version = "0.1.0"
4+
authors = ["Your Name <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("Hello, world!");
3+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "baby_fuzzer"
3+
version = "0.1.0"
4+
authors = ["Your Name <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
libafl = { path = "path/to/libafl/" }
11+
12+
[profile.dev]
13+
panic = "abort"
14+
15+
[profile.release]
16+
panic = "abort"
17+
lto = true
18+
codegen-units = 1
19+
opt-level = 3
20+
debug = true
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("Hello, world!");
3+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "baby_fuzzer"
3+
version = "0.1.0"
4+
authors = ["Your Name <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
libafl = { path = "path/to/libafl/" }
11+
12+
[profile.dev]
13+
panic = "abort"
14+
15+
[profile.release]
16+
panic = "abort"
17+
lto = true
18+
codegen-units = 1
19+
opt-level = 3
20+
debug = true
21+
22+
[features]
23+
panic = []
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
extern crate libafl;
2+
use libafl::{
3+
bolts::AsSlice,
4+
executors::ExitKind,
5+
inputs::{BytesInput, HasTargetBytes},
6+
};
7+
8+
fn main() {
9+
let mut harness = |input: &BytesInput| {
10+
let target = input.target_bytes();
11+
let buf = target.as_slice();
12+
if buf.len() > 0 && buf[0] == 'a' as u8 {
13+
if buf.len() > 1 && buf[1] == 'b' as u8 {
14+
if buf.len() > 2 && buf[2] == 'c' as u8 {
15+
panic!("=)");
16+
}
17+
}
18+
}
19+
ExitKind::Ok
20+
};
21+
// To test the panic:
22+
let input = BytesInput::new(Vec::from("abc"));
23+
#[cfg(feature = "panic")]
24+
harness(&input);
25+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "baby_fuzzer"
3+
version = "0.1.0"
4+
authors = ["Your Name <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
libafl = { path = "path/to/libafl/" }
11+
12+
[profile.dev]
13+
panic = "abort"
14+
15+
[profile.release]
16+
panic = "abort"
17+
lto = true
18+
codegen-units = 1
19+
opt-level = 3
20+
debug = true
21+
22+
[features]
23+
panic = []
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/* ANCHOR: use */
2+
extern crate libafl;
3+
4+
use libafl::{
5+
bolts::{current_nanos, rands::StdRand, AsSlice},
6+
corpus::{InMemoryCorpus, OnDiskCorpus},
7+
events::SimpleEventManager,
8+
executors::{inprocess::InProcessExecutor, ExitKind},
9+
fuzzer::StdFuzzer,
10+
generators::RandPrintablesGenerator,
11+
inputs::{BytesInput, HasTargetBytes},
12+
monitors::SimpleMonitor,
13+
schedulers::QueueScheduler,
14+
state::StdState,
15+
};
16+
use std::path::PathBuf;
17+
/* ANCHOR_END: use */
18+
19+
fn main() {
20+
let mut harness = |input: &BytesInput| {
21+
let target = input.target_bytes();
22+
let buf = target.as_slice();
23+
if buf.len() > 0 && buf[0] == 'a' as u8 {
24+
if buf.len() > 1 && buf[1] == 'b' as u8 {
25+
if buf.len() > 2 && buf[2] == 'c' as u8 {
26+
panic!("=)");
27+
}
28+
}
29+
}
30+
ExitKind::Ok
31+
};
32+
// To test the panic:
33+
let input = BytesInput::new(Vec::from("abc"));
34+
#[cfg(feature = "panic")]
35+
harness(&input);
36+
37+
/* ANCHOR: state */
38+
// create a State from scratch
39+
let mut state = StdState::new(
40+
// RNG
41+
StdRand::with_seed(current_nanos()),
42+
// Corpus that will be evolved, we keep it in memory for performance
43+
InMemoryCorpus::new(),
44+
// Corpus in which we store solutions (crashes in this example),
45+
// on disk so the user can get them after stopping the fuzzer
46+
OnDiskCorpus::new(PathBuf::from("./crashes")).unwrap(),
47+
&mut (),
48+
&mut (),
49+
)
50+
.unwrap();
51+
/* ANCHOR_END: state */
52+
53+
/* ANCHOR: event_manager */
54+
// The Monitor trait defines how the fuzzer stats are displayed to the user
55+
let mon = SimpleMonitor::new(|s| println!("{s}"));
56+
57+
// The event manager handles the various events generated during the fuzzing loop
58+
// such as the notification of the addition of a new item to the corpus
59+
let mut mgr = SimpleEventManager::new(mon);
60+
/* ANCHOR_END: event_manager */
61+
62+
/* ANCHOR: scheduler_fuzzer */
63+
// A queue policy to get testcasess from the corpus
64+
let scheduler = QueueScheduler::new();
65+
66+
// A fuzzer with feedbacks and a corpus scheduler
67+
let mut fuzzer = StdFuzzer::new(scheduler, (), ());
68+
/* ANCHOR_END: scheduler_fuzzer */
69+
70+
/* ANCHOR: executor */
71+
// Create the executor for an in-process function
72+
let mut executor = InProcessExecutor::new(&mut harness, (), &mut fuzzer, &mut state, &mut mgr)
73+
.expect("Failed to create the Executor");
74+
/* ANCHOR_END: executor */
75+
76+
/* ANCHOR: generator */
77+
// Generator of printable bytearrays of max size 32
78+
let mut generator = RandPrintablesGenerator::new(32);
79+
80+
// Generate 8 initial inputs
81+
state
82+
.generate_initial_inputs(&mut fuzzer, &mut executor, &mut generator, &mut mgr, 8)
83+
.expect("Failed to generate the initial corpus");
84+
/* ANCHOR_END: generator */
85+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "baby_fuzzer"
3+
version = "0.1.0"
4+
authors = ["Your Name <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
libafl = { path = "path/to/libafl/" }
11+
12+
[profile.dev]
13+
panic = "abort"
14+
15+
[profile.release]
16+
panic = "abort"
17+
lto = true
18+
codegen-units = 1
19+
opt-level = 3
20+
debug = true
21+
22+
[features]
23+
panic = []

0 commit comments

Comments
 (0)