From 77e5965e97669ac91c415592f79dcf0c74b63cd9 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 19 Jan 2022 00:02:33 +0100 Subject: [PATCH] Add AsSlice, AsMutSlice traits, refactor MapObservers to be iterable, and have associated types (#477) * from warning * fix latest clippy * clippy fixes++ * renamed shmem parameters * renamed map to shmem * make forkserver executor work for any (non-system) shmem * Mem -> ShMem * rework windows * fix nit * fix symbolic * refacctor map observers * iterator for map observers * removed unused ownedptr, added asslice trait to most functions * make map entry type an associated type * fix fuzzers * fix docs * typo fix * fix windows, add try_from_slice to shmid * missing import * fix fuzzbench * cleanup * fmt * more asslice * fmt * added doc link about token-level fuzzing * cods --- docs/src/baby_fuzzer.md | 6 +- fuzzers/baby_fuzzer/src/main.rs | 2 +- fuzzers/baby_no_std/src/main.rs | 2 +- fuzzers/forkserver_simple/src/main.rs | 1 + fuzzers/frida_libpng/src/fuzzer.rs | 1 + fuzzers/fuzzbench/src/lib.rs | 1 + fuzzers/fuzzbench_qemu/src/fuzzer.rs | 1 + fuzzers/generic_inmemory/src/lib.rs | 1 + fuzzers/libafl_atheris/src/lib.rs | 1 + fuzzers/libfuzzer_libmozjpeg/src/lib.rs | 1 + fuzzers/libfuzzer_libpng/src/lib.rs | 1 + fuzzers/libfuzzer_libpng_ctx/src/lib.rs | 1 + fuzzers/libfuzzer_libpng_launcher/src/lib.rs | 1 + fuzzers/libfuzzer_reachability/src/lib.rs | 2 +- fuzzers/libfuzzer_stb_image/src/main.rs | 2 +- .../fuzzer/build.rs | 2 +- .../fuzzer/src/main.rs | 1 + fuzzers/push_harness/src/main.rs | 2 +- fuzzers/push_stage_harness/src/main.rs | 2 +- fuzzers/qemu_launcher/src/fuzzer.rs | 1 + fuzzers/tutorial/src/lib.rs | 2 +- libafl/src/bolts/llmp.rs | 16 +- libafl/src/bolts/mod.rs | 6 + libafl/src/bolts/os/unix_shmem_server.rs | 18 +- libafl/src/bolts/ownedref.rs | 184 ++------ libafl/src/bolts/shmem.rs | 82 +++- libafl/src/bolts/staterestore.rs | 5 +- libafl/src/executors/command.rs | 2 +- libafl/src/executors/forkserver.rs | 2 + libafl/src/executors/mod.rs | 1 + libafl/src/feedbacks/map.rs | 31 +- libafl/src/inputs/encoded.rs | 1 + libafl/src/lib.rs | 17 +- libafl/src/mutators/scheduled.rs | 9 +- libafl/src/observers/cmp.rs | 37 +- libafl/src/observers/map.rs | 416 +++++++++++++----- libafl/src/stages/calibrate.rs | 30 +- libafl/src/stages/power.rs | 26 +- .../test/dump_constraints/src/main.rs | 5 +- libafl_frida/src/drcov_rt.rs | 1 + libafl_frida/src/helper.rs | 8 +- libafl_sugar/src/forkserver.rs | 1 + libafl_sugar/src/inmemory.rs | 1 + libafl_sugar/src/qemu.rs | 1 + libafl_targets/src/cmplog.rs | 4 +- 45 files changed, 580 insertions(+), 358 deletions(-) diff --git a/docs/src/baby_fuzzer.md b/docs/src/baby_fuzzer.md index fe23511da8..fe85c4e3aa 100644 --- a/docs/src/baby_fuzzer.md +++ b/docs/src/baby_fuzzer.md @@ -77,7 +77,10 @@ To start, we create the closure that we want to fuzz. It takes a buffer as input ```rust extern crate libafl; -use libafl::inputs::{BytesInput, HasTargetBytes}; +use libafl::{ + bolts::AsSlice, + inputs::{BytesInput, HasTargetBytes}, +}; let mut harness = |input: &BytesInput| { let target = input.target_bytes(); @@ -218,6 +221,7 @@ As we don't rely on any instrumentation engine, we have to manually track the sa ```rust extern crate libafl; use libafl::{ + bolts::AsSlice, inputs::{BytesInput, HasTargetBytes}, executors::ExitKind, }; diff --git a/fuzzers/baby_fuzzer/src/main.rs b/fuzzers/baby_fuzzer/src/main.rs index 45b664d93a..2d6d6ce2d8 100644 --- a/fuzzers/baby_fuzzer/src/main.rs +++ b/fuzzers/baby_fuzzer/src/main.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use std::ptr::write_volatile; use libafl::{ - bolts::{current_nanos, rands::StdRand, tuples::tuple_list}, + bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler}, events::SimpleEventManager, executors::{inprocess::InProcessExecutor, ExitKind}, diff --git a/fuzzers/baby_no_std/src/main.rs b/fuzzers/baby_no_std/src/main.rs index 450bc57040..a9ba389e2b 100644 --- a/fuzzers/baby_no_std/src/main.rs +++ b/fuzzers/baby_no_std/src/main.rs @@ -5,7 +5,7 @@ #![cfg_attr(not(any(windows, unix)), feature(default_alloc_error_handler))] use libafl::{ - bolts::{current_nanos, rands::StdRand, tuples::tuple_list}, + bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, corpus::{InMemoryCorpus, QueueCorpusScheduler}, events::SimpleEventManager, executors::{inprocess::InProcessExecutor, ExitKind}, diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index a7fa081eab..1daacfda51 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -5,6 +5,7 @@ use libafl::{ rands::StdRand, shmem::{ShMem, ShMemProvider, StdShMemProvider}, tuples::tuple_list, + AsMutSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index 3b3bda0984..42ff451c32 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -20,6 +20,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ ondisk::OnDiskMetadataFormat, CachedOnDiskCorpus, Corpus, diff --git a/fuzzers/fuzzbench/src/lib.rs b/fuzzers/fuzzbench/src/lib.rs index ecdccae0fe..7af42e89c1 100644 --- a/fuzzers/fuzzbench/src/lib.rs +++ b/fuzzers/fuzzbench/src/lib.rs @@ -24,6 +24,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler, diff --git a/fuzzers/fuzzbench_qemu/src/fuzzer.rs b/fuzzers/fuzzbench_qemu/src/fuzzer.rs index 2cede7f60d..bf974a67ed 100644 --- a/fuzzers/fuzzbench_qemu/src/fuzzer.rs +++ b/fuzzers/fuzzbench_qemu/src/fuzzer.rs @@ -21,6 +21,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler, diff --git a/fuzzers/generic_inmemory/src/lib.rs b/fuzzers/generic_inmemory/src/lib.rs index ac614be4a4..3a29204c61 100644 --- a/fuzzers/generic_inmemory/src/lib.rs +++ b/fuzzers/generic_inmemory/src/lib.rs @@ -16,6 +16,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/libafl_atheris/src/lib.rs b/fuzzers/libafl_atheris/src/lib.rs index 1ebd696a2f..8c0526546f 100644 --- a/fuzzers/libafl_atheris/src/lib.rs +++ b/fuzzers/libafl_atheris/src/lib.rs @@ -19,6 +19,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/libfuzzer_libmozjpeg/src/lib.rs b/fuzzers/libfuzzer_libmozjpeg/src/lib.rs index ddcbc5907a..8504a86b7e 100644 --- a/fuzzers/libfuzzer_libmozjpeg/src/lib.rs +++ b/fuzzers/libfuzzer_libmozjpeg/src/lib.rs @@ -11,6 +11,7 @@ use libafl::{ current_nanos, rands::StdRand, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler}, events::{setup_restarting_mgr_std, EventConfig}, diff --git a/fuzzers/libfuzzer_libpng/src/lib.rs b/fuzzers/libfuzzer_libpng/src/lib.rs index dc3810f15f..cd873b5ee6 100644 --- a/fuzzers/libfuzzer_libpng/src/lib.rs +++ b/fuzzers/libfuzzer_libpng/src/lib.rs @@ -12,6 +12,7 @@ use libafl::{ current_nanos, rands::StdRand, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/libfuzzer_libpng_ctx/src/lib.rs b/fuzzers/libfuzzer_libpng_ctx/src/lib.rs index 315bca5d12..d161d390aa 100644 --- a/fuzzers/libfuzzer_libpng_ctx/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_ctx/src/lib.rs @@ -18,6 +18,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/libfuzzer_libpng_launcher/src/lib.rs b/fuzzers/libfuzzer_libpng_launcher/src/lib.rs index 3732a17a5e..2a507d1491 100644 --- a/fuzzers/libfuzzer_libpng_launcher/src/lib.rs +++ b/fuzzers/libfuzzer_libpng_launcher/src/lib.rs @@ -18,6 +18,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/libfuzzer_reachability/src/lib.rs b/fuzzers/libfuzzer_reachability/src/lib.rs index 4d27fa8e92..82ff8232d4 100644 --- a/fuzzers/libfuzzer_reachability/src/lib.rs +++ b/fuzzers/libfuzzer_reachability/src/lib.rs @@ -7,7 +7,7 @@ static GLOBAL: MiMalloc = MiMalloc; use std::{env, path::PathBuf}; use libafl::{ - bolts::{current_nanos, rands::StdRand, tuples::tuple_list}, + bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler}, events::{setup_restarting_mgr_std, EventConfig, EventRestarter}, executors::{inprocess::InProcessExecutor, ExitKind}, diff --git a/fuzzers/libfuzzer_stb_image/src/main.rs b/fuzzers/libfuzzer_stb_image/src/main.rs index 810251735e..456968a694 100644 --- a/fuzzers/libfuzzer_stb_image/src/main.rs +++ b/fuzzers/libfuzzer_stb_image/src/main.rs @@ -7,7 +7,7 @@ static GLOBAL: MiMalloc = MiMalloc; use std::{env, path::PathBuf}; use libafl::{ - bolts::{current_nanos, rands::StdRand, tuples::tuple_list}, + bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, QueueCorpusScheduler, diff --git a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/build.rs b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/build.rs index 69e1eb97f7..32077e5ca8 100644 --- a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/build.rs +++ b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/build.rs @@ -4,7 +4,7 @@ use std::{ env, io::{stdout, Write}, path::{Path, PathBuf}, - process::{exit, Command}, + process::exit, }; use which::which; diff --git a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs index c707e5fe61..54387b12d8 100644 --- a/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs +++ b/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs @@ -13,6 +13,7 @@ use libafl::{ rands::StdRand, shmem::{ShMem, ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Named}, + AsMutSlice, AsSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/push_harness/src/main.rs b/fuzzers/push_harness/src/main.rs index 8ea8c02d71..ddc4696cd7 100644 --- a/fuzzers/push_harness/src/main.rs +++ b/fuzzers/push_harness/src/main.rs @@ -3,7 +3,7 @@ use klo_routines::*; use libafl::inputs::{BytesInput, HasTargetBytes}; use libafl::{ - bolts::{current_nanos, rands::StdRand, tuples::tuple_list}, + bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler}, events::SimpleEventManager, executors::{inprocess::InProcessExecutor, ExitKind}, diff --git a/fuzzers/push_stage_harness/src/main.rs b/fuzzers/push_stage_harness/src/main.rs index f2fed619bc..43398fa749 100644 --- a/fuzzers/push_stage_harness/src/main.rs +++ b/fuzzers/push_stage_harness/src/main.rs @@ -8,7 +8,7 @@ use core::cell::{Cell, RefCell}; use std::{path::PathBuf, rc::Rc}; use libafl::{ - bolts::{current_nanos, rands::StdRand, tuples::tuple_list}, + bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, corpus::{ Corpus, CorpusScheduler, InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler, Testcase, }, diff --git a/fuzzers/qemu_launcher/src/fuzzer.rs b/fuzzers/qemu_launcher/src/fuzzer.rs index e7a3927b2f..80bbe0bbcc 100644 --- a/fuzzers/qemu_launcher/src/fuzzer.rs +++ b/fuzzers/qemu_launcher/src/fuzzer.rs @@ -11,6 +11,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, + AsSlice, }, corpus::{ Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/fuzzers/tutorial/src/lib.rs b/fuzzers/tutorial/src/lib.rs index f87c8dc7ed..14e5ffec33 100644 --- a/fuzzers/tutorial/src/lib.rs +++ b/fuzzers/tutorial/src/lib.rs @@ -7,7 +7,7 @@ use core::time::Duration; use std::{env, path::PathBuf}; use libafl::{ - bolts::{current_nanos, rands::StdRand, tuples::tuple_list}, + bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, PowerQueueCorpusScheduler}, events::{setup_restarting_mgr_std, EventConfig, EventRestarter}, executors::{inprocess::InProcessExecutor, ExitKind, TimeoutExecutor}, diff --git a/libafl/src/bolts/llmp.rs b/libafl/src/bolts/llmp.rs index dfb5ee505d..92a2420e7f 100644 --- a/libafl/src/bolts/llmp.rs +++ b/libafl/src/bolts/llmp.rs @@ -542,7 +542,7 @@ impl LlmpMsg { /// Gets the buffer from this message as slice, with the corrent length. #[inline] - pub fn as_slice(&self, map: &mut LlmpSharedMap) -> Result<&[u8], Error> { + pub fn try_as_slice(&self, map: &mut LlmpSharedMap) -> Result<&[u8], Error> { unsafe { if self.in_shmem(map) { Ok(self.as_slice_unsafe()) @@ -1110,7 +1110,7 @@ where #[allow(clippy::cast_ptr_alignment)] let mut end_of_page_msg = (*out).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo; (*end_of_page_msg).map_size = new_map_shmem.shmem.len(); - (*end_of_page_msg).shm_str = *new_map_shmem.shmem.id().as_slice(); + (*end_of_page_msg).shm_str = *new_map_shmem.shmem.id().as_array(); /* Send the last msg on the old buf */ self.send(out, true)?; @@ -1439,7 +1439,7 @@ where // Map the new page. The old one should be unmapped by Drop self.current_recv_shmem = LlmpSharedMap::existing(self.shmem_provider.shmem_from_id_and_size( - ShMemId::from_slice(&pageinfo_cpy.shm_str), + ShMemId::from_array(&pageinfo_cpy.shm_str), pageinfo_cpy.map_size, )?); page = self.current_recv_shmem.page_mut(); @@ -1512,7 +1512,7 @@ where (*msg).sender, (*msg).tag, (*msg).flags, - (*msg).as_slice(&mut self.current_recv_shmem)?, + (*msg).try_as_slice(&mut self.current_recv_shmem)?, )), None => None, }) @@ -1527,7 +1527,7 @@ where Ok(( (*msg).sender, (*msg).tag, - (*msg).as_slice(&mut self.current_recv_shmem)?, + (*msg).try_as_slice(&mut self.current_recv_shmem)?, )) } } @@ -1997,7 +1997,7 @@ where (*msg).tag = LLMP_TAG_NEW_SHM_CLIENT; #[allow(clippy::cast_ptr_alignment)] let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo; - (*pageinfo).shm_str = *shmem_description.id.as_slice(); + (*pageinfo).shm_str = *shmem_description.id.as_array(); (*pageinfo).map_size = shmem_description.size; sender.send(msg, true) } @@ -2329,7 +2329,7 @@ where let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo; match self.shmem_provider.shmem_from_id_and_size( - ShMemId::from_slice(&(*pageinfo).shm_str), + ShMemId::from_array(&(*pageinfo).shm_str), (*pageinfo).map_size, ) { Ok(new_shmem) => { @@ -2363,7 +2363,7 @@ where let mut should_forward_msg = true; let map = &mut self.llmp_clients[client_id as usize].current_recv_shmem; - let msg_buf = (*msg).as_slice(map)?; + let msg_buf = (*msg).try_as_slice(map)?; if let LlmpMsgHookResult::Handled = (on_new_msg)(client_id, (*msg).tag, (*msg).flags, msg_buf)? { diff --git a/libafl/src/bolts/mod.rs b/libafl/src/bolts/mod.rs index b896d2d6c7..e86ef6bef0 100644 --- a/libafl/src/bolts/mod.rs +++ b/libafl/src/bolts/mod.rs @@ -30,6 +30,12 @@ pub trait AsSlice { fn as_slice(&self) -> &[T]; } +/// Can be converted to a mutable slice +pub trait AsMutSlice { + /// Convert to a slice + fn as_mut_slice(&mut self) -> &mut [T]; +} + /// Has a length field pub trait HasLen { /// The length diff --git a/libafl/src/bolts/os/unix_shmem_server.rs b/libafl/src/bolts/os/unix_shmem_server.rs index 660f40b240..8b31144cf8 100644 --- a/libafl/src/bolts/os/unix_shmem_server.rs +++ b/libafl/src/bolts/os/unix_shmem_server.rs @@ -6,7 +6,10 @@ and forwards them over unix domain sockets. */ use crate::{ - bolts::shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider}, + bolts::{ + shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider}, + AsMutSlice, AsSlice, + }, Error, }; use core::{mem::ManuallyDrop, ptr::addr_of}; @@ -88,11 +91,20 @@ where fn len(&self) -> usize { self.inner.len() } +} +impl AsSlice for ServedShMem +where + SH: ShMem, +{ fn as_slice(&self) -> &[u8] { self.inner.as_slice() } - +} +impl AsMutSlice for ServedShMem +where + SH: ShMem, +{ fn as_mut_slice(&mut self) -> &mut [u8] { self.inner.as_mut_slice() } @@ -124,7 +136,7 @@ where .recv_fds(&mut shm_slice, &mut fd_buf) .expect("Did not receive a response"); - let server_id = ShMemId::from_slice(&shm_slice); + let server_id = ShMemId::from_array(&shm_slice); let server_fd: i32 = server_id.into(); Ok((server_fd, fd_buf[0])) } diff --git a/libafl/src/bolts/ownedref.rs b/libafl/src/bolts/ownedref.rs index 025632d910..81cd12f3cc 100644 --- a/libafl/src/bolts/ownedref.rs +++ b/libafl/src/bolts/ownedref.rs @@ -1,7 +1,12 @@ //! Wrappers that abstracts references (or pointers) and owned data accesses. // The serialization is towards owned, allowing to serialize pointers without troubles. -use alloc::{boxed::Box, vec::Vec}; +use crate::bolts::{AsMutSlice, AsSlice}; +use alloc::{ + boxed::Box, + slice::{Iter, IterMut}, + vec::Vec, +}; use core::{clone::Clone, fmt::Debug, slice}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -234,6 +239,15 @@ impl<'a, T> OwnedSlice<'a, T> { } } +impl<'a, 'it, T> IntoIterator for &'it OwnedSlice<'a, T> { + type Item = as Iterator>::Item; + type IntoIter = Iter<'it, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_slice().iter() + } +} + /// Create a new [`OwnedSlice`] from a vector impl<'a, T> From> for OwnedSlice<'a, T> { fn from(vec: Vec) -> Self { @@ -274,10 +288,10 @@ impl<'a, T> From> for OwnedSlice<'a, T> { } } -impl<'a, T: Sized> OwnedSlice<'a, T> { +impl<'a, T: Sized> AsSlice for OwnedSlice<'a, T> { /// Get the [`OwnedSlice`] as slice. #[must_use] - pub fn as_slice(&self) -> &[T] { + fn as_slice(&self) -> &[T] { match &self.inner { OwnedSliceInner::Ref(r) => r, OwnedSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) }, @@ -361,6 +375,24 @@ pub struct OwnedSliceMut<'a, T: 'a + Sized> { inner: OwnedSliceMutInner<'a, T>, } +impl<'a, 'it, T> IntoIterator for &'it mut OwnedSliceMut<'a, T> { + type Item = as Iterator>::Item; + type IntoIter = IterMut<'it, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_mut_slice().iter_mut() + } +} + +impl<'a, 'it, T> IntoIterator for &'it OwnedSliceMut<'a, T> { + type Item = as Iterator>::Item; + type IntoIter = Iter<'it, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_slice().iter() + } +} + impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> { /// Create a new [`OwnedSliceMut`] from a raw pointer and length /// @@ -382,20 +414,21 @@ impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> { } } -impl<'a, T: Sized> OwnedSliceMut<'a, T> { +impl<'a, T: Sized> AsSlice for OwnedSliceMut<'a, T> { /// Get the value as slice #[must_use] - pub fn as_slice(&self) -> &[T] { + fn as_slice(&self) -> &[T] { match &self.inner { OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) }, OwnedSliceMutInner::Ref(r) => r, OwnedSliceMutInner::Owned(v) => v.as_slice(), } } - +} +impl<'a, T: Sized> AsMutSlice for OwnedSliceMut<'a, T> { /// Get the value as mut slice #[must_use] - pub fn as_mut_slice(&mut self) -> &mut [T] { + fn as_mut_slice(&mut self) -> &mut [T] { match &mut self.inner { OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts_mut(*rr, *len) }, OwnedSliceMutInner::Ref(r) => r, @@ -608,140 +641,3 @@ where } } } - -/// Wrap a C-style pointer to an array (with size) and convert to a Vec on serialize -#[derive(Clone, Debug)] -pub enum OwnedArrayPtr { - /// Ptr to a slice - ArrayPtr((*const T, usize)), - /// A owned [`Vec`]. - Owned(Vec), -} - -impl Serialize for OwnedArrayPtr { - fn serialize(&self, se: S) -> Result - where - S: Serializer, - { - self.as_slice().serialize(se) - } -} - -impl<'de, T: Sized + Serialize> Deserialize<'de> for OwnedArrayPtr -where - Vec: Deserialize<'de>, -{ - fn deserialize(de: D) -> Result - where - D: Deserializer<'de>, - { - Deserialize::deserialize(de).map(OwnedArrayPtr::Owned) - } -} - -impl OwnedArrayPtr { - /// Get a slice from this array. - #[must_use] - pub fn as_slice(&self) -> &[T] { - match self { - OwnedArrayPtr::ArrayPtr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) }, - OwnedArrayPtr::Owned(v) => v.as_slice(), - } - } -} - -impl IntoOwned for OwnedArrayPtr -where - T: Sized + Clone, -{ - #[must_use] - fn is_owned(&self) -> bool { - match self { - OwnedArrayPtr::ArrayPtr(_) => false, - OwnedArrayPtr::Owned(_) => true, - } - } - - #[must_use] - fn into_owned(self) -> Self { - match self { - OwnedArrayPtr::ArrayPtr(p) => unsafe { - OwnedArrayPtr::Owned(core::slice::from_raw_parts(p.0, p.1).to_vec()) - }, - OwnedArrayPtr::Owned(v) => OwnedArrayPtr::Owned(v), - } - } -} - -/// Wrap a C-style mutable pointer to an array (with size) and convert to a Vec on serialize -#[derive(Clone, Debug)] -pub enum OwnedArrayPtrMut { - /// A ptr to the array (or slice). - ArrayPtr((*mut T, usize)), - /// An owned [`Vec`]. - Owned(Vec), -} - -impl Serialize for OwnedArrayPtrMut { - fn serialize(&self, se: S) -> Result - where - S: Serializer, - { - self.as_slice().serialize(se) - } -} - -impl<'de, T: Sized + Serialize> Deserialize<'de> for OwnedArrayPtrMut -where - Vec: Deserialize<'de>, -{ - fn deserialize(de: D) -> Result - where - D: Deserializer<'de>, - { - Deserialize::deserialize(de).map(OwnedArrayPtrMut::Owned) - } -} - -impl OwnedArrayPtrMut { - /// Return this array as slice - #[must_use] - pub fn as_slice(&self) -> &[T] { - match self { - OwnedArrayPtrMut::ArrayPtr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) }, - OwnedArrayPtrMut::Owned(v) => v.as_slice(), - } - } - - /// Return this array as mut slice - #[must_use] - pub fn as_mut_slice(&mut self) -> &mut [T] { - match self { - OwnedArrayPtrMut::ArrayPtr(p) => unsafe { core::slice::from_raw_parts_mut(p.0, p.1) }, - OwnedArrayPtrMut::Owned(v) => v.as_mut_slice(), - } - } -} - -impl IntoOwned for OwnedArrayPtrMut -where - T: Sized + Clone, -{ - #[must_use] - fn is_owned(&self) -> bool { - match self { - OwnedArrayPtrMut::ArrayPtr(_) => false, - OwnedArrayPtrMut::Owned(_) => true, - } - } - - #[must_use] - fn into_owned(self) -> Self { - match self { - OwnedArrayPtrMut::ArrayPtr(p) => unsafe { - OwnedArrayPtrMut::Owned(core::slice::from_raw_parts(p.0, p.1).to_vec()) - }, - OwnedArrayPtrMut::Owned(v) => OwnedArrayPtrMut::Owned(v), - } - } -} diff --git a/libafl/src/bolts/shmem.rs b/libafl/src/bolts/shmem.rs index ea9936f9ee..c17b4a7382 100644 --- a/libafl/src/bolts/shmem.rs +++ b/libafl/src/bolts/shmem.rs @@ -3,7 +3,10 @@ #[cfg(all(unix, feature = "std"))] use crate::bolts::os::pipes::Pipe; -use crate::Error; +use crate::{ + bolts::{AsMutSlice, AsSlice}, + Error, +}; use alloc::{rc::Rc, string::ToString}; use core::{ cell::RefCell, @@ -89,10 +92,17 @@ pub struct ShMemId { } impl ShMemId { - /// Create a new id from a fixed-size string + /// Create a new id from a fixed-size string/bytes array + /// It should contain a valid cstring. #[must_use] - pub fn from_slice(slice: &[u8; 20]) -> Self { - Self { id: *slice } + pub fn from_array(array: &[u8; 20]) -> Self { + Self { id: *array } + } + + /// Try to create a new id from a bytes string. + /// The slice must have a length of at least 20 bytes and contain a valid cstring. + pub fn try_from_slice(slice: &[u8]) -> Result { + Ok(Self::from_array(&slice[0..20].try_into()?)) } /// Create a new id from an int @@ -113,7 +123,7 @@ impl ShMemId { /// Get the id as a fixed-length slice #[must_use] - pub fn as_slice(&self) -> &[u8; 20] { + pub fn as_array(&self) -> &[u8; 20] { &self.id } @@ -129,6 +139,11 @@ impl ShMemId { alloc::str::from_utf8(&self.id[..self.null_pos()]).unwrap() } } +impl AsSlice for ShMemId { + fn as_slice(&self) -> &[u8] { + &self.id + } +} impl From for i32 { fn from(id: ShMemId) -> i32 { @@ -145,7 +160,7 @@ impl Display for ShMemId { /// A [`ShMem`] is an interface to shared maps. /// They are the backbone of [`crate::bolts::llmp`] for inter-process communication. /// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`]. -pub trait ShMem: Sized + Debug + Clone { +pub trait ShMem: Sized + Debug + Clone + AsSlice + AsMutSlice { /// Get the id of this shared memory mapping fn id(&self) -> ShMemId; @@ -165,12 +180,6 @@ pub trait ShMem: Sized + Debug + Clone { } } - /// The actual shared map, in memory - fn as_slice(&self) -> &[u8]; - - /// The actual shared map, mutable - fn as_mut_slice(&mut self) -> &mut [u8]; - /// Write this map's config to env #[cfg(feature = "std")] fn write_to_env(&self, env_name: &str) -> Result<(), Error> { @@ -264,11 +273,21 @@ where fn len(&self) -> usize { self.internal.len() } +} +impl AsSlice for RcShMem +where + T: ShMemProvider + Debug, +{ fn as_slice(&self) -> &[u8] { self.internal.as_slice() } +} +impl AsMutSlice for RcShMem +where + T: ShMemProvider + Debug, +{ fn as_mut_slice(&mut self) -> &mut [u8] { self.internal.as_mut_slice() } @@ -489,7 +508,10 @@ pub mod unix_shmem { use std::{io::Write, process}; use crate::{ - bolts::shmem::{ShMem, ShMemId, ShMemProvider}, + bolts::{ + shmem::{ShMem, ShMemId, ShMemProvider}, + AsMutSlice, AsSlice, + }, Error, }; #[cfg(unix)] @@ -691,11 +713,15 @@ pub mod unix_shmem { fn len(&self) -> usize { self.map_size } + } + impl AsSlice for MmapShMem { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.map, self.map_size) } } + } + impl AsMutSlice for MmapShMem { fn as_mut_slice(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } @@ -790,11 +816,15 @@ pub mod unix_shmem { fn len(&self) -> usize { self.map_size } + } + impl AsSlice for CommonUnixShMem { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.map, self.map_size) } } + } + impl AsMutSlice for CommonUnixShMem { fn as_mut_slice(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } @@ -858,7 +888,10 @@ pub mod unix_shmem { use std::ffi::CString; use crate::{ - bolts::shmem::{ShMem, ShMemId, ShMemProvider}, + bolts::{ + shmem::{ShMem, ShMemId, ShMemProvider}, + AsMutSlice, AsSlice, + }, Error, }; @@ -992,11 +1025,15 @@ pub mod unix_shmem { fn len(&self) -> usize { self.map_size } + } + impl AsSlice for AshmemShMem { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.map, self.map_size) } } + } + impl AsMutSlice for AshmemShMem { fn as_mut_slice(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } @@ -1069,7 +1106,10 @@ pub mod unix_shmem { pub mod win32_shmem { use crate::{ - bolts::shmem::{ShMem, ShMemId, ShMemProvider}, + bolts::{ + shmem::{ShMem, ShMemId, ShMemProvider}, + AsMutSlice, AsSlice, + }, Error, }; @@ -1141,7 +1181,7 @@ pub mod win32_shmem { } Ok(Self { - id: ShMemId::from_slice(&map_str_bytes[0..20].try_into().unwrap()), + id: ShMemId::try_from_slice(&map_str_bytes).unwrap(), handle, map, map_size, @@ -1189,11 +1229,14 @@ pub mod win32_shmem { fn len(&self) -> usize { self.map_size } + } + impl AsSlice for Win32ShMem { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.map, self.map_size) } } - + } + impl AsMutSlice for Win32ShMem { fn as_mut_slice(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } } @@ -1348,7 +1391,10 @@ impl std::io::Seek for ShMemCursor { mod tests { use serial_test::serial; - use crate::bolts::shmem::{ShMem, ShMemProvider, StdShMemProvider}; + use crate::bolts::{ + shmem::{ShMemProvider, StdShMemProvider}, + AsMutSlice, AsSlice, + }; #[test] #[serial] diff --git a/libafl/src/bolts/staterestore.rs b/libafl/src/bolts/staterestore.rs index 4b113cb6b0..2a01959e70 100644 --- a/libafl/src/bolts/staterestore.rs +++ b/libafl/src/bolts/staterestore.rs @@ -12,7 +12,10 @@ use std::{ }; use crate::{ - bolts::shmem::{ShMem, ShMemProvider}, + bolts::{ + shmem::{ShMem, ShMemProvider}, + AsSlice, + }, Error, }; diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 24c8525422..54c47f380a 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -105,7 +105,7 @@ where /// # Example /// ``` /// use std::{io::Write, process::{Stdio, Command, Child}}; -/// use libafl::{Error, inputs::{Input, HasTargetBytes}, executors::{Executor, command::CommandConfigurator}}; +/// use libafl::{Error, bolts::AsSlice, inputs::{Input, HasTargetBytes}, executors::{Executor, command::CommandConfigurator}}; /// #[derive(Debug)] /// struct MyExecutor; /// diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index ffe3314f3b..ae6cbad57c 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -19,6 +19,7 @@ use crate::{ bolts::{ os::{dup2, pipes::Pipe}, shmem::{ShMem, ShMemProvider, StdShMemProvider}, + AsMutSlice, AsSlice, }, executors::{Executor, ExitKind, HasObservers}, inputs::{HasTargetBytes, Input}, @@ -832,6 +833,7 @@ mod tests { bolts::{ shmem::{ShMem, ShMemProvider, StdShMemProvider}, tuples::tuple_list, + AsMutSlice, }, executors::ForkserverExecutor, inputs::NopInput, diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index bf2b977789..2afabb8ab1 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -32,6 +32,7 @@ pub mod command; pub use command::CommandExecutor; use crate::{ + bolts::AsSlice, inputs::{HasTargetBytes, Input}, observers::ObserversTuple, Error, diff --git a/libafl/src/feedbacks/map.rs b/libafl/src/feedbacks/map.rs index 8abf2dd24d..c49fc4e388 100644 --- a/libafl/src/feedbacks/map.rs +++ b/libafl/src/feedbacks/map.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use crate::{ bolts::{ tuples::{MatchName, Named}, - AsSlice, HasRefCnt, + AsMutSlice, AsSlice, HasRefCnt, }, corpus::Testcase, events::{Event, EventFirer}, @@ -214,6 +214,12 @@ impl AsSlice for MapIndexesMetadata { self.list.as_slice() } } +impl AsMutSlice for MapIndexesMetadata { + /// Convert to a slice + fn as_mut_slice(&mut self) -> &mut [usize] { + self.list.as_mut_slice() + } +} impl HasRefCnt for MapIndexesMetadata { fn refcnt(&self) -> isize { @@ -249,6 +255,13 @@ impl AsSlice for MapNoveltiesMetadata { self.list.as_slice() } } +impl AsMutSlice for MapNoveltiesMetadata { + /// Convert to a slice + #[must_use] + fn as_mut_slice(&mut self) -> &mut [usize] { + self.list.as_mut_slice() + } +} impl MapNoveltiesMetadata { /// Creates a new [`struct@MapNoveltiesMetadata`] #[must_use] @@ -308,7 +321,7 @@ where /// Create new `MapFeedbackState` for the observer type. pub fn with_observer(map_observer: &O) -> Self where - O: MapObserver, + O: MapObserver, T: Debug, { Self { @@ -335,7 +348,7 @@ pub struct MapFeedback where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, R: Reducer, - O: MapObserver, + O: MapObserver, N: IsNovel, S: HasFeedbackStates, { @@ -355,7 +368,7 @@ impl Feedback for MapFeedback where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, R: Reducer, - O: MapObserver, + O: MapObserver, N: IsNovel, I: Input, S: HasFeedbackStates + HasClientPerfMonitor + Debug, @@ -464,7 +477,7 @@ where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, R: Reducer, N: IsNovel, - O: MapObserver, + O: MapObserver, S: HasFeedbackStates, { #[inline] @@ -485,7 +498,7 @@ where + Debug, R: Reducer, N: IsNovel, - O: MapObserver, + O: MapObserver, S: HasFeedbackStates, { /// Create new `MapFeedback` @@ -557,7 +570,7 @@ pub struct ReachabilityFeedback { impl ReachabilityFeedback where - O: MapObserver, + O: MapObserver, { /// Creates a new [`ReachabilityFeedback`] for a [`MapObserver`]. #[must_use] @@ -583,7 +596,7 @@ where impl Feedback for ReachabilityFeedback where I: Input, - O: MapObserver, + O: MapObserver, S: HasClientPerfMonitor, { fn is_interesting( @@ -632,7 +645,7 @@ where impl Named for ReachabilityFeedback where - O: MapObserver, + O: MapObserver, { #[inline] fn name(&self) -> &str { diff --git a/libafl/src/inputs/encoded.rs b/libafl/src/inputs/encoded.rs index 1a0f14de34..02e9e3e05c 100644 --- a/libafl/src/inputs/encoded.rs +++ b/libafl/src/inputs/encoded.rs @@ -1,5 +1,6 @@ //! The `EncodedInput` is the "normal" input, a map of codes, that can be sent directly to the client //! (As opposed to other, more abstract, imputs, like an Grammar-Based AST Input) +//! See also [the paper on token-level fuzzing](https://www.usenix.org/system/files/sec21-salls.pdf) use ahash::AHasher; use core::hash::Hasher; diff --git a/libafl/src/lib.rs b/libafl/src/lib.rs index 8ce8d7df4e..b59bf65ed8 100644 --- a/libafl/src/lib.rs +++ b/libafl/src/lib.rs @@ -113,11 +113,11 @@ pub mod stats { pub use crate::monitors::UserStats; } -use alloc::string::String; -use core::fmt; +use alloc::string::{FromUtf8Error, String}; +use core::{array::TryFromSliceError, fmt, num::ParseIntError, num::TryFromIntError}; #[cfg(feature = "std")] -use std::{env::VarError, io, num::ParseIntError, num::TryFromIntError, string::FromUtf8Error}; +use std::{env::VarError, io}; /// Main error struct for AFL #[derive(Debug)] @@ -209,10 +209,9 @@ impl From for Error { } } -#[cfg(feature = "std")] impl From for Error { fn from(err: FromUtf8Error) -> Self { - Self::Unknown(format!("Could not convert byte to utf-8: {:?}", err)) + Self::Unknown(format!("Could not convert byte / utf-8: {:?}", err)) } } @@ -223,20 +222,24 @@ impl From for Error { } } -#[cfg(feature = "std")] impl From for Error { fn from(err: ParseIntError) -> Self { Self::Unknown(format!("Failed to parse Int: {:?}", err)) } } -#[cfg(feature = "std")] impl From for Error { fn from(err: TryFromIntError) -> Self { Self::IllegalState(format!("Expected conversion failed: {:?}", err)) } } +impl From for Error { + fn from(err: TryFromSliceError) -> Self { + Self::IllegalArgument(format!("Could not convert slice: {:?}", err)) + } +} + #[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/libafl/src/mutators/scheduled.rs b/libafl/src/mutators/scheduled.rs index 55da803579..c232473deb 100644 --- a/libafl/src/mutators/scheduled.rs +++ b/libafl/src/mutators/scheduled.rs @@ -11,7 +11,7 @@ use crate::{ bolts::{ rands::Rand, tuples::{tuple_list, tuple_list_type, NamedTuple}, - AsSlice, + AsMutSlice, AsSlice, }, corpus::Corpus, inputs::Input, @@ -33,10 +33,17 @@ pub struct LogMutationMetadata { crate::impl_serdeany!(LogMutationMetadata); impl AsSlice for LogMutationMetadata { + #[must_use] fn as_slice(&self) -> &[String] { self.list.as_slice() } } +impl AsMutSlice for LogMutationMetadata { + #[must_use] + fn as_mut_slice(&mut self) -> &mut [String] { + self.list.as_mut_slice() + } +} impl LogMutationMetadata { /// Creates new [`struct@LogMutationMetadata`]. diff --git a/libafl/src/observers/cmp.rs b/libafl/src/observers/cmp.rs index 5bc5be7a19..e68f8b50a4 100644 --- a/libafl/src/observers/cmp.rs +++ b/libafl/src/observers/cmp.rs @@ -8,7 +8,7 @@ use core::fmt::Debug; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{ - bolts::{ownedref::OwnedRefMut, tuples::Named, AsSlice}, + bolts::{ownedref::OwnedRefMut, tuples::Named, AsMutSlice, AsSlice}, observers::Observer, state::HasMetadata, Error, @@ -69,6 +69,13 @@ impl AsSlice for CmpValuesMetadata { self.list.as_slice() } } +impl AsMutSlice for CmpValuesMetadata { + /// Convert to a slice + #[must_use] + fn as_mut_slice(&mut self) -> &mut [CmpValues] { + self.list.as_mut_slice() + } +} impl CmpValuesMetadata { /// Creates a new [`struct@CmpValuesMetadata`] @@ -111,10 +118,10 @@ where fn usable_count(&self) -> usize; /// Get the `CmpMap` - fn map(&self) -> &CM; + fn cmp_map(&self) -> &CM; /// Get the `CmpMap` (mut) - fn map_mut(&mut self) -> &mut CM; + fn cmp_map_mut(&mut self) -> &mut CM; /// Add [`struct@CmpValuesMetadata`] to the State including the logged values. /// This routine does a basic loop filtering because loop index cmps are not interesting. @@ -132,7 +139,7 @@ where meta.list.clear(); let count = self.usable_count(); for i in 0..count { - let execs = self.map().usable_executions_for(i); + let execs = self.cmp_map().usable_executions_for(i); if execs > 0 { // Recongize loops and discard if needed if execs > 4 { @@ -143,7 +150,7 @@ where let mut last: Option = None; for j in 0..execs { - let val = self.map().values_of(i, j); + let val = self.cmp_map().values_of(i, j); if let Some(l) = last.and_then(|x| x.to_u64_tuple()) { if let Some(v) = val.to_u64_tuple() { if l.0.wrapping_add(1) == v.0 { @@ -173,7 +180,7 @@ where } } for j in 0..execs { - meta.list.push(self.map().values_of(i, j)); + meta.list.push(self.cmp_map().values_of(i, j)); } } } @@ -187,7 +194,7 @@ pub struct StdCmpObserver<'a, CM> where CM: CmpMap + Serialize + DeserializeOwned, { - map: OwnedRefMut<'a, CM>, + cmp_map: OwnedRefMut<'a, CM>, size: Option>, name: String, } @@ -199,17 +206,17 @@ where /// Get the number of usable cmps (all by default) fn usable_count(&self) -> usize { match &self.size { - None => self.map.as_ref().len(), + None => self.cmp_map.as_ref().len(), Some(o) => *o.as_ref(), } } - fn map(&self) -> &CM { - self.map.as_ref() + fn cmp_map(&self) -> &CM { + self.cmp_map.as_ref() } - fn map_mut(&mut self) -> &mut CM { - self.map.as_mut() + fn cmp_map_mut(&mut self) -> &mut CM { + self.cmp_map.as_mut() } } @@ -218,7 +225,7 @@ where CM: CmpMap + Serialize + DeserializeOwned, { fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { - self.map.as_mut().reset()?; + self.cmp_map.as_mut().reset()?; Ok(()) } } @@ -242,7 +249,7 @@ where Self { name: name.to_string(), size: None, - map: OwnedRefMut::Ref(map), + cmp_map: OwnedRefMut::Ref(map), } } @@ -252,7 +259,7 @@ where Self { name: name.to_string(), size: Some(OwnedRefMut::Ref(size)), - map: OwnedRefMut::Ref(map), + cmp_map: OwnedRefMut::Ref(map), } } } diff --git a/libafl/src/observers/map.rs b/libafl/src/observers/map.rs index cca20be32f..f0bb09a6f1 100644 --- a/libafl/src/observers/map.rs +++ b/libafl/src/observers/map.rs @@ -5,7 +5,12 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; -use core::{fmt::Debug, hash::Hasher, slice::from_raw_parts}; +use core::{ + fmt::Debug, + hash::Hasher, + iter::Flatten, + slice::{from_raw_parts, Iter, IterMut}, +}; use intervaltree::IntervalTree; use num_traits::PrimInt; use serde::{Deserialize, Serialize}; @@ -14,41 +19,36 @@ use crate::{ bolts::{ ownedref::{OwnedRefMut, OwnedSliceMut}, tuples::Named, - HasLen, + AsMutSlice, AsSlice, HasLen, }, observers::Observer, Error, }; -/// A [`MapObserver`] observes the static map, as oftentimes used for afl-like coverage information -pub trait MapObserver: HasLen + Named + Serialize + serde::de::DeserializeOwned + Debug -where - T: PrimInt + Default + Copy + Debug, -{ - /// Get the map if the observer can be represented with a slice - fn map(&self) -> Option<&[T]>; +/// Compute the hash of a slice +fn hash_slice(slice: &[T]) -> u64 { + let mut hasher = AHasher::new_with_keys(0, 0); + let ptr = slice.as_ptr() as *const u8; + let map_size = slice.len() / core::mem::size_of::(); + unsafe { + hasher.write(from_raw_parts(ptr, map_size)); + } + hasher.finish() +} - /// Get the map (mutable) if the observer can be represented with a slice - fn map_mut(&mut self) -> Option<&mut [T]>; +/// A [`MapObserver`] observes the static map, as oftentimes used for afl-like coverage information +pub trait MapObserver: HasLen + Named + Serialize + serde::de::DeserializeOwned + Debug { + /// Type of each entry in this map + type Entry: PrimInt + Default + Copy + Debug; /// Get the value at `idx` - fn get(&self, idx: usize) -> &T { - &self - .map() - .expect("Cannot get a map that cannot be represented as slice")[idx] - } + fn get(&self, idx: usize) -> &Self::Entry; /// Get the value at `idx` (mutable) - fn get_mut(&mut self, idx: usize) -> &mut T { - &mut self - .map_mut() - .expect("Cannot get a map that cannot be represented as slice")[idx] - } + fn get_mut(&mut self, idx: usize) -> &mut Self::Entry; /// Get the number of usable entries in the map (all by default) - fn usable_count(&self) -> usize { - self.len() - } + fn usable_count(&self) -> usize; /// Count the set bytes in the map fn count_bytes(&self) -> u64 { @@ -64,27 +64,16 @@ where } /// Compute the hash of the map - fn hash(&self) -> u64 { - let mut hasher = AHasher::new_with_keys(0, 0); - let slice = self - .map() - .expect("Cannot hash a map that cannot be represented as slice"); - let ptr = slice.as_ptr() as *const u8; - let map_size = slice.len() / core::mem::size_of::(); - unsafe { - hasher.write(from_raw_parts(ptr, map_size)); - } - hasher.finish() - } + fn hash(&self) -> u64; /// Get the initial value for reset() - fn initial(&self) -> T; + fn initial(&self) -> Self::Entry; /// Get the initial value for reset() - fn initial_mut(&mut self) -> &mut T; + fn initial_mut(&mut self) -> &mut Self::Entry; /// Set the initial value for reset() - fn set_initial(&mut self, initial: T); + fn set_initial(&mut self, initial: Self::Entry); /// Reset the map #[inline] @@ -97,6 +86,16 @@ where } Ok(()) } + + /// Get these observer's contents as [`Vec`] + fn to_vec(&self) -> Vec { + let cnt = self.usable_count(); + let mut res = Vec::with_capacity(cnt); + for i in 0..cnt { + res.push(*self.get(i)); + } + res + } } /// The Map Observer retrieves the state of a map, @@ -117,7 +116,7 @@ where impl<'a, I, S, T> Observer for StdMapObserver<'a, T> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, - Self: MapObserver, + Self: MapObserver, { #[inline] fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { @@ -145,18 +144,53 @@ where } } -impl<'a, T> MapObserver for StdMapObserver<'a, T> +impl<'a, 'it, T> IntoIterator for &'it StdMapObserver<'a, T> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { + type Item = as Iterator>::Item; + type IntoIter = Iter<'it, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_slice().iter() + } +} + +impl<'a, 'it, T> IntoIterator for &'it mut StdMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Item = as Iterator>::Item; + type IntoIter = IterMut<'it, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_mut_slice().iter_mut() + } +} + +impl<'a, T> MapObserver for StdMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Entry = T; + #[inline] - fn map(&self) -> Option<&[T]> { - Some(self.map.as_slice()) + fn get(&self, pos: usize) -> &T { + &self.as_slice()[pos] } #[inline] - fn map_mut(&mut self) -> Option<&mut [T]> { - Some(self.map.as_mut_slice()) + fn get_mut(&mut self, idx: usize) -> &mut T { + &mut self.as_mut_slice()[idx] + } + + #[inline] + fn usable_count(&self) -> usize { + self.as_slice().len() + } + + fn hash(&self) -> u64 { + hash_slice(self.as_slice()) } #[inline] @@ -173,6 +207,31 @@ where fn set_initial(&mut self, initial: T) { self.initial = initial; } + + fn to_vec(&self) -> Vec { + self.as_slice().to_vec() + } +} + +impl<'a, T> AsSlice for StdMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + #[must_use] + #[inline] + fn as_slice(&self) -> &[T] { + self.map.as_slice() + } +} +impl<'a, T> AsMutSlice for StdMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + #[must_use] + #[inline] + fn as_mut_slice(&mut self) -> &mut [T] { + self.map.as_mut_slice() + } } impl<'a, T> StdMapObserver<'a, T> @@ -251,7 +310,7 @@ where impl<'a, I, S, T, const N: usize> Observer for ConstMapObserver<'a, T, N> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, - Self: MapObserver, + Self: MapObserver, { #[inline] fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { @@ -279,24 +338,35 @@ where } } -impl<'a, T, const N: usize> MapObserver for ConstMapObserver<'a, T, N> +impl<'a, 'it, T, const N: usize> IntoIterator for &'it ConstMapObserver<'a, T, N> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { - #[inline] - fn usable_count(&self) -> usize { - N - } + type Item = as Iterator>::Item; + type IntoIter = Iter<'it, T>; - #[inline] - fn map(&self) -> Option<&[T]> { - Some(self.map.as_slice()) + fn into_iter(self) -> Self::IntoIter { + self.as_slice().iter() } +} - #[inline] - fn map_mut(&mut self) -> Option<&mut [T]> { - Some(self.map.as_mut_slice()) +impl<'a, 'it, T, const N: usize> IntoIterator for &'it mut ConstMapObserver<'a, T, N> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Item = as Iterator>::Item; + type IntoIter = IterMut<'it, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_mut_slice().iter_mut() } +} + +impl<'a, T, const N: usize> MapObserver for ConstMapObserver<'a, T, N> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Entry = T; #[inline] fn initial(&self) -> T { @@ -312,6 +382,47 @@ where fn set_initial(&mut self, initial: T) { self.initial = initial; } + + #[inline] + fn get(&self, idx: usize) -> &T { + &self.as_slice()[idx] + } + + #[inline] + fn get_mut(&mut self, idx: usize) -> &mut T { + &mut self.as_mut_slice()[idx] + } + + fn usable_count(&self) -> usize { + self.as_slice().len() + } + + fn hash(&self) -> u64 { + hash_slice(self.as_slice()) + } + + fn to_vec(&self) -> Vec { + self.as_slice().to_vec() + } +} + +impl<'a, T, const N: usize> AsSlice for ConstMapObserver<'a, T, N> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + #[inline] + fn as_slice(&self) -> &[T] { + self.map.as_slice() + } +} +impl<'a, T, const N: usize> AsMutSlice for ConstMapObserver<'a, T, N> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + #[inline] + fn as_mut_slice(&mut self) -> &mut [T] { + self.map.as_mut_slice() + } } impl<'a, T, const N: usize> ConstMapObserver<'a, T, N> @@ -373,7 +484,7 @@ where impl<'a, I, S, T> Observer for VariableMapObserver<'a, T> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, - Self: MapObserver, + Self: MapObserver, { #[inline] fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { @@ -401,24 +512,35 @@ where } } -impl<'a, T> MapObserver for VariableMapObserver<'a, T> +impl<'a, 'it, T> IntoIterator for &'it VariableMapObserver<'a, T> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { - #[inline] - fn map(&self) -> Option<&[T]> { - Some(self.map.as_slice()) - } + type Item = as Iterator>::Item; + type IntoIter = Iter<'it, T>; - #[inline] - fn map_mut(&mut self) -> Option<&mut [T]> { - Some(self.map.as_mut_slice()) + fn into_iter(self) -> Self::IntoIter { + self.as_slice().iter() } +} - #[inline] - fn usable_count(&self) -> usize { - *self.size.as_ref() +impl<'a, 'it, T> IntoIterator for &'it mut VariableMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Item = as Iterator>::Item; + type IntoIter = IterMut<'it, T>; + + fn into_iter(self) -> Self::IntoIter { + self.as_mut_slice().iter_mut() } +} + +impl<'a, T> MapObserver for VariableMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Entry = T; #[inline] fn initial(&self) -> T { @@ -434,6 +556,45 @@ where fn set_initial(&mut self, initial: T) { self.initial = initial; } + + #[inline] + fn usable_count(&self) -> usize { + *self.size.as_ref() + } + + fn get(&self, idx: usize) -> &T { + &self.as_slice()[idx] + } + + fn get_mut(&mut self, idx: usize) -> &mut T { + &mut self.as_mut_slice()[idx] + } + + fn hash(&self) -> u64 { + hash_slice(self.as_slice()) + } + fn to_vec(&self) -> Vec { + self.as_slice().to_vec() + } +} + +impl<'a, T> AsSlice for VariableMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + #[inline] + fn as_slice(&self) -> &[T] { + self.map.as_slice() + } +} +impl<'a, T> AsMutSlice for VariableMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + #[inline] + fn as_mut_slice(&mut self) -> &mut [T] { + self.map.as_mut_slice() + } } impl<'a, T> VariableMapObserver<'a, T> @@ -498,7 +659,7 @@ static COUNT_CLASS_LOOKUP: [u8; 256] = [ impl Observer for HitcountsMapObserver where - M: MapObserver + Observer, + M: MapObserver + Observer, { #[inline] fn pre_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> { @@ -527,7 +688,7 @@ where impl HasLen for HitcountsMapObserver where - M: MapObserver, + M: MapObserver, { #[inline] fn len(&self) -> usize { @@ -535,24 +696,11 @@ where } } -impl MapObserver for HitcountsMapObserver +impl MapObserver for HitcountsMapObserver where - M: MapObserver, + M: MapObserver, { - #[inline] - fn map(&self) -> Option<&[u8]> { - self.base.map() - } - - #[inline] - fn map_mut(&mut self) -> Option<&mut [u8]> { - self.base.map_mut() - } - - #[inline] - fn usable_count(&self) -> usize { - self.base.usable_count() - } + type Entry = u8; #[inline] fn initial(&self) -> u8 { @@ -568,6 +716,47 @@ where fn set_initial(&mut self, initial: u8) { self.base.set_initial(initial); } + + #[inline] + fn usable_count(&self) -> usize { + self.base.usable_count() + } + + #[inline] + fn get(&self, idx: usize) -> &u8 { + self.base.get(idx) + } + + #[inline] + fn get_mut(&mut self, idx: usize) -> &mut u8 { + self.base.get_mut(idx) + } + + fn hash(&self) -> u64 { + self.base.hash() + } + fn to_vec(&self) -> Vec { + self.base.to_vec() + } +} + +impl AsSlice for HitcountsMapObserver +where + M: MapObserver + AsSlice, +{ + #[inline] + fn as_slice(&self) -> &[u8] { + self.base.as_slice() + } +} +impl AsMutSlice for HitcountsMapObserver +where + M: MapObserver + AsMutSlice, +{ + #[inline] + fn as_mut_slice(&mut self) -> &mut [u8] { + self.base.as_mut_slice() + } } impl HitcountsMapObserver @@ -586,19 +775,20 @@ where #[allow(clippy::unsafe_derive_deserialize)] pub struct MultiMapObserver<'a, T> where - T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { maps: Vec>, intervals: IntervalTree, len: usize, initial: T, name: String, + iter_idx: usize, } impl<'a, I, S, T> Observer for MultiMapObserver<'a, T> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, - Self: MapObserver, + Self: MapObserver, { #[inline] fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> { @@ -608,7 +798,7 @@ where impl<'a, T> Named for MultiMapObserver<'a, T> where - T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { #[inline] fn name(&self) -> &str { @@ -618,7 +808,7 @@ where impl<'a, T> HasLen for MultiMapObserver<'a, T> where - T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { #[inline] fn len(&self) -> usize { @@ -626,19 +816,11 @@ where } } -impl<'a, T> MapObserver for MultiMapObserver<'a, T> +impl<'a, T> MapObserver for MultiMapObserver<'a, T> where T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { - #[inline] - fn map(&self) -> Option<&[T]> { - None - } - - #[inline] - fn map_mut(&mut self) -> Option<&mut [T]> { - None - } + type Entry = T; #[inline] fn get(&self, idx: usize) -> &T { @@ -706,11 +888,15 @@ where } Ok(()) } + + fn usable_count(&self) -> usize { + self.len() + } } impl<'a, T> MultiMapObserver<'a, T> where - T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, { /// Creates a new [`MultiMapObserver`] #[must_use] @@ -739,6 +925,7 @@ where len: idx, name: name.to_string(), initial, + iter_idx: 0, } } @@ -769,6 +956,31 @@ where len: idx, name: name.to_string(), initial, + iter_idx: 0, } } } + +impl<'a, 'it, T> IntoIterator for &'it mut MultiMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Item = as Iterator>::Item; + type IntoIter = Flatten>>; + + fn into_iter(self) -> Self::IntoIter { + self.maps.iter_mut().flatten() + } +} + +impl<'a, 'it, T> IntoIterator for &'it MultiMapObserver<'a, T> +where + T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, +{ + type Item = as Iterator>::Item; + type IntoIter = Flatten>>; + + fn into_iter(self) -> Self::IntoIter { + self.maps.iter().flatten() + } +} diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 3aa24b8d6e..84edde2c36 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -19,34 +19,33 @@ use alloc::{ vec::Vec, }; use core::{fmt::Debug, marker::PhantomData, time::Duration}; -use num_traits::PrimInt; +use num_traits::Bounded; use serde::{Deserialize, Serialize}; /// The calibration stage will measure the average exec time and the target's stability for this input. #[derive(Clone, Debug)] -pub struct CalibrationStage +pub struct CalibrationStage where - T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, I: Input, - O: MapObserver, + O: MapObserver, OT: ObserversTuple, S: HasCorpus + HasMetadata, { map_observer_name: String, stage_max: usize, - phantom: PhantomData<(I, O, OT, S, T)>, + phantom: PhantomData<(I, O, OT, S)>, } const CAL_STAGE_START: usize = 4; const CAL_STAGE_MAX: usize = 16; -impl Stage for CalibrationStage +impl Stage for CalibrationStage where - T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, E: Executor + HasObservers, EM: EventFirer, I: Input, - O: MapObserver, + O: MapObserver, + for<'de> ::Entry: Serialize + Deserialize<'de> + 'static, OT: ObserversTuple, S: HasCorpus + HasMetadata + HasFeedbackStates + HasClientPerfMonitor, Z: Evaluator, @@ -94,8 +93,6 @@ where .observers() .match_name::(&self.map_observer_name) .ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))? - .map() - .unwrap() .to_vec(); // Run CAL_STAGE_START - 1 times, increase by 2 for every time a new @@ -137,19 +134,17 @@ where .observers() .match_name::(&self.map_observer_name) .ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))? - .map() - .unwrap() .to_vec(); let history_map = &mut state .feedback_states_mut() - .match_name_mut::>(&self.map_observer_name) + .match_name_mut::>(&self.map_observer_name) .unwrap() .history_map; for j in 0..map_len { - if map_first[j] != map[j] && history_map[j] != T::max_value() { - history_map[j] = T::max_value(); + if map_first[j] != map[j] && history_map[j] != O::Entry::max_value() { + history_map[j] = O::Entry::max_value(); unstable_entries += 1; }; } @@ -306,11 +301,10 @@ impl PowerScheduleMetadata { crate::impl_serdeany!(PowerScheduleMetadata); -impl CalibrationStage +impl CalibrationStage where - T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, I: Input, - O: MapObserver, + O: MapObserver, OT: ObserversTuple, S: HasCorpus + HasMetadata, { diff --git a/libafl/src/stages/power.rs b/libafl/src/stages/power.rs index 250723589b..5dff22eadd 100644 --- a/libafl/src/stages/power.rs +++ b/libafl/src/stages/power.rs @@ -2,7 +2,6 @@ use alloc::string::{String, ToString}; use core::{fmt::Debug, marker::PhantomData}; -use num_traits::PrimInt; use crate::{ corpus::{Corpus, IsFavoredMetadata, PowerScheduleTestcaseMetaData, Testcase}, @@ -34,13 +33,12 @@ const HAVOC_MAX_MULT: f64 = 64.0; /// The mutational stage using power schedules #[derive(Clone, Debug)] -pub struct PowerMutationalStage +pub struct PowerMutationalStage where - T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, E: Executor + HasObservers, I: Input, M: Mutator, - O: MapObserver, + O: MapObserver, OT: ObserversTuple, S: HasClientPerfMonitor + HasCorpus + HasMetadata, Z: Evaluator, @@ -50,17 +48,16 @@ where /// The employed power schedule strategy strat: PowerSchedule, #[allow(clippy::type_complexity)] - phantom: PhantomData<(E, EM, I, O, OT, S, T, Z)>, + phantom: PhantomData<(E, EM, I, O, OT, S, Z)>, } -impl MutationalStage - for PowerMutationalStage +impl MutationalStage + for PowerMutationalStage where - T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, E: Executor + HasObservers, I: Input, M: Mutator, - O: MapObserver, + O: MapObserver, OT: ObserversTuple, S: HasClientPerfMonitor + HasCorpus + HasMetadata, Z: Evaluator, @@ -153,14 +150,12 @@ where } } -impl Stage - for PowerMutationalStage +impl Stage for PowerMutationalStage where - T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, E: Executor + HasObservers, I: Input, M: Mutator, - O: MapObserver, + O: MapObserver, OT: ObserversTuple, S: HasClientPerfMonitor + HasCorpus + HasMetadata, Z: Evaluator, @@ -180,13 +175,12 @@ where } } -impl PowerMutationalStage +impl PowerMutationalStage where - T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug, E: Executor + HasObservers, I: Input, M: Mutator, - O: MapObserver, + O: MapObserver, OT: ObserversTuple, S: HasClientPerfMonitor + HasCorpus + HasMetadata, Z: Evaluator, diff --git a/libafl_concolic/test/dump_constraints/src/main.rs b/libafl_concolic/test/dump_constraints/src/main.rs index 2a70fb0906..116ea7ad97 100644 --- a/libafl_concolic/test/dump_constraints/src/main.rs +++ b/libafl_concolic/test/dump_constraints/src/main.rs @@ -13,7 +13,10 @@ use std::{ }; use libafl::{ - bolts::shmem::{ShMem, ShMemProvider, StdShMemProvider}, + bolts::{ + shmem::{ShMem, ShMemProvider, StdShMemProvider}, + AsSlice, + }, observers::concolic::{ serialization_format::{MessageFileReader, MessageFileWriter, DEFAULT_ENV_NAME}, EXPRESSION_PRUNING, HITMAP_ENV_NAME, NO_FLOAT_ENV_NAME, SELECTIVE_SYMBOLICATION_ENV_NAME, diff --git a/libafl_frida/src/drcov_rt.rs b/libafl_frida/src/drcov_rt.rs index cbf08d6089..e4152e276a 100644 --- a/libafl_frida/src/drcov_rt.rs +++ b/libafl_frida/src/drcov_rt.rs @@ -1,6 +1,7 @@ //! Generates `DrCov` traces use ahash::AHasher; use libafl::{ + bolts::AsSlice, inputs::{HasTargetBytes, Input}, Error, }; diff --git a/libafl_frida/src/helper.rs b/libafl_frida/src/helper.rs index 8aa3f7144a..172c91708b 100644 --- a/libafl_frida/src/helper.rs +++ b/libafl_frida/src/helper.rs @@ -1,6 +1,8 @@ -use libafl::inputs::{HasTargetBytes, Input}; -use libafl::Error; - +use libafl::{ + bolts::AsSlice, + inputs::{HasTargetBytes, Input}, + Error, +}; #[cfg(unix)] use libafl_targets::drcov::DrCovBasicBlock; diff --git a/libafl_sugar/src/forkserver.rs b/libafl_sugar/src/forkserver.rs index ab8cfebd3b..b66e70b76d 100644 --- a/libafl_sugar/src/forkserver.rs +++ b/libafl_sugar/src/forkserver.rs @@ -11,6 +11,7 @@ use libafl::{ rands::StdRand, shmem::{ShMem, ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsMutSlice, }, corpus::{ CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/libafl_sugar/src/inmemory.rs b/libafl_sugar/src/inmemory.rs index fd0f6f140d..dba079d872 100644 --- a/libafl_sugar/src/inmemory.rs +++ b/libafl_sugar/src/inmemory.rs @@ -13,6 +13,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/libafl_sugar/src/qemu.rs b/libafl_sugar/src/qemu.rs index ed1ff9fe42..4c6bde7f03 100644 --- a/libafl_sugar/src/qemu.rs +++ b/libafl_sugar/src/qemu.rs @@ -12,6 +12,7 @@ use libafl::{ rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::{tuple_list, Merge}, + AsSlice, }, corpus::{ CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, diff --git a/libafl_targets/src/cmplog.rs b/libafl_targets/src/cmplog.rs index 8108af6b35..7fa5c88ce3 100644 --- a/libafl_targets/src/cmplog.rs +++ b/libafl_targets/src/cmplog.rs @@ -187,11 +187,11 @@ where } } - fn map(&self) -> &CmpLogMap { + fn cmp_map(&self) -> &CmpLogMap { self.map.as_ref() } - fn map_mut(&mut self) -> &mut CmpLogMap { + fn cmp_map_mut(&mut self) -> &mut CmpLogMap { self.map.as_mut() } }