From 26122b20a07285ac8a2f5ac4b0e2096afbd8f9e7 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 2 Apr 2024 10:17:59 +0200 Subject: [PATCH] Add unsafe to AsanErrorsObserver, fix UBs, fix Frida Version missmatch (#1987) * Add unsafe to AsanErrorsObserver, fix UBs, fix Frida Version missmatch * Clippy * simpler API * fix build * fix --- fuzzers/frida_executable_libpng/Cargo.toml | 2 +- fuzzers/frida_executable_libpng/src/fuzzer.rs | 28 ++++++++----------- fuzzers/frida_executable_libpng/src/lib.rs | 2 +- fuzzers/frida_gdiplus/Cargo.toml | 2 +- fuzzers/frida_gdiplus/src/fuzzer.rs | 26 +++++++---------- fuzzers/frida_libpng/Cargo.toml | 2 +- fuzzers/frida_libpng/src/fuzzer.rs | 22 ++++++--------- libafl_bolts/src/ownedref.rs | 22 +++++++++++++++ libafl_frida/Cargo.toml | 4 +-- libafl_frida/src/asan/errors.rs | 24 +++++++++++----- libafl_frida/src/lib.rs | 6 ++-- libafl_frida/src/pthread_hook.rs | 8 +----- libafl_frida/src/utils.rs | 4 +-- 13 files changed, 81 insertions(+), 71 deletions(-) diff --git a/fuzzers/frida_executable_libpng/Cargo.toml b/fuzzers/frida_executable_libpng/Cargo.toml index da135b32d4..1b08bfc7cb 100644 --- a/fuzzers/frida_executable_libpng/Cargo.toml +++ b/fuzzers/frida_executable_libpng/Cargo.toml @@ -28,7 +28,7 @@ reqwest = { version = "0.11.4", features = ["blocking"] } [dependencies] libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]} libafl_bolts = { path = "../../libafl_bolts/" } -frida-gum = { version = "0.13.2", features = [ "auto-download", "event-sink", "invocation-listener"] } +frida-gum = { version = "0.13.6", features = [ "auto-download", "event-sink", "invocation-listener"] } libafl_frida = { path = "../../libafl_frida", features = ["cmplog"] } libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] } libc = "0.2" diff --git a/fuzzers/frida_executable_libpng/src/fuzzer.rs b/fuzzers/frida_executable_libpng/src/fuzzer.rs index f1d6ded886..114b43538b 100644 --- a/fuzzers/frida_executable_libpng/src/fuzzer.rs +++ b/fuzzers/frida_executable_libpng/src/fuzzer.rs @@ -39,7 +39,7 @@ use libafl_bolts::{ #[cfg(unix)] use libafl_frida::asan::{ asan_rt::AsanRuntime, - errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, + errors::{AsanErrorsFeedback, AsanErrorsObserver}, }; use libafl_frida::{ cmplog_rt::CmpLogRuntime, @@ -104,7 +104,7 @@ unsafe fn fuzz( let coverage = CoverageRuntime::new(); #[cfg(unix)] - let asan = AsanRuntime::new(&options); + let asan = AsanRuntime::new(options); #[cfg(unix)] let mut frida_helper = @@ -183,11 +183,9 @@ unsafe fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer); @@ -298,11 +296,9 @@ unsafe fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer,); @@ -428,11 +424,9 @@ unsafe fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer,); diff --git a/fuzzers/frida_executable_libpng/src/lib.rs b/fuzzers/frida_executable_libpng/src/lib.rs index 3090b533b0..da9fdeae51 100644 --- a/fuzzers/frida_executable_libpng/src/lib.rs +++ b/fuzzers/frida_executable_libpng/src/lib.rs @@ -48,7 +48,7 @@ pub unsafe extern "C" fn __libc_start_main( ORIG_MAIN = main; let orig_libc_start_main_addr: *mut c_void = - dlsym(RTLD_NEXT, "__libc_start_main\0".as_ptr().cast::()); + dlsym(RTLD_NEXT, c"__libc_start_main".as_ptr()); let orig_libc_start_main: LibcStartMainFunc = transmute(orig_libc_start_main_addr); diff --git a/fuzzers/frida_gdiplus/Cargo.toml b/fuzzers/frida_gdiplus/Cargo.toml index bc374e315f..1a19f5e929 100644 --- a/fuzzers/frida_gdiplus/Cargo.toml +++ b/fuzzers/frida_gdiplus/Cargo.toml @@ -26,7 +26,7 @@ reqwest = { version = "0.11.4", features = ["blocking"] } [dependencies] libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]} libafl_bolts = { path = "../../libafl_bolts/" } -frida-gum = { version = "0.13.2", features = [ "auto-download", "event-sink", "invocation-listener"] } +frida-gum = { version = "0.13.6", features = [ "auto-download", "event-sink", "invocation-listener"] } libafl_frida = { path = "../../libafl_frida", features = ["cmplog"] } libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] } libloading = "0.7" diff --git a/fuzzers/frida_gdiplus/src/fuzzer.rs b/fuzzers/frida_gdiplus/src/fuzzer.rs index 6cc4c53828..57a334c072 100644 --- a/fuzzers/frida_gdiplus/src/fuzzer.rs +++ b/fuzzers/frida_gdiplus/src/fuzzer.rs @@ -45,7 +45,7 @@ use libafl_bolts::{ #[cfg(unix)] use libafl_frida::asan::asan_rt::AsanRuntime; #[cfg(unix)] -use libafl_frida::asan::errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}; +use libafl_frida::asan::errors::{AsanErrorsFeedback, AsanErrorsObserver}; use libafl_frida::{ cmplog_rt::CmpLogRuntime, coverage_rt::{CoverageRuntime, MAP_SIZE}, @@ -177,11 +177,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer); @@ -292,11 +290,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer,); @@ -423,11 +419,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer,); diff --git a/fuzzers/frida_libpng/Cargo.toml b/fuzzers/frida_libpng/Cargo.toml index ca21f6ba6d..d367f03110 100644 --- a/fuzzers/frida_libpng/Cargo.toml +++ b/fuzzers/frida_libpng/Cargo.toml @@ -28,7 +28,7 @@ reqwest = { version = "0.11.4", features = ["blocking"] } [dependencies] libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]} libafl_bolts = { path = "../../libafl_bolts/" } -frida-gum = { version = "0.13.2", features = [ "auto-download", "event-sink", "invocation-listener"] } +frida-gum = { version = "0.13.6", features = [ "auto-download", "event-sink", "invocation-listener"] } libafl_frida = { path = "../../libafl_frida", features = ["cmplog"] } libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] } libloading = "0.7" diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index 80adabe2b8..afd4ed7c51 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -39,7 +39,7 @@ use libafl_bolts::{ #[cfg(unix)] use libafl_frida::asan::{ asan_rt::AsanRuntime, - errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, + errors::{AsanErrorsFeedback, AsanErrorsObserver}, }; use libafl_frida::{ cmplog_rt::CmpLogRuntime, @@ -94,7 +94,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let coverage = CoverageRuntime::new(); #[cfg(unix)] - let asan = AsanRuntime::new(&options); + let asan = AsanRuntime::new(options); #[cfg(unix)] let mut frida_helper = @@ -173,11 +173,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer); @@ -289,11 +287,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); #[cfg(unix)] - let observers = tuple_list!( - edges_observer, - time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) - ); + let observers = tuple_list!(edges_observer, time_observer, unsafe { + AsanErrorsObserver::from_static_asan_errors() + }); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer,); @@ -422,7 +418,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> { let observers = tuple_list!( edges_observer, time_observer, - AsanErrorsObserver::new(&ASAN_ERRORS) + AsanErrorsObserver::from_static_asan_errors() ); #[cfg(windows)] let observers = tuple_list!(edges_observer, time_observer,); diff --git a/libafl_bolts/src/ownedref.rs b/libafl_bolts/src/ownedref.rs index f778f1b31e..9bd14b85f2 100644 --- a/libafl_bolts/src/ownedref.rs +++ b/libafl_bolts/src/ownedref.rs @@ -761,6 +761,17 @@ pub enum OwnedPtr { Owned(Box), } +impl OwnedPtr { + /// Creates a new [`OwnedPtr`] from a raw pointer + /// + /// # Safety + /// The raw pointer will later be dereferenced. + /// It must outlive this `OwnedPtr` type and remain valid. + pub unsafe fn from_raw(ptr: *const T) -> Self { + Self::Ptr(ptr) + } +} + impl Serialize for OwnedPtr { fn serialize(&self, se: S) -> Result where @@ -822,6 +833,17 @@ pub enum OwnedMutPtr { Owned(Box), } +impl OwnedMutPtr { + /// Creates a new [`OwnedMutPtr`] from a raw pointer + /// + /// # Safety + /// The raw pointer will later be dereferenced. + /// It must outlive this `OwnedPtr` type and remain valid. + pub unsafe fn from_raw_mut(ptr: *mut T) -> Self { + Self::Ptr(ptr) + } +} + impl Serialize for OwnedMutPtr { fn serialize(&self, se: S) -> Result where diff --git a/libafl_frida/Cargo.toml b/libafl_frida/Cargo.toml index 9a7d9bc20e..3dd4a0471e 100644 --- a/libafl_frida/Cargo.toml +++ b/libafl_frida/Cargo.toml @@ -55,12 +55,12 @@ nix = { version = "0.27", features = ["mman"] } libc = "0.2" hashbrown = "0.14" rangemap = "1.3" -frida-gum-sys = { version = "0.8.1", features = [ +frida-gum-sys = { version = "0.13.6", features = [ "auto-download", "event-sink", "invocation-listener", ] } -frida-gum = { version = "0.13.2", features = [ +frida-gum = { version = "0.13.6", features = [ "auto-download", "event-sink", "invocation-listener", diff --git a/libafl_frida/src/asan/errors.rs b/libafl_frida/src/asan/errors.rs index 170d126053..ae825500d8 100644 --- a/libafl_frida/src/asan/errors.rs +++ b/libafl_frida/src/asan/errors.rs @@ -1,5 +1,5 @@ //! Errors that can be caught by the `libafl_frida` address sanitizer. -use std::{fmt::Debug, io::Write, marker::PhantomData}; +use std::{fmt::Debug, io::Write, marker::PhantomData, ptr::addr_of}; use backtrace::Backtrace; use color_backtrace::{default_output_stream, BacktracePrinter, Verbosity}; @@ -576,12 +576,18 @@ impl Named for AsanErrorsObserver { } impl AsanErrorsObserver { - /// Creates a new `AsanErrorsObserver`, pointing to a constant `AsanErrors` field + /// Creates a new [`AsanErrorsObserver`], pointing to a constant `AsanErrors` field #[must_use] - pub fn new(errors: *const Option) -> Self { - Self { - errors: OwnedPtr::Ptr(errors), - } + pub fn new(errors: OwnedPtr>) -> Self { + Self { errors } + } + + /// Creates a new [`AsanErrorsObserver`], pointing to the [`ASAN_ERRORS`] global static field. + /// + /// # Safety + /// The field should not be accessed multiple times at the same time (i.e., from different threads)! + pub unsafe fn from_static_asan_errors() -> Self { + Self::from_ptr(addr_of!(ASAN_ERRORS)) } /// Creates a new `AsanErrorsObserver`, owning the `AsanErrors` @@ -593,8 +599,12 @@ impl AsanErrorsObserver { } /// Creates a new `AsanErrorsObserver` from a raw ptr + /// + /// # Safety + /// Will dereference this pointer at a later point in time. + /// The pointer *must* outlive this [`AsanErrorsObserver`]'s lifetime. #[must_use] - pub fn from_mut_ptr(errors: *const Option) -> Self { + pub unsafe fn from_ptr(errors: *const Option) -> Self { Self { errors: OwnedPtr::Ptr(errors), } diff --git a/libafl_frida/src/lib.rs b/libafl_frida/src/lib.rs index f5c929809e..2b14b03df7 100644 --- a/libafl_frida/src/lib.rs +++ b/libafl_frida/src/lib.rs @@ -346,7 +346,7 @@ impl Default for FridaOptions { #[cfg(test)] mod tests { - use std::{ptr::addr_of, sync::OnceLock}; + use std::sync::OnceLock; use clap::Parser; use frida_gum::Gum; @@ -370,7 +370,7 @@ mod tests { use crate::{ asan::{ asan_rt::AsanRuntime, - errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, + errors::{AsanErrorsFeedback, AsanErrorsObserver}, }, coverage_rt::CoverageRuntime, executor::FridaInProcessExecutor, @@ -438,7 +438,7 @@ mod tests { let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective); let observers = tuple_list!( - AsanErrorsObserver::new(addr_of!(ASAN_ERRORS)) //, + AsanErrorsObserver::from_static_asan_errors() //, ); { diff --git a/libafl_frida/src/pthread_hook.rs b/libafl_frida/src/pthread_hook.rs index de1e4ca421..c436251e8b 100644 --- a/libafl_frida/src/pthread_hook.rs +++ b/libafl_frida/src/pthread_hook.rs @@ -1,11 +1,5 @@ -use std::{ - convert::{TryFrom, TryInto}, - sync::RwLock, -}; - /// Rust bindings for Apple's [`pthread_introspection`](https://opensource.apple.com/source/libpthread/libpthread-218.20.1/pthread/introspection.h.auto.html) hooks. -use libc; - +use std::sync::RwLock; const PTHREAD_INTROSPECTION_THREAD_CREATE: libc::c_uint = 1; const PTHREAD_INTROSPECTION_THREAD_START: libc::c_uint = 2; const PTHREAD_INTROSPECTION_THREAD_TERMINATE: libc::c_uint = 3; diff --git a/libafl_frida/src/utils.rs b/libafl_frida/src/utils.rs index f1f074482f..b382b064aa 100644 --- a/libafl_frida/src/utils.rs +++ b/libafl_frida/src/utils.rs @@ -159,8 +159,8 @@ const X86_64_REGS: [(RegSpec, X86Register); 34] = [ ]; /// The writer registers -/// frida registers: -/// capstone registers: +/// frida registers: +/// capstone registers: #[cfg(target_arch = "x86_64")] #[must_use] #[inline]