From e513b86df027adff7a11ffa2bfffea347cfa5728 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 5 May 2022 06:52:37 -0700 Subject: [PATCH] Backtrace in libafl::Error (#617) * backtrace errors * qemu * remove mopt-specific error * fixes * fixes * duh * clap * clippy * clippy * clippy Co-authored-by: Dominik Maier --- libafl/Cargo.toml | 3 +- libafl/src/bolts/compress.rs | 2 +- libafl/src/bolts/launcher.rs | 2 +- libafl/src/bolts/llmp.rs | 56 ++--- libafl/src/bolts/os/mod.rs | 8 +- libafl/src/bolts/os/unix_shmem_server.rs | 4 +- libafl/src/bolts/os/unix_signals.rs | 6 +- libafl/src/bolts/shmem.rs | 40 +-- libafl/src/bolts/staterestore.rs | 8 +- libafl/src/corpus/cached.rs | 8 +- libafl/src/corpus/inmemory.rs | 2 +- libafl/src/corpus/ondisk.rs | 2 +- libafl/src/events/llmp.rs | 6 +- libafl/src/events/simple.rs | 2 +- libafl/src/executors/command.rs | 20 +- libafl/src/executors/forkserver.rs | 36 +-- libafl/src/executors/mod.rs | 2 +- libafl/src/feedbacks/differential.rs | 4 +- libafl/src/fuzzer/mod.rs | 2 +- libafl/src/inputs/encoded.rs | 4 +- libafl/src/inputs/gramatron.rs | 2 +- libafl/src/inputs/mod.rs | 4 +- libafl/src/lib.rs | 236 +++++++++++++++--- libafl/src/mutators/grimoire.rs | 2 +- libafl/src/mutators/mopt_mutator.rs | 12 +- libafl/src/mutators/mutations.rs | 2 +- libafl/src/mutators/token_mutations.rs | 10 +- libafl/src/schedulers/accounting.rs | 2 +- libafl/src/schedulers/minimizer.rs | 6 +- libafl/src/schedulers/mod.rs | 2 +- libafl/src/schedulers/powersched.rs | 6 +- .../src/schedulers/probabilistic_sampling.rs | 6 +- libafl/src/schedulers/queue.rs | 2 +- libafl/src/schedulers/testcase_score.rs | 20 +- libafl/src/schedulers/weighted.rs | 12 +- libafl/src/stages/calibrate.rs | 10 +- libafl/src/stages/generalization.rs | 4 +- libafl/src/stages/power.rs | 12 +- libafl_qemu/src/elf.rs | 4 +- libafl_targets/src/coverage.rs | 5 +- 40 files changed, 371 insertions(+), 205 deletions(-) diff --git a/libafl/Cargo.toml b/libafl/Cargo.toml index da4529cbad..20c8b73904 100644 --- a/libafl/Cargo.toml +++ b/libafl/Cargo.toml @@ -25,6 +25,7 @@ cli = ["clap"] # expose bolts::cli qemu_cli = ["cli"] frida_cli = ["cli"] afl_exec_sec = [] # calculate exec/sec like AFL +errors_backtrace = ["backtrace"] # features hiding dependencies licensed under GPL gpl = [] @@ -77,7 +78,7 @@ uuid = { version = "0.8.2", optional = true, features = ["serde", "v4"] } libm = "0.2.1" tui = { version = "0.16", default-features = false, features = ['crossterm'], optional = true } crossterm = { version = "0.20", optional = true } -clap = {version = "3.0", features = ["derive", "wrap_help"], optional = true} +clap = {version = "3.1", features = ["derive", "wrap_help"], optional = true} wait-timeout = { version = "0.2", optional = true } # used by CommandExecutor to wait for child process diff --git a/libafl/src/bolts/compress.rs b/libafl/src/bolts/compress.rs index 48f29b9777..9d2fcb2399 100644 --- a/libafl/src/bolts/compress.rs +++ b/libafl/src/bolts/compress.rs @@ -46,7 +46,7 @@ impl GzipCompressor { match decompressed { Ok(buf) => Ok(buf), - Err(_) => Err(Error::Compression), + Err(_) => Err(Error::compression()), } } } diff --git a/libafl/src/bolts/launcher.rs b/libafl/src/bolts/launcher.rs index 33e08b6449..3c065f25d3 100644 --- a/libafl/src/bolts/launcher.rs +++ b/libafl/src/bolts/launcher.rs @@ -122,7 +122,7 @@ where #[allow(clippy::similar_names)] pub fn launch(&mut self) -> Result<(), Error> { if self.run_client.is_none() { - return Err(Error::IllegalArgument( + return Err(Error::illegal_argument( "No client callback provided".to_string(), )); } diff --git a/libafl/src/bolts/llmp.rs b/libafl/src/bolts/llmp.rs index d873331f63..7d5d969869 100644 --- a/libafl/src/bolts/llmp.rs +++ b/libafl/src/bolts/llmp.rs @@ -392,7 +392,7 @@ where { let msg = postcard::to_allocvec(msg)?; if msg.len() > u32::MAX as usize { - return Err(Error::IllegalState(format!( + return Err(Error::illegal_state(format!( "Trying to send message a tcp message > u32! (size: {})", msg.len() ))); @@ -499,7 +499,7 @@ unsafe fn llmp_next_msg_ptr_checked( if next_ptr >= msg_begin_min && next_ptr <= msg_begin_max { Ok(next) } else { - Err(Error::IllegalState(format!( + Err(Error::illegal_state(format!( "Inconsistent data on sharedmap, or Bug (next_ptr was {:x}, sharedmap page was {:x})", next_ptr as usize, page as usize ))) @@ -577,7 +577,7 @@ impl LlmpMsg { if self.in_shmem(map) { Ok(self.as_slice_unsafe()) } else { - Err(Error::IllegalState("Current message not in page. The sharedmap get tampered with or we have a BUG.".into())) + Err(Error::illegal_state("Current message not in page. The sharedmap get tampered with or we have a BUG.")) } } } @@ -635,7 +635,7 @@ where let _listener_thread = broker.launch_listener(Listener::Tcp(listener))?; Ok(LlmpConnection::IsBroker { broker }) } - Err(Error::File(e)) if e.kind() == ErrorKind::AddrInUse => { + Err(Error::File(e, _)) if e.kind() == ErrorKind::AddrInUse => { // We are the client :) println!( "We're the client (internal port already bound by broker, {:#?})", @@ -1077,7 +1077,7 @@ where } let page = self.out_shmems.last_mut().unwrap().page_mut(); if msg.is_null() || !llmp_msg_in_page(page, msg) { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Llmp Message {:?} is null or not in current page", msg ))); @@ -1184,7 +1184,7 @@ where match unsafe { self.alloc_next_if_space(buf_len) } { Some(msg) => Ok(msg), - None => Err(Error::Unknown(format!( + None => Err(Error::unknown(format!( "Error allocating {} bytes in shmap", buf_len ))), @@ -1212,12 +1212,10 @@ where shrinked_len: usize, ) -> Result<(), Error> { if msg.is_null() { - return Err(Error::IllegalArgument( - "Null msg passed to shrink_alloced".into(), - )); + return Err(Error::illegal_argument("Null msg passed to shrink_alloced")); } else if !self.has_unsent_message { - return Err(Error::IllegalState( - "Called shrink_alloced, but the msg was not unsent".into(), + return Err(Error::illegal_state( + "Called shrink_alloced, but the msg was not unsent", )); } @@ -1230,7 +1228,7 @@ where - size_of::(); if buf_len_padded > old_len_padded.try_into().unwrap() { - return Err(Error::IllegalArgument(format!("Cannot shrink msg of size {} (paded: {}) to requested larger size of {} (padded: {})!", (*msg).buf_len, old_len_padded, shrinked_len, buf_len_padded))); + return Err(Error::illegal_argument(format!("Cannot shrink msg of size {} (paded: {}) to requested larger size of {} (padded: {})!", (*msg).buf_len, old_len_padded, shrinked_len, buf_len_padded))); } (*msg).buf_len = shrinked_len as u64; @@ -1255,7 +1253,7 @@ where || tag == LLMP_TAG_UNINITIALIZED || tag == LLMP_TAG_UNSET { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Reserved tag supplied to send_buf ({:#X})", tag ))); @@ -1279,7 +1277,7 @@ where || tag == LLMP_TAG_UNINITIALIZED || tag == LLMP_TAG_UNSET { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Reserved tag supplied to send_buf ({:#X})", tag ))); @@ -1434,7 +1432,7 @@ where // Let's see what we got. if let Some(msg) = ret { if !(*msg).in_shmem(&mut self.current_recv_shmem) { - return Err(Error::IllegalState("Unexpected message in map (out of map bounds) - bugy client or tampered shared map detedted!".into())); + return Err(Error::illegal_state("Unexpected message in map (out of map bounds) - bugy client or tampered shared map detedted!")); } // Handle special, LLMP internal, messages. match (*msg).tag { @@ -1446,7 +1444,7 @@ where LLMP_TAG_EXITING => { // The other side is done. assert_eq!((*msg).buf_len, 0); - return Err(Error::ShuttingDown); + return Err(Error::shuttingdown()); } LLMP_TAG_END_OF_PAGE => { #[cfg(feature = "std")] @@ -1684,7 +1682,7 @@ where } /// Gets the offset of a message on this here page. - /// Will return [`crate::Error::IllegalArgument`] error if msg is not on page. + /// Will return [`crate::Error::illegal_argument`] error if msg is not on page. /// /// # Safety /// This dereferences msg, make sure to pass a proper pointer to it. @@ -1695,7 +1693,7 @@ where // Cast both sides to u8 arrays, get the offset, then cast the return isize to u64 Ok((msg as *const u8).offset_from((*page).messages.as_ptr() as *const u8) as u64) } else { - Err(Error::IllegalArgument(format!( + Err(Error::illegal_argument(format!( "Message (0x{:X}) not in page (0x{:X})", page as u64, msg as u64 ))) @@ -1731,7 +1729,7 @@ where } /// Gets this message from this page, at the indicated offset. - /// Will return [`crate::Error::IllegalArgument`] error if the offset is out of bounds. + /// Will return [`crate::Error::illegal_argument`] error if the offset is out of bounds. #[allow(clippy::cast_ptr_alignment)] pub fn msg_from_offset(&mut self, offset: u64) -> Result<*mut LlmpMsg, Error> { let offset = offset as usize; @@ -1739,7 +1737,7 @@ where let page = self.page_mut(); let page_size = self.shmem.as_slice().len() - size_of::(); if offset > page_size { - Err(Error::IllegalArgument(format!( + Err(Error::illegal_argument(format!( "Msg offset out of bounds (size: {}, requested offset: {})", page_size, offset ))) @@ -1864,7 +1862,7 @@ where hostname, } => println!("B2B: Connected to {}", hostname), _ => { - return Err(Error::IllegalState( + return Err(Error::illegal_state( "Unexpected response from B2B server received.".to_string(), )) } @@ -1883,7 +1881,7 @@ where broker_id } _ => { - return Err(Error::IllegalState( + return Err(Error::illegal_state( "Unexpected response from B2B server received.".to_string(), )); } @@ -2157,7 +2155,7 @@ where }); let ret = recv.recv().map_err(|_| { - Error::Unknown("Error launching background thread for b2b communcation".to_string()) + Error::unknown("Error launching background thread for b2b communcation".to_string()) }); #[cfg(all(feature = "llmp_debug", feature = "std"))] @@ -2346,7 +2344,7 @@ where match (*msg).tag { // first, handle the special, llmp-internal messages LLMP_SLOW_RECEIVER_PANIC => { - return Err(Error::Unknown(format!("The broker was too slow to handle messages of client {} in time, so it quit. Either the client sent messages too fast, or we (the broker) got stuck!", client_id))); + return Err(Error::unknown(format!("The broker was too slow to handle messages of client {} in time, so it quit. Either the client sent messages too fast, or we (the broker) got stuck!", client_id))); } LLMP_TAG_NEW_SHM_CLIENT => { /* This client informs us about yet another new client @@ -2359,7 +2357,7 @@ where size_of::() ); #[cfg(not(feature = "std"))] - return Err(Error::Unknown(format!("Broken CLIENT_ADDED msg with incorrect size received. Expected {} but got {}", + return Err(Error::unknown(format!("Broken CLIENT_ADDED msg with incorrect size received. Expected {} but got {}", msg_buf_len_padded, size_of::() ))); @@ -2387,7 +2385,7 @@ where #[cfg(feature = "std")] println!("Error adding client! Ignoring: {:?}", e); #[cfg(not(feature = "std"))] - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Error adding client! PANIC! {:?}", e ))); @@ -2674,7 +2672,7 @@ where } } } - _ => return Err(Error::IllegalState(e.to_string())), + _ => return Err(Error::illegal_state(e.to_string())), } } }; @@ -2687,7 +2685,7 @@ where { broker_shmem_description } else { - return Err(Error::IllegalState( + return Err(Error::illegal_state( "Received unexpected Broker Hello".to_string(), )); }; @@ -2710,7 +2708,7 @@ where { client_id } else { - return Err(Error::IllegalState( + return Err(Error::illegal_state( "Unexpected Response from Broker".to_string(), )); }; diff --git a/libafl/src/bolts/os/mod.rs b/libafl/src/bolts/os/mod.rs index c763fee0b0..b5b0be31bc 100644 --- a/libafl/src/bolts/os/mod.rs +++ b/libafl/src/bolts/os/mod.rs @@ -80,7 +80,7 @@ pub unsafe fn fork() -> Result { let err_str = CString::new("Fork failed").unwrap(); libc::perror(err_str.as_ptr()); } - Err(Error::Unknown(format!("Fork failed ({})", pid))) + Err(Error::unknown(format!("Fork failed ({})", pid))) } _ => Ok(ForkResult::Child), } @@ -101,7 +101,7 @@ pub fn startable_self() -> Result { #[cfg(all(unix, feature = "std"))] pub fn dup2(fd: i32, device: i32) -> Result<(), Error> { match unsafe { libc::dup2(fd, device) } { - -1 => Err(Error::File(std::io::Error::last_os_error())), + -1 => Err(Error::file(std::io::Error::last_os_error())), _ => Ok(()), } } @@ -184,7 +184,7 @@ impl Cores { let num_cores = if let Some(cores) = core_affinity::get_core_ids() { cores.len() } else { - return Err(Error::IllegalState( + return Err(Error::illegal_state( "Could not read core count from core_affinity".to_string(), )); }; @@ -208,7 +208,7 @@ impl Cores { } if cores.is_empty() { - return Err(Error::IllegalArgument(format!( + return Err(Error::illegal_argument(format!( "No cores specified! parsed: {}", args ))); diff --git a/libafl/src/bolts/os/unix_shmem_server.rs b/libafl/src/bolts/os/unix_shmem_server.rs index 8b31144cf8..aedbecd0a7 100644 --- a/libafl/src/bolts/os/unix_shmem_server.rs +++ b/libafl/src/bolts/os/unix_shmem_server.rs @@ -571,7 +571,7 @@ where ServedShMemRequest::Exit => { println!("ShMemService - Exiting"); // stopping the server - return Err(Error::ShuttingDown); + return Err(Error::shuttingdown()); } }; // println!("send ashmem client: {}, response: {:?}", client_id, &response); @@ -637,7 +637,7 @@ where *lock.lock().unwrap() = ShMemServiceStatus::Failed; cvar.notify_one(); - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "The ShMem server appears to already be running. We are probably a client. Error: {:?}", err))); } }; diff --git a/libafl/src/bolts/os/unix_signals.rs b/libafl/src/bolts/os/unix_signals.rs index 50aadddf21..7937920dcb 100644 --- a/libafl/src/bolts/os/unix_signals.rs +++ b/libafl/src/bolts/os/unix_signals.rs @@ -266,7 +266,7 @@ pub unsafe fn setup_signal_handler(handler: &mut T) -> Res let err_str = CString::new(format!("Failed to setup {} handler", sig)).unwrap(); libc::perror(err_str.as_ptr()); } - return Err(Error::Unknown(format!("Could not set up {} handler", sig))); + return Err(Error::unknown(format!("Could not set up {} handler", sig))); } } compiler_fence(Ordering::SeqCst); @@ -293,10 +293,10 @@ pub fn ucontext() -> Result { libc::perror(b"Failed to get ucontext\n".as_ptr() as _); }; #[cfg(not(feature = "std"))] - return Err(Error::Unknown("Failed to get ucontex".into())); + return Err(Error::unknown("Failed to get ucontex")); #[cfg(feature = "std")] - Err(Error::Unknown(format!( + Err(Error::unknown(format!( "Failed to get ucontext: {:?}", Errno::from_i32(errno()) ))) diff --git a/libafl/src/bolts/shmem.rs b/libafl/src/bolts/shmem.rs index c97f316b67..3e36a4cd17 100644 --- a/libafl/src/bolts/shmem.rs +++ b/libafl/src/bolts/shmem.rs @@ -450,7 +450,7 @@ where pipe.write_all(&ok)?; Ok(()) } - None => Err(Error::IllegalState( + None => Err(Error::illegal_state( "Unexpected `None` Pipe in RcShMemProvider! Missing post_fork()?".to_string(), )), } @@ -466,13 +466,13 @@ where if ret == ok { Ok(()) } else { - Err(Error::Unknown(format!( + Err(Error::unknown(format!( "Wrong result read from pipe! Expected 0, got {:?}", ret ))) } } - None => Err(Error::IllegalState( + None => Err(Error::illegal_state( "Unexpected `None` Pipe in RcShMemProvider! Missing post_fork()?".to_string(), )), } @@ -626,7 +626,7 @@ pub mod unix_shmem { ); if shm_fd == -1 { perror(b"shm_open\0".as_ptr() as *const _); - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Failed to shm_open map with id {:?}", shmem_ctr ))); @@ -636,7 +636,7 @@ pub mod unix_shmem { if ftruncate(shm_fd, map_size.try_into()?) != 0 { perror(b"ftruncate\0".as_ptr() as *const _); shm_unlink(filename_path.as_ptr() as *const _); - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "setup_shm(): ftruncate() failed for map with id {:?}", shmem_ctr ))); @@ -655,7 +655,7 @@ pub mod unix_shmem { perror(b"mmap\0".as_ptr() as *const _); close(shm_fd); shm_unlink(filename_path.as_ptr() as *const _); - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "mmap() failed for map with id {:?}", shmem_ctr ))); @@ -687,7 +687,7 @@ pub mod unix_shmem { if map == libc::MAP_FAILED || map.is_null() { perror(b"mmap\0".as_ptr() as *const _); close(shm_fd); - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "mmap() failed for map with fd {:?}", shm_fd ))); @@ -809,14 +809,14 @@ pub mod unix_shmem { ); if os_id < 0_i32 { - return Err(Error::Unknown(format!("Failed to allocate a shared mapping of size {} - check OS limits (i.e shmall, shmmax)", map_size))); + return Err(Error::unknown(format!("Failed to allocate a shared mapping of size {} - check OS limits (i.e shmall, shmmax)", map_size))); } let map = shmat(os_id, ptr::null(), 0) as *mut c_uchar; if map as c_int == -1 || map.is_null() { shmctl(os_id, libc::IPC_RMID, ptr::null_mut()); - return Err(Error::Unknown( + return Err(Error::unknown( "Failed to map the shared mapping".to_string(), )); } @@ -836,7 +836,7 @@ pub mod unix_shmem { let map = shmat(id_int, ptr::null(), 0) as *mut c_uchar; if map.is_null() || map == ptr::null_mut::().wrapping_sub(1) { - return Err(Error::Unknown( + return Err(Error::unknown( "Failed to map the shared mapping".to_string(), )); } @@ -978,7 +978,7 @@ pub mod unix_shmem { let fd = open(device_path.as_ptr(), O_RDWR); if fd == -1 { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Failed to open the ashmem device at {:?}", device_path ))); @@ -986,13 +986,13 @@ pub mod unix_shmem { //if ioctl(fd, ASHMEM_SET_NAME, name) != 0 { //close(fd); - //return Err(Error::Unknown("Failed to set the ashmem mapping's name".to_string())); + //return Err(Error::unknown("Failed to set the ashmem mapping's name".to_string())); //}; #[allow(trivial_numeric_casts)] if ioctl(fd, ASHMEM_SET_SIZE as _, map_size) != 0 { close(fd); - return Err(Error::Unknown( + return Err(Error::unknown( "Failed to set the ashmem mapping's size".to_string(), )); }; @@ -1007,7 +1007,7 @@ pub mod unix_shmem { ); if map == usize::MAX as *mut c_void { close(fd); - return Err(Error::Unknown( + return Err(Error::unknown( "Failed to map the ashmem mapping".to_string(), )); } @@ -1026,7 +1026,7 @@ pub mod unix_shmem { let fd: i32 = id.to_string().parse().unwrap(); #[allow(trivial_numeric_casts, clippy::cast_sign_loss)] if ioctl(fd, ASHMEM_GET_SIZE as _) as u32 as usize != map_size { - return Err(Error::Unknown( + return Err(Error::unknown( "The mapping's size differs from the requested size".to_string(), )); }; @@ -1041,7 +1041,7 @@ pub mod unix_shmem { ); if map == usize::MAX as *mut c_void { close(fd); - return Err(Error::Unknown( + return Err(Error::unknown( "Failed to map the ashmem mapping".to_string(), )); } @@ -1205,14 +1205,14 @@ pub mod win32_shmem { PSTR(map_str_bytes.as_mut_ptr()), ); if handle == HANDLE(0) { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Cannot create shared memory {}", String::from_utf8_lossy(map_str_bytes) ))); } let map = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, map_size) as *mut u8; if map.is_null() { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Cannot map shared memory {}", String::from_utf8_lossy(map_str_bytes) ))); @@ -1237,14 +1237,14 @@ pub mod win32_shmem { PSTR(map_str_bytes.as_ptr() as *mut _), ); if handle == HANDLE(0) { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Cannot open shared memory {}", String::from_utf8_lossy(&map_str_bytes) ))); } let map = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, map_size) as *mut u8; if map.is_null() { - return Err(Error::Unknown(format!( + return Err(Error::unknown(format!( "Cannot map shared memory {}", String::from_utf8_lossy(&map_str_bytes) ))); diff --git a/libafl/src/bolts/staterestore.rs b/libafl/src/bolts/staterestore.rs index 2a01959e70..251676a41d 100644 --- a/libafl/src/bolts/staterestore.rs +++ b/libafl/src/bolts/staterestore.rs @@ -45,7 +45,7 @@ impl StateShMemContent { pub fn buf_len_checked(&self, shmem_size: usize) -> Result { let buf_len = unsafe { read_volatile(&self.buf_len) }; if size_of::() + buf_len > shmem_size { - Err(Error::IllegalState(format!("Stored buf_len is larger than the shared map! Shared data corrupted? Expected {} bytes max, but got {} (buf_len {})", shmem_size, size_of::() + buf_len, buf_len))) + Err(Error::illegal_state(format!("Stored buf_len is larger than the shared map! Shared data corrupted? Expected {} bytes max, but got {} (buf_len {})", shmem_size, size_of::() + buf_len, buf_len))) } else { Ok(buf_len) } @@ -103,7 +103,7 @@ where S: Serialize, { if self.has_content() { - return Err(Error::IllegalState( + return Err(Error::illegal_state( "Trying to save state to a non-empty state map".to_string(), )); } @@ -125,7 +125,7 @@ where let len = filename_buf.len(); if len > self.shmem.len() { - return Err(Error::IllegalState(format!( + return Err(Error::illegal_state(format!( "The state restorer map is too small to fit anything, even the filename! It needs to be at least {} bytes. The tmpfile was written to {:?}.", @@ -226,7 +226,7 @@ where file_content = vec![]; File::open(tmpfile)?.read_to_end(&mut file_content)?; if file_content.is_empty() { - return Err(Error::IllegalState(format!( + return Err(Error::illegal_state(format!( "Colud not restore state from file {}", &filename ))); diff --git a/libafl/src/corpus/cached.rs b/libafl/src/corpus/cached.rs index 3652b9dde4..df9fd9adc2 100644 --- a/libafl/src/corpus/cached.rs +++ b/libafl/src/corpus/cached.rs @@ -104,8 +104,8 @@ where /// Creates the [`CachedOnDiskCorpus`]. pub fn new(dir_path: PathBuf, cache_max_len: usize) -> Result { if cache_max_len == 0 { - return Err(Error::IllegalArgument( - "The max cache len in CachedOnDiskCorpus cannot be 0".into(), + return Err(Error::illegal_argument( + "The max cache len in CachedOnDiskCorpus cannot be 0", )); } Ok(Self { @@ -122,8 +122,8 @@ where cache_max_len: usize, ) -> Result { if cache_max_len == 0 { - return Err(Error::IllegalArgument( - "The max cache len in CachedOnDiskCorpus cannot be 0".into(), + return Err(Error::illegal_argument( + "The max cache len in CachedOnDiskCorpus cannot be 0", )); } Ok(Self { diff --git a/libafl/src/corpus/inmemory.rs b/libafl/src/corpus/inmemory.rs index bd250935fd..937d415f0a 100644 --- a/libafl/src/corpus/inmemory.rs +++ b/libafl/src/corpus/inmemory.rs @@ -38,7 +38,7 @@ where #[inline] fn replace(&mut self, idx: usize, testcase: Testcase) -> Result<(), Error> { if idx >= self.entries.len() { - return Err(Error::KeyNotFound(format!("Index {} out of bounds", idx))); + return Err(Error::key_not_found(format!("Index {} out of bounds", idx))); } self.entries[idx] = RefCell::new(testcase); Ok(()) diff --git a/libafl/src/corpus/ondisk.rs b/libafl/src/corpus/ondisk.rs index 9bf891da73..90ed986c90 100644 --- a/libafl/src/corpus/ondisk.rs +++ b/libafl/src/corpus/ondisk.rs @@ -133,7 +133,7 @@ where #[inline] fn replace(&mut self, idx: usize, testcase: Testcase) -> Result<(), Error> { if idx >= self.entries.len() { - return Err(Error::KeyNotFound(format!("Index {} out of bounds", idx))); + return Err(Error::key_not_found(format!("Index {} out of bounds", idx))); } self.entries[idx] = RefCell::new(testcase); Ok(()) diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index 93c9f00bb0..99d089b0c3 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -384,7 +384,7 @@ where } Ok(()) } - _ => Err(Error::Unknown(format!( + _ => Err(Error::unknown(format!( "Received illegal message that message should not have arrived: {:?}.", event.name() ))), @@ -789,7 +789,7 @@ where broker_things(event_broker, self.remote_broker_addr)?; - return Err(Error::ShuttingDown); + return Err(Error::shuttingdown()); } LlmpConnection::IsClient { client } => { let mgr = @@ -807,7 +807,7 @@ where broker_things(event_broker, self.remote_broker_addr)?; - return Err(Error::ShuttingDown); + return Err(Error::shuttingdown()); } ManagerKind::Client { cpu_core } => { // We are a client diff --git a/libafl/src/events/simple.rs b/libafl/src/events/simple.rs index 79c3ba10e7..b46aeb2873 100644 --- a/libafl/src/events/simple.rs +++ b/libafl/src/events/simple.rs @@ -208,7 +208,7 @@ where // Handle arriving events in the client #[allow(clippy::needless_pass_by_value, clippy::unused_self)] fn handle_in_client(&mut self, _state: &mut S, event: Event) -> Result<(), Error> { - Err(Error::Unknown(format!( + Err(Error::unknown(format!( "Received illegal message that message should not have arrived: {:?}.", event ))) diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 9a13297ad0..817311fed9 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -279,15 +279,15 @@ where for (pos, arg) in args.into_iter().enumerate() { if pos == 0 { if arg.as_ref() == afl_delim { - return Err(Error::IllegalArgument( - "The first argument must not be @@ but the program to execute".into(), + return Err(Error::illegal_argument( + "The first argument must not be @@ but the program to execute", )); } builder.program(arg); } else if arg.as_ref() == afl_delim { if atat_at.is_some() { - return Err(Error::IllegalArgument( - "Multiple @@ in afl commandline are not permitted".into(), + return Err(Error::illegal_argument( + "Multiple @@ in afl commandline are not permitted", )); } atat_at = Some(pos); @@ -344,8 +344,8 @@ where if self.has_asan_observer || self.has_stderr_observer { let mut stderr = String::new(); child.stderr.as_mut().ok_or_else(|| { - Error::IllegalState( - "Observer tries to read stderr, but stderr was not `Stdio::pipe` in CommandExecutor".into(), + Error::illegal_state( + "Observer tries to read stderr, but stderr was not `Stdio::pipe` in CommandExecutor", ) })?.read_to_string(&mut stderr)?; if self.has_asan_observer { @@ -364,8 +364,8 @@ where if self.has_stdout_observer { let mut stdout = String::new(); child.stdout.as_mut().ok_or_else(|| { - Error::IllegalState( - "Observer tries to read stdout, but stdout was not `Stdio::pipe` in CommandExecutor".into(), + Error::illegal_state( + "Observer tries to read stdout, but stdout was not `Stdio::pipe` in CommandExecutor", ) })?.read_to_string(&mut stdout)?; self.observers @@ -540,8 +540,8 @@ impl CommandExecutorBuilder { let program = if let Some(program) = &self.program { program } else { - return Err(Error::IllegalArgument( - "ComandExecutor::builder: no program set!".into(), + return Err(Error::illegal_argument( + "ComandExecutor::builder: no program set!", )); }; let mut command = Command::new(program); diff --git a/libafl/src/executors/forkserver.rs b/libafl/src/executors/forkserver.rs index aeea0cd44b..0f445dee98 100644 --- a/libafl/src/executors/forkserver.rs +++ b/libafl/src/executors/forkserver.rs @@ -209,7 +209,7 @@ impl Forkserver { { Ok(_) => (), Err(err) => { - return Err(Error::Forkserver(format!( + return Err(Error::forkserver(format!( "Could not spawn the forkserver: {:#?}", err ))) @@ -292,7 +292,7 @@ impl Forkserver { let st_read = match self.st_pipe.read_end() { Some(fd) => fd, None => { - return Err(Error::File(io::Error::new( + return Err(Error::file(io::Error::new( ErrorKind::BrokenPipe, "Read pipe end was already closed", ))); @@ -314,7 +314,7 @@ impl Forkserver { let val: i32 = i32::from_ne_bytes(buf); Ok(Some(val)) } else { - Err(Error::Forkserver( + Err(Error::forkserver( "Unable to communicate with fork server (OOM?)".to_string(), )) } @@ -417,20 +417,20 @@ where self.executor.forkserver_mut().set_last_run_timed_out(0); if send_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Unable to request new process from fork server (OOM?)".to_string(), )); } let (recv_pid_len, pid) = self.executor.forkserver_mut().read_st()?; if recv_pid_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Unable to request new process from fork server (OOM?)".to_string(), )); } if pid <= 0 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Fork server is misbehaving (OOM?)".to_string(), )); } @@ -455,7 +455,7 @@ where let _ = kill(self.executor.forkserver().child_pid(), self.signal); let (recv_status_len, _) = self.executor.forkserver_mut().read_st()?; if recv_status_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Could not kill timed-out child".to_string(), )); } @@ -601,7 +601,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { (t.clone(), forkserver) } None => { - return Err(Error::IllegalArgument( + return Err(Error::illegal_argument( "ForkserverExecutorBuilder::build: target file not found".to_string(), )) } @@ -610,7 +610,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { let (rlen, status) = forkserver.read_st()?; // Initial handshake, read 4-bytes hello message from the forkserver. if rlen != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Failed to start a forkserver".to_string(), )); } @@ -631,7 +631,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { let send_len = forkserver.write_ctl(send_status)?; if send_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Writing to forkserver failed.".to_string(), )); } @@ -639,13 +639,13 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { if (send_status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT { let (read_len, dict_size) = forkserver.read_st()?; if read_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Reading from forkserver failed.".to_string(), )); } if !(2..=0xffffff).contains(&dict_size) { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Dictionary has an illegal size".to_string(), )); } @@ -655,7 +655,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> { let (rlen, buf) = forkserver.read_st_size(dict_size as usize)?; if rlen != dict_size as usize { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Failed to load autodictionary".to_string(), )); } @@ -890,20 +890,20 @@ where .forkserver .write_ctl(self.forkserver().last_run_timed_out())?; if send_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Unable to request new process from fork server (OOM?)".to_string(), )); } let (recv_pid_len, pid) = self.forkserver.read_st()?; if recv_pid_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Unable to request new process from fork server (OOM?)".to_string(), )); } if pid <= 0 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Fork server is misbehaving (OOM?)".to_string(), )); } @@ -912,7 +912,7 @@ where let (recv_status_len, status) = self.forkserver.read_st()?; if recv_status_len != 4 { - return Err(Error::Forkserver( + return Err(Error::forkserver( "Unable to communicate with fork server (OOM?)".to_string(), )); } @@ -1058,7 +1058,7 @@ mod tests { let result = match executor { Ok(_) => true, Err(e) => match e { - Error::Forkserver(s) => s == "Failed to start a forkserver", + Error::Forkserver(s, _) => s == "Failed to start a forkserver", _ => false, }, }; diff --git a/libafl/src/executors/mod.rs b/libafl/src/executors/mod.rs index 22dd9a9c34..3f7296df63 100644 --- a/libafl/src/executors/mod.rs +++ b/libafl/src/executors/mod.rs @@ -159,7 +159,7 @@ where input: &I, ) -> Result { if input.target_bytes().as_slice().is_empty() { - Err(Error::Empty("Input Empty".into())) + Err(Error::empty("Input Empty")) } else { Ok(ExitKind::Ok) } diff --git a/libafl/src/feedbacks/differential.rs b/libafl/src/feedbacks/differential.rs index db2c23887c..b82f91f986 100644 --- a/libafl/src/feedbacks/differential.rs +++ b/libafl/src/feedbacks/differential.rs @@ -73,7 +73,7 @@ where let o1_name = o1.name().to_string(); let o2_name = o2.name().to_string(); if o1_name == o2_name { - Err(Error::IllegalArgument(format!( + Err(Error::illegal_argument(format!( "DiffFeedback: observer names must be different (both were {})", o1_name ))) @@ -137,7 +137,7 @@ where OT: ObserversTuple + MatchName, { fn err(name: &str) -> Error { - Error::IllegalArgument(format!("DiffFeedback: observer {} not found", name)) + Error::illegal_argument(format!("DiffFeedback: observer {} not found", name)) } let o1: &O1 = observers diff --git a/libafl/src/fuzzer/mod.rs b/libafl/src/fuzzer/mod.rs index 0015e1a6ae..fd6a0077fc 100644 --- a/libafl/src/fuzzer/mod.rs +++ b/libafl/src/fuzzer/mod.rs @@ -198,7 +198,7 @@ where iters: u64, ) -> Result { if iters == 0 { - return Err(Error::IllegalArgument( + return Err(Error::illegal_argument( "Cannot fuzz for 0 iterations!".to_string(), )); } diff --git a/libafl/src/inputs/encoded.rs b/libafl/src/inputs/encoded.rs index 64599256b9..0c82dc849c 100644 --- a/libafl/src/inputs/encoded.rs +++ b/libafl/src/inputs/encoded.rs @@ -74,7 +74,7 @@ impl InputDecoder for TokenInputEncoderDecoder { fn decode(&self, input: &EncodedInput, bytes: &mut Vec) -> Result<(), Error> { for id in input.codes() { let tok = self.id_table.get(&(id % self.next_id)).ok_or_else(|| { - Error::IllegalState(format!("Id {} not in the decoder table", id)) + Error::illegal_state(format!("Id {} not in the decoder table", id)) })?; bytes.extend_from_slice(tok.as_bytes()); bytes.push(b' '); @@ -145,7 +145,7 @@ impl Tokenizer for NaiveTokenizer { fn tokenize(&self, bytes: &[u8]) -> Result, Error> { let mut tokens = vec![]; let string = - from_utf8(bytes).map_err(|_| Error::IllegalArgument("Invalid UTF-8".to_owned()))?; + from_utf8(bytes).map_err(|_| Error::illegal_argument("Invalid UTF-8".to_owned()))?; let string = self.comment_re.replace_all(string, "").to_string(); let mut str_prev = 0; for str_match in self.string_re.find_iter(&string) { diff --git a/libafl/src/inputs/gramatron.rs b/libafl/src/inputs/gramatron.rs index 3a3657a38d..bd7a26d622 100644 --- a/libafl/src/inputs/gramatron.rs +++ b/libafl/src/inputs/gramatron.rs @@ -98,7 +98,7 @@ impl GramatronInput { terms.clone_from_slice(&self.terms[from..to]); Ok(Self { terms }) } else { - Err(Error::IllegalArgument("Invalid from or to argument".into())) + Err(Error::illegal_argument("Invalid from or to argument")) } } } diff --git a/libafl/src/inputs/mod.rs b/libafl/src/inputs/mod.rs index ae02d89d2a..40f9d486ee 100644 --- a/libafl/src/inputs/mod.rs +++ b/libafl/src/inputs/mod.rs @@ -35,12 +35,12 @@ use crate::{bolts::ownedref::OwnedSlice, Error}; pub trait Input: Clone + Serialize + serde::de::DeserializeOwned + Debug { /// Write this input to the file fn to_file

(&self, _path: P) -> Result<(), Error> { - Err(Error::NotImplemented("Not supported in no_std".into())) + Err(Error::not_implemented("Not supported in no_std")) } /// Write this input to the file fn from_file

(_path: P) -> Result { - Err(Error::NotImplemented("Not supprted in no_std".into())) + Err(Error::not_implemented("Not supprted in no_std")) } /// Generate a name for this input diff --git a/libafl/src/lib.rs b/libafl/src/lib.rs index c16c2a7c3c..ddfdf2191e 100644 --- a/libafl/src/lib.rs +++ b/libafl/src/lib.rs @@ -105,62 +105,218 @@ pub use fuzzer::*; #[cfg(feature = "std")] use std::{env::VarError, io}; -/// Main error struct for AFL +#[cfg(feature = "errors_backtrace")] +pub type ErrorBacktrace = backtrace::Backtrace; + +#[cfg(not(feature = "errors_backtrace"))] +#[derive(Debug, Default)] +/// Empty struct to use when `errors_backtrace` is disabled +pub struct ErrorBacktrace {} +#[cfg(not(feature = "errors_backtrace"))] +impl ErrorBacktrace { + /// Nop + #[must_use] + pub fn new() -> Self { + Self {} + } +} + +#[cfg(feature = "errors_backtrace")] +fn display_error_backtrace(f: &mut fmt::Formatter, err: &ErrorBacktrace) -> fmt::Result { + write!(f, "\nBacktrace: {:?}", err) +} +#[cfg(not(feature = "errors_backtrace"))] +fn display_error_backtrace(_f: &mut fmt::Formatter, _err: &ErrorBacktrace) -> fmt::Result { + fmt::Result::Ok(()) +} + +/// Main error struct for `LibAFL` #[derive(Debug)] pub enum Error { /// Serialization error - Serialize(String), + Serialize(String, ErrorBacktrace), /// Compression error #[cfg(feature = "llmp_compression")] - Compression, + Compression(ErrorBacktrace), /// File related error #[cfg(feature = "std")] - File(io::Error), + File(io::Error, ErrorBacktrace), /// Optional val was supposed to be set, but isn't. - EmptyOptional(String), + EmptyOptional(String, ErrorBacktrace), /// Key not in Map - KeyNotFound(String), + KeyNotFound(String, ErrorBacktrace), /// No elements in the current item - Empty(String), + Empty(String, ErrorBacktrace), /// End of iteration - IteratorEnd(String), + IteratorEnd(String, ErrorBacktrace), /// This is not supported (yet) - NotImplemented(String), + NotImplemented(String, ErrorBacktrace), /// You're holding it wrong - IllegalState(String), + IllegalState(String, ErrorBacktrace), /// The argument passed to this method or function is not valid - IllegalArgument(String), + IllegalArgument(String, ErrorBacktrace), /// Forkserver related Error - Forkserver(String), - /// MOpt related Error - MOpt(String), + Forkserver(String, ErrorBacktrace), /// Shutting down, not really an error. ShuttingDown, /// Something else happened - Unknown(String), + Unknown(String, ErrorBacktrace), +} + +impl Error { + /// Serialization error + #[must_use] + pub fn serialize(arg: S) -> Self + where + S: Into, + { + Error::Serialize(arg.into(), ErrorBacktrace::new()) + } + #[cfg(feature = "llmp_compression")] + /// Compression error + #[must_use] + pub fn compression() -> Self { + Error::Compression(ErrorBacktrace::new()) + } + #[cfg(feature = "std")] + /// File related error + #[must_use] + pub fn file(arg: io::Error) -> Self { + Error::File(arg, ErrorBacktrace::new()) + } + /// Optional val was supposed to be set, but isn't. + #[must_use] + pub fn empty_optional(arg: S) -> Self + where + S: Into, + { + Error::EmptyOptional(arg.into(), ErrorBacktrace::new()) + } + /// Key not in Map + #[must_use] + pub fn key_not_found(arg: S) -> Self + where + S: Into, + { + Error::KeyNotFound(arg.into(), ErrorBacktrace::new()) + } + /// No elements in the current item + #[must_use] + pub fn empty(arg: S) -> Self + where + S: Into, + { + Error::Empty(arg.into(), ErrorBacktrace::new()) + } + /// End of iteration + #[must_use] + pub fn iterator_end(arg: S) -> Self + where + S: Into, + { + Error::IteratorEnd(arg.into(), ErrorBacktrace::new()) + } + /// This is not supported (yet) + #[must_use] + pub fn not_implemented(arg: S) -> Self + where + S: Into, + { + Error::NotImplemented(arg.into(), ErrorBacktrace::new()) + } + /// You're holding it wrong + #[must_use] + pub fn illegal_state(arg: S) -> Self + where + S: Into, + { + Error::IllegalState(arg.into(), ErrorBacktrace::new()) + } + /// The argument passed to this method or function is not valid + #[must_use] + pub fn illegal_argument(arg: S) -> Self + where + S: Into, + { + Error::IllegalArgument(arg.into(), ErrorBacktrace::new()) + } + /// Forkserver related Error + #[must_use] + pub fn forkserver(arg: S) -> Self + where + S: Into, + { + Error::Forkserver(arg.into(), ErrorBacktrace::new()) + } + /// Shutting down, not really an error. + #[must_use] + pub fn shuttingdown() -> Self { + Error::ShuttingDown + } + /// Something else happened + #[must_use] + pub fn unknown(arg: S) -> Self + where + S: Into, + { + Error::Unknown(arg.into(), ErrorBacktrace::new()) + } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Serialize(s) => write!(f, "Error in Serialization: `{0}`", &s), - #[cfg(feature = "llmp_compression")] - Self::Compression => write!(f, "Error in decompression"), - #[cfg(feature = "std")] - Self::File(err) => write!(f, "File IO failed: {:?}", &err), - Self::EmptyOptional(s) => write!(f, "Optional value `{0}` was not set", &s), - Self::KeyNotFound(s) => write!(f, "Key `{0}` not in Corpus", &s), - Self::Empty(s) => write!(f, "No items in {0}", &s), - Self::IteratorEnd(s) => { - write!(f, "All elements have been processed in {0} iterator", &s) + Self::Serialize(s, b) => { + write!(f, "Error in Serialization: `{0}`", &s)?; + display_error_backtrace(f, b) + } + #[cfg(feature = "llmp_compression")] + Self::Compression(b) => { + write!(f, "Error in decompression")?; + display_error_backtrace(f, b) + } + #[cfg(feature = "std")] + Self::File(err, b) => { + write!(f, "File IO failed: {:?}", &err)?; + display_error_backtrace(f, b) + } + Self::EmptyOptional(s, b) => { + write!(f, "Optional value `{0}` was not set", &s)?; + display_error_backtrace(f, b) + } + Self::KeyNotFound(s, b) => { + write!(f, "Key `{0}` not in Corpus", &s)?; + display_error_backtrace(f, b) + } + Self::Empty(s, b) => { + write!(f, "No items in {0}", &s)?; + display_error_backtrace(f, b) + } + Self::IteratorEnd(s, b) => { + write!(f, "All elements have been processed in {0} iterator", &s)?; + display_error_backtrace(f, b) + } + Self::NotImplemented(s, b) => { + write!(f, "Not implemented: {0}", &s)?; + display_error_backtrace(f, b) + } + Self::IllegalState(s, b) => { + write!(f, "Illegal state: {0}", &s)?; + display_error_backtrace(f, b) + } + Self::IllegalArgument(s, b) => { + write!(f, "Illegal argument: {0}", &s)?; + display_error_backtrace(f, b) + } + Self::Forkserver(s, b) => { + write!(f, "Forkserver : {0}", &s)?; + display_error_backtrace(f, b) } - Self::NotImplemented(s) => write!(f, "Not implemented: {0}", &s), - Self::IllegalState(s) => write!(f, "Illegal state: {0}", &s), - Self::IllegalArgument(s) => write!(f, "Illegal argument: {0}", &s), - Self::Forkserver(s) => write!(f, "Forkserver : {0}", &s), - Self::MOpt(s) => write!(f, "MOpt: {0}", &s), Self::ShuttingDown => write!(f, "Shutting down!"), - Self::Unknown(s) => write!(f, "Unknown error: {0}", &s), + Self::Unknown(s, b) => { + write!(f, "Unknown error: {0}", &s)?; + display_error_backtrace(f, b) + } } } } @@ -168,7 +324,7 @@ impl fmt::Display for Error { /// Stringify the postcard serializer error impl From for Error { fn from(err: postcard::Error) -> Self { - Self::Serialize(format!("{:?}", err)) + Self::serialize(format!("{:?}", err)) } } @@ -176,14 +332,14 @@ impl From for Error { #[cfg(feature = "std")] impl From for Error { fn from(err: serde_json::Error) -> Self { - Self::Serialize(format!("{:?}", err)) + Self::serialize(format!("{:?}", err)) } } #[cfg(all(unix, feature = "std"))] impl From for Error { fn from(err: nix::Error) -> Self { - Self::Unknown(format!("Unix error: {:?}", err)) + Self::unknown(format!("Unix error: {:?}", err)) } } @@ -191,38 +347,38 @@ impl From for Error { #[cfg(feature = "std")] impl From for Error { fn from(err: io::Error) -> Self { - Self::File(err) + Self::file(err) } } impl From for Error { fn from(err: FromUtf8Error) -> Self { - Self::Unknown(format!("Could not convert byte / utf-8: {:?}", err)) + Self::unknown(format!("Could not convert byte / utf-8: {:?}", err)) } } #[cfg(feature = "std")] impl From for Error { fn from(err: VarError) -> Self { - Self::Empty(format!("Could not get env var: {:?}", err)) + Self::empty(format!("Could not get env var: {:?}", err)) } } impl From for Error { fn from(err: ParseIntError) -> Self { - Self::Unknown(format!("Failed to parse Int: {:?}", err)) + Self::unknown(format!("Failed to parse Int: {:?}", err)) } } impl From for Error { fn from(err: TryFromIntError) -> Self { - Self::IllegalState(format!("Expected conversion failed: {:?}", err)) + Self::illegal_state(format!("Expected conversion failed: {:?}", err)) } } impl From for Error { fn from(err: TryFromSliceError) -> Self { - Self::IllegalArgument(format!("Could not convert slice: {:?}", err)) + Self::illegal_argument(format!("Could not convert slice: {:?}", err)) } } diff --git a/libafl/src/mutators/grimoire.rs b/libafl/src/mutators/grimoire.rs index 0c1a7eb6ed..3691345781 100644 --- a/libafl/src/mutators/grimoire.rs +++ b/libafl/src/mutators/grimoire.rs @@ -30,7 +30,7 @@ where let idx = { let meta = state.metadata_mut().get_mut::().ok_or_else(|| { - Error::KeyNotFound("GeneralizedIndexesMetadata needed by extend_with_random_generalized() not found, make sure that you have GeneralizationStage in".into()) + Error::key_not_found("GeneralizedIndexesMetadata needed by extend_with_random_generalized() not found, make sure that you have GeneralizationStage in") })?; *meta diff --git a/libafl/src/mutators/mopt_mutator.rs b/libafl/src/mutators/mopt_mutator.rs index 45badd8c0f..1891daba7c 100644 --- a/libafl/src/mutators/mopt_mutator.rs +++ b/libafl/src/mutators/mopt_mutator.rs @@ -233,7 +233,9 @@ impl MOpt { if self.probability_now[swarm][self.operator_num - 1] < 0.99 || self.probability_now[swarm][self.operator_num - 1] > 1.01 { - return Err(Error::MOpt("Error in pso_update".to_string())); + return Err(Error::illegal_state( + "MOpt: Error in pso_update".to_string(), + )); } } Ok(()) @@ -301,7 +303,9 @@ impl MOpt { if self.probability_now[swarm][self.operator_num - 1] < 0.99 || self.probability_now[swarm][self.operator_num - 1] > 1.01 { - return Err(Error::MOpt("Error in pso_update".to_string())); + return Err(Error::illegal_state( + "MOpt: Error in pso_update".to_string(), + )); } } self.swarm_now = 0; @@ -340,7 +344,9 @@ impl MOpt { || (res + 1 < operator_num && select_prob > self.probability_now[self.swarm_now][res + 1]) { - return Err(Error::MOpt("Error in select_algorithm".to_string())); + return Err(Error::illegal_state( + "MOpt: Error in select_algorithm".to_string(), + )); } Ok(res) } diff --git a/libafl/src/mutators/mutations.rs b/libafl/src/mutators/mutations.rs index 9d9c065196..f915d89649 100644 --- a/libafl/src/mutators/mutations.rs +++ b/libafl/src/mutators/mutations.rs @@ -1127,7 +1127,7 @@ fn from_hex(hex: u8) -> Result { 48..=57 => Ok(hex - 48), 65..=70 => Ok(hex - 55), 97..=102 => Ok(hex - 87), - _ => Err(Error::IllegalArgument("Invalid hex character".to_owned())), + _ => Err(Error::illegal_argument("Invalid hex character".to_owned())), } } diff --git a/libafl/src/mutators/token_mutations.rs b/libafl/src/mutators/token_mutations.rs index c2633f4451..3071cdfadf 100644 --- a/libafl/src/mutators/token_mutations.rs +++ b/libafl/src/mutators/token_mutations.rs @@ -111,7 +111,7 @@ impl Tokens { return Ok(Self::new()); } if token_stop < token_start { - return Err(Error::IllegalArgument(format!( + return Err(Error::illegal_argument(format!( "Tried to create tokens from illegal section: stop < start ({:?} < {:?})", token_stop, token_start ))); @@ -170,16 +170,16 @@ impl Tokens { } let pos_quote = match line.find('\"') { Some(x) => x, - None => return Err(Error::IllegalArgument("Illegal line: ".to_owned() + line)), + None => return Err(Error::illegal_argument("Illegal line: ".to_owned() + line)), }; if line.chars().nth(line.len() - 1) != Some('"') { - return Err(Error::IllegalArgument("Illegal line: ".to_owned() + line)); + return Err(Error::illegal_argument("Illegal line: ".to_owned() + line)); } // extract item let item = match line.get(pos_quote + 1..line.len() - 1) { Some(x) => x, - None => return Err(Error::IllegalArgument("Illegal line: ".to_owned() + line)), + None => return Err(Error::illegal_argument("Illegal line: ".to_owned() + line)), }; if item.is_empty() { continue; @@ -189,7 +189,7 @@ impl Tokens { let token: Vec = match str_decode(item) { Ok(val) => val, Err(_) => { - return Err(Error::IllegalArgument( + return Err(Error::illegal_argument( "Illegal line (hex decoding): ".to_owned() + line, )) } diff --git a/libafl/src/schedulers/accounting.rs b/libafl/src/schedulers/accounting.rs index a8d739ccd4..cf3c01c09a 100644 --- a/libafl/src/schedulers/accounting.rs +++ b/libafl/src/schedulers/accounting.rs @@ -188,7 +188,7 @@ where let mut old = state.corpus().get(*old_idx)?.borrow_mut(); let must_remove = { let old_meta = old.metadata_mut().get_mut::().ok_or_else(|| { - Error::KeyNotFound(format!( + Error::key_not_found(format!( "AccountingIndexesMetadata, needed by CoverageAccountingScheduler, not found in testcase #{}", old_idx )) diff --git a/libafl/src/schedulers/minimizer.rs b/libafl/src/schedulers/minimizer.rs index c05b1b0b35..69cc414526 100644 --- a/libafl/src/schedulers/minimizer.rs +++ b/libafl/src/schedulers/minimizer.rs @@ -142,7 +142,7 @@ where let mut entry = state.corpus().get(idx)?.borrow_mut(); let factor = F::compute(&mut *entry, state)?; let meta = entry.metadata_mut().get_mut::().ok_or_else(|| { - Error::KeyNotFound(format!( + Error::key_not_found(format!( "Metadata needed for MinimizerScheduler not found in testcase #{}", idx )) @@ -162,7 +162,7 @@ where let must_remove = { let old_meta = old.metadata_mut().get_mut::().ok_or_else(|| { - Error::KeyNotFound(format!( + Error::key_not_found(format!( "Metadata needed for MinimizerScheduler not found in testcase #{}", old_idx )) @@ -219,7 +219,7 @@ where if !acc.contains(key) { let mut entry = state.corpus().get(*idx)?.borrow_mut(); let meta = entry.metadata().get::().ok_or_else(|| { - Error::KeyNotFound(format!( + Error::key_not_found(format!( "Metadata needed for MinimizerScheduler not found in testcase #{}", idx )) diff --git a/libafl/src/schedulers/mod.rs b/libafl/src/schedulers/mod.rs index 25d3ffa47d..33314a765f 100644 --- a/libafl/src/schedulers/mod.rs +++ b/libafl/src/schedulers/mod.rs @@ -80,7 +80,7 @@ where /// Gets the next entry at random fn next(&self, state: &mut S) -> Result { if state.corpus().count() == 0 { - Err(Error::Empty("No entries in corpus".to_owned())) + Err(Error::empty("No entries in corpus".to_owned())) } else { let len = state.corpus().count(); let id = state.rand_mut().below(len as u64) as usize; diff --git a/libafl/src/schedulers/powersched.rs b/libafl/src/schedulers/powersched.rs index 2e5ab68faf..a984ee9ac7 100644 --- a/libafl/src/schedulers/powersched.rs +++ b/libafl/src/schedulers/powersched.rs @@ -167,7 +167,7 @@ where .borrow_mut() .metadata_mut() .get_mut::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleTestData not found".to_string()))? + .ok_or_else(|| Error::key_not_found("PowerScheduleTestData not found".to_string()))? .depth(), None => 0, }; @@ -184,7 +184,7 @@ where fn next(&self, state: &mut S) -> Result { if state.corpus().count() == 0 { - Err(Error::Empty(String::from("No entries in corpus"))) + Err(Error::empty(String::from("No entries in corpus"))) } else { let id = match state.corpus().current() { Some(cur) => { @@ -193,7 +193,7 @@ where .metadata_mut() .get_mut::() .ok_or_else(|| { - Error::KeyNotFound("PowerScheduleMetadata not found".to_string()) + Error::key_not_found("PowerScheduleMetadata not found".to_string()) })?; psmeta.set_queue_cycles(psmeta.queue_cycles() + 1); 0 diff --git a/libafl/src/schedulers/probabilistic_sampling.rs b/libafl/src/schedulers/probabilistic_sampling.rs index 8ff6cd0ab3..f4a1bfb5b3 100644 --- a/libafl/src/schedulers/probabilistic_sampling.rs +++ b/libafl/src/schedulers/probabilistic_sampling.rs @@ -73,8 +73,8 @@ where pub fn store_probability(&self, state: &mut S, idx: usize) -> Result<(), Error> { let factor = F::compute(&mut *state.corpus().get(idx)?.borrow_mut(), state)?; if factor == 0.0 { - return Err(Error::IllegalState( - "Infinity probability calculated for probabilistic sampling scheduler".into(), + return Err(Error::illegal_state( + "Infinity probability calculated for probabilistic sampling scheduler", )); } let meta = state @@ -105,7 +105,7 @@ where #[allow(clippy::cast_precision_loss)] fn next(&self, state: &mut S) -> Result { if state.corpus().count() == 0 { - Err(Error::Empty(String::from("No entries in corpus"))) + Err(Error::empty(String::from("No entries in corpus"))) } else { let rand_prob: f64 = (state.rand_mut().below(100) as f64) / 100.0; let meta = state.metadata().get::().unwrap(); diff --git a/libafl/src/schedulers/queue.rs b/libafl/src/schedulers/queue.rs index fa22d9f4ff..f238162f3c 100644 --- a/libafl/src/schedulers/queue.rs +++ b/libafl/src/schedulers/queue.rs @@ -16,7 +16,7 @@ where /// Gets the next entry in the queue fn next(&self, state: &mut S) -> Result { if state.corpus().count() == 0 { - Err(Error::Empty("No entries in corpus".to_owned())) + Err(Error::empty("No entries in corpus".to_owned())) } else { let id = match state.corpus().current() { Some(cur) => { diff --git a/libafl/src/schedulers/testcase_score.rs b/libafl/src/schedulers/testcase_score.rs index 412c397042..4c70d1db06 100644 --- a/libafl/src/schedulers/testcase_score.rs +++ b/libafl/src/schedulers/testcase_score.rs @@ -80,7 +80,7 @@ where let psmeta = state .metadata() .get::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleMetadata not found".to_string()))?; + .ok_or_else(|| Error::key_not_found("PowerScheduleMetadata not found".to_string()))?; let fuzz_mu = if psmeta.strat() == PowerSchedule::COE { let corpus = state.corpus(); @@ -93,7 +93,7 @@ where .metadata() .get::() .ok_or_else(|| { - Error::KeyNotFound("PowerScheduleTestData not found".to_string()) + Error::key_not_found("PowerScheduleTestData not found".to_string()) })? .n_fuzz_entry() } else { @@ -103,7 +103,7 @@ where .metadata() .get::() .ok_or_else(|| { - Error::KeyNotFound("PowerScheduleTestData not found".to_string()) + Error::key_not_found("PowerScheduleTestData not found".to_string()) })? .n_fuzz_entry() }; @@ -112,7 +112,7 @@ where } if n_paths == 0 { - return Err(Error::Unknown(String::from("Queue state corrput"))); + return Err(Error::unknown(String::from("Queue state corrput"))); } v /= f64::from(n_paths); @@ -124,7 +124,7 @@ where let mut perf_score = 100.0; let q_exec_us = entry .exec_time() - .ok_or_else(|| Error::KeyNotFound("exec_time not set".to_string()))? + .ok_or_else(|| Error::key_not_found("exec_time not set".to_string()))? .as_nanos() as f64; let avg_exec_us = psmeta.exec_time().as_nanos() as f64 / psmeta.cycles() as f64; @@ -135,7 +135,7 @@ where .metadata() .get::() .ok_or_else(|| { - Error::KeyNotFound("PowerScheduleTestcaseMetaData not found".to_string()) + Error::key_not_found("PowerScheduleTestcaseMetaData not found".to_string()) })?; if q_exec_us * 0.1 > avg_exec_us { @@ -300,12 +300,12 @@ where let psmeta = state .metadata() .get::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleMetadata not found".to_string()))?; + .ok_or_else(|| Error::key_not_found("PowerScheduleMetadata not found".to_string()))?; let tcmeta = entry .metadata() .get::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleTestData not found".to_string()))?; + .ok_or_else(|| Error::key_not_found("PowerScheduleTestData not found".to_string()))?; // This means that this testcase has never gone through the calibration stage before1, // In this case we'll just return the default weight @@ -315,7 +315,7 @@ where let q_exec_us = entry .exec_time() - .ok_or_else(|| Error::KeyNotFound("exec_time not set".to_string()))? + .ok_or_else(|| Error::key_not_found("exec_time not set".to_string()))? .as_nanos() as f64; let favored = entry.has_metadata::(); @@ -346,7 +346,7 @@ where let avg_top_size = state .metadata() .get::() - .ok_or_else(|| Error::KeyNotFound("TopRatedsMetadata not found".to_string()))? + .ok_or_else(|| Error::key_not_found("TopRatedsMetadata not found".to_string()))? .map() .len() as f64; weight *= 1.0 + (tc_ref / avg_top_size); diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index fba9cd9de6..bc12f94945 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -196,7 +196,9 @@ where let wsmeta = state .metadata_mut() .get_mut::() - .ok_or_else(|| Error::KeyNotFound("WeigthedScheduleMetadata not found".to_string()))?; + .ok_or_else(|| { + Error::key_not_found("WeigthedScheduleMetadata not found".to_string()) + })?; // Update metadata wsmeta.set_alias_probability(alias_probability); @@ -226,7 +228,7 @@ where .borrow_mut() .metadata_mut() .get_mut::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleTestData not found".to_string()))? + .ok_or_else(|| Error::key_not_found("PowerScheduleTestData not found".to_string()))? .depth(), None => 0, }; @@ -247,7 +249,7 @@ where #[allow(clippy::similar_names, clippy::cast_precision_loss)] fn next(&self, state: &mut S) -> Result { if state.corpus().count() == 0 { - Err(Error::Empty(String::from("No entries in corpus"))) + Err(Error::empty(String::from("No entries in corpus"))) } else { let corpus_counts = state.corpus().count(); let s = state.rand_mut().below(corpus_counts as u64) as usize; @@ -258,7 +260,7 @@ where .metadata_mut() .get_mut::() .ok_or_else(|| { - Error::KeyNotFound("WeigthedScheduleMetadata not found".to_string()) + Error::key_not_found("WeigthedScheduleMetadata not found".to_string()) })?; let current_cycles = wsmeta.runs_in_current_cycle(); @@ -281,7 +283,7 @@ where .metadata_mut() .get_mut::() .ok_or_else(|| { - Error::KeyNotFound("PowerScheduleMetadata not found".to_string()) + Error::key_not_found("PowerScheduleMetadata not found".to_string()) })?; psmeta.set_queue_cycles(psmeta.queue_cycles() + 1); } diff --git a/libafl/src/stages/calibrate.rs b/libafl/src/stages/calibrate.rs index 702bbea3a2..4812bd9a04 100644 --- a/libafl/src/stages/calibrate.rs +++ b/libafl/src/stages/calibrate.rs @@ -91,7 +91,7 @@ where let map_first = &executor .observers() .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))? + .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? .to_vec(); // Run CAL_STAGE_START - 1 times, increase by 2 for every time a new @@ -132,7 +132,7 @@ where let map = &executor .observers() .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))? + .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? .to_vec(); let history_map = &mut state @@ -172,7 +172,7 @@ where let map = executor .observers() .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))?; + .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))?; let bitmap_size = map.count_bytes(); @@ -197,7 +197,9 @@ where let data = testcase .metadata_mut() .get_mut::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleTestData not found".to_string()))?; + .ok_or_else(|| { + Error::key_not_found("PowerScheduleTestData not found".to_string()) + })?; data.set_bitmap_size(bitmap_size); data.set_handicap(handicap); diff --git a/libafl/src/stages/generalization.rs b/libafl/src/stages/generalization.rs index f0a9a9ef8c..aa39f3a28a 100644 --- a/libafl/src/stages/generalization.rs +++ b/libafl/src/stages/generalization.rs @@ -117,7 +117,7 @@ where let payload: Vec<_> = input.bytes().iter().map(|&x| Some(x)).collect(); let original = input.clone(); let meta = entry.metadata().get::().ok_or_else(|| { - Error::KeyNotFound(format!( + Error::key_not_found(format!( "MapNoveltiesMetadata needed for GeneralizationStage not found in testcase #{} (check the arguments of MapFeedback::new(...))", corpus_idx )) @@ -402,7 +402,7 @@ where let cnt = executor .observers() .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))? + .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))? .how_many_set(novelties); Ok(cnt == novelties.len()) diff --git a/libafl/src/stages/power.rs b/libafl/src/stages/power.rs index c2cadcb091..484d524832 100644 --- a/libafl/src/stages/power.rs +++ b/libafl/src/stages/power.rs @@ -70,7 +70,7 @@ where let use_random = state .metadata_mut() .get_mut::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleMetadata not found".to_string()))? + .ok_or_else(|| Error::key_not_found("PowerScheduleMetadata not found".to_string()))? .strat() == PowerSchedule::RAND; if use_random { @@ -83,7 +83,7 @@ where .metadata_mut() .get_mut::() .ok_or_else(|| { - Error::KeyNotFound("PowerScheduleTestcaseMetaData not found".to_string()) + Error::key_not_found("PowerScheduleTestcaseMetaData not found".to_string()) })?; if tcmeta.handicap() >= 4 { tcmeta.set_handicap(tcmeta.handicap() - 4); @@ -120,14 +120,16 @@ where let observer = executor .observers() .match_name::(&self.map_observer_name) - .ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))?; + .ok_or_else(|| Error::key_not_found("MapObserver not found".to_string()))?; let mut hash = observer.hash() as usize; let psmeta = state .metadata_mut() .get_mut::() - .ok_or_else(|| Error::KeyNotFound("PowerScheduleMetadata not found".to_string()))?; + .ok_or_else(|| { + Error::key_not_found("PowerScheduleMetadata not found".to_string()) + })?; hash %= psmeta.n_fuzz().len(); // Update the path frequency @@ -141,7 +143,7 @@ where .metadata_mut() .get_mut::() .ok_or_else(|| { - Error::KeyNotFound("PowerScheduleTestData not found".to_string()) + Error::key_not_found("PowerScheduleTestData not found".to_string()) })? .set_n_fuzz_entry(hash); } diff --git a/libafl_qemu/src/elf.rs b/libafl_qemu/src/elf.rs index 84270fbd79..916af64022 100644 --- a/libafl_qemu/src/elf.rs +++ b/libafl_qemu/src/elf.rs @@ -19,13 +19,13 @@ impl<'a> EasyElf<'a> { let elf = { let mut binary_file = File::open(path)?; binary_file.read_to_end(buffer)?; - Elf::parse(buffer).map_err(|e| Error::Unknown(format!("{}", e))) + Elf::parse(buffer).map_err(|e| Error::unknown(format!("{}", e))) }?; Ok(Self { elf }) } pub fn from_slice(buffer: &'a [u8]) -> Result { - let elf = Elf::parse(buffer).map_err(|e| Error::Unknown(format!("{}", e)))?; + let elf = Elf::parse(buffer).map_err(|e| Error::unknown(format!("{}", e)))?; Ok(Self { elf }) } diff --git a/libafl_targets/src/coverage.rs b/libafl_targets/src/coverage.rs index 81ef7949b2..158a32a9be 100644 --- a/libafl_targets/src/coverage.rs +++ b/libafl_targets/src/coverage.rs @@ -46,9 +46,8 @@ pub use __afl_area_ptr as EDGES_MAP_PTR; pub fn autotokens() -> Result { unsafe { if __token_start.is_null() || __token_stop.is_null() { - Err(Error::IllegalState( - "AutoTokens section not found, likely the targe is not compiled with AutoTokens" - .into(), + Err(Error::illegal_state( + "AutoTokens section not found, likely the targe is not compiled with AutoTokens", )) } else { // we can safely unwrap