Add serdeany_autoreg
feature flag to allow disabling ctor
use (#1398)
* Add feature flag to allow disabling use * fix typo * undo cargo.toml change * Fix no_std * Backticks * rename register_at_startup to create_register * fix * Move Tui_monitor to default instead of std
This commit is contained in:
parent
83f739f010
commit
a0c03fccc5
@ -12,8 +12,8 @@ edition = "2021"
|
||||
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
||||
|
||||
[features]
|
||||
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "llmp_broker_timeouts", "rand_trait", "fork", "prelude", "gzip", "regex"]
|
||||
std = ["serde_json", "serde_json/std", "nix", "serde/std", "bincode", "wait-timeout", "uuid", "tui_monitor", "ctor", "backtrace", "serial_test", "libafl_bolts/std", "typed-builder"] # print, env, launcher ... support
|
||||
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "llmp_broker_timeouts", "rand_trait", "fork", "prelude", "gzip", "regex", "serdeany_autoreg", "tui_monitor"]
|
||||
std = ["serde_json", "serde_json/std", "nix", "serde/std", "bincode", "wait-timeout", "uuid", "backtrace", "serial_test", "libafl_bolts/std", "typed-builder"] # print, env, launcher ... support
|
||||
derive = ["libafl_derive", "libafl_bolts/derive"] # provide derive(SerdeAny) macro.
|
||||
fork = ["libafl_bolts/derive"] # uses the fork() syscall to spawn children, instead of launching a new command, if supported by the OS (has no effect on Windows, no_std).
|
||||
rand_trait = ["libafl_bolts/rand_trait"] # If set, libafl's rand implementations will implement `rand::Rng`
|
||||
@ -42,6 +42,9 @@ gpl = []
|
||||
agpl = ["gpl", "nautilus"]
|
||||
nautilus = ["grammartec", "std", "serde_json/std"]
|
||||
|
||||
# SerdeAny features
|
||||
serdeany_autoreg = ["libafl_bolts/serdeany_autoreg"] # Automatically register all `#[derive(SerdeAny)]` types at startup.
|
||||
|
||||
# LLMP features
|
||||
llmp_bind_public = ["libafl_bolts/llmp_bind_public"] # If set, llmp will bind to 0.0.0.0, allowing cross-device communication. Binds to localhost by default.
|
||||
llmp_compression = ["libafl_bolts/llmp_compression"] # llmp compression using GZip
|
||||
@ -74,7 +77,6 @@ intervaltree = { version = "0.2.7", default-features = false, features = ["serde
|
||||
backtrace = {version = "0.3", optional = true} # Used to get the stacktrace in StacktraceObserver
|
||||
typed-builder = { version = "0.15.1", optional = true } # Implement the builder pattern at compiletime
|
||||
|
||||
ctor = { optional = true, version = "0.2" }
|
||||
serde_json = { version = "1.0", optional = true, default-features = false, features = ["alloc"] }
|
||||
nix = { version = "0.26", optional = true }
|
||||
regex = { version = "1", optional = true }
|
||||
|
@ -169,6 +169,8 @@ where
|
||||
if self.cores.ids.iter().any(|&x| x == id.into()) {
|
||||
index += 1;
|
||||
self.shmem_provider.pre_fork()?;
|
||||
// # Safety
|
||||
// Fork is safe in general, apart from potential side effects to the OS and other threads
|
||||
match unsafe { fork() }? {
|
||||
ForkResult::Parent(child) => {
|
||||
self.shmem_provider.post_fork(false)?;
|
||||
@ -177,6 +179,8 @@ where
|
||||
log::info!("child spawned and bound to core {id}");
|
||||
}
|
||||
ForkResult::Child => {
|
||||
// # Safety
|
||||
// A call to `getpid` is safe.
|
||||
log::info!("{:?} PostFork", unsafe { libc::getpid() });
|
||||
self.shmem_provider.post_fork(true)?;
|
||||
|
||||
@ -232,6 +236,8 @@ where
|
||||
|
||||
// Broker exited. kill all clients.
|
||||
for handle in &handles {
|
||||
// # Safety
|
||||
// Normal libc call, no dereferences whatsoever
|
||||
unsafe {
|
||||
libc::kill(*handle, libc::SIGINT);
|
||||
}
|
||||
|
@ -79,9 +79,6 @@ extern crate std;
|
||||
#[macro_use]
|
||||
#[doc(hidden)]
|
||||
pub extern crate alloc;
|
||||
#[cfg(feature = "ctor")]
|
||||
#[doc(hidden)]
|
||||
pub use ctor::ctor;
|
||||
|
||||
// Re-export derive(SerdeAny)
|
||||
#[cfg(feature = "derive")]
|
||||
|
@ -12,8 +12,8 @@ edition = "2021"
|
||||
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
||||
|
||||
[features]
|
||||
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "rand_trait", "prelude", "gzip"]
|
||||
std = ["serde_json", "serde_json/std", "hostname", "nix", "serde/std", "once_cell", "uuid", "ctor", "byteorder", "backtrace", "uds", "serial_test"] # print, env, launcher ... support
|
||||
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "rand_trait", "prelude", "gzip", "serdeany_autoreg"]
|
||||
std = ["serde_json", "serde_json/std", "hostname", "nix", "serde/std", "once_cell", "uuid", "byteorder", "backtrace", "uds", "serial_test"] # print, env, launcher ... support
|
||||
derive = ["libafl_derive"] # provide derive(SerdeAny) macro.
|
||||
rand_trait = ["rand_core"] # If set, libafl's rand implementations will implement `rand::Rng`
|
||||
python = ["pyo3"]
|
||||
@ -24,6 +24,9 @@ frida_cli = ["cli"] # Commandline flags for frida-based fuzzers
|
||||
errors_backtrace = ["backtrace"]
|
||||
gzip = ["miniz_oxide"] # Enables gzip compression in certain parts of the lib
|
||||
|
||||
# SerdeAny features
|
||||
serdeany_autoreg = ["ctor"] # Automatically register all `#[derive(SerdeAny)]` types at startup.
|
||||
|
||||
# LLMP features
|
||||
llmp_bind_public = [] # If set, llmp will bind to 0.0.0.0, allowing cross-device communication. Binds to localhost by default.
|
||||
llmp_compression = ["gzip"] # llmp compression using GZip
|
||||
|
@ -143,7 +143,7 @@ macro_rules! create_serde_registry_for_trait {
|
||||
finalized: false,
|
||||
};
|
||||
|
||||
/// This shugar must be used to register all the structs which
|
||||
/// This sugar must be used to register all the structs which
|
||||
/// have trait objects that can be serialized and deserialized in the program
|
||||
#[derive(Debug)]
|
||||
pub struct RegistryBuilder {}
|
||||
@ -151,7 +151,11 @@ macro_rules! create_serde_registry_for_trait {
|
||||
#[allow(unused_qualifications)]
|
||||
impl RegistryBuilder {
|
||||
/// Register a given struct type for trait object (de)serialization
|
||||
pub fn register<T>()
|
||||
///
|
||||
/// # Safety
|
||||
/// This may never be called concurrently or at the same time as `finalize`.
|
||||
/// It dereferences the `REGISTRY` hashmap and adds the given type to it.
|
||||
pub unsafe fn register<T>()
|
||||
where
|
||||
T: $trait_name + Serialize + serde::de::DeserializeOwned,
|
||||
{
|
||||
@ -161,6 +165,10 @@ macro_rules! create_serde_registry_for_trait {
|
||||
}
|
||||
|
||||
/// Finalize the registry, no more registrations are allowed after this call
|
||||
///
|
||||
/// # Safety
|
||||
/// This may never be called concurrently or at the same time as `register`.
|
||||
/// It dereferences the `REGISTRY` hashmap and adds the given type to it.
|
||||
pub fn finalize() {
|
||||
unsafe {
|
||||
REGISTRY.finalize();
|
||||
@ -603,26 +611,36 @@ create_serde_registry_for_trait!(serdeany_registry, crate::serdeany::SerdeAny);
|
||||
pub use serdeany_registry::*;
|
||||
|
||||
/// Register a `SerdeAny` type in the [`RegistryBuilder`]
|
||||
#[cfg(feature = "std")]
|
||||
///
|
||||
/// Do nothing for without the `serdeany_autoreg` feature, you'll have to register it manually
|
||||
/// in `main()` with [`RegistryBuilder::register`] or using `<T>::register()`.
|
||||
#[macro_export]
|
||||
macro_rules! register_at_startup {
|
||||
macro_rules! create_register {
|
||||
($struct_type:ty) => {
|
||||
const _: () = {
|
||||
#[$crate::ctor]
|
||||
fn constructor() {
|
||||
/// Manually register this type at a later point in time
|
||||
///
|
||||
/// # Safety
|
||||
/// This may never be called concurrently as it dereferences the `RegistryBuilder` without acquiring a lock.
|
||||
#[cfg(not(feature = "serdeany_autoreg"))]
|
||||
pub unsafe fn register() {
|
||||
$crate::serdeany::RegistryBuilder::register::<$struct_type>();
|
||||
}
|
||||
|
||||
/// Automatically register this type
|
||||
#[cfg(feature = "serdeany_autoreg")]
|
||||
#[$crate::ctor]
|
||||
fn register() {
|
||||
// # Safety
|
||||
// This `register` call will always run at startup and never in parallel.
|
||||
unsafe {
|
||||
$crate::serdeany::RegistryBuilder::register::<$struct_type>();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/// Do nothing for `no_std`, you have to register it manually in `main()` with [`RegistryBuilder::register`]
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[macro_export]
|
||||
macro_rules! register_at_startup {
|
||||
($struct_type:ty) => {};
|
||||
}
|
||||
|
||||
/// Implement a [`SerdeAny`], registering it in the [`RegistryBuilder`] when on std
|
||||
#[macro_export]
|
||||
macro_rules! impl_serdeany {
|
||||
@ -648,7 +666,7 @@ macro_rules! impl_serdeany {
|
||||
}
|
||||
|
||||
$(
|
||||
$crate::register_at_startup!($struct_name < $( $opt ),+ >);
|
||||
$crate::create_register!($struct_name < $( $opt ),+ >);
|
||||
)*
|
||||
};
|
||||
($struct_name:ident) =>
|
||||
@ -672,6 +690,6 @@ macro_rules! impl_serdeany {
|
||||
}
|
||||
}
|
||||
|
||||
$crate::register_at_startup!($struct_name);
|
||||
$crate::create_register!($struct_name);
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user