CustomBuf Events to exchange any data between fuzzers (#672)
* custom buf events * clippy, nits * nostd * testcase * maturin build * fmt * pybind imports cleanup * remove unneded lifetime annotation * docs
This commit is contained in:
parent
a2388d4400
commit
f7c997ec65
@ -1,4 +1,5 @@
|
|||||||
use libafl;
|
use libafl;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
use libafl_qemu;
|
use libafl_qemu;
|
||||||
use libafl_sugar;
|
use libafl_sugar;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
@ -92,10 +93,14 @@ pub fn python_module(py: Python, m: &PyModule) -> PyResult<()> {
|
|||||||
|
|
||||||
modules.set_item("pylibafl.sugar", sugar_module)?;
|
modules.set_item("pylibafl.sugar", sugar_module)?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
let qemu_module = PyModule::new(py, "qemu")?;
|
let qemu_module = PyModule::new(py, "qemu")?;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
libafl_qemu::python_module(py, qemu_module)?;
|
libafl_qemu::python_module(py, qemu_module)?;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
m.add_submodule(qemu_module)?;
|
m.add_submodule(qemu_module)?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
modules.set_item("pylibafl.qemu", qemu_module)?;
|
modules.set_item("pylibafl.qemu", qemu_module)?;
|
||||||
|
|
||||||
let libafl_module = PyModule::new(py, "libafl")?;
|
let libafl_module = PyModule::new(py, "libafl")?;
|
||||||
|
@ -137,9 +137,7 @@ where
|
|||||||
/// ``CachedOnDiskCorpus`` Python bindings
|
/// ``CachedOnDiskCorpus`` Python bindings
|
||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::corpus::pybind::PythonCorpus;
|
use crate::{corpus::pybind::PythonCorpus, corpus::CachedOnDiskCorpus, inputs::BytesInput};
|
||||||
use crate::corpus::CachedOnDiskCorpus;
|
|
||||||
use crate::inputs::BytesInput;
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -91,9 +91,10 @@ where
|
|||||||
/// `InMemoryCorpus` Python bindings
|
/// `InMemoryCorpus` Python bindings
|
||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::corpus::pybind::PythonCorpus;
|
use crate::{
|
||||||
use crate::corpus::InMemoryCorpus;
|
corpus::{pybind::PythonCorpus, InMemoryCorpus},
|
||||||
use crate::inputs::BytesInput;
|
inputs::BytesInput,
|
||||||
|
};
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -56,18 +56,19 @@ where
|
|||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::corpus::inmemory::pybind::PythonInMemoryCorpus;
|
use crate::{
|
||||||
use crate::corpus::testcase::pybind::PythonTestcaseWrapper;
|
corpus::{
|
||||||
use crate::corpus::{Corpus, Testcase};
|
cached::pybind::PythonCachedOnDiskCorpus, inmemory::pybind::PythonInMemoryCorpus,
|
||||||
use crate::inputs::BytesInput;
|
ondisk::pybind::PythonOnDiskCorpus, testcase::pybind::PythonTestcaseWrapper, Corpus,
|
||||||
use crate::Error;
|
Testcase,
|
||||||
|
},
|
||||||
|
inputs::BytesInput,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use super::cached::pybind::PythonCachedOnDiskCorpus;
|
|
||||||
use super::ondisk::pybind::PythonOnDiskCorpus;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
enum PythonCorpusWrapper {
|
enum PythonCorpusWrapper {
|
||||||
InMemory(Py<PythonInMemoryCorpus>),
|
InMemory(Py<PythonInMemoryCorpus>),
|
||||||
|
@ -208,9 +208,10 @@ where
|
|||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
/// `OnDiskCorpus` Python bindings
|
/// `OnDiskCorpus` Python bindings
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::corpus::pybind::PythonCorpus;
|
use crate::{
|
||||||
use crate::corpus::OnDiskCorpus;
|
corpus::{pybind::PythonCorpus, OnDiskCorpus},
|
||||||
use crate::inputs::BytesInput;
|
inputs::BytesInput,
|
||||||
|
};
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -351,12 +351,13 @@ crate::impl_serdeany!(SchedulerTestcaseMetaData);
|
|||||||
/// `Testcase` Python bindings
|
/// `Testcase` Python bindings
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use super::{HasMetadata, Testcase};
|
use super::{HasMetadata, Testcase};
|
||||||
use crate::bolts::ownedref::OwnedPtrMut;
|
use crate::{
|
||||||
use crate::inputs::{BytesInput, HasBytesVec};
|
bolts::ownedref::OwnedPtrMut,
|
||||||
use crate::pybind::PythonMetadata;
|
inputs::{BytesInput, HasBytesVec},
|
||||||
|
pybind::PythonMetadata,
|
||||||
|
};
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
use pyo3::prelude::*;
|
use pyo3::{prelude::*, types::PyDict};
|
||||||
use pyo3::types::PyDict;
|
|
||||||
|
|
||||||
/// `PythonTestcase` with fixed generics
|
/// `PythonTestcase` with fixed generics
|
||||||
pub type PythonTestcase = Testcase<BytesInput>;
|
pub type PythonTestcase = Testcase<BytesInput>;
|
||||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
events::{
|
events::{
|
||||||
BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerId,
|
BrokerEventResult, Event, EventConfig, EventFirer, EventManager, EventManagerId,
|
||||||
EventProcessor, EventRestarter, HasEventManagerId, ProgressReporter,
|
EventProcessor, EventRestarter, HasCustomBufHandlers, HasEventManagerId, ProgressReporter,
|
||||||
},
|
},
|
||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
fuzzer::{EvaluatorObservers, ExecutionProcessor},
|
||||||
@ -29,7 +29,11 @@ use crate::{
|
|||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use alloc::string::ToString;
|
use alloc::{
|
||||||
|
boxed::Box,
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
use core::{marker::PhantomData, time::Duration};
|
use core::{marker::PhantomData, time::Duration};
|
||||||
@ -41,6 +45,8 @@ use std::net::{SocketAddr, ToSocketAddrs};
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use typed_builder::TypedBuilder;
|
use typed_builder::TypedBuilder;
|
||||||
|
|
||||||
|
use super::{CustomBufEventResult, CustomBufHandlerFn};
|
||||||
|
|
||||||
/// Forward this to the client
|
/// Forward this to the client
|
||||||
const _LLMP_TAG_EVENT_TO_CLIENT: Tag = 0x2C11E471;
|
const _LLMP_TAG_EVENT_TO_CLIENT: Tag = 0x2C11E471;
|
||||||
/// Only handle this in the broker
|
/// Only handle this in the broker
|
||||||
@ -228,14 +234,15 @@ where
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
println!("[LOG {}]: {}", severity_level, message);
|
println!("[LOG {}]: {}", severity_level, message);
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
} //_ => Ok(BrokerEventResult::Forward),
|
}
|
||||||
|
Event::CustomBuf { .. } => Ok(BrokerEventResult::Forward),
|
||||||
|
//_ => Ok(BrokerEventResult::Forward),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp,
|
/// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp,
|
||||||
/// using low-level message passing, [`crate::bolts::llmp`].
|
/// using low-level message passing, [`crate::bolts::llmp`].
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct LlmpEventManager<I, OT, S, SP>
|
pub struct LlmpEventManager<I, OT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -244,12 +251,33 @@ where
|
|||||||
//CE: CustomEvent<I>,
|
//CE: CustomEvent<I>,
|
||||||
{
|
{
|
||||||
llmp: LlmpClient<SP>,
|
llmp: LlmpClient<SP>,
|
||||||
|
/// The custom buf handler
|
||||||
|
custom_buf_handlers: Vec<Box<CustomBufHandlerFn<S>>>,
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
compressor: GzipCompressor,
|
compressor: GzipCompressor,
|
||||||
configuration: EventConfig,
|
configuration: EventConfig,
|
||||||
phantom: PhantomData<(I, OT, S)>,
|
phantom: PhantomData<(I, OT, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<I, OT, S, SP> core::fmt::Debug for LlmpEventManager<I, OT, S, SP>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
SP: ShMemProvider + 'static,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
let mut debug_struct = f.debug_struct("LlmpEventManager");
|
||||||
|
let debug = debug_struct.field("llmp", &self.llmp);
|
||||||
|
//.field("custom_buf_handlers", &self.custom_buf_handlers)
|
||||||
|
#[cfg(feature = "llmp_compression")]
|
||||||
|
let debug = debug.field("compressor", &self.compressor);
|
||||||
|
debug
|
||||||
|
.field("configuration", &self.configuration)
|
||||||
|
.field("phantom", &self.phantom)
|
||||||
|
.finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<I, OT, S, SP> Drop for LlmpEventManager<I, OT, S, SP>
|
impl<I, OT, S, SP> Drop for LlmpEventManager<I, OT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
@ -276,6 +304,7 @@ where
|
|||||||
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
||||||
configuration,
|
configuration,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
custom_buf_handlers: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,6 +323,7 @@ where
|
|||||||
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
||||||
configuration,
|
configuration,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
custom_buf_handlers: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +340,7 @@ where
|
|||||||
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
||||||
configuration,
|
configuration,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
custom_buf_handlers: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,6 +361,7 @@ where
|
|||||||
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
compressor: GzipCompressor::new(COMPRESS_THRESHOLD),
|
||||||
configuration,
|
configuration,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
custom_buf_handlers: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,6 +416,14 @@ where
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Event::CustomBuf { tag, buf } => {
|
||||||
|
for handler in &mut self.custom_buf_handlers {
|
||||||
|
if handler(state, &tag, &buf)? == CustomBufEventResult::Handled {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
_ => Err(Error::unknown(format!(
|
_ => Err(Error::unknown(format!(
|
||||||
"Received illegal message that message should not have arrived: {:?}.",
|
"Received illegal message that message should not have arrived: {:?}.",
|
||||||
event.name()
|
event.name()
|
||||||
@ -496,6 +536,20 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<I, OT, S, SP> HasCustomBufHandlers<S> for LlmpEventManager<I, OT, S, SP>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
SP: ShMemProvider,
|
||||||
|
{
|
||||||
|
fn add_custom_buf_handler(
|
||||||
|
&mut self,
|
||||||
|
handler: Box<dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>>,
|
||||||
|
) {
|
||||||
|
self.custom_buf_handlers.push(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<I, OT, S, SP> ProgressReporter<I> for LlmpEventManager<I, OT, S, SP>
|
impl<I, OT, S, SP> ProgressReporter<I> for LlmpEventManager<I, OT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
|
@ -7,6 +7,7 @@ pub use llmp::*;
|
|||||||
|
|
||||||
use ahash::AHasher;
|
use ahash::AHasher;
|
||||||
use alloc::{
|
use alloc::{
|
||||||
|
boxed::Box,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
@ -36,8 +37,6 @@ pub struct EventManagerId {
|
|||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
use crate::monitors::ClientPerfMonitor;
|
use crate::monitors::ClientPerfMonitor;
|
||||||
#[cfg(feature = "introspection")]
|
|
||||||
use alloc::boxed::Box;
|
|
||||||
|
|
||||||
/// The log event severity
|
/// The log event severity
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
||||||
@ -63,6 +62,15 @@ impl fmt::Display for LogSeverity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The result of a custom buf handler added using [`HasCustomBufHandlers::add_custom_buf_handler`]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum CustomBufEventResult {
|
||||||
|
/// Exit early from event handling
|
||||||
|
Handled,
|
||||||
|
/// Call the next handler, if available
|
||||||
|
Next,
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicate if an event worked or not
|
/// Indicate if an event worked or not
|
||||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
|
||||||
pub enum BrokerEventResult {
|
pub enum BrokerEventResult {
|
||||||
@ -231,6 +239,13 @@ where
|
|||||||
/// `PhantomData`
|
/// `PhantomData`
|
||||||
phantom: PhantomData<I>,
|
phantom: PhantomData<I>,
|
||||||
},
|
},
|
||||||
|
/// Sends a custom buffer to other clients
|
||||||
|
CustomBuf {
|
||||||
|
/// The buffer
|
||||||
|
buf: Vec<u8>,
|
||||||
|
/// Tag of this buffer
|
||||||
|
tag: String,
|
||||||
|
},
|
||||||
/*/// A custom type
|
/*/// A custom type
|
||||||
Custom {
|
Custom {
|
||||||
// TODO: Allow custom events
|
// TODO: Allow custom events
|
||||||
@ -270,12 +285,13 @@ where
|
|||||||
introspection_monitor: _,
|
introspection_monitor: _,
|
||||||
phantom: _,
|
phantom: _,
|
||||||
} => "PerfMonitor",
|
} => "PerfMonitor",
|
||||||
Event::Objective { objective_size: _ } => "Objective",
|
Event::Objective { .. } => "Objective",
|
||||||
Event::Log {
|
Event::Log {
|
||||||
severity_level: _,
|
severity_level: _,
|
||||||
message: _,
|
message: _,
|
||||||
phantom: _,
|
phantom: _,
|
||||||
} => "Log",
|
} => "Log",
|
||||||
|
Event::CustomBuf { .. } => "CustomBuf",
|
||||||
/*Event::Custom {
|
/*Event::Custom {
|
||||||
sender_id: _, /*custom_event} => custom_event.name()*/
|
sender_id: _, /*custom_event} => custom_event.name()*/
|
||||||
} => "todo",*/
|
} => "todo",*/
|
||||||
@ -451,6 +467,16 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The handler function for custom buffers exchanged via [`EventManager`]
|
||||||
|
type CustomBufHandlerFn<S> =
|
||||||
|
dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>;
|
||||||
|
|
||||||
|
/// Supports custom buf handlers to handle `CustomBuf` events.
|
||||||
|
pub trait HasCustomBufHandlers<S> {
|
||||||
|
/// Adds a custom buffer handler that will run for each incoming `CustomBuf` event.
|
||||||
|
fn add_custom_buf_handler(&mut self, handler: Box<CustomBufHandlerFn<S>>);
|
||||||
|
}
|
||||||
|
|
||||||
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
/// An eventmgr for tests, and as placeholder if you really don't need an event manager.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct NopEventManager {}
|
pub struct NopEventManager {}
|
||||||
@ -479,6 +505,14 @@ impl<E, I, S, Z> EventProcessor<E, I, S, Z> for NopEventManager {
|
|||||||
|
|
||||||
impl<E, I, S, Z> EventManager<E, I, S, Z> for NopEventManager where I: Input {}
|
impl<E, I, S, Z> EventManager<E, I, S, Z> for NopEventManager where I: Input {}
|
||||||
|
|
||||||
|
impl<S> HasCustomBufHandlers<S> for NopEventManager {
|
||||||
|
fn add_custom_buf_handler(
|
||||||
|
&mut self,
|
||||||
|
_handler: Box<dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<I> ProgressReporter<I> for NopEventManager where I: Input {}
|
impl<I> ProgressReporter<I> for NopEventManager where I: Input {}
|
||||||
|
|
||||||
impl HasEventManagerId for NopEventManager {
|
impl HasEventManagerId for NopEventManager {
|
||||||
@ -548,16 +582,17 @@ mod tests {
|
|||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::events::simple::pybind::PythonSimpleEventManager;
|
use crate::{
|
||||||
use crate::events::{
|
events::{
|
||||||
Event, EventFirer, EventManager, EventManagerId, EventProcessor, EventRestarter,
|
simple::pybind::PythonSimpleEventManager, Event, EventFirer, EventManager,
|
||||||
HasEventManagerId, ProgressReporter,
|
EventManagerId, EventProcessor, EventRestarter, HasEventManagerId, ProgressReporter,
|
||||||
|
},
|
||||||
|
executors::pybind::PythonExecutor,
|
||||||
|
fuzzer::pybind::PythonStdFuzzer,
|
||||||
|
inputs::BytesInput,
|
||||||
|
state::pybind::PythonStdState,
|
||||||
|
Error,
|
||||||
};
|
};
|
||||||
use crate::executors::pybind::PythonExecutor;
|
|
||||||
use crate::fuzzer::pybind::PythonStdFuzzer;
|
|
||||||
use crate::inputs::BytesInput;
|
|
||||||
use crate::state::pybind::PythonStdState;
|
|
||||||
use crate::Error;
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -9,9 +9,14 @@ use crate::{
|
|||||||
monitors::Monitor,
|
monitors::Monitor,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use alloc::{string::ToString, vec::Vec};
|
use alloc::{
|
||||||
|
boxed::Box,
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
|
use core::{fmt::Debug, marker::PhantomData};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
@ -23,10 +28,11 @@ use crate::bolts::os::{fork, ForkResult};
|
|||||||
use crate::{
|
use crate::{
|
||||||
bolts::{shmem::ShMemProvider, staterestore::StateRestorer},
|
bolts::{shmem::ShMemProvider, staterestore::StateRestorer},
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
|
executors::Executor,
|
||||||
state::{HasCorpus, HasSolutions},
|
state::{HasCorpus, HasSolutions},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ProgressReporter;
|
use super::{CustomBufEventResult, CustomBufHandlerFn, HasCustomBufHandlers, ProgressReporter};
|
||||||
|
|
||||||
/// The llmp connection from the actual fuzzer to the process supervising it
|
/// The llmp connection from the actual fuzzer to the process supervising it
|
||||||
const _ENV_FUZZER_SENDER: &str = "_AFL_ENV_FUZZER_SENDER";
|
const _ENV_FUZZER_SENDER: &str = "_AFL_ENV_FUZZER_SENDER";
|
||||||
@ -35,24 +41,40 @@ const _ENV_FUZZER_RECEIVER: &str = "_AFL_ENV_FUZZER_RECEIVER";
|
|||||||
const _ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = "_AFL_ENV_FUZZER_BROKER_CLIENT";
|
const _ENV_FUZZER_BROKER_CLIENT_INITIAL: &str = "_AFL_ENV_FUZZER_BROKER_CLIENT";
|
||||||
|
|
||||||
/// A simple, single-threaded event manager that just logs
|
/// A simple, single-threaded event manager that just logs
|
||||||
#[derive(Clone, Debug)]
|
pub struct SimpleEventManager<I, MT, S>
|
||||||
pub struct SimpleEventManager<I, MT>
|
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
/// The monitor
|
/// The monitor
|
||||||
monitor: MT,
|
monitor: MT,
|
||||||
/// The events that happened since the last handle_in_broker
|
/// The events that happened since the last handle_in_broker
|
||||||
events: Vec<Event<I>>,
|
events: Vec<Event<I>>,
|
||||||
|
/// The custom buf handler
|
||||||
|
custom_buf_handlers: Vec<Box<CustomBufHandlerFn<S>>>,
|
||||||
|
phantom: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT> EventFirer<I> for SimpleEventManager<I, MT>
|
impl<I, MT, S> Debug for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug,
|
||||||
{
|
{
|
||||||
fn fire<S>(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_struct("SimpleEventManager")
|
||||||
|
//.field("custom_buf_handlers", self.custom_buf_handlers)
|
||||||
|
.field("monitor", &self.monitor)
|
||||||
|
.field("events", &self.events)
|
||||||
|
.finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, MT, S> EventFirer<I> for SimpleEventManager<I, MT, S>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
|
{
|
||||||
|
fn fire<S2>(&mut self, _state: &mut S2, event: Event<I>) -> Result<(), Error> {
|
||||||
match Self::handle_in_broker(&mut self.monitor, &event)? {
|
match Self::handle_in_broker(&mut self.monitor, &event)? {
|
||||||
BrokerEventResult::Forward => self.events.push(event),
|
BrokerEventResult::Forward => self.events.push(event),
|
||||||
BrokerEventResult::Handled => (),
|
BrokerEventResult::Handled => (),
|
||||||
@ -61,17 +83,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, S> EventRestarter<S> for SimpleEventManager<I, MT>
|
impl<I, MT, S> EventRestarter<S> for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, I, MT, S, Z> EventProcessor<E, I, S, Z> for SimpleEventManager<I, MT>
|
impl<E, I, MT, S, Z> EventProcessor<E, I, S, Z> for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -88,44 +110,60 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, I, MT, S, Z> EventManager<E, I, S, Z> for SimpleEventManager<I, MT>
|
impl<E, I, MT, S, Z> EventManager<E, I, S, Z> for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT> ProgressReporter<I> for SimpleEventManager<I, MT>
|
impl<I, MT, S> HasCustomBufHandlers<S> for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
|
{
|
||||||
|
/// Adds a custom buffer handler that will run for each incoming `CustomBuf` event.
|
||||||
|
fn add_custom_buf_handler(
|
||||||
|
&mut self,
|
||||||
|
handler: Box<dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>>,
|
||||||
|
) {
|
||||||
|
self.custom_buf_handlers.push(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, MT, S> ProgressReporter<I> for SimpleEventManager<I, MT, S>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT> HasEventManagerId for SimpleEventManager<I, MT>
|
impl<I, MT, S> HasEventManagerId for SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor,
|
MT: Monitor + Debug,
|
||||||
{
|
{
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
EventManagerId { id: 0 }
|
EventManagerId { id: 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT> SimpleEventManager<I, MT>
|
impl<I, MT, S> SimpleEventManager<I, MT, S>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
MT: Monitor, //TODO CE: CustomEvent,
|
MT: Monitor + Debug, //TODO CE: CustomEvent,
|
||||||
{
|
{
|
||||||
/// Creates a new [`SimpleEventManager`].
|
/// Creates a new [`SimpleEventManager`].
|
||||||
pub fn new(monitor: MT) -> Self {
|
pub fn new(monitor: MT) -> Self {
|
||||||
Self {
|
Self {
|
||||||
monitor,
|
monitor,
|
||||||
events: vec![],
|
events: vec![],
|
||||||
|
custom_buf_handlers: vec![],
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle arriving events in the broker
|
/// Handle arriving events in the broker
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn handle_in_broker(monitor: &mut MT, event: &Event<I>) -> Result<BrokerEventResult, Error> {
|
fn handle_in_broker(monitor: &mut MT, event: &Event<I>) -> Result<BrokerEventResult, Error> {
|
||||||
match event {
|
match event {
|
||||||
@ -201,17 +239,26 @@ where
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
println!("[LOG {}]: {}", severity_level, message);
|
println!("[LOG {}]: {}", severity_level, message);
|
||||||
Ok(BrokerEventResult::Handled)
|
Ok(BrokerEventResult::Handled)
|
||||||
} //_ => Ok(BrokerEventResult::Forward),
|
}
|
||||||
|
Event::CustomBuf { .. } => Ok(BrokerEventResult::Forward),
|
||||||
|
//_ => Ok(BrokerEventResult::Forward),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle arriving events in the client
|
// Handle arriving events in the client
|
||||||
#[allow(clippy::needless_pass_by_value, clippy::unused_self)]
|
#[allow(clippy::needless_pass_by_value, clippy::unused_self)]
|
||||||
fn handle_in_client<S>(&mut self, _state: &mut S, event: Event<I>) -> Result<(), Error> {
|
fn handle_in_client(&mut self, state: &mut S, event: Event<I>) -> Result<(), Error> {
|
||||||
Err(Error::unknown(format!(
|
if let Event::CustomBuf { tag, buf } = &event {
|
||||||
"Received illegal message that message should not have arrived: {:?}.",
|
for handler in &mut self.custom_buf_handlers {
|
||||||
event
|
handler(state, tag, buf)?;
|
||||||
)))
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::unknown(format!(
|
||||||
|
"Received illegal message that message should not have arrived: {:?}.",
|
||||||
|
event
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,25 +267,25 @@ where
|
|||||||
/// `restarter` will start a new process each time the child crashes or times out.
|
/// `restarter` will start a new process each time the child crashes or times out.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[allow(clippy::default_trait_access)]
|
#[allow(clippy::default_trait_access)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct SimpleRestartingEventManager<I, MT, SP>
|
pub struct SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
/// The actual simple event mgr
|
/// The actual simple event mgr
|
||||||
simple_event_mgr: SimpleEventManager<I, MT>,
|
simple_event_mgr: SimpleEventManager<I, MT, S>,
|
||||||
/// [`StateRestorer`] for restarts
|
/// [`StateRestorer`] for restarts
|
||||||
staterestorer: StateRestorer<SP>,
|
staterestorer: StateRestorer<SP>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<I, MT, SP> EventFirer<I> for SimpleRestartingEventManager<I, MT, SP>
|
impl<I, MT, S, SP> EventFirer<I> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
fn fire<S2>(&mut self, _state: &mut S2, event: Event<I>) -> Result<(), Error> {
|
fn fire<S2>(&mut self, _state: &mut S2, event: Event<I>) -> Result<(), Error> {
|
||||||
self.simple_event_mgr.fire(_state, event)
|
self.simple_event_mgr.fire(_state, event)
|
||||||
@ -246,12 +293,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<I, MT, S, SP> EventRestarter<S> for SimpleRestartingEventManager<I, MT, SP>
|
impl<I, MT, S, SP> EventRestarter<S> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
/// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner.
|
||||||
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
fn on_restart(&mut self, state: &mut S) -> Result<(), Error> {
|
||||||
@ -262,12 +309,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<E, I, S, SP, MT, Z> EventProcessor<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
|
impl<E, I, S, SP, MT, Z> EventProcessor<E, I, S, Z> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
fn process(&mut self, fuzzer: &mut Z, state: &mut S, executor: &mut E) -> Result<usize, Error> {
|
||||||
self.simple_event_mgr.process(fuzzer, state, executor)
|
self.simple_event_mgr.process(fuzzer, state, executor)
|
||||||
@ -275,30 +322,46 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<E, I, S, SP, MT, Z> EventManager<E, I, S, Z> for SimpleRestartingEventManager<I, MT, SP>
|
impl<E, I, S, SP, MT, Z> EventManager<E, I, S, Z> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
|
E: Executor<Self, I, S, Z>,
|
||||||
I: Input,
|
I: Input,
|
||||||
S: Serialize,
|
S: Serialize,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<I, MT, SP> ProgressReporter<I> for SimpleRestartingEventManager<I, MT, SP>
|
impl<I, MT, S, SP> HasCustomBufHandlers<S> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //CE: CustomEvent<I, OT>,
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
|
{
|
||||||
|
fn add_custom_buf_handler(
|
||||||
|
&mut self,
|
||||||
|
handler: Box<dyn FnMut(&mut S, &String, &[u8]) -> Result<CustomBufEventResult, Error>>,
|
||||||
|
) {
|
||||||
|
self.simple_event_mgr.add_custom_buf_handler(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<I, MT, S, SP> ProgressReporter<I> for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
SP: ShMemProvider,
|
||||||
|
MT: Monitor + Debug, //CE: CustomEvent<I, OT>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<I, MT, SP> HasEventManagerId for SimpleRestartingEventManager<I, MT, SP>
|
impl<I, MT, S, SP> HasEventManagerId for SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor,
|
MT: Monitor + Debug,
|
||||||
{
|
{
|
||||||
fn mgr_id(&self) -> EventManagerId {
|
fn mgr_id(&self) -> EventManagerId {
|
||||||
self.simple_event_mgr.mgr_id()
|
self.simple_event_mgr.mgr_id()
|
||||||
@ -307,11 +370,11 @@ where
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[allow(clippy::type_complexity, clippy::too_many_lines)]
|
#[allow(clippy::type_complexity, clippy::too_many_lines)]
|
||||||
impl<I, MT, SP> SimpleRestartingEventManager<I, MT, SP>
|
impl<I, MT, S, SP> SimpleRestartingEventManager<I, MT, S, SP>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
MT: Monitor, //TODO CE: CustomEvent,
|
MT: Monitor + Debug, //TODO CE: CustomEvent,
|
||||||
{
|
{
|
||||||
/// Creates a new [`SimpleEventManager`].
|
/// Creates a new [`SimpleEventManager`].
|
||||||
fn new_launched(monitor: MT, staterestorer: StateRestorer<SP>) -> Self {
|
fn new_launched(monitor: MT, staterestorer: StateRestorer<SP>) -> Self {
|
||||||
@ -325,9 +388,10 @@ where
|
|||||||
/// This [`EventManager`] is simple and single threaded,
|
/// This [`EventManager`] is simple and single threaded,
|
||||||
/// but can still used shared maps to recover from crashes and timeouts.
|
/// but can still used shared maps to recover from crashes and timeouts.
|
||||||
#[allow(clippy::similar_names)]
|
#[allow(clippy::similar_names)]
|
||||||
pub fn launch<S>(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error>
|
pub fn launch(mut monitor: MT, shmem_provider: &mut SP) -> Result<(Option<S>, Self), Error>
|
||||||
where
|
where
|
||||||
S: DeserializeOwned + Serialize + HasCorpus<I> + HasSolutions<I>,
|
S: DeserializeOwned + Serialize + HasCorpus<I> + HasSolutions<I>,
|
||||||
|
MT: Debug,
|
||||||
{
|
{
|
||||||
// We start ourself as child process to actually fuzz
|
// We start ourself as child process to actually fuzz
|
||||||
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
|
let mut staterestorer = if std::env::var(_ENV_FUZZER_SENDER).is_err() {
|
||||||
@ -430,18 +494,18 @@ where
|
|||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::events::pybind::PythonEventManager;
|
use crate::{
|
||||||
use crate::events::SimpleEventManager;
|
events::pybind::PythonEventManager, events::SimpleEventManager, inputs::BytesInput,
|
||||||
use crate::inputs::BytesInput;
|
monitors::pybind::PythonMonitor, state::pybind::PythonStdState,
|
||||||
use crate::monitors::pybind::PythonMonitor;
|
};
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
#[pyclass(unsendable, name = "SimpleEventManager")]
|
#[pyclass(unsendable, name = "SimpleEventManager")]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
/// Python class for SimpleEventManager
|
/// Python class for SimpleEventManager
|
||||||
pub struct PythonSimpleEventManager {
|
pub struct PythonSimpleEventManager {
|
||||||
/// Rust wrapped SimpleEventManager object
|
/// Rust wrapped SimpleEventManager object
|
||||||
pub inner: SimpleEventManager<BytesInput, PythonMonitor>,
|
pub inner: SimpleEventManager<BytesInput, PythonMonitor, PythonStdState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
|
@ -674,7 +674,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn test_builder() {
|
fn test_builder() {
|
||||||
let mut mgr = SimpleEventManager::<BytesInput, _>::new(SimpleMonitor::new(|status| {
|
let mut mgr = SimpleEventManager::<BytesInput, _, ()>::new(SimpleMonitor::new(|status| {
|
||||||
println!("{}", status);
|
println!("{}", status);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -700,7 +700,7 @@ mod tests {
|
|||||||
fn test_parse_afl_cmdline() {
|
fn test_parse_afl_cmdline() {
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
|
|
||||||
let mut mgr = SimpleEventManager::<BytesInput, _>::new(SimpleMonitor::new(|status| {
|
let mut mgr = SimpleEventManager::<BytesInput, _, ()>::new(SimpleMonitor::new(|status| {
|
||||||
println!("{}", status);
|
println!("{}", status);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1689,16 +1689,16 @@ mod tests {
|
|||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
/// `InProcess` Python bindings
|
/// `InProcess` Python bindings
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::events::pybind::PythonEventManager;
|
use crate::{
|
||||||
use crate::executors::pybind::PythonExecutor;
|
events::pybind::PythonEventManager,
|
||||||
use crate::executors::{inprocess::OwnedInProcessExecutor, ExitKind};
|
executors::{inprocess::OwnedInProcessExecutor, pybind::PythonExecutor, ExitKind},
|
||||||
use crate::fuzzer::pybind::PythonStdFuzzerWrapper;
|
fuzzer::pybind::PythonStdFuzzerWrapper,
|
||||||
use crate::inputs::{BytesInput, HasBytesVec};
|
inputs::{BytesInput, HasBytesVec},
|
||||||
use crate::observers::pybind::PythonObserversTuple;
|
observers::pybind::PythonObserversTuple,
|
||||||
use crate::state::pybind::{PythonStdState, PythonStdStateWrapper};
|
state::pybind::{PythonStdState, PythonStdStateWrapper},
|
||||||
|
};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use pyo3::prelude::*;
|
use pyo3::{prelude::*, types::PyBytes};
|
||||||
use pyo3::types::PyBytes;
|
|
||||||
|
|
||||||
#[pyclass(unsendable, name = "InProcessExecutor")]
|
#[pyclass(unsendable, name = "InProcessExecutor")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -12,7 +12,7 @@ pub mod disk;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use disk::OnDiskTOMLMonitor;
|
pub use disk::OnDiskTOMLMonitor;
|
||||||
|
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{fmt::Debug, string::String, vec::Vec};
|
||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
@ -282,7 +282,7 @@ impl Default for NopMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Tracking monitor during fuzzing.
|
/// Tracking monitor during fuzzing.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub struct SimpleMonitor<F>
|
pub struct SimpleMonitor<F>
|
||||||
where
|
where
|
||||||
F: FnMut(String),
|
F: FnMut(String),
|
||||||
@ -292,6 +292,18 @@ where
|
|||||||
client_stats: Vec<ClientStats>,
|
client_stats: Vec<ClientStats>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F> Debug for SimpleMonitor<F>
|
||||||
|
where
|
||||||
|
F: FnMut(String),
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("SimpleMonitor")
|
||||||
|
.field("start_time", &self.start_time)
|
||||||
|
.field("client_stats", &self.client_stats)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F> Monitor for SimpleMonitor<F>
|
impl<F> Monitor for SimpleMonitor<F>
|
||||||
where
|
where
|
||||||
F: FnMut(String),
|
F: FnMut(String),
|
||||||
|
@ -261,13 +261,14 @@ where
|
|||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::events::pybind::PythonEventManager;
|
use crate::{
|
||||||
use crate::executors::pybind::PythonExecutor;
|
events::pybind::PythonEventManager,
|
||||||
use crate::fuzzer::pybind::{PythonStdFuzzer, PythonStdFuzzerWrapper};
|
executors::pybind::PythonExecutor,
|
||||||
use crate::stages::mutational::pybind::PythonStdMutationalStage;
|
fuzzer::pybind::{PythonStdFuzzer, PythonStdFuzzerWrapper},
|
||||||
use crate::stages::{Stage, StagesTuple};
|
stages::{mutational::pybind::PythonStdMutationalStage, Stage, StagesTuple},
|
||||||
use crate::state::pybind::{PythonStdState, PythonStdStateWrapper};
|
state::pybind::{PythonStdState, PythonStdStateWrapper},
|
||||||
use crate::Error;
|
Error,
|
||||||
|
};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
@ -166,14 +166,15 @@ where
|
|||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
/// `StdMutationalStage` Python bindings
|
/// `StdMutationalStage` Python bindings
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::events::pybind::PythonEventManager;
|
use crate::{
|
||||||
use crate::executors::pybind::PythonExecutor;
|
events::pybind::PythonEventManager,
|
||||||
use crate::fuzzer::pybind::PythonStdFuzzer;
|
executors::pybind::PythonExecutor,
|
||||||
use crate::inputs::BytesInput;
|
fuzzer::pybind::PythonStdFuzzer,
|
||||||
use crate::mutators::pybind::PythonMutator;
|
inputs::BytesInput,
|
||||||
use crate::stages::pybind::PythonStage;
|
mutators::pybind::PythonMutator,
|
||||||
use crate::stages::StdMutationalStage;
|
stages::{pybind::PythonStage, StdMutationalStage},
|
||||||
use crate::state::pybind::PythonStdState;
|
state::pybind::PythonStdState,
|
||||||
|
};
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
#[pyclass(unsendable, name = "StdMutationalStage")]
|
#[pyclass(unsendable, name = "StdMutationalStage")]
|
||||||
|
@ -655,22 +655,22 @@ where
|
|||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
/// `State` Python bindings
|
/// `State` Python bindings
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
use crate::bolts::ownedref::OwnedPtrMut;
|
use crate::{
|
||||||
use crate::bolts::rands::pybind::PythonRand;
|
bolts::{ownedref::OwnedPtrMut, rands::pybind::PythonRand},
|
||||||
use crate::corpus::pybind::PythonCorpus;
|
corpus::pybind::PythonCorpus,
|
||||||
use crate::events::pybind::PythonEventManager;
|
events::pybind::PythonEventManager,
|
||||||
use crate::executors::pybind::PythonExecutor;
|
executors::pybind::PythonExecutor,
|
||||||
use crate::feedbacks::pybind::PythonFeedback;
|
feedbacks::pybind::PythonFeedback,
|
||||||
use crate::fuzzer::pybind::PythonStdFuzzerWrapper;
|
fuzzer::pybind::PythonStdFuzzerWrapper,
|
||||||
use crate::generators::pybind::PythonGenerator;
|
generators::pybind::PythonGenerator,
|
||||||
use crate::inputs::BytesInput;
|
inputs::BytesInput,
|
||||||
use crate::pybind::PythonMetadata;
|
pybind::PythonMetadata,
|
||||||
use crate::state::{
|
state::{
|
||||||
HasCorpus, HasExecutions, HasMaxSize, HasMetadata, HasRand, HasSolutions, StdState,
|
HasCorpus, HasExecutions, HasMaxSize, HasMetadata, HasRand, HasSolutions, StdState,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
use pyo3::prelude::*;
|
use pyo3::{prelude::*, types::PyDict};
|
||||||
use pyo3::types::PyDict;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// `StdState` with fixed generics
|
/// `StdState` with fixed generics
|
||||||
|
Loading…
x
Reference in New Issue
Block a user