Skip to content

Commit

Permalink
introduce CustomFilenameToTestcaseFeedback (AFLplusplus#2256)
Browse files Browse the repository at this point in the history
* introduce CustomTestcaseFilenameFeedback

* rename CustomTestcaseFilenameFeedback to CustomFilenameToTestcaseFeedback

* rename custom_testcase_filename to custom_filename

---------

Co-authored-by: Romain Malmain <[email protected]>
  • Loading branch information
R9295 and rmalmain authored May 30, 2024
1 parent 1102ea0 commit 7b90873
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 3 deletions.
134 changes: 134 additions & 0 deletions libafl/src/feedbacks/custom_filename.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use alloc::{borrow::Cow, string::String};
use core::{
fmt::{self, Debug, Formatter},
marker::PhantomData,
};

use libafl_bolts::Named;
use serde::{Deserialize, Serialize};

use crate::{
corpus::Testcase,
events::EventFirer,
executors::ExitKind,
feedbacks::{Feedback, FeedbackFactory},
inputs::Input,
observers::ObserversTuple,
state::State,
Error,
};

/// A [`CustomFilenameToTestcaseFeedback`] takes a closure which returns a filename for the testcase.
/// Is never interesting (use with an Eager OR).
/// Note: Use only in conjunction with a `Corpus` type that writes to disk.
/// Note: If used as part of the `Objective` chain, then it will only apply to testcases which are
/// `Objectives`, vice versa for `Feedback`.
#[derive(Serialize, Deserialize)]
pub struct CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
/// Closure that returns the filename.
func: F,
phantomm: PhantomData<(I, S)>,
}

impl<F, I, S> CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
/// Create a new [`CustomFilenameToTestcaseFeedback`].
pub fn new(func: F) -> Self {
Self {
func,
phantomm: PhantomData,
}
}
}

impl<F, I, S, T> FeedbackFactory<CustomFilenameToTestcaseFeedback<F, I, S>, S, T>
for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error> + Clone,
{
fn create_feedback(&self, _ctx: &T) -> CustomFilenameToTestcaseFeedback<F, I, S> {
Self {
func: self.func.clone(),
phantomm: self.phantomm,
}
}
}

impl<F, I, S> Named for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("CustomFilenameToTestcaseFeedback");
&NAME
}
}

impl<F, I, S> Debug for CustomFilenameToTestcaseFeedback<F, I, S>
where
I: Input,
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<I>) -> Result<String, Error>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("CustomFilenameToTestcaseFeedback")
.finish_non_exhaustive()
}
}

impl<F, I, S> Feedback<S> for CustomFilenameToTestcaseFeedback<F, I, S>
where
S: State<Input = I>,
F: FnMut(&mut S, &mut Testcase<S::Input>) -> Result<String, Error>,
I: Input,
{
#[allow(clippy::wrong_self_convention)]
#[inline]
fn is_interesting<EM, OT>(
&mut self,
_state: &mut S,
_manager: &mut EM,
_input: &I,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
{
Ok(false)
}

fn append_metadata<EM, OT>(
&mut self,
state: &mut S,
_manager: &mut EM,
_observers: &OT,
testcase: &mut Testcase<<S>::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
EM: EventFirer<State = S>,
{
*testcase.filename_mut() = Some((self.func)(state, testcase)?);
Ok(())
}

#[cfg(feature = "track_hit_feedbacks")]
#[inline]
fn last_result(&self) -> Result<bool, Error> {
Ok(false)
}
}
8 changes: 5 additions & 3 deletions libafl/src/feedbacks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ use crate::{
};
#[cfg(feature = "std")]
pub mod concolic;
#[cfg(feature = "std")]
/// The module for `CustomFilenameToTestcaseFeedback`
pub mod custom_filename;
pub mod differential;
/// The module for list feedback
pub mod list;
pub mod map;
#[cfg(feature = "nautilus")]
pub mod nautilus;
Expand All @@ -49,9 +54,6 @@ pub mod new_hash_feedback;
pub mod stdio;
pub mod transferred;

/// The module for list feedback
pub mod list;

/// Feedbacks evaluate the observers.
/// Basically, they reduce the information provided by an observer to a value,
/// indicating the "interestingness" of the last run.
Expand Down

0 comments on commit 7b90873

Please sign in to comment.