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"]
|
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "llmp_broker_timeouts", "rand_trait", "fork", "prelude", "gzip", "regex"]
|
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", "tui_monitor", "ctor", "backtrace", "serial_test", "libafl_bolts/std", "typed-builder"] # print, env, launcher ... support
|
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.
|
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).
|
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`
|
rand_trait = ["libafl_bolts/rand_trait"] # If set, libafl's rand implementations will implement `rand::Rng`
|
||||||
@ -42,6 +42,9 @@ gpl = []
|
|||||||
agpl = ["gpl", "nautilus"]
|
agpl = ["gpl", "nautilus"]
|
||||||
nautilus = ["grammartec", "std", "serde_json/std"]
|
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 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_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
|
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
|
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
|
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"] }
|
serde_json = { version = "1.0", optional = true, default-features = false, features = ["alloc"] }
|
||||||
nix = { version = "0.26", optional = true }
|
nix = { version = "0.26", optional = true }
|
||||||
regex = { version = "1", optional = true }
|
regex = { version = "1", optional = true }
|
||||||
|
@ -169,6 +169,8 @@ where
|
|||||||
if self.cores.ids.iter().any(|&x| x == id.into()) {
|
if self.cores.ids.iter().any(|&x| x == id.into()) {
|
||||||
index += 1;
|
index += 1;
|
||||||
self.shmem_provider.pre_fork()?;
|
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() }? {
|
match unsafe { fork() }? {
|
||||||
ForkResult::Parent(child) => {
|
ForkResult::Parent(child) => {
|
||||||
self.shmem_provider.post_fork(false)?;
|
self.shmem_provider.post_fork(false)?;
|
||||||
@ -177,6 +179,8 @@ where
|
|||||||
log::info!("child spawned and bound to core {id}");
|
log::info!("child spawned and bound to core {id}");
|
||||||
}
|
}
|
||||||
ForkResult::Child => {
|
ForkResult::Child => {
|
||||||
|
// # Safety
|
||||||
|
// A call to `getpid` is safe.
|
||||||
log::info!("{:?} PostFork", unsafe { libc::getpid() });
|
log::info!("{:?} PostFork", unsafe { libc::getpid() });
|
||||||
self.shmem_provider.post_fork(true)?;
|
self.shmem_provider.post_fork(true)?;
|
||||||
|
|
||||||
@ -232,6 +236,8 @@ where
|
|||||||
|
|
||||||
// Broker exited. kill all clients.
|
// Broker exited. kill all clients.
|
||||||
for handle in &handles {
|
for handle in &handles {
|
||||||
|
// # Safety
|
||||||
|
// Normal libc call, no dereferences whatsoever
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::kill(*handle, libc::SIGINT);
|
libc::kill(*handle, libc::SIGINT);
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,6 @@ extern crate std;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub extern crate alloc;
|
pub extern crate alloc;
|
||||||
#[cfg(feature = "ctor")]
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub use ctor::ctor;
|
|
||||||
|
|
||||||
// Re-export derive(SerdeAny)
|
// Re-export derive(SerdeAny)
|
||||||
#[cfg(feature = "derive")]
|
#[cfg(feature = "derive")]
|
||||||
|
@ -12,8 +12,8 @@ edition = "2021"
|
|||||||
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "rand_trait", "prelude", "gzip"]
|
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", "ctor", "byteorder", "backtrace", "uds", "serial_test"] # print, env, launcher ... support
|
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.
|
derive = ["libafl_derive"] # provide derive(SerdeAny) macro.
|
||||||
rand_trait = ["rand_core"] # If set, libafl's rand implementations will implement `rand::Rng`
|
rand_trait = ["rand_core"] # If set, libafl's rand implementations will implement `rand::Rng`
|
||||||
python = ["pyo3"]
|
python = ["pyo3"]
|
||||||
@ -24,6 +24,9 @@ frida_cli = ["cli"] # Commandline flags for frida-based fuzzers
|
|||||||
errors_backtrace = ["backtrace"]
|
errors_backtrace = ["backtrace"]
|
||||||
gzip = ["miniz_oxide"] # Enables gzip compression in certain parts of the lib
|
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 features
|
||||||
llmp_bind_public = [] # If set, llmp will bind to 0.0.0.0, allowing cross-device communication. Binds to localhost by default.
|
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
|
llmp_compression = ["gzip"] # llmp compression using GZip
|
||||||
|
@ -143,7 +143,7 @@ macro_rules! create_serde_registry_for_trait {
|
|||||||
finalized: false,
|
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
|
/// have trait objects that can be serialized and deserialized in the program
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RegistryBuilder {}
|
pub struct RegistryBuilder {}
|
||||||
@ -151,7 +151,11 @@ macro_rules! create_serde_registry_for_trait {
|
|||||||
#[allow(unused_qualifications)]
|
#[allow(unused_qualifications)]
|
||||||
impl RegistryBuilder {
|
impl RegistryBuilder {
|
||||||
/// Register a given struct type for trait object (de)serialization
|
/// 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
|
where
|
||||||
T: $trait_name + Serialize + serde::de::DeserializeOwned,
|
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
|
/// 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() {
|
pub fn finalize() {
|
||||||
unsafe {
|
unsafe {
|
||||||
REGISTRY.finalize();
|
REGISTRY.finalize();
|
||||||
@ -603,26 +611,36 @@ create_serde_registry_for_trait!(serdeany_registry, crate::serdeany::SerdeAny);
|
|||||||
pub use serdeany_registry::*;
|
pub use serdeany_registry::*;
|
||||||
|
|
||||||
/// Register a `SerdeAny` type in the [`RegistryBuilder`]
|
/// 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_export]
|
||||||
macro_rules! register_at_startup {
|
macro_rules! create_register {
|
||||||
($struct_type:ty) => {
|
($struct_type:ty) => {
|
||||||
const _: () = {
|
const _: () = {
|
||||||
#[$crate::ctor]
|
/// Manually register this type at a later point in time
|
||||||
fn constructor() {
|
///
|
||||||
|
/// # 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>();
|
$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
|
/// Implement a [`SerdeAny`], registering it in the [`RegistryBuilder`] when on std
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_serdeany {
|
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) =>
|
($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