AFLplusplus / LibAFL

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...
Other
1.91k stars 292 forks source link

Make `current_corpus_idx` infallible? #2200

Open langston-barrett opened 1 month ago

langston-barrett commented 1 month ago

Currently, current_corpus_idx returns an Option. However, most places where current_(testcase|corpus_idx) are called don't meaningfully handle it returning None, instead just propagating the error. In most fuzzers, we'd actually expect the None-handling branch to be dead code. I wonder if there's a way to actually make this method infallible. Hopefully this could even result in some performance gains by eliminating these branches? The revised trait would look like this:

/// Trait for types which track the current corpus index
pub trait HasCurrentCorpusIdx {
    /// Set the current corpus index; we have started processing this corpus entry
    fn set_corpus_idx(&mut self, idx: CorpusId) -> Result<(), Error>;

    /// Fetch the current corpus index
    fn current_corpus_idx(&self) -> Result<CorpusId, Error>;
}

The difficulty is that the State would have to choose an initial index at the time it is constructed (probably using a Scheduler). Right now, we generally construct States before loading/generating the initial corpus. Perhaps there's some kind of type-state pattern, like there could be an InitialStdState that doesn't implement HasCurrentCorpusIdx, but has methods to load/generate the initial corpus and pick an initial index, and they all return StdState (which would implement the infallible version of HasCurrentCorpusIdx).

Just an idea :shrug: Feel free to close if not helpful!

tokatoka commented 1 month ago

sounds like a good idea to me

tokatoka commented 1 month ago

if you plan to do this I would suggest to move this InitialStdState to a differnet file. such as state/init.rs or state/loader.rs

domenukk commented 1 month ago

I guess a state without corpus id would be the same state we can use for generation base fuzzing, right?

More lightweight, we could just set CorpusId(0) in the beginning, it's a sane default..