diff --git a/libafl/examples/llmp_test/main.rs b/libafl/examples/llmp_test/main.rs index ac02feff2d..5356514eec 100644 --- a/libafl/examples/llmp_test/main.rs +++ b/libafl/examples/llmp_test/main.rs @@ -3,9 +3,8 @@ This shows how llmp can be used directly, without libafl abstractions */ extern crate alloc; -use alloc::rc::Rc; #[cfg(all(unix, feature = "std"))] -use core::{cell::RefCell, convert::TryInto, time::Duration}; +use core::{convert::TryInto, time::Duration}; #[cfg(all(unix, feature = "std"))] use std::{thread, time}; diff --git a/libafl/src/bolts/llmp.rs b/libafl/src/bolts/llmp.rs index 11888c19d3..544e941d1d 100644 --- a/libafl/src/bolts/llmp.rs +++ b/libafl/src/bolts/llmp.rs @@ -1683,6 +1683,7 @@ where /// Reattach to a vacant client map. /// It is essential, that the broker (or someone else) kept a pointer to the out_map /// else reattach will get a new, empty page, from the OS, or fail + #[allow(clippy::needless_pass_by_value)] pub fn on_existing_map( shmem_provider: SP, _current_out_map: SP::Mem, diff --git a/libafl/src/bolts/os/ashmem_server.rs b/libafl/src/bolts/os/ashmem_server.rs index 2beb506efb..03d3f77e63 100644 --- a/libafl/src/bolts/os/ashmem_server.rs +++ b/libafl/src/bolts/os/ashmem_server.rs @@ -215,7 +215,6 @@ enum AshmemResponse { impl AshmemService { /// Create a new AshMem service - #[must_use] fn new() -> Result { Ok(AshmemService { provider: AshmemShMemProvider::new()?, @@ -316,11 +315,7 @@ impl AshmemService { client .stream .send_fds(&id.to_string().as_bytes(), &[server_fd])?; - client - .maps - .entry(server_fd) - .or_default() - .push(mapping.clone()); + client.maps.entry(server_fd).or_default().push(mapping); } AshmemResponse::Id(id) => { let client = self.clients.get_mut(&client_id).unwrap(); @@ -342,7 +337,7 @@ impl AshmemService { let syncpair = Arc::new((Mutex::new(false), Condvar::new())); let childsyncpair = Arc::clone(&syncpair); let join_handle = - thread::spawn(move || Self::new()?.listen(ASHMEM_SERVER_NAME, childsyncpair)); + thread::spawn(move || Self::new()?.listen(ASHMEM_SERVER_NAME, &childsyncpair)); let (lock, cvar) = &*syncpair; let mut started = lock.lock().unwrap(); @@ -358,14 +353,14 @@ impl AshmemService { fn listen( &mut self, filename: &str, - syncpair: Arc<(Mutex, Condvar)>, + syncpair: &Arc<(Mutex, Condvar)>, ) -> Result<(), Error> { let listener = if let Ok(listener) = UnixListener::bind_unix_addr(&UnixSocketAddr::new(filename)?) { listener } else { - let (lock, cvar) = &*syncpair; + let (lock, cvar) = &**syncpair; *lock.lock().unwrap() = true; cvar.notify_one(); return Err(Error::Unknown( @@ -377,7 +372,7 @@ impl AshmemService { PollFlags::POLLIN | PollFlags::POLLRDNORM | PollFlags::POLLRDBAND, )]; - let (lock, cvar) = &*syncpair; + let (lock, cvar) = &**syncpair; *lock.lock().unwrap() = true; cvar.notify_one(); diff --git a/libafl/src/bolts/shmem.rs b/libafl/src/bolts/shmem.rs index 9fe1cbf076..2b64dfc04f 100644 --- a/libafl/src/bolts/shmem.rs +++ b/libafl/src/bolts/shmem.rs @@ -230,9 +230,9 @@ where type Mem = RcShMem; fn new() -> Result { - return Ok(Self { + Ok(Self { internal: Rc::new(RefCell::new(T::new()?)), - }); + }) } fn new_map(&mut self, map_size: usize) -> Result { @@ -354,7 +354,7 @@ pub mod unix_shmem { let map = shmat(os_id, ptr::null(), 0) as *mut c_uchar; - if map == usize::MAX as c_int as *mut c_void as *mut c_uchar || map.is_null() { + if map as c_int == -1 || map.is_null() { shmctl(os_id, 0, ptr::null_mut()); return Err(Error::Unknown( "Failed to map the shared mapping".to_string(), @@ -557,7 +557,8 @@ pub mod unix_shmem { pub fn from_id_and_size(id: ShMemId, map_size: usize) -> Result { unsafe { let fd: i32 = id.to_string().parse().unwrap(); - if ioctl(fd, ASHMEM_GET_SIZE) != map_size as i32 { + #[allow(clippy::cast_sign_loss)] + if ioctl(fd, ASHMEM_GET_SIZE) as u32 as usize != map_size { return Err(Error::Unknown( "The mapping's size differs from the requested size".to_string(), )); @@ -613,11 +614,12 @@ pub mod unix_shmem { unsafe { let fd: i32 = self.id.to_string().parse().unwrap(); - let length = ioctl(fd, ASHMEM_GET_SIZE); + #[allow(clippy::cast_sign_loss)] + let length = ioctl(fd, ASHMEM_GET_SIZE) as u32; let ap = ashmem_pin { offset: 0, - len: length as u32, + len: length, }; ioctl(fd, ASHMEM_UNPIN, &ap); diff --git a/libafl_frida/src/asan_rt.rs b/libafl_frida/src/asan_rt.rs index 942ae71d2b..529bc469e0 100644 --- a/libafl_frida/src/asan_rt.rs +++ b/libafl_frida/src/asan_rt.rs @@ -30,7 +30,7 @@ use serde::{Deserialize, Serialize}; use std::{ cell::{RefCell, RefMut}, ffi::c_void, - io::Write, + io::{self, Write}, rc::Rc, }; use termcolor::{Color, ColorSpec, WriteColor}; @@ -72,8 +72,13 @@ struct AllocationMetadata { } impl Allocator { - fn new(runtime: Rc>) { - let page_size = unsafe { sysconf(_SC_PAGESIZE) as usize }; + fn setup(runtime: Rc>) { + let ret = unsafe { sysconf(_SC_PAGESIZE) }; + if ret < 0 { + panic!("Failed to read pagesize {:?}", io::Error::last_os_error()); + } + #[allow(clippy::cast_sign_loss)] + let page_size = ret as usize; // probe to find a usable shadow bit: let mut shadow_bit: usize = 0; for try_shadow_bit in &[46usize, 36usize] { @@ -98,7 +103,7 @@ impl Allocator { // attempt to pre-map the entire shadow-memory space let addr: usize = 1 << shadow_bit; - let pre_allocated_shadow = if let Ok(_) = unsafe { + let pre_allocated_shadow = unsafe { mmap( addr as *mut c_void, addr + addr, @@ -107,13 +112,10 @@ impl Allocator { -1, 0, ) - } { - true - } else { - false - }; + } + .is_ok(); - let res = Self { + let allocator = Self { runtime, page_size, pre_allocated_shadow, @@ -124,7 +126,7 @@ impl Allocator { allocation_queue: HashMap::new(), }; unsafe { - ALLOCATOR_SINGLETON = Some(RefCell::new(res)); + ALLOCATOR_SINGLETON = Some(RefCell::new(allocator)); } } @@ -139,7 +141,7 @@ impl Allocator { } pub fn init(runtime: Rc>) { - Self::new(runtime); + Self::setup(runtime); } #[inline] @@ -210,7 +212,7 @@ impl Allocator { address: mapping + self.page_size, size, actual_size: rounded_up_size, - ..Default::default() + ..AllocationMetadata::default() }; if self @@ -235,17 +237,16 @@ impl Allocator { } pub unsafe fn release(&mut self, ptr: *mut c_void) { - let mut metadata = match self.allocations.get_mut(&(ptr as usize)) { - Some(metadata) => metadata, - None => { - if !ptr.is_null() { - // TODO: report this as an observer - self.runtime - .borrow_mut() - .report_error(AsanError::UnallocatedFree((ptr as usize, Backtrace::new()))); - } - return; + let mut metadata = if let Some(metadata) = self.allocations.get_mut(&(ptr as usize)) { + metadata + } else { + if !ptr.is_null() { + // TODO: report this as an observer + self.runtime + .borrow_mut() + .report_error(AsanError::UnallocatedFree((ptr as usize, Backtrace::new()))); } + return; }; if metadata.freed { @@ -876,7 +877,7 @@ impl AsanRuntime { let mut actual_pc = self.regs[31]; actual_pc = match self.stalked_addresses.get(&actual_pc) { Some(addr) => *addr, - _ => actual_pc, + None => actual_pc, }; let cs = Capstone::new() @@ -1006,12 +1007,10 @@ impl AsanRuntime { } else { AsanError::OobRead(asan_readwrite_error) } + } else if metadata.freed { + AsanError::WriteAfterFree(asan_readwrite_error) } else { - if metadata.freed { - AsanError::WriteAfterFree(asan_readwrite_error) - } else { - AsanError::OobWrite(asan_readwrite_error) - } + AsanError::OobWrite(asan_readwrite_error) } } else { AsanError::Unknown(( @@ -1043,6 +1042,7 @@ impl AsanRuntime { ) })); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " Memory error detected! ").unwrap(); output .set_color(ColorSpec::new().set_fg(Some(Color::Red))) @@ -1075,6 +1075,7 @@ impl AsanRuntime { } output.reset().unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " REGISTERS ").unwrap(); for reg in 0..=30 { if reg == basereg { @@ -1094,11 +1095,12 @@ impl AsanRuntime { .unwrap(); output.reset().unwrap(); if reg % 4 == 3 { - write!(output, "\n").unwrap(); + writeln!(output).unwrap(); } } writeln!(output, "pc : 0x{:016x} ", error.pc).unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " CODE ").unwrap(); let mut cs = Capstone::new() .arm64() @@ -1131,6 +1133,7 @@ impl AsanRuntime { .print_trace(&error.backtrace, output) .unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " ALLOCATION INFO ").unwrap(); let offset: i64 = fault_address as i64 - error.metadata.address as i64; let direction = if offset > 0 { "right" } else { "left" }; @@ -1152,6 +1155,7 @@ impl AsanRuntime { } if error.metadata.freed { + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " FREE INFO ").unwrap(); if let Some(backtrace) = error.metadata.release_site_backtrace.as_mut() { writeln!(output, "free site backtrace:").unwrap(); @@ -1183,6 +1187,7 @@ impl AsanRuntime { } output.reset().unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " REGISTERS ").unwrap(); for reg in 0..=30 { if reg == basereg { @@ -1202,6 +1207,7 @@ impl AsanRuntime { } writeln!(output, "pc : 0x{:016x} ", pc).unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " CODE ").unwrap(); let mut cs = Capstone::new() .arm64() @@ -1237,6 +1243,7 @@ impl AsanRuntime { output.reset().unwrap(); backtrace_printer.print_trace(&backtrace, output).unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " ALLOCATION INFO ").unwrap(); writeln!( output, @@ -1253,6 +1260,7 @@ impl AsanRuntime { backtrace.resolve(); backtrace_printer.print_trace(backtrace, output).unwrap(); } + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " FREE INFO ").unwrap(); if let Some(backtrace) = metadata.release_site_backtrace.as_mut() { writeln!(output, "previous free site backtrace:").unwrap(); @@ -1269,6 +1277,7 @@ impl AsanRuntime { writeln!(output, " of {:?}", ptr).unwrap(); output.reset().unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " ALLOCATION INFO ").unwrap(); writeln!( output, @@ -1310,6 +1319,7 @@ impl AsanRuntime { } output.reset().unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " REGISTERS ").unwrap(); for reg in 0..=30 { if reg == basereg { @@ -1329,6 +1339,7 @@ impl AsanRuntime { } writeln!(output, "pc : 0x{:016x} ", pc).unwrap(); + #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " CODE ").unwrap(); let mut cs = Capstone::new() .arm64() @@ -1367,6 +1378,7 @@ impl AsanRuntime { } /// Generate the instrumentation blobs for the current arch. + #[allow(clippy::similar_names)] // We allow things like dword and qword fn generate_instrumentation_blobs(&mut self) { let shadow_bit = Allocator::get().shadow_bit as u32; macro_rules! shadow_check { @@ -1765,6 +1777,7 @@ impl AsanRuntime { pub static mut ASAN_ERRORS: Option = None; #[derive(Serialize, Deserialize)] +#[allow(clippy::unsafe_derive_deserialize)] pub struct AsanErrorsObserver { errors: OwnedPtr>, } @@ -1832,7 +1845,7 @@ where ) -> Result { let observer = observers .match_first_type::() - .expect("An AsanErrorsFeedback needs an AsanErrorsObserver".into()); + .expect("An AsanErrorsFeedback needs an AsanErrorsObserver"); match observer.errors() { None => Ok(0), Some(errors) => { diff --git a/libafl_frida/src/helper.rs b/libafl_frida/src/helper.rs index f3e14fa672..fe0172aac8 100644 --- a/libafl_frida/src/helper.rs +++ b/libafl_frida/src/helper.rs @@ -193,7 +193,7 @@ impl<'a> FridaInstrumentationHelper<'a> { gum: &'a Gum, options: FridaOptions, _harness_module_name: &str, - modules_to_instrument: &'a Vec<&str>, + modules_to_instrument: &'a [&str], ) -> Self { let mut helper = Self { map: [0u8; MAP_SIZE], @@ -247,7 +247,7 @@ impl<'a> FridaInstrumentationHelper<'a> { .real_address_for_stalked(get_pc(&context)) { Some(address) => *address, - _ => get_pc(&context), + None => get_pc(&context), }; //let (range, (id, name)) = helper.ranges.get_key_value(&real_address).unwrap(); //println!("{}:0x{:016x}", name, real_address - range.start); diff --git a/libafl_frida/src/lib.rs b/libafl_frida/src/lib.rs index 8f2940ed26..277aaca000 100644 --- a/libafl_frida/src/lib.rs +++ b/libafl_frida/src/lib.rs @@ -3,6 +3,7 @@ pub mod helper; /// A representation of the various Frida options #[derive(Clone, Copy, Debug)] +#[allow(clippy::struct_excessive_bools)] pub struct FridaOptions { enable_asan: bool, enable_asan_leak_detection: bool, @@ -66,44 +67,44 @@ impl FridaOptions { /// Is ASAN enabled? #[inline] - pub fn asan_enabled(&self) -> bool { + pub fn asan_enabled(self) -> bool { self.enable_asan } /// Is coverage enabled? #[inline] - pub fn coverage_enabled(&self) -> bool { + pub fn coverage_enabled(self) -> bool { self.enable_coverage } /// Is DrCov enabled? #[inline] - pub fn drcov_enabled(&self) -> bool { + pub fn drcov_enabled(self) -> bool { self.enable_drcov } /// Should ASAN detect leaks #[inline] - pub fn asan_detect_leaks(&self) -> bool { + pub fn asan_detect_leaks(self) -> bool { self.enable_asan_leak_detection } /// Should ASAN continue after a memory error is detected #[inline] - pub fn asan_continue_after_error(&self) -> bool { + pub fn asan_continue_after_error(self) -> bool { self.enable_asan_continue_after_error } /// Should ASAN gather (and report) allocation-/free-site backtraces #[inline] - pub fn asan_allocation_backtraces(&self) -> bool { + pub fn asan_allocation_backtraces(self) -> bool { self.enable_asan_allocation_backtraces } /// Whether stalker should be enabled. I.e. whether at least one stalker requiring option is /// enabled. #[inline] - pub fn stalker_enabled(&self) -> bool { + pub fn stalker_enabled(self) -> bool { self.enable_asan || self.enable_coverage || self.enable_drcov } } diff --git a/libafl_targets/src/lib.rs b/libafl_targets/src/lib.rs index f2ad1f9095..a8322e7431 100644 --- a/libafl_targets/src/lib.rs +++ b/libafl_targets/src/lib.rs @@ -11,9 +11,7 @@ pub mod libfuzzer; pub use libfuzzer::*; #[cfg(all(feature = "value_profile", feature = "cmplog"))] -compile_error!( - "the libafl_targets `value_profile` and `cmplog` features are mutually exclusive." -); +compile_error!("the libafl_targets `value_profile` and `cmplog` features are mutually exclusive."); #[cfg(feature = "value_profile")] pub mod value_profile;