working on restore

This commit is contained in:
Dominik Maier 2021-01-03 19:55:13 +01:00
parent dd861e2396
commit bade18eaf3
3 changed files with 46 additions and 26 deletions

View File

@ -413,6 +413,13 @@ where
})
}
/// Completely reset the current sender map.
/// Afterwards, no receiver should read from it at a different location.
/// This is only useful if all connected llmp parties start over, for example after a crash.
pub unsafe fn reset_last_page(&mut self) {
_llmp_page_init(&mut self.out_maps.last_mut().unwrap().shmem, self.id);
}
/// Reattach to a vacant out_map, to with a previous sender stored the information in an env before.
#[cfg(feature = "std")]
pub fn on_existing_from_env(env_name: &str) -> Result<Self, AflError> {

View File

@ -23,6 +23,8 @@ num_cpus = "1.0"
[dependencies]
clap = "2.32.0"
serde = { version = "1.0", default-features = false, features = ["alloc"] }
postcard = { version = "0.5.1", features = ["alloc"] }
afl = { path = "../../afl/" }
[[bin]]

View File

@ -2,6 +2,7 @@
extern crate clap;
use clap::{App, Arg};
use postcard;
use std::{env, path::PathBuf, process::Command};
use afl::{
@ -25,7 +26,8 @@ use afl::{
};
/// The llmp connection from the actual fuzzer to the process supervising it
const ENV_FUZZER_PARENT_SENDER: &str = &"_AFL_ENV_FUZZER_PARENT_SENDER";
const ENV_FUZZER_SENDER: &str = &"_AFL_ENV_FUZZER_SENDER";
const ENV_FUZZER_RECEIVER: &str = &"_AFL_ENV_FUZZER_RECEIVER";
/// The llmp (2 way) connection from a fuzzer to the broker (broadcasting all other fuzzer messages)
const ENV_FUZZER_BROKER_CLIENT: &str = &"_AFL_ENV_FUZZER_BROKER_CLIENT";
@ -56,13 +58,12 @@ fn harness<I>(_executor: &dyn Executor<I>, buf: &[u8]) -> ExitKind {
/// The actual fuzzer
fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
let mut rand = StdRand::new(0);
let mut corpus = InMemoryCorpus::new();
let mut generator = RandPrintablesGenerator::new(32);
let stats = SimpleStats::new(|s| println!("{}", s));
let mut mgr;
// We start ourself as child process to actually fuzz
if std::env::var(ENV_FUZZER_PARENT_SENDER).is_err() {
if std::env::var(ENV_FUZZER_SENDER).is_err() {
// We are either the broker, or the parent of the fuzzing instance
mgr = LlmpEventManager::new_on_port_std(broker_port, stats.clone())?;
if mgr.is_broker() {
@ -77,12 +78,13 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
// First, create a channel from the fuzzer (sender) to us (receiver) to report its state for restarts.
let sender = LlmpSender::new(0, false)?;
let mut receiver = LlmpReceiver::on_existing_map(
let receiver = LlmpReceiver::on_existing_map(
AflShmem::clone_ref(&sender.out_maps.last().unwrap().shmem)?,
None,
)?;
// Store the information to a map.
sender.to_env(ENV_FUZZER_PARENT_SENDER)?;
sender.to_env(ENV_FUZZER_SENDER)?;
receiver.to_env(ENV_FUZZER_RECEIVER)?;
loop {
dbg!("Spawning next client");
@ -90,23 +92,38 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
.current_dir(env::current_dir()?)
.args(env::args())
.status()?;
match receiver.recv_buf()? {
None => panic!("Fuzzer process exited without giving us its result."),
Some((sender, tag, msg)) => {
todo!("Restore this: {}, {}, {:?}", sender, tag, msg);
}
}
}
}
}
println!("We're a client, let's fuzz :)");
// We are the fuzzing instance
// We are the fuzzing instance, first, connect to all channels.
// Mgr to send and receive msgs from/to all other fuzzer instances
mgr = LlmpEventManager::existing_client_from_env_std(ENV_FUZZER_BROKER_CLIENT, stats)?;
let channel_sender = LlmpSender::<AflShmem>::on_existing_from_env(ENV_FUZZER_PARENT_SENDER)?;
// A sender and a receiver for single communication
let mut receiver = LlmpReceiver::<AflShmem>::on_existing_from_env(ENV_FUZZER_RECEIVER)?;
let mut sender = LlmpSender::<AflShmem>::on_existing_from_env(ENV_FUZZER_SENDER)?;
// Call LLVMFUzzerInitialize() if present.
unsafe {
if afl_libfuzzer_init() == -1 {
println!("Warning: LLVMFuzzerInitialize failed with -1")
}
}
// If we're restarting, deserialize the old corpus.
let mut corpus = match receiver.recv_buf()? {
None => {
// Initial execution, read or generate initial inputs
InMemoryCorpus::new()
}
Some((_sender, _tag, msg)) => postcard::from_bytes(msg)?,
};
// We reset the sender, the next sender and receiver (after crash) will reuse the page from the initial message.
unsafe { sender.reset_last_page() };
// TODO: How to restore the observer state?
let edges_observer =
StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { __lafl_edges_map }, unsafe {
__lafl_max_edges_size as usize
@ -118,20 +135,14 @@ fn fuzz(input: Option<Vec<PathBuf>>, broker_port: u16) -> Result<(), AflError> {
let mut engine = Engine::new(executor);
// Call LLVMFUzzerInitialize() if present.
unsafe {
if afl_libfuzzer_init() == -1 {
println!("Warning: LLVMFuzzerInitialize failed with -1")
if corpus.count() < 1 {
match input {
Some(x) => state
.load_initial_inputs(&mut corpus, &mut generator, &mut engine, &mut mgr, &x)
.expect(&format!("Failed to load initial corpus at {:?}", &x)),
None => (),
}
}
match input {
Some(x) => state
.load_initial_inputs(&mut corpus, &mut generator, &mut engine, &mut mgr, &x)
.expect(&format!("Failed to load initial corpus at {:?}", &x)),
None => (),
}
if corpus.count() < 1 {
println!("Generating random inputs");
state