Skip to content

Commit 3d702f4

Browse files
Implement CanTrack tracking enforcement through rust types (#1886)
* sample implementation of tracking enforcement (incomplete) * helpful compiler output * make it look like a real compiler output * ensure that the macro may be used outside of libafl * separate index/novelty tracking funcs * default const generic values so that we don't need to change this everywhere * fix tests * rollback unnecessary specification of stdmapobserver * register metadata in doc tests * doc fixes * doc cleanup * doc cleanup 2 * reduce implementor overhead to zero * renaming/docs fixes * asref isn't reflexive?? * generalization stage updates * add better documentation about require_{indices,novelties}_tracking * remaining generic updates * round one CI pass (knowingly introduces breaking changes) * typo * round 2 clippy * rollback: libafl_frida changes * fmt * moar porting * fix remaining fuzzers * fix windows build, maybe * fixup libafl_libfuzzer * fmt nighlty all the things * attempt to fix some broken additions * fix fmt * oops * fix new invocation * minimizer scheduler fixes * fix accounting * rename * fix * Fix build * Sort generics * Move more generics into the right place * Rename A -> C * Fix test * Fix test some more * Fix doc some more * critical formatting * More A->C * CanTrack harder --------- Co-authored-by: Dominik Maier <[email protected]>
1 parent ec935bf commit 3d702f4

File tree

61 files changed

+1183
-515
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1183
-515
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ For bugs, feel free to open issues or contact us directly. Thank you for your su
117117

118118
Even though we will gladly assist you in finishing up your PR, try to
119119
- keep all the crates compiling with *stable* rust (hide the eventual non-stable code under [`cfg`s](https://github.com/AFLplusplus/LibAFL/blob/main/libafl/build.rs#L26))
120-
- run `cargo fmt` on your code before pushing
120+
- run `cargo +nightly fmt` on your code before pushing
121121
- check the output of `cargo clippy --all` or `./clippy.sh`
122122
- run `cargo build --no-default-features` to check for `no_std` compatibility (and possibly add `#[cfg(feature = "std")]`) to hide parts of your code.
123123

fuzzers/baby_fuzzer_grimoire/src/main.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use libafl::{
1515
GrimoireRandomDeleteMutator, GrimoireRecursiveReplacementMutator,
1616
GrimoireStringReplacementMutator, Tokens,
1717
},
18-
observers::StdMapObserver,
18+
observers::{CanTrack, StdMapObserver},
1919
schedulers::QueueScheduler,
2020
stages::{mutational::StdMutationalStage, GeneralizationStage},
2121
state::StdState,
@@ -83,9 +83,11 @@ pub fn main() {
8383
};
8484

8585
// Create an observation channel using the signals map
86-
let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) };
86+
let observer = unsafe {
87+
StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()).track_novelties()
88+
};
8789
// Feedback to rate the interestingness of an input
88-
let mut feedback = MaxMapFeedback::tracking(&observer, false, true);
90+
let mut feedback = MaxMapFeedback::new(&observer);
8991

9092
// A feedback to choose if an input is a solution or not
9193
let mut objective = CrashFeedback::new();

fuzzers/baby_fuzzer_swap_differential/Makefile.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ command = "cargo"
1919
args = ["build" , "--profile", "${PROFILE}", "--bin", "${FUZZER_NAME}"]
2020
dependencies = [ "cc" ]
2121

22+
[tasks.build]
23+
alias = "fuzzer"
24+
2225
# Run the fuzzer
2326
[tasks.run]
2427
command = "${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}"
@@ -50,4 +53,4 @@ clear = true
5053
script_runner="@shell"
5154
script='''
5255
cargo clean
53-
'''
56+
'''

fuzzers/backtrace_baby_fuzzers/forkserver_executor/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn main() {
5454

5555
// Feedback to rate the interestingness of an input
5656
// This one is composed by two Feedbacks in OR
57-
let mut feedback = MaxMapFeedback::tracking(&edges_observer, true, false);
57+
let mut feedback = MaxMapFeedback::new(&edges_observer);
5858

5959
// A feedback to choose if an input is a solution or not
6060
// We want to do the same crash deduplication that AFL does

fuzzers/forkserver_libafl_cc/src/main.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use libafl::{
1212
inputs::BytesInput,
1313
monitors::SimpleMonitor,
1414
mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens},
15-
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
15+
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
1616
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
1717
stages::mutational::StdMutationalStage,
1818
state::{HasCorpus, StdState},
@@ -101,8 +101,9 @@ pub fn main() {
101101
let shmem_buf = shmem.as_mut_slice();
102102

103103
// Create an observation channel using the signals map
104-
let edges_observer =
105-
unsafe { HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)) };
104+
let edges_observer = unsafe {
105+
HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)).track_indices()
106+
};
106107

107108
// Create an observation channel to keep track of the execution time
108109
let time_observer = TimeObserver::new("time");
@@ -111,7 +112,7 @@ pub fn main() {
111112
// This one is composed by two Feedbacks in OR
112113
let mut feedback = feedback_or!(
113114
// New maximization map feedback linked to the edges observer and the feedback state
114-
MaxMapFeedback::tracking(&edges_observer, true, false),
115+
MaxMapFeedback::new(&edges_observer),
115116
// Time feedback, this one does not need a feedback state
116117
TimeFeedback::with_observer(&time_observer)
117118
);
@@ -151,7 +152,7 @@ pub fn main() {
151152
let mut mgr = SimpleEventManager::new(monitor);
152153

153154
// A minimization+queue policy to get testcasess from the corpus
154-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
155+
let scheduler = IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
155156

156157
// A fuzzer with feedbacks and a corpus scheduler
157158
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

fuzzers/forkserver_simple/src/main.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use libafl::{
1212
inputs::BytesInput,
1313
monitors::SimpleMonitor,
1414
mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens},
15-
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
15+
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
1616
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
1717
stages::mutational::StdMutationalStage,
1818
state::{HasCorpus, StdState},
@@ -101,8 +101,9 @@ pub fn main() {
101101
let shmem_buf = shmem.as_mut_slice();
102102

103103
// Create an observation channel using the signals map
104-
let edges_observer =
105-
unsafe { HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)) };
104+
let edges_observer = unsafe {
105+
HitcountsMapObserver::new(StdMapObserver::new("shared_mem", shmem_buf)).track_indices()
106+
};
106107

107108
// Create an observation channel to keep track of the execution time
108109
let time_observer = TimeObserver::new("time");
@@ -111,7 +112,7 @@ pub fn main() {
111112
// This one is composed by two Feedbacks in OR
112113
let mut feedback = feedback_or!(
113114
// New maximization map feedback linked to the edges observer and the feedback state
114-
MaxMapFeedback::tracking(&edges_observer, true, false),
115+
MaxMapFeedback::new(&edges_observer),
115116
// Time feedback, this one does not need a feedback state
116117
TimeFeedback::with_observer(&time_observer)
117118
);
@@ -151,7 +152,7 @@ pub fn main() {
151152
let mut mgr = SimpleEventManager::new(monitor);
152153

153154
// A minimization+queue policy to get testcasess from the corpus
154-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
155+
let scheduler = IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
155156

156157
// A fuzzer with feedbacks and a corpus scheduler
157158
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

fuzzers/frida_executable_libpng/src/fuzzer.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
22
//! The example harness is built for libpng.
3-
use mimalloc::MiMalloc;
4-
#[global_allocator]
5-
static GLOBAL: MiMalloc = MiMalloc;
6-
73
use std::{path::PathBuf, ptr::null};
84

95
use frida_gum::Gum;
@@ -20,7 +16,7 @@ use libafl::{
2016
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
2117
token_mutations::{I2SRandReplace, Tokens},
2218
},
23-
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
19+
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
2420
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
2521
stages::{ShadowTracingStage, StdMutationalStage},
2622
state::{HasCorpus, StdState},
@@ -39,7 +35,7 @@ use libafl_bolts::{
3935
#[cfg(unix)]
4036
use libafl_frida::asan::{
4137
asan_rt::AsanRuntime,
42-
errors::{AsanErrorsFeedback, AsanErrorsObserver},
38+
errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS},
4339
};
4440
use libafl_frida::{
4541
cmplog_rt::CmpLogRuntime,
@@ -48,6 +44,10 @@ use libafl_frida::{
4844
helper::FridaInstrumentationHelper,
4945
};
5046
use libafl_targets::cmplog::CmpLogObserver;
47+
use mimalloc::MiMalloc;
48+
49+
#[global_allocator]
50+
static GLOBAL: MiMalloc = MiMalloc;
5151

5252
pub unsafe fn lib(main: extern "C" fn(i32, *const *const u8, *const *const u8) -> i32) {
5353
color_backtrace::install();
@@ -104,7 +104,7 @@ unsafe fn fuzz(
104104

105105
let coverage = CoverageRuntime::new();
106106
#[cfg(unix)]
107-
let asan = AsanRuntime::new(options);
107+
let asan = AsanRuntime::new(&options);
108108

109109
#[cfg(unix)]
110110
let mut frida_helper =
@@ -118,7 +118,8 @@ unsafe fn fuzz(
118118
"edges",
119119
frida_helper.map_mut_ptr().unwrap(),
120120
MAP_SIZE,
121-
));
121+
))
122+
.track_indices();
122123

123124
// Create an observation channel to keep track of the execution time
124125
let time_observer = TimeObserver::new("time");
@@ -127,7 +128,7 @@ unsafe fn fuzz(
127128
// This one is composed by two Feedbacks in OR
128129
let mut feedback = feedback_or!(
129130
// New maximization map feedback linked to the edges observer and the feedback state
130-
MaxMapFeedback::tracking(&edges_observer, true, false),
131+
MaxMapFeedback::new(&edges_observer),
131132
// Time feedback, this one does not need a feedback state
132133
TimeFeedback::with_observer(&time_observer)
133134
);
@@ -177,7 +178,8 @@ unsafe fn fuzz(
177178
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
178179

179180
// A minimization+queue policy to get testcasess from the corpus
180-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
181+
let scheduler =
182+
IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
181183

182184
// A fuzzer with feedbacks and a corpus scheduler
183185
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
@@ -233,7 +235,8 @@ unsafe fn fuzz(
233235
"edges",
234236
frida_helper.map_mut_ptr().unwrap(),
235237
MAP_SIZE,
236-
));
238+
))
239+
.track_indices();
237240

238241
// Create an observation channel to keep track of the execution time
239242
let time_observer = TimeObserver::new("time");
@@ -242,7 +245,7 @@ unsafe fn fuzz(
242245
// This one is composed by two Feedbacks in OR
243246
let mut feedback = feedback_or!(
244247
// New maximization map feedback linked to the edges observer and the feedback state
245-
MaxMapFeedback::tracking(&edges_observer, true, false),
248+
MaxMapFeedback::new(&edges_observer),
246249
// Time feedback, this one does not need a feedback state
247250
TimeFeedback::with_observer(&time_observer)
248251
);
@@ -290,7 +293,8 @@ unsafe fn fuzz(
290293
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
291294

292295
// A minimization+queue policy to get testcasess from the corpus
293-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
296+
let scheduler =
297+
IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
294298

295299
// A fuzzer with feedbacks and a corpus scheduler
296300
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
@@ -361,7 +365,8 @@ unsafe fn fuzz(
361365
"edges",
362366
frida_helper.map_mut_ptr().unwrap(),
363367
MAP_SIZE,
364-
));
368+
))
369+
.track_indices();
365370

366371
// Create an observation channel to keep track of the execution time
367372
let time_observer = TimeObserver::new("time");
@@ -370,7 +375,7 @@ unsafe fn fuzz(
370375
// This one is composed by two Feedbacks in OR
371376
let mut feedback = feedback_or!(
372377
// New maximization map feedback linked to the edges observer and the feedback state
373-
MaxMapFeedback::tracking(&edges_observer, true, false),
378+
MaxMapFeedback::new(&edges_observer),
374379
// Time feedback, this one does not need a feedback state
375380
TimeFeedback::with_observer(&time_observer)
376381
);
@@ -418,7 +423,8 @@ unsafe fn fuzz(
418423
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
419424

420425
// A minimization+queue policy to get testcasess from the corpus
421-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
426+
let scheduler =
427+
IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
422428

423429
// A fuzzer with feedbacks and a corpus scheduler
424430
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

fuzzers/frida_gdiplus/src/fuzzer.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use libafl::{
2626
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
2727
token_mutations::{I2SRandReplace, Tokens},
2828
},
29-
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
29+
observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
3030
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
3131
stages::{ShadowTracingStage, StdMutationalStage},
3232
state::{HasCorpus, StdState},
@@ -113,7 +113,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
113113
"edges",
114114
frida_helper.map_mut_ptr().unwrap(),
115115
MAP_SIZE,
116-
));
116+
))
117+
.track_indices();
117118

118119
// Create an observation channel to keep track of the execution time
119120
let time_observer = TimeObserver::new("time");
@@ -122,7 +123,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
122123
// This one is composed by two Feedbacks in OR
123124
let mut feedback = feedback_or!(
124125
// New maximization map feedback linked to the edges observer and the feedback state
125-
MaxMapFeedback::tracking(&edges_observer, true, false),
126+
MaxMapFeedback::new(&edges_observer),
126127
// Time feedback, this one does not need a feedback state
127128
TimeFeedback::with_observer(&time_observer)
128129
);
@@ -171,7 +172,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
171172
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
172173

173174
// A minimization+queue policy to get testcasess from the corpus
174-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
175+
let scheduler =
176+
IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
175177

176178
// A fuzzer with feedbacks and a corpus scheduler
177179
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
@@ -227,7 +229,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
227229
"edges",
228230
frida_helper.map_mut_ptr().unwrap(),
229231
MAP_SIZE,
230-
));
232+
))
233+
.track_indices();
231234

232235
// Create an observation channel to keep track of the execution time
233236
let time_observer = TimeObserver::new("time");
@@ -236,7 +239,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
236239
// This one is composed by two Feedbacks in OR
237240
let mut feedback = feedback_or!(
238241
// New maximization map feedback linked to the edges observer and the feedback state
239-
MaxMapFeedback::tracking(&edges_observer, true, false),
242+
MaxMapFeedback::new(&edges_observer),
240243
// Time feedback, this one does not need a feedback state
241244
TimeFeedback::with_observer(&time_observer)
242245
);
@@ -284,7 +287,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
284287
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
285288

286289
// A minimization+queue policy to get testcasess from the corpus
287-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
290+
let scheduler =
291+
IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
288292

289293
// A fuzzer with feedbacks and a corpus scheduler
290294
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
@@ -356,7 +360,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
356360
"edges",
357361
frida_helper.map_mut_ptr().unwrap(),
358362
MAP_SIZE,
359-
));
363+
))
364+
.track_indices();
360365

361366
// Create an observation channel to keep track of the execution time
362367
let time_observer = TimeObserver::new("time");
@@ -365,7 +370,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
365370
// This one is composed by two Feedbacks in OR
366371
let mut feedback = feedback_or!(
367372
// New maximization map feedback linked to the edges observer and the feedback state
368-
MaxMapFeedback::tracking(&edges_observer, true, false),
373+
MaxMapFeedback::new(&edges_observer),
369374
// Time feedback, this one does not need a feedback state
370375
TimeFeedback::with_observer(&time_observer)
371376
);
@@ -413,7 +418,8 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
413418
let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
414419

415420
// A minimization+queue policy to get testcasess from the corpus
416-
let scheduler = IndexesLenTimeMinimizerScheduler::new(QueueScheduler::new());
421+
let scheduler =
422+
IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new());
417423

418424
// A fuzzer with feedbacks and a corpus scheduler
419425
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

0 commit comments

Comments
 (0)