Skip to content

Commit bfa3fff

Browse files
Observers lifetime (#89)
* introduce MatchName and alow lifetimes in observers * adapt fuzzers to observers with lifetime * introduce type_eq when on nightly * fix no_std * fmt
1 parent 08a32c3 commit bfa3fff

File tree

16 files changed

+193
-129
lines changed

16 files changed

+193
-129
lines changed

fuzzers/baby_fuzzer/src/main.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,8 @@ pub fn main() {
4646
// such as the notification of the addition of a new item to the corpus
4747
let mut mgr = SimpleEventManager::new(stats);
4848

49-
// Create an observation channel using the siganls map
50-
let observer =
51-
StdMapObserver::new("signals", unsafe { &mut SIGNALS }, unsafe { SIGNALS.len() });
49+
// Create an observation channel using the signals map
50+
let observer = StdMapObserver::new("signals", unsafe { &mut SIGNALS });
5251

5352
// create a State from scratch
5453
let mut state = State::new(
@@ -76,13 +75,9 @@ pub fn main() {
7675
let scheduler = QueueCorpusScheduler::new();
7776

7877
// Create the executor for an in-process function with just one observer
79-
let mut executor = InProcessExecutor::new(
80-
&mut harness,
81-
tuple_list!(observer),
82-
&mut state,
83-
&mut mgr,
84-
)
85-
.expect("Failed to create the Executor".into());
78+
let mut executor =
79+
InProcessExecutor::new(&mut harness, tuple_list!(observer), &mut state, &mut mgr)
80+
.expect("Failed to create the Executor".into());
8681

8782
// Generator of printable bytearrays of max size 32
8883
let mut generator = RandPrintablesGenerator::new(32);

fuzzers/frida_libpng/src/fuzzer.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,8 @@ unsafe fn fuzz(
258258
};
259259

260260
let frida_options = FridaOptions::parse_env_options();
261-
let mut frida_helper = FridaInstrumentationHelper::new(
262-
&gum,
263-
&frida_options,
264-
module_name,
265-
&modules_to_instrument,
266-
);
261+
let mut frida_helper =
262+
FridaInstrumentationHelper::new(&gum, &frida_options, module_name, &modules_to_instrument);
267263

268264
// Create an observation channel using the coverage map
269265
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new_from_ptr(

fuzzers/libfuzzer_libmozjpeg/src/lib.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use libafl::{
2222
};
2323

2424
use libafl_targets::{
25-
libfuzzer_initialize, libfuzzer_test_one_input, CMP_MAP, CMP_MAP_SIZE, EDGES_MAP, MAX_EDGES_NUM,
25+
libfuzzer_initialize, libfuzzer_test_one_input, CMP_MAP, EDGES_MAP, MAX_EDGES_NUM,
2626
};
2727

2828
const ALLOC_MAP_SIZE: usize = 16 * 1024;
@@ -59,15 +59,14 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
5959
setup_restarting_mgr_std(stats, broker_port).expect("Failed to setup the restarter".into());
6060

6161
// Create an observation channel using the coverage map
62-
let edges_observer =
63-
StdMapObserver::new("edges", unsafe { &mut EDGES_MAP }, unsafe { MAX_EDGES_NUM });
62+
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] };
63+
let edges_observer = StdMapObserver::new("edges", edges);
6464

6565
// Create an observation channel using the cmp map
66-
let cmps_observer = StdMapObserver::new("cmps", unsafe { &mut CMP_MAP }, CMP_MAP_SIZE);
66+
let cmps_observer = StdMapObserver::new("cmps", unsafe { &mut CMP_MAP });
6767

6868
// Create an observation channel using the allocations map
69-
let allocs_observer =
70-
StdMapObserver::new("allocs", unsafe { &mut libafl_alloc_map }, ALLOC_MAP_SIZE);
69+
let allocs_observer = StdMapObserver::new("allocs", unsafe { &mut libafl_alloc_map });
7170

7271
// If not restarting, create a State from scratch
7372
let mut state = state.unwrap_or_else(|| {

fuzzers/libfuzzer_libpng/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,13 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
6363
}
6464
},
6565
};
66-
66+
6767
// Create an observation channel using the coverage map
68-
let edges_observer = HitcountsMapObserver::new(unsafe {
69-
StdMapObserver::new("edges", &mut EDGES_MAP, MAX_EDGES_NUM)
70-
});
68+
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] };
69+
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
70+
71+
// Create an observation channel to keep track of the execution time
72+
let time_observer = TimeObserver::new("time");
7173

7274
// If not restarting, create a State from scratch
7375
let mut state = state.unwrap_or_else(|| {
@@ -79,7 +81,7 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
7981
// Feedbacks to rate the interestingness of an input
8082
feedback_or!(
8183
MaxMapFeedback::new_with_observer_track(&edges_observer, true, false),
82-
TimeFeedback::new()
84+
TimeFeedback::new_with_observer(&time_observer)
8385
),
8486
// Corpus in which we store solutions (crashes in this example),
8587
// on disk so the user can get them after stopping the fuzzer
@@ -122,7 +124,7 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
122124
let mut executor = TimeoutExecutor::new(
123125
InProcessExecutor::new(
124126
&mut harness,
125-
tuple_list!(edges_observer, TimeObserver::new("time")),
127+
tuple_list!(edges_observer, time_observer),
126128
&mut state,
127129
&mut restarting_mgr,
128130
)?,

fuzzers/libfuzzer_reachability/src/lib.rs

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,28 @@
11
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
22
//! The example harness is built for libpng.
33
4-
use core::time::Duration;
54
use std::{env, path::PathBuf};
65

76
use libafl::{
87
bolts::tuples::tuple_list,
9-
corpus::{
10-
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
11-
QueueCorpusScheduler,
12-
},
8+
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler},
139
events::{setup_restarting_mgr_std, EventManager},
14-
executors::{inprocess::InProcessExecutor, ExitKind, TimeoutExecutor},
15-
feedback_or,
16-
feedbacks::{
17-
CrashFeedback, MaxMapFeedback, ReachabilityFeedback, TimeFeedback, TimeoutFeedback,
18-
},
10+
executors::{inprocess::InProcessExecutor, ExitKind},
11+
feedbacks::{MaxMapFeedback, ReachabilityFeedback},
1912
fuzzer::{Fuzzer, StdFuzzer},
2013
mutators::scheduled::{havoc_mutations, StdScheduledMutator},
2114
mutators::token_mutations::Tokens,
22-
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
15+
observers::{HitcountsMapObserver, StdMapObserver},
2316
stages::mutational::StdMutationalStage,
2417
state::{HasCorpus, HasMetadata, State},
2518
stats::SimpleStats,
2619
utils::{current_nanos, StdRand},
2720
Error,
2821
};
29-
3022
use libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM};
3123

32-
#[cfg(unix)]
3324
const TARGET_SIZE: usize = 4;
3425

35-
#[cfg(unix)]
3626
extern "C" {
3727
static __libafl_target_list: *mut usize;
3828
}
@@ -75,12 +65,12 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
7565
};
7666

7767
// Create an observation channel using the coverage map
78-
let edges_observer = HitcountsMapObserver::new(unsafe {
79-
StdMapObserver::new("edges", &mut EDGES_MAP, MAX_EDGES_NUM)
80-
});
68+
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] };
69+
let edges_observer = HitcountsMapObserver::new(StdMapObserver::new("edges", edges));
8170

8271
let reachability_observer =
8372
unsafe { StdMapObserver::new_from_ptr("png.c", __libafl_target_list, TARGET_SIZE) };
73+
8474
// If not restarting, create a State from scratch
8575
let mut state = state.unwrap_or_else(|| {
8676
State::new(
@@ -89,19 +79,12 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
8979
// Corpus that will be evolved, we keep it in memory for performance
9080
InMemoryCorpus::new(),
9181
// Feedbacks to rate the interestingness of an input
92-
feedback_or!(
93-
MaxMapFeedback::new_with_observer_track(&edges_observer, true, false),
94-
TimeFeedback::new()
95-
),
82+
MaxMapFeedback::new_with_observer_track(&edges_observer, true, false),
9683
// Corpus in which we store solutions (crashes in this example),
9784
// on disk so the user can get them after stopping the fuzzer
9885
OnDiskCorpus::new(objective_dir).unwrap(),
9986
// Feedbacks to recognize an input as solution
100-
feedback_or!(
101-
CrashFeedback::new(),
102-
TimeoutFeedback::new(),
103-
ReachabilityFeedback::new_with_observer(&reachability_observer)
104-
),
87+
ReachabilityFeedback::new_with_observer(&reachability_observer),
10588
)
10689
});
10790

@@ -125,8 +108,8 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
125108
// A fuzzer with just one stage
126109
let mut fuzzer = StdFuzzer::new(tuple_list!(stage));
127110

128-
// A minimization+queue policy to get testcasess from the corpus
129-
let scheduler = IndexesLenTimeMinimizerCorpusScheduler::new(QueueCorpusScheduler::new());
111+
// A random policy to get testcasess from the corpus
112+
let scheduler = RandCorpusScheduler::new();
130113

131114
// The wrapped harness function, calling out to the LLVM-style harness
132115
let mut harness = |buf: &[u8]| {
@@ -135,20 +118,12 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
135118
};
136119

137120
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
138-
let mut executor = TimeoutExecutor::new(
139-
InProcessExecutor::new(
140-
&mut harness,
141-
tuple_list!(
142-
edges_observer,
143-
reachability_observer,
144-
TimeObserver::new("time")
145-
),
146-
&mut state,
147-
&mut restarting_mgr,
148-
)?,
149-
// 10 seconds timeout
150-
Duration::new(10, 0),
151-
);
121+
let mut executor = InProcessExecutor::new(
122+
&mut harness,
123+
tuple_list!(edges_observer, reachability_observer,),
124+
&mut state,
125+
&mut restarting_mgr,
126+
)?;
152127

153128
// The actual target run starts here.
154129
// Call LLVMFUzzerInitialize() if present.

fuzzers/libfuzzer_stb_image/src/main.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,11 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
6363

6464
// Create an observation channel using the coverage map
6565
// We don't use the hitcounts (see the Cargo.toml, we use pcguard_edges)
66-
let edges_observer =
67-
StdMapObserver::new("edges", unsafe { &mut EDGES_MAP }, unsafe { MAX_EDGES_NUM });
66+
let edges = unsafe { &mut EDGES_MAP[0..MAX_EDGES_NUM] };
67+
let edges_observer = StdMapObserver::new("edges", edges);
68+
69+
// Create an observation channel to keep track of the execution time
70+
let time_observer = TimeObserver::new("time");
6871

6972
// If not restarting, create a State from scratch
7073
let mut state = state.unwrap_or_else(|| {
@@ -76,7 +79,7 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
7679
// Feedbacks to rate the interestingness of an input
7780
feedback_or!(
7881
MaxMapFeedback::new_with_observer_track(&edges_observer, true, false),
79-
TimeFeedback::new()
82+
TimeFeedback::new_with_observer(&time_observer)
8083
),
8184
// Corpus in which we store solutions (crashes in this example),
8285
// on disk so the user can get them after stopping the fuzzer
@@ -118,7 +121,7 @@ fn fuzz(corpus_dirs: Vec<PathBuf>, objective_dir: PathBuf, broker_port: u16) ->
118121
// Create the executor for an in-process function with just one observer for edge coverage
119122
let mut executor = InProcessExecutor::new(
120123
&mut harness,
121-
tuple_list!(edges_observer, TimeObserver::new("time")),
124+
tuple_list!(edges_observer, time_observer),
122125
&mut state,
123126
&mut restarting_mgr,
124127
)?;

libafl/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ keywords = ["fuzzing", "testing", "security"]
1010
edition = "2018"
1111
build = "build.rs"
1212

13-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13+
[build-dependencies]
14+
rustc_version = "0.3.3"
1415

1516
[dev-dependencies]
1617
criterion = "0.3" # Benchmarking

libafl/build.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! special handling to build and link libafl
22
3+
use rustc_version::{version_meta, Channel};
4+
35
fn main() {
46
#[cfg(target_os = "windows")]
57
windows::build!(
@@ -9,4 +11,20 @@ fn main() {
911
windows::win32::system_services::{CreateFileMappingA, OpenFileMappingA, MapViewOfFile, UnmapViewOfFile},
1012
windows::win32::debug::{SetUnhandledExceptionFilter, EXCEPTION_POINTERS, EXCEPTION_RECORD, LPTOP_LEVEL_EXCEPTION_FILTER}
1113
);
14+
15+
// Set cfg flags depending on release channel
16+
match version_meta().unwrap().channel {
17+
Channel::Stable => {
18+
println!("cargo:rustc-cfg=RUSTC_IS_STABLE");
19+
}
20+
Channel::Beta => {
21+
println!("cargo:rustc-cfg=RUSTC_IS_BETA");
22+
}
23+
Channel::Nightly => {
24+
println!("cargo:rustc-cfg=RUSTC_IS_NIGHTLY");
25+
}
26+
Channel::Dev => {
27+
println!("cargo:rustc-cfg=RUSTC_IS_DEV");
28+
}
29+
}
1230
}

0 commit comments

Comments
 (0)