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
This commit is contained in:
Dominik Maier 2024-04-02 10:17:59 +02:00 committed by GitHub
parent 10f373d587
commit 26122b20a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 81 additions and 71 deletions

View File

@ -28,7 +28,7 @@ reqwest = { version = "0.11.4", features = ["blocking"] }
[dependencies] [dependencies]
libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]} libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]}
libafl_bolts = { path = "../../libafl_bolts/" } 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_frida = { path = "../../libafl_frida", features = ["cmplog"] }
libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] } libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] }
libc = "0.2" libc = "0.2"

View File

@ -39,7 +39,7 @@ use libafl_bolts::{
#[cfg(unix)] #[cfg(unix)]
use libafl_frida::asan::{ use libafl_frida::asan::{
asan_rt::AsanRuntime, asan_rt::AsanRuntime,
errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, errors::{AsanErrorsFeedback, AsanErrorsObserver},
}; };
use libafl_frida::{ use libafl_frida::{
cmplog_rt::CmpLogRuntime, cmplog_rt::CmpLogRuntime,
@ -104,7 +104,7 @@ unsafe fn fuzz(
let coverage = CoverageRuntime::new(); let coverage = CoverageRuntime::new();
#[cfg(unix)] #[cfg(unix)]
let asan = AsanRuntime::new(&options); let asan = AsanRuntime::new(options);
#[cfg(unix)] #[cfg(unix)]
let mut frida_helper = let mut frida_helper =
@ -183,11 +183,9 @@ unsafe fn fuzz(
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer); let observers = tuple_list!(edges_observer, time_observer);
@ -298,11 +296,9 @@ unsafe fn fuzz(
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer,); let observers = tuple_list!(edges_observer, time_observer,);
@ -428,11 +424,9 @@ unsafe fn fuzz(
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer,); let observers = tuple_list!(edges_observer, time_observer,);

View File

@ -48,7 +48,7 @@ pub unsafe extern "C" fn __libc_start_main(
ORIG_MAIN = main; ORIG_MAIN = main;
let orig_libc_start_main_addr: *mut c_void = let orig_libc_start_main_addr: *mut c_void =
dlsym(RTLD_NEXT, "__libc_start_main\0".as_ptr().cast::<i8>()); dlsym(RTLD_NEXT, c"__libc_start_main".as_ptr());
let orig_libc_start_main: LibcStartMainFunc = transmute(orig_libc_start_main_addr); let orig_libc_start_main: LibcStartMainFunc = transmute(orig_libc_start_main_addr);

View File

@ -26,7 +26,7 @@ reqwest = { version = "0.11.4", features = ["blocking"] }
[dependencies] [dependencies]
libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]} libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]}
libafl_bolts = { path = "../../libafl_bolts/" } 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_frida = { path = "../../libafl_frida", features = ["cmplog"] }
libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] } libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] }
libloading = "0.7" libloading = "0.7"

View File

@ -45,7 +45,7 @@ use libafl_bolts::{
#[cfg(unix)] #[cfg(unix)]
use libafl_frida::asan::asan_rt::AsanRuntime; use libafl_frida::asan::asan_rt::AsanRuntime;
#[cfg(unix)] #[cfg(unix)]
use libafl_frida::asan::errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}; use libafl_frida::asan::errors::{AsanErrorsFeedback, AsanErrorsObserver};
use libafl_frida::{ use libafl_frida::{
cmplog_rt::CmpLogRuntime, cmplog_rt::CmpLogRuntime,
coverage_rt::{CoverageRuntime, MAP_SIZE}, coverage_rt::{CoverageRuntime, MAP_SIZE},
@ -177,11 +177,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer); 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); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer,); 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); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer,); let observers = tuple_list!(edges_observer, time_observer,);

View File

@ -28,7 +28,7 @@ reqwest = { version = "0.11.4", features = ["blocking"] }
[dependencies] [dependencies]
libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]} libafl = { path = "../../libafl/", features = [ "std", "llmp_compression", "llmp_bind_public", "frida_cli" ] } #, "llmp_small_maps", "llmp_debug"]}
libafl_bolts = { path = "../../libafl_bolts/" } 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_frida = { path = "../../libafl_frida", features = ["cmplog"] }
libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] } libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] }
libloading = "0.7" libloading = "0.7"

View File

@ -39,7 +39,7 @@ use libafl_bolts::{
#[cfg(unix)] #[cfg(unix)]
use libafl_frida::asan::{ use libafl_frida::asan::{
asan_rt::AsanRuntime, asan_rt::AsanRuntime,
errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, errors::{AsanErrorsFeedback, AsanErrorsObserver},
}; };
use libafl_frida::{ use libafl_frida::{
cmplog_rt::CmpLogRuntime, cmplog_rt::CmpLogRuntime,
@ -94,7 +94,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
let coverage = CoverageRuntime::new(); let coverage = CoverageRuntime::new();
#[cfg(unix)] #[cfg(unix)]
let asan = AsanRuntime::new(&options); let asan = AsanRuntime::new(options);
#[cfg(unix)] #[cfg(unix)]
let mut frida_helper = let mut frida_helper =
@ -173,11 +173,9 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer); 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); let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
#[cfg(unix)] #[cfg(unix)]
let observers = tuple_list!( let observers = tuple_list!(edges_observer, time_observer, unsafe {
edges_observer, AsanErrorsObserver::from_static_asan_errors()
time_observer, });
AsanErrorsObserver::new(&ASAN_ERRORS)
);
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer,); let observers = tuple_list!(edges_observer, time_observer,);
@ -422,7 +418,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
let observers = tuple_list!( let observers = tuple_list!(
edges_observer, edges_observer,
time_observer, time_observer,
AsanErrorsObserver::new(&ASAN_ERRORS) AsanErrorsObserver::from_static_asan_errors()
); );
#[cfg(windows)] #[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer,); let observers = tuple_list!(edges_observer, time_observer,);

View File

@ -761,6 +761,17 @@ pub enum OwnedPtr<T: Sized> {
Owned(Box<T>), Owned(Box<T>),
} }
impl<T: Sized> OwnedPtr<T> {
/// 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<T: Sized + Serialize> Serialize for OwnedPtr<T> { impl<T: Sized + Serialize> Serialize for OwnedPtr<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where where
@ -822,6 +833,17 @@ pub enum OwnedMutPtr<T: Sized> {
Owned(Box<T>), Owned(Box<T>),
} }
impl<T: Sized> OwnedMutPtr<T> {
/// 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<T: Sized + Serialize> Serialize for OwnedMutPtr<T> { impl<T: Sized + Serialize> Serialize for OwnedMutPtr<T> {
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
where where

View File

@ -55,12 +55,12 @@ nix = { version = "0.27", features = ["mman"] }
libc = "0.2" libc = "0.2"
hashbrown = "0.14" hashbrown = "0.14"
rangemap = "1.3" rangemap = "1.3"
frida-gum-sys = { version = "0.8.1", features = [ frida-gum-sys = { version = "0.13.6", features = [
"auto-download", "auto-download",
"event-sink", "event-sink",
"invocation-listener", "invocation-listener",
] } ] }
frida-gum = { version = "0.13.2", features = [ frida-gum = { version = "0.13.6", features = [
"auto-download", "auto-download",
"event-sink", "event-sink",
"invocation-listener", "invocation-listener",

View File

@ -1,5 +1,5 @@
//! Errors that can be caught by the `libafl_frida` address sanitizer. //! 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 backtrace::Backtrace;
use color_backtrace::{default_output_stream, BacktracePrinter, Verbosity}; use color_backtrace::{default_output_stream, BacktracePrinter, Verbosity};
@ -576,12 +576,18 @@ impl Named for AsanErrorsObserver {
} }
impl 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] #[must_use]
pub fn new(errors: *const Option<AsanErrors>) -> Self { pub fn new(errors: OwnedPtr<Option<AsanErrors>>) -> Self {
Self { Self { errors }
errors: OwnedPtr::Ptr(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` /// Creates a new `AsanErrorsObserver`, owning the `AsanErrors`
@ -593,8 +599,12 @@ impl AsanErrorsObserver {
} }
/// Creates a new `AsanErrorsObserver` from a raw ptr /// 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] #[must_use]
pub fn from_mut_ptr(errors: *const Option<AsanErrors>) -> Self { pub unsafe fn from_ptr(errors: *const Option<AsanErrors>) -> Self {
Self { Self {
errors: OwnedPtr::Ptr(errors), errors: OwnedPtr::Ptr(errors),
} }

View File

@ -346,7 +346,7 @@ impl Default for FridaOptions {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{ptr::addr_of, sync::OnceLock}; use std::sync::OnceLock;
use clap::Parser; use clap::Parser;
use frida_gum::Gum; use frida_gum::Gum;
@ -370,7 +370,7 @@ mod tests {
use crate::{ use crate::{
asan::{ asan::{
asan_rt::AsanRuntime, asan_rt::AsanRuntime,
errors::{AsanErrorsFeedback, AsanErrorsObserver, ASAN_ERRORS}, errors::{AsanErrorsFeedback, AsanErrorsObserver},
}, },
coverage_rt::CoverageRuntime, coverage_rt::CoverageRuntime,
executor::FridaInProcessExecutor, executor::FridaInProcessExecutor,
@ -438,7 +438,7 @@ mod tests {
let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective); let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective);
let observers = tuple_list!( let observers = tuple_list!(
AsanErrorsObserver::new(addr_of!(ASAN_ERRORS)) //, AsanErrorsObserver::from_static_asan_errors() //,
); );
{ {

View File

@ -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. /// 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_CREATE: libc::c_uint = 1;
const PTHREAD_INTROSPECTION_THREAD_START: libc::c_uint = 2; const PTHREAD_INTROSPECTION_THREAD_START: libc::c_uint = 2;
const PTHREAD_INTROSPECTION_THREAD_TERMINATE: libc::c_uint = 3; const PTHREAD_INTROSPECTION_THREAD_TERMINATE: libc::c_uint = 3;

View File

@ -159,8 +159,8 @@ const X86_64_REGS: [(RegSpec, X86Register); 34] = [
]; ];
/// The writer registers /// The writer registers
/// frida registers: <https://docs.rs/frida-gum/0.4.0/frida_gum/instruction_writer/enum.X86Register.html> /// frida registers: <https://docs.rs/frida-gum/latest/frida_gum/instruction_writer/enum.X86Register.html>
/// capstone registers: <https://docs.rs/capstone-sys/0.14.0/capstone_sys/x86_reg/index.html> /// capstone registers: <https://docs.rs/capstone-sys/latest/capstone_sys/x86_reg/index.html>
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[must_use] #[must_use]
#[inline] #[inline]