Skip to content

Commit 234a331

Browse files
committed
you get a pre_fork, and you get a post_fork, forks for everyone
1 parent 7fc3a85 commit 234a331

File tree

4 files changed

+42
-40
lines changed

4 files changed

+42
-40
lines changed

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: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -589,9 +589,9 @@ where
589589
.launch()
590590
}
591591

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.
592+
/// Provides a `builder` which can be used to build a [`RestartingMgr`], 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 new process each time the child crashes or times out.
595595
#[cfg(feature = "std")]
596596
#[allow(clippy::default_trait_access)]
597597
#[derive(Builder, Debug)]
@@ -642,11 +642,12 @@ where
642642
)?;
643643

644644
// We start ourself as child process to actually fuzz
645-
let (sender, mut receiver, mut new_shmem_provider, core_id) = if std::env::var(
645+
let (sender, mut receiver, new_shmem_provider, core_id) = if std::env::var(
646646
_ENV_FUZZER_SENDER,
647647
)
648648
.is_err()
649649
{
650+
// We get here if we are on Unix, or we are a broker on Windows.
650651
let core_id = if mgr.is_broker() {
651652
match self.kind {
652653
ManagerKind::Broker | ManagerKind::Any => {
@@ -709,12 +710,19 @@ where
709710
loop {
710711
dbg!("Spawning next client (id {})", ctr);
711712

712-
// On Unix, we fork (todo: measure if that is actually faster.)
713+
// On Unix, we fork
713714
#[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)
715+
let child_status = {
716+
self.shmem_provider.pre_fork()?;
717+
match unsafe { fork() }? {
718+
ForkResult::Parent(handle) => {
719+
self.shmem_provider.post_fork(false)?;
720+
handle.status()
721+
}
722+
ForkResult::Child => {
723+
self.shmem_provider.post_fork(true)?;
724+
break (sender, receiver, self.shmem_provider.clone(), core_id);
725+
}
718726
}
719727
};
720728

@@ -739,9 +747,9 @@ where
739747
ctr = ctr.wrapping_add(1);
740748
}
741749
} else {
742-
// We are the newly started fuzzing instance, first, connect to our own restore map.
750+
// We are the newly started fuzzing instance (i.e. on Windows), first, connect to our own restore map.
751+
// We get here *only on Windows*, if we were started by a restarting fuzzer.
743752
// A sender and a receiver for single communication
744-
self.shmem_provider.post_fork(true)?;
745753
(
746754
LlmpSender::on_existing_from_env(self.shmem_provider.clone(), _ENV_FUZZER_SENDER)?,
747755
LlmpReceiver::on_existing_from_env(
@@ -753,8 +761,6 @@ where
753761
)
754762
};
755763

756-
new_shmem_provider.post_fork(false)?;
757-
758764
if let Some(core_id) = core_id {
759765
core_affinity::set_for_current(core_id);
760766
}

libafl/src/utils.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ where
658658
//spawn clients
659659
for (id, bind_to) in core_ids.iter().enumerate().take(num_cores) {
660660
if self.cores.iter().any(|&x| x == id) {
661+
self.shmem_provider.pre_fork()?;
661662
match unsafe { fork() }? {
662663
ForkResult::Parent(child) => {
663664
self.shmem_provider.post_fork(false)?;
@@ -698,27 +699,15 @@ where
698699
#[cfg(feature = "std")]
699700
println!("I am broker!!.");
700701

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-
.kind(ManagerKind::ConnectedBroker {
707-
connect_to: remote_broker_addr,
708-
})
709-
.build()
710-
.unwrap()
711-
.launch()?;
712-
} else {
713-
RestartingMgrBuilder::<I, S, SP, ST>::default()
714-
.shmem_provider(self.shmem_provider.clone())
715-
.stats(self.stats.clone())
716-
.broker_port(self.broker_port)
717-
.kind(ManagerKind::Broker)
718-
.build()
719-
.unwrap()
720-
.launch()?;
721-
}
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+
.kind(ManagerKind::Broker)
707+
.remote_broker_addr(self.remote_broker_addr)
708+
.build()
709+
.unwrap()
710+
.launch()?;
722711

723712
//broker exited. kill all clients.
724713
for handle in &handles {

0 commit comments

Comments
 (0)