From e5390126602affe5cefcd629c027dfe5aaee186a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 27 Nov 2020 12:10:24 +0100 Subject: [PATCH] implemented drop for llmp structs --- afl/Cargo.toml | 4 +- afl/src/corpus/mod.rs | 6 +-- afl/src/engines/mod.rs | 4 +- afl/src/events/llmp_translated.rs | 40 +++++++++----- afl/src/events/mod.rs | 86 ++++++++++++++++++++++++++++++- afl/src/executors/inmemory.rs | 2 +- afl/src/feedbacks/mod.rs | 8 +-- afl/src/generators/mod.rs | 4 +- afl/src/inputs/bytes.rs | 2 +- afl/src/mutators/scheduled.rs | 4 +- afl/src/observers/mod.rs | 2 +- afl/src/stages/mutational.rs | 2 +- 12 files changed, 131 insertions(+), 33 deletions(-) diff --git a/afl/Cargo.toml b/afl/Cargo.toml index a21238edca..d6ca4c4758 100644 --- a/afl/Cargo.toml +++ b/afl/Cargo.toml @@ -17,4 +17,6 @@ std = [] hashbrown = "0.9" # A faster hashmap, nostd compatible libc = "0.2" # For (*nix) libc num = "*" -xxhash-rust = { version = "0.8.0-beta.5", features = ["xxh3"] } # xxh3 hashing for rust \ No newline at end of file +xxhash-rust = { version = "0.8.0-beta.5", features = ["xxh3"] } # xxh3 hashing for rust +serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib +postcard = "0.5.1" # no_std compatible serde serialization fromat \ No newline at end of file diff --git a/afl/src/corpus/mod.rs b/afl/src/corpus/mod.rs index ea7467a95c..8a50907f7a 100644 --- a/afl/src/corpus/mod.rs +++ b/afl/src/corpus/mod.rs @@ -158,7 +158,7 @@ where R: Rand, { pub fn new() -> Self { - InMemoryCorpus { + Self { entries: vec![], pos: 0, phantom: PhantomData, @@ -238,7 +238,7 @@ where R: Rand, { pub fn new(dir_path: PathBuf) -> Self { - OnDiskCorpus { + Self { dir_path: dir_path, entries: vec![], pos: 0, @@ -326,7 +326,7 @@ where R: Rand, { pub fn new(corpus: C) -> Self { - QueueCorpus { + Self { corpus: corpus, phantom: PhantomData, cycles: 0, diff --git a/afl/src/engines/mod.rs b/afl/src/engines/mod.rs index e616b2a8c8..b353e7f2fd 100644 --- a/afl/src/engines/mod.rs +++ b/afl/src/engines/mod.rs @@ -267,7 +267,7 @@ where R: Rand, { pub fn new(executor: E) -> Self { - StdState { + Self { executions: 0, start_time: current_milliseconds(), metadatas: HashMap::default(), @@ -386,7 +386,7 @@ where R: Rand, { pub fn new() -> Self { - StdEngine { + Self { stages: vec![], phantom: PhantomData, } diff --git a/afl/src/events/llmp_translated.rs b/afl/src/events/llmp_translated.rs index 07971b4507..694c3c0f07 100644 --- a/afl/src/events/llmp_translated.rs +++ b/afl/src/events/llmp_translated.rs @@ -92,7 +92,7 @@ pub struct afl_alloc_buf { pub buf: [u8; 0], } -#[derive(Copy, Clone)] +#[derive(Clone)] #[repr(C)] pub struct llmp_client { pub id: u32, @@ -123,7 +123,7 @@ pub struct llmp_message { pub buf: [u8; 0], } -#[derive(Copy, Clone)] +#[derive(Clone)] #[repr(C)] pub struct llmp_broker_state { pub last_msg_sent: *mut llmp_message, @@ -626,7 +626,7 @@ unsafe fn llmp_handle_out_eop( } } /* no more space left! We'll have to start a new page */ -pub unsafe fn llmp_broker_handle_out_eop(mut broker: *mut llmp_broker_state) -> AflRet { +pub unsafe fn llmp_broker_handle_out_eop(broker: *mut llmp_broker_state) -> AflRet { (*broker).broadcast_maps = llmp_handle_out_eop( (*broker).broadcast_maps, &mut (*broker).broadcast_map_count, @@ -669,7 +669,7 @@ pub unsafe fn llmp_broker_alloc_next( /* Registers a new client for the given sharedmap str and size. Be careful: Intenral realloc may change the location of the client map */ unsafe fn llmp_broker_register_client( - mut broker: *mut llmp_broker_state, + broker: *mut llmp_broker_state, shm_str: &CStr, map_size: c_ulong, ) -> *mut llmp_broker_client_metadata { @@ -716,7 +716,7 @@ unsafe fn llmp_broker_register_client( /* broker broadcast to its own page for all others to read */ #[inline] unsafe fn llmp_broker_handle_new_msgs( - mut broker: *mut llmp_broker_state, + broker: *mut llmp_broker_state, mut client: *mut llmp_broker_client_metadata, ) { // TODO: We could memcpy a range of pending messages, instead of one by one. @@ -1010,7 +1010,7 @@ pub unsafe fn llmp_broker_run(broker: *mut llmp_broker_state) -> ! { eventually. This function This funtion sees if we can unallocate older pages. The broker would have informed us by setting the save_to_unmap-flag. */ -unsafe fn llmp_client_prune_old_pages(mut client: *mut llmp_client) { +unsafe fn llmp_client_prune_old_pages(client: *mut llmp_client) { let current_map: *mut u8 = (*(*client) .out_maps .offset((*client).out_map_count.wrapping_sub(1 as c_ulong) as isize)) @@ -1034,7 +1034,7 @@ unsafe fn llmp_client_prune_old_pages(mut client: *mut llmp_client) { } } /* We don't have any space. Send eop, the reset to beginning of ringbuf */ -unsafe fn llmp_client_handle_out_eop(mut client: *mut llmp_client) -> bool { +unsafe fn llmp_client_handle_out_eop(client: *mut llmp_client) -> bool { (*client).out_maps = llmp_handle_out_eop( (*client).out_maps, &mut (*client).out_map_count, @@ -1054,7 +1054,7 @@ unsafe fn llmp_client_handle_out_eop(mut client: *mut llmp_client) -> bool { } /* A client receives a broadcast message. Returns null if no message is * availiable */ -pub unsafe fn llmp_client_recv(mut client: *mut llmp_client) -> *mut llmp_message { +pub unsafe fn llmp_client_recv(client: *mut llmp_client) -> *mut llmp_message { loop { let msg = llmp_recv( shmem2page((*client).current_broadcast_map), @@ -1218,7 +1218,7 @@ pub unsafe fn llmp_client_cancel(client: *mut llmp_client, mut msg: *mut llmp_me } /* Commits a msg to the client's out ringbuf */ pub unsafe fn llmp_client_send( - mut client_state: *mut llmp_client, + client_state: *mut llmp_client, msg: *mut llmp_message, ) -> Result<(), AflError> { let page: *mut llmp_page = shmem2page( @@ -1233,7 +1233,7 @@ pub unsafe fn llmp_client_send( /* Creates a new, unconnected, client state */ pub unsafe fn llmp_client_new_unconnected() -> *mut llmp_client { - let mut client_state: *mut llmp_client = calloc( + let client_state: *mut llmp_client = calloc( 1 as c_ulong, ::std::mem::size_of::() as c_ulong, ) as *mut llmp_client; @@ -1269,7 +1269,7 @@ pub unsafe fn llmp_client_new_unconnected() -> *mut llmp_client { return client_state; } /* Destroys the given cient state */ -pub unsafe fn llmp_client_delete(mut client_state: *mut llmp_client) { +pub unsafe fn llmp_client_delete(client_state: *mut llmp_client) { let mut i: c_ulong = 0; while i < (*client_state).out_map_count { afl_shmem_deinit(&mut *(*client_state).out_maps.offset(i as isize)); @@ -1287,6 +1287,12 @@ pub unsafe fn llmp_client_delete(mut client_state: *mut llmp_client) { free(client_state as *mut c_void); } +impl Drop for llmp_client { + fn drop(&mut self) { + unsafe { llmp_client_delete(self) }; + } +} + /* Register a new forked/child client. Client thread will be called with llmp_client client, containing the data in ->data. This will register a client to be spawned up as soon as @@ -1294,7 +1300,7 @@ broker_loop() starts. Clients can also be added later via llmp_broker_register_remote(..) or the local_tcp_client */ pub unsafe fn llmp_broker_register_childprocess_clientloop( - mut broker: *mut llmp_broker_state, + broker: *mut llmp_broker_state, clientloop: LlmpClientloopFn, data: *mut c_void, ) -> Result<(), AflError> { @@ -1414,7 +1420,7 @@ pub unsafe fn llmp_broker_add_message_hook( /* Allocate and set up the new broker instance. Afterwards, run with * broker_run. */ -pub unsafe fn llmp_broker_init(mut broker: *mut llmp_broker_state) -> Result<(), AflError> { +pub unsafe fn llmp_broker_init(broker: *mut llmp_broker_state) -> Result<(), AflError> { memset( broker as *mut c_void, 0 as c_int, @@ -1444,7 +1450,7 @@ pub unsafe fn llmp_broker_init(mut broker: *mut llmp_broker_state) -> Result<(), return Ok(()); } /* Clean up the broker instance */ -pub unsafe fn llmp_broker_deinit(mut broker: *mut llmp_broker_state) { +pub unsafe fn llmp_broker_deinit(broker: *mut llmp_broker_state) { let mut i: c_ulong; i = 0 as c_ulong; while i < (*broker).broadcast_map_count { @@ -1463,3 +1469,9 @@ pub unsafe fn llmp_broker_deinit(mut broker: *mut llmp_broker_state) { afl_free((*broker).llmp_clients as *mut c_void); (*broker).llmp_client_count = 0 as c_ulong; } + +impl Drop for llmp_broker_state { + fn drop(&mut self) { + unsafe { llmp_broker_deinit(self) }; + } +} diff --git a/afl/src/events/mod.rs b/afl/src/events/mod.rs index f396ab522d..634555e720 100644 --- a/afl/src/events/mod.rs +++ b/afl/src/events/mod.rs @@ -5,6 +5,8 @@ use alloc::borrow::ToOwned; use alloc::string::String; use core::marker::PhantomData; +use serde::{Deserialize, Serialize}; + #[cfg(feature = "std")] pub mod llmp_translated; // TODO: Abstract away. #[cfg(feature = "std")] @@ -65,6 +67,7 @@ where */ /// Events sent around in the library +#[derive(Serialize, Deserialize, Debug)] pub enum Event where S: State, @@ -345,9 +348,90 @@ where //TODO CE: CustomEvent, { pub fn new(writer: W) -> Self { - LoggerEventManager { + Self { events: vec![], writer: writer, } } } + +/// Eventmanager for multi-processed application +#[cfg(feature = "std")] +pub struct LLMPEventManager +where + S: State, + C: Corpus, + I: Input, + E: Executor, + R: Rand, + //CE: CustomEvent, +{ + // TODO... + _marker: PhantomData<(S, C, E, I, R)>, +} + +#[cfg(feature = "std")] +impl EventManager for LLMPEventManager +where + S: State, + C: Corpus, + E: Executor, + I: Input, + R: Rand, + //CE: CustomEvent, +{ + fn enabled(&self) -> bool { + true + } + + fn fire(&mut self, event: Event) -> Result<(), AflError> { + //self.events.push(event); + Ok(()) + } + + fn process(&mut self, state: &mut S, corpus: &mut C) -> Result { + // TODO: iterators + /* + let mut handled = vec![]; + for x in self.events.iter() { + handled.push(x.handle_in_broker(state, corpus)?); + } + handled + .iter() + .zip(self.events.iter()) + .map(|(x, event)| match x { + BrokerEventResult::Forward => event.handle_in_client(state, corpus), + // Ignore broker-only events + BrokerEventResult::Handled => Ok(()), + }) + .for_each(drop); + let count = self.events.len(); + dbg!("Handled {} events", count); + self.events.clear(); + + let num = self.events.len(); + for event in &self.events {} + + self.events.clear(); + */ + + Ok(0) + } +} + +#[cfg(feature = "std")] +impl LLMPEventManager +where + S: State, + C: Corpus, + I: Input, + E: Executor, + R: Rand, + //TODO CE: CustomEvent, +{ + pub fn new() -> Self { + Self { + _marker: PhantomData, + } + } +} diff --git a/afl/src/executors/inmemory.rs b/afl/src/executors/inmemory.rs index 4c60b37261..b51f927496 100644 --- a/afl/src/executors/inmemory.rs +++ b/afl/src/executors/inmemory.rs @@ -53,7 +53,7 @@ where unsafe { os_signals::setup_crash_handlers::(); } - InMemoryExecutor { + Self { harness: harness_fn, } } diff --git a/afl/src/feedbacks/mod.rs b/afl/src/feedbacks/mod.rs index f77f3debe3..2481020891 100644 --- a/afl/src/feedbacks/mod.rs +++ b/afl/src/feedbacks/mod.rs @@ -137,7 +137,7 @@ where { /// Create new MapFeedback using a map observer pub fn new(map_observer: Rc>, map_size: usize) -> Self { - MapFeedback { + Self { map_observer: map_observer, history_map: create_history_map::(map_size), phantom: PhantomData, @@ -157,7 +157,7 @@ where map_observer: Rc>, history_map: Rc>>, ) -> Self { - MapFeedback { + Self { map_observer: map_observer, history_map: history_map, phantom: PhantomData, @@ -179,7 +179,7 @@ impl MapNoveltiesMetadata { } pub fn new(novelties: Vec) -> Self { - MapNoveltiesMetadata { + Self { novelties: novelties, } } @@ -253,7 +253,7 @@ where { /// Create new MapFeedback using a map observer pub fn new(map_observer: Rc>, map_size: usize) -> Self { - MapTrackerFeedback { + Self { map_observer: map_observer, history_map: create_history_map::(map_size), phantom: PhantomData, diff --git a/afl/src/generators/mod.rs b/afl/src/generators/mod.rs index 1f1fefaa13..b3b6f5e112 100644 --- a/afl/src/generators/mod.rs +++ b/afl/src/generators/mod.rs @@ -53,7 +53,7 @@ where R: Rand, { pub fn new(max_size: usize) -> Self { - RandBytesGenerator { + Self { max_size: max_size, phantom: PhantomData, } @@ -92,7 +92,7 @@ where R: Rand, { pub fn new(max_size: usize) -> Self { - RandPrintablesGenerator { + Self { max_size: max_size, phantom: PhantomData, } diff --git a/afl/src/inputs/bytes.rs b/afl/src/inputs/bytes.rs index 70847b0f8b..4dda8c3f33 100644 --- a/afl/src/inputs/bytes.rs +++ b/afl/src/inputs/bytes.rs @@ -62,7 +62,7 @@ impl From<&[u8]> for BytesInput { impl BytesInput { /// Creates a new bytes input using the given bytes pub fn new(bytes: Vec) -> Self { - BytesInput { bytes: bytes } + Self { bytes: bytes } } } diff --git a/afl/src/mutators/scheduled.rs b/afl/src/mutators/scheduled.rs index 52e3cd815e..6508033ae0 100644 --- a/afl/src/mutators/scheduled.rs +++ b/afl/src/mutators/scheduled.rs @@ -129,7 +129,7 @@ where { /// Create a new StdScheduledMutator instance without mutations and corpus pub fn new() -> Self { - StdScheduledMutator { + Self { mutations: vec![], max_size: DEFAULT_MAX_SIZE, } @@ -186,7 +186,7 @@ where pub fn new(mut scheduled: SM) -> Self { scheduled.add_mutation(mutation_bitflip); scheduled.add_mutation(mutation_splice); - HavocBytesMutator { + Self { scheduled: scheduled, phantom: PhantomData, } diff --git a/afl/src/observers/mod.rs b/afl/src/observers/mod.rs index eae56fe435..4db03f8d5a 100644 --- a/afl/src/observers/mod.rs +++ b/afl/src/observers/mod.rs @@ -100,7 +100,7 @@ where /// Creates a new MapObserver pub fn new(map: &'a mut [T]) -> Self { let initial = if map.len() > 0 { map[0] } else { T::zero() }; - StdMapObserver { + Self { map: map, initial: initial, } diff --git a/afl/src/stages/mutational.rs b/afl/src/stages/mutational.rs index aab4c3f529..bd96aa15c3 100644 --- a/afl/src/stages/mutational.rs +++ b/afl/src/stages/mutational.rs @@ -142,7 +142,7 @@ where { /// Creates a new default mutational stage pub fn new(mutator: M) -> Self { - StdMutationalStage { + Self { mutator: mutator, phantom: PhantomData, }