Skip to content

Commit bc18cbc

Browse files
committed
Merge branch 'launcher' of https://github.com/AFLplusplus/LibAFL into launcher
2 parents 04bafff + f0c6e37 commit bc18cbc

File tree

5 files changed

+59
-62
lines changed

5 files changed

+59
-62
lines changed

libafl/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ harness = false
3737

3838
[features]
3939
default = ["std", "anymap_debug", "derive", "llmp_compression"]
40-
std = ["derive_builder"] # print, sharedmap, ... support
40+
std = [] # print, env, launcher ... support
4141
anymap_debug = ["serde_json"] # uses serde_json to Debug the anymap trait. Disable for smaller footprint.
4242
derive = ["libafl_derive"] # provide derive(SerdeAny) macro.
4343
llmp_small_maps = [] # reduces initial map size for llmp
@@ -66,7 +66,7 @@ compression = { version = "0.1.5" }
6666
core_affinity = { version = "0.5", git = "https://github.com/s1341/core_affinity_rs" }
6767
num_enum = "0.5.1"
6868
hostname = "^0.3" # Is there really no gethostname in the stdlib?
69-
derive_builder = { version="0.10", optional = true }
69+
typed-builder = "0.9.0"
7070

7171
[target.'cfg(target_os = "android")'.dependencies]
7272
backtrace = { version = "0.3", optional = true, default-features = false, features = ["std", "libbacktrace"] } # for llmp_debug

libafl/src/bolts/llmp.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,7 +1707,7 @@ where
17071707
// TODO: handle broker_ids properly/at all.
17081708
let map_description = Self::b2b_thread_on(
17091709
stream,
1710-
&self.shmem_provider,
1710+
&mut self.shmem_provider,
17111711
self.llmp_clients.len() as ClientId,
17121712
&self.llmp_out.out_maps.first().unwrap().shmem.description(),
17131713
)?;
@@ -1858,11 +1858,13 @@ where
18581858
#[allow(clippy::let_and_return)]
18591859
fn b2b_thread_on(
18601860
mut stream: TcpStream,
1861-
shmem_provider: &SP,
1861+
shmem_provider: &mut SP,
18621862
b2b_client_id: ClientId,
18631863
broker_map_description: &ShMemDescription,
18641864
) -> Result<ShMemDescription, Error> {
18651865
let broker_map_description = *broker_map_description;
1866+
1867+
shmem_provider.pre_fork()?;
18661868
let mut shmem_provider_clone = shmem_provider.clone();
18671869

18681870
// A channel to get the new "client's" sharedmap id from
@@ -1963,6 +1965,8 @@ where
19631965
}
19641966
});
19651967

1968+
shmem_provider.post_fork(false)?;
1969+
19661970
let ret = recv.recv().map_err(|_| {
19671971
Error::Unknown("Error launching background thread for b2b communcation".to_string())
19681972
});
@@ -1980,7 +1984,7 @@ where
19801984
request: &TcpRequest,
19811985
current_client_id: &mut u32,
19821986
sender: &mut LlmpSender<SP>,
1983-
shmem_provider: &SP,
1987+
shmem_provider: &mut SP,
19841988
broker_map_description: &ShMemDescription,
19851989
) {
19861990
match request {
@@ -2060,6 +2064,7 @@ where
20602064
let tcp_out_map_description = tcp_out_map.shmem.description();
20612065
self.register_client(tcp_out_map);
20622066

2067+
self.shmem_provider.pre_fork()?;
20632068
let mut shmem_provider_clone = self.shmem_provider.clone();
20642069

20652070
let ret = thread::spawn(move || {
@@ -2116,7 +2121,7 @@ where
21162121
&req,
21172122
&mut current_client_id,
21182123
&mut tcp_incoming_sender,
2119-
&shmem_provider_clone,
2124+
&mut shmem_provider_clone,
21202125
&broker_map_description,
21212126
);
21222127
}

libafl/src/bolts/shmem.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,15 @@ pub trait ShMemProvider: Send + Clone + Default + Debug {
196196

197197
/// This method should be called before a fork or a thread creation event, allowing the [`ShMemProvider`] to
198198
/// get ready for a potential reset of thread specific info, and for potential reconnects.
199+
/// Make sure to call [`Self::post_fork()`] after threading!
199200
fn pre_fork(&mut self) -> Result<(), Error> {
200201
// do nothing
201202
Ok(())
202203
}
203204

204205
/// This method should be called after a fork or after cloning/a thread creation event, allowing the [`ShMemProvider`] to
205206
/// reset thread specific info, and potentially reconnect.
207+
/// Make sure to call [`Self::pre_fork()`] before threading!
206208
fn post_fork(&mut self, _is_child: bool) -> Result<(), Error> {
207209
// do nothing
208210
Ok(())
@@ -356,7 +358,7 @@ where
356358
Ok(())
357359
}
358360
None => Err(Error::IllegalState(
359-
"Unexpected `None` Pipe in RcShMemProvider!".to_string(),
361+
"Unexpected `None` Pipe in RcShMemProvider! Missing post_fork()?".to_string(),
360362
)),
361363
}
362364
}
@@ -378,7 +380,7 @@ where
378380
}
379381
}
380382
None => Err(Error::IllegalState(
381-
"Unexpected `None` Pipe in RcShMemProvider!".to_string(),
383+
"Unexpected `None` Pipe in RcShMemProvider! Missing post_fork()?".to_string(),
382384
)),
383385
}
384386
}

libafl/src/events/llmp.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ use crate::utils::{fork, ForkResult};
4848
#[cfg(all(target_os = "android", feature = "std"))]
4949
use crate::bolts::os::ashmem_server::AshmemService;
5050

51-
#[cfg(feature = "std")]
52-
use derive_builder::Builder;
51+
use typed_builder::TypedBuilder;
5352

5453
/// Forward this to the client
5554
const _LLMP_TAG_EVENT_TO_CLIENT: llmp::Tag = 0x2C11E471;
@@ -580,22 +579,20 @@ where
580579
#[cfg(target_os = "android")]
581580
AshmemService::start().expect("Error starting Ashmem Service");
582581

583-
RestartingMgrBuilder::default()
582+
RestartingMgr::builder()
584583
.shmem_provider(StdShMemProvider::new()?)
585584
.stats(stats)
586585
.broker_port(broker_port)
587586
.build()
588-
.unwrap()
589587
.launch()
590588
}
591589

592-
/// Provides a builder which can be used to build a restarting manager, which is a combination of a
593-
/// restarter and runner, that can be used on systems both with and without `fork` support. The
594-
/// restarter will start a nre process each time the child crashes or timesout.
590+
/// Provides a `builder` which can be used to build a [`RestartingMgr`], which is a combination of a
591+
/// `restarter` and `runner`, that can be used on systems both with and without `fork` support. The
592+
/// `restarter` will start a new process each time the child crashes or times out.
595593
#[cfg(feature = "std")]
596594
#[allow(clippy::default_trait_access)]
597-
#[derive(Builder, Debug)]
598-
#[builder(pattern = "owned")]
595+
#[derive(TypedBuilder, Debug)]
599596
pub struct RestartingMgr<I, S, SP, ST>
600597
where
601598
I: Input,
@@ -609,15 +606,15 @@ where
609606
/// The stats to use
610607
stats: ST,
611608
/// The broker port to use
612-
#[builder(default = "1337")]
609+
#[builder(default = 1337_u16)]
613610
broker_port: u16,
614611
/// The address to connect to
615-
#[builder(default = "Option::None")]
612+
#[builder(default = None)]
616613
remote_broker_addr: Option<SocketAddr>,
617614
/// The type of manager to build
618-
#[builder(default = "ManagerKind::Any")]
615+
#[builder(default = ManagerKind::Any)]
619616
kind: ManagerKind,
620-
#[builder(setter(skip))]
617+
#[builder(setter(skip), default = PhantomData {})]
621618
_phantom: PhantomData<(I, S)>,
622619
}
623620

@@ -642,11 +639,12 @@ where
642639
)?;
643640

644641
// We start ourself as child process to actually fuzz
645-
let (sender, mut receiver, mut new_shmem_provider, core_id) = if std::env::var(
642+
let (sender, mut receiver, new_shmem_provider, core_id) = if std::env::var(
646643
_ENV_FUZZER_SENDER,
647644
)
648645
.is_err()
649646
{
647+
// We get here if we are on Unix, or we are a broker on Windows.
650648
let core_id = if mgr.is_broker() {
651649
match self.kind {
652650
ManagerKind::Broker | ManagerKind::Any => {
@@ -709,12 +707,19 @@ where
709707
loop {
710708
dbg!("Spawning next client (id {})", ctr);
711709

712-
// On Unix, we fork (todo: measure if that is actually faster.)
710+
// On Unix, we fork
713711
#[cfg(unix)]
714-
let child_status = match unsafe { fork() }? {
715-
ForkResult::Parent(handle) => handle.status(),
716-
ForkResult::Child => {
717-
break (sender, receiver, self.shmem_provider.clone(), core_id)
712+
let child_status = {
713+
self.shmem_provider.pre_fork()?;
714+
match unsafe { fork() }? {
715+
ForkResult::Parent(handle) => {
716+
self.shmem_provider.post_fork(false)?;
717+
handle.status()
718+
}
719+
ForkResult::Child => {
720+
self.shmem_provider.post_fork(true)?;
721+
break (sender, receiver, self.shmem_provider.clone(), core_id);
722+
}
718723
}
719724
};
720725

@@ -739,9 +744,9 @@ where
739744
ctr = ctr.wrapping_add(1);
740745
}
741746
} else {
742-
// We are the newly started fuzzing instance, first, connect to our own restore map.
747+
// We are the newly started fuzzing instance (i.e. on Windows), first, connect to our own restore map.
748+
// We get here *only on Windows*, if we were started by a restarting fuzzer.
743749
// A sender and a receiver for single communication
744-
self.shmem_provider.post_fork(true)?;
745750
(
746751
LlmpSender::on_existing_from_env(self.shmem_provider.clone(), _ENV_FUZZER_SENDER)?,
747752
LlmpReceiver::on_existing_from_env(
@@ -753,8 +758,6 @@ where
753758
)
754759
};
755760

756-
new_shmem_provider.post_fork(false)?;
757-
758761
if let Some(core_id) = core_id {
759762
core_affinity::set_for_current(core_id);
760763
}

libafl/src/utils.rs

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use xxhash_rust::xxh3::xxh3_64_with_seed;
1818
use serde::{de::DeserializeOwned, Deserialize, Serialize};
1919

2020
#[cfg(feature = "std")]
21-
use crate::events::llmp::RestartingMgrBuilder;
21+
use crate::events::llmp::RestartingMgr;
2222

2323
#[cfg(unix)]
2424
use libc::pid_t;
@@ -40,8 +40,7 @@ use core_affinity::CoreId;
4040
#[cfg(all(windows, feature = "std"))]
4141
use std::process::Stdio;
4242

43-
#[cfg(feature = "std")]
44-
use derive_builder::Builder;
43+
use typed_builder::TypedBuilder;
4544

4645
/// Can be converted to a slice
4746
pub trait AsSlice<T> {
@@ -601,9 +600,8 @@ mod tests {
601600

602601
/// Provides a Launcher, which can be used to launch a fuzzing run on a specified list of cores
603602
#[cfg(feature = "std")]
604-
#[derive(Builder)]
603+
#[derive(TypedBuilder)]
605604
#[allow(clippy::type_complexity)]
606-
#[builder(pattern = "owned")]
607605
pub struct Launcher<'a, I, S, SP, ST>
608606
where
609607
I: Input,
@@ -621,16 +619,16 @@ where
621619
run_client:
622620
&'a mut dyn FnMut(Option<S>, LlmpRestartingEventManager<I, S, SP, ST>) -> Result<(), Error>,
623621
/// The broker port to use
624-
#[builder(default = "1337")]
622+
#[builder(default = 1337_u16)]
625623
broker_port: u16,
626624
/// The list of cores to run on
627625
cores: &'a [usize],
628626
/// A file name to write all client output to
629-
#[builder(default = "None")]
627+
#[builder(default = None)]
630628
stdout_file: Option<&'a str>,
631629
/// The `ip:port` address of another broker to connect our new broker to for multi-machine
632630
/// clusters.
633-
#[builder(default = "None")]
631+
#[builder(default = None)]
634632
remote_broker_addr: Option<SocketAddr>,
635633
}
636634

@@ -658,6 +656,7 @@ where
658656
//spawn clients
659657
for (id, bind_to) in core_ids.iter().enumerate().take(num_cores) {
660658
if self.cores.iter().any(|&x| x == id) {
659+
self.shmem_provider.pre_fork()?;
661660
match unsafe { fork() }? {
662661
ForkResult::Parent(child) => {
663662
self.shmem_provider.post_fork(false)?;
@@ -678,15 +677,14 @@ where
678677
}
679678
//fuzzer client. keeps retrying the connection to broker till the broker starts
680679
let stats = (self.client_init_stats)()?;
681-
let (state, mgr) = RestartingMgrBuilder::default()
680+
let (state, mgr) = RestartingMgr::builder()
682681
.shmem_provider(self.shmem_provider.clone())
683682
.stats(stats)
684683
.broker_port(self.broker_port)
685684
.kind(ManagerKind::Client {
686685
cpu_core: Some(*bind_to),
687686
})
688687
.build()
689-
.unwrap()
690688
.launch()?;
691689

692690
(self.run_client)(state, mgr)?;
@@ -698,25 +696,14 @@ where
698696
#[cfg(feature = "std")]
699697
println!("I am broker!!.");
700698

701-
if let Some(remote_broker_addr) = self.remote_broker_addr {
702-
RestartingMgrBuilder::<I, S, SP, ST>::default()
703-
.shmem_provider(self.shmem_provider.clone())
704-
.stats(self.stats.clone())
705-
.broker_port(self.broker_port)
706-
.remote_broker_addr(Some(remote_broker_addr))
707-
.build()
708-
.unwrap()
709-
.launch()?;
710-
} else {
711-
RestartingMgrBuilder::<I, S, SP, ST>::default()
712-
.shmem_provider(self.shmem_provider.clone())
713-
.stats(self.stats.clone())
714-
.broker_port(self.broker_port)
715-
.kind(ManagerKind::Broker)
716-
.build()
717-
.unwrap()
718-
.launch()?;
719-
}
699+
RestartingMgr::<I, S, SP, ST>::builder()
700+
.shmem_provider(self.shmem_provider.clone())
701+
.stats(self.stats.clone())
702+
.broker_port(self.broker_port)
703+
.kind(ManagerKind::Broker)
704+
.remote_broker_addr(self.remote_broker_addr)
705+
.build()
706+
.launch()?;
720707

721708
//broker exited. kill all clients.
722709
for handle in &handles {
@@ -740,7 +727,7 @@ where
740727

741728
// the actual client. do the fuzzing
742729
let stats = (self.client_init_stats)()?;
743-
let (state, mgr) = RestartingMgrBuilder::<I, S, SP, ST>::default()
730+
let (state, mgr) = RestartingMgr::<I, S, SP, ST>::builder()
744731
.shmem_provider(self.shmem_provider.clone())
745732
.stats(stats)
746733
.broker_port(self.broker_port)
@@ -798,7 +785,7 @@ where
798785
#[cfg(feature = "std")]
799786
println!("I am broker!!.");
800787

801-
RestartingMgrBuilder::<I, S, SP, ST>::default()
788+
RestartingMgr::<I, S, SP, ST>::builder()
802789
.shmem_provider(self.shmem_provider.clone())
803790
.stats(self.stats.clone())
804791
.broker_port(self.broker_port)

0 commit comments

Comments
 (0)