From db1d38eeb6e41750dabe635deb2074e328bf58fd Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Tue, 20 May 2025 20:48:08 +0100 Subject: [PATCH] LibAFL_QEMU/librasan: Add support for reading environment (#3241) * Add support for reading environment * Fix clippy * Review fixes --- libafl_qemu/librasan/Justfile | 10 +- libafl_qemu/librasan/asan/src/env/mod.rs | 119 +++++++++++++ libafl_qemu/librasan/asan/src/file/libc.rs | 161 ++++++++++++++++++ libafl_qemu/librasan/asan/src/file/linux.rs | 36 ++++ libafl_qemu/librasan/asan/src/file/mod.rs | 14 ++ libafl_qemu/librasan/asan/src/hooks/mod.rs | 2 +- libafl_qemu/librasan/asan/src/host/libc.rs | 6 +- libafl_qemu/librasan/asan/src/lib.rs | 4 + libafl_qemu/librasan/asan/src/logger/libc.rs | 4 +- .../librasan/asan/src/maps/iterator.rs | 16 +- libafl_qemu/librasan/asan/src/maps/libc.rs | 8 +- libafl_qemu/librasan/asan/src/maps/mod.rs | 26 +-- libafl_qemu/librasan/asan/src/mmap/libc.rs | 15 +- libafl_qemu/librasan/asan/src/patch/mod.rs | 4 +- .../librasan/asan/src/symbols/dlsym.rs | 2 +- libafl_qemu/librasan/asan/src/symbols/mod.rs | 16 +- libafl_qemu/librasan/asan/src/symbols/nop.rs | 2 +- libafl_qemu/librasan/asan/src/test.rs | 2 +- .../asan/tests/default_frontend_mock.rs | 2 +- libafl_qemu/librasan/asan/tests/env.rs | 39 +++++ libafl_qemu/librasan/asan/tests/hooks_free.rs | 2 +- .../librasan/asan/tests/hooks_malloc.rs | 2 +- .../asan/tests/hooks_malloc_usable_size.rs | 2 +- .../librasan/asan/tests/hooks_memalign.rs | 2 +- .../librasan/asan/tests/hooks_memcpy.rs | 2 +- .../librasan/asan/tests/hooks_memmem.rs | 2 +- .../librasan/asan/tests/hooks_memmove.rs | 2 +- .../librasan/asan/tests/hooks_mempcpy.rs | 2 +- .../librasan/asan/tests/hooks_pvalloc.rs | 2 +- .../librasan/asan/tests/hooks_realloc.rs | 2 +- .../librasan/asan/tests/hooks_reallocarray.rs | 2 +- .../librasan/asan/tests/hooks_stpcpy.rs | 2 +- .../librasan/asan/tests/hooks_stpncpy.rs | 2 +- .../librasan/asan/tests/hooks_strncpy.rs | 4 +- .../librasan/asan/tests/hooks_valloc.rs | 2 +- .../librasan/asan/tests/libc_map_reader.rs | 10 +- .../librasan/asan/tests/linux_map_reader.rs | 10 +- libafl_qemu/librasan/asan/tests/patch_raw.rs | 4 +- .../librasan/asan/tests/symbols_dlsym.rs | 12 +- libafl_qemu/librasan/gasan/src/lib.rs | 25 ++- libafl_qemu/librasan/qasan/src/lib.rs | 24 ++- libafl_qemu/librasan/zasan/Justfile | 1 - libafl_qemu/librasan/zasan/src/lib.rs | 16 +- 43 files changed, 506 insertions(+), 116 deletions(-) create mode 100644 libafl_qemu/librasan/asan/src/env/mod.rs create mode 100644 libafl_qemu/librasan/asan/src/file/libc.rs create mode 100644 libafl_qemu/librasan/asan/src/file/linux.rs create mode 100644 libafl_qemu/librasan/asan/src/file/mod.rs create mode 100644 libafl_qemu/librasan/asan/tests/env.rs diff --git a/libafl_qemu/librasan/Justfile b/libafl_qemu/librasan/Justfile index b2fb2ec053..73ce113a0b 100644 --- a/libafl_qemu/librasan/Justfile +++ b/libafl_qemu/librasan/Justfile @@ -26,7 +26,7 @@ fix: fix_asan fix_dummy fix_fuzz fix_gasan fix_qasan fix_runner fix_zasan clippy: #!/bin/sh - cargo clippy + cargo clippy -F test doc: #!/bin/sh @@ -52,6 +52,8 @@ build_i386_dev: build_ppc_dev: #!/bin/sh + RUSTC_BOOTSTRAP=1 \ + RUSTFLAGS="--cfg rustix_use_experimental_asm" \ ARCH=ppc PROFILE=dev just build build_arm_release: @@ -72,6 +74,8 @@ build_i386_release: build_ppc_release: #!/bin/sh + RUSTC_BOOTSTRAP=1 \ + RUSTFLAGS="--cfg rustix_use_experimental_asm" \ ARCH=ppc PROFILE=release just build build_everything_dev: \ @@ -92,6 +96,8 @@ build_everything: build_everything_dev build_everything_release test_arm: #!/bin/sh + RUSTC_BOOTSTRAP=1 \ + RUSTFLAGS="--cfg rustix_use_experimental_asm" \ ARCH=arm \ PROFILE=dev \ RUSTLOG=debug \ @@ -124,6 +130,8 @@ test_i386: test_ppc: #!/bin/sh + RUSTC_BOOTSTRAP=1 \ + RUSTFLAGS="--cfg rustix_use_experimental_asm" \ ARCH=ppc \ PROFILE=dev \ RUSTLOG=debug \ diff --git a/libafl_qemu/librasan/asan/src/env/mod.rs b/libafl_qemu/librasan/asan/src/env/mod.rs new file mode 100644 index 0000000000..9788216623 --- /dev/null +++ b/libafl_qemu/librasan/asan/src/env/mod.rs @@ -0,0 +1,119 @@ +use alloc::{ + fmt::Debug, + string::{String, ToString}, + vec, +}; +use core::{hash::BuildHasherDefault, marker::PhantomData}; + +use ahash::AHasher; +use hashbrown::HashMap; +use log::Level; +use thiserror::Error; + +use crate::file::FileReader; + +type Hasher = BuildHasherDefault; + +#[derive(Debug)] +pub struct Env { + envs: HashMap, + phantom: PhantomData, +} + +impl Env { + /* Environment variable buffer size, should be larger than single largest env variable */ + const BUFFER_SIZE: usize = 131072; + /* Expected maximum number of environment variables to initialize hash table */ + const MAX_ENVS: usize = 4096; + + pub fn initialize() -> Result, EnvError> { + let mut reader = R::new(c"/proc/self/environ").map_err(EnvError::FailedToCreateReader)?; + + let mut buffer = vec![0u8; Self::BUFFER_SIZE]; + + let mut envs = HashMap::::with_capacity_and_hasher( + Self::MAX_ENVS, + Hasher::default(), + ); + + let mut start = 0; + let mut bytes_read = 0; + loop { + let skip = bytes_read - start; + start = 0; + bytes_read = reader + .read(&mut buffer[skip..]) + .map_err(EnvError::FailedToRead)? + + skip; + + let mut i = 0; + + while i < bytes_read { + if buffer[i] == 0 { + if i == start { + /* We found the null string at the end */ + return Ok(Env { + envs, + phantom: PhantomData, + }); + } + + let pair = String::from_utf8_lossy(&buffer[start..i]).to_string(); + log::debug!("pair: {pair}"); + + let (key, value) = pair + .split_once('=') + .map(|(k, v)| (k.to_string(), v.to_string())) + .ok_or(EnvError::Split(pair))?; + log::debug!("key: {key} value: {value}"); + + envs.insert(key, value); + start = i + 1; + } + i += 1; + } + buffer.copy_within(start..bytes_read, 0); + + if bytes_read == 0 { + if start == bytes_read { + break; + } + let fragment = String::from_utf8_lossy(&buffer[start..bytes_read]).to_string(); + return Err(EnvError::StringFragment(fragment)); + } + } + Ok(Env { + envs, + phantom: PhantomData, + }) + } + + pub fn get(&self, name: &str) -> Option<&str> { + self.envs.get(name).map(|s| s.as_str()) + } + + pub fn log_level(&self) -> Option { + self.get("RUST_LOG").and_then(|s| s.parse().ok()) + } +} + +impl IntoIterator for Env { + type Item = (String, String); + type IntoIter = hashbrown::hash_map::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.envs.into_iter() + } +} + +#[derive(Error, Debug, PartialEq)] +pub enum EnvError { + #[error("Failed to create reader: {0}")] + FailedToCreateReader(R::Error), + #[error("Failed to read: {0}")] + FailedToRead(R::Error), + #[error("Failed to split")] + Split(String), + #[error("String framgent: {0}")] + StringFragment(String), +} diff --git a/libafl_qemu/librasan/asan/src/file/libc.rs b/libafl_qemu/librasan/asan/src/file/libc.rs new file mode 100644 index 0000000000..6da428ee79 --- /dev/null +++ b/libafl_qemu/librasan/asan/src/file/libc.rs @@ -0,0 +1,161 @@ +use core::{ + ffi::{CStr, c_char, c_int}, + marker::PhantomData, +}; + +use libc::{O_NONBLOCK, O_RDONLY}; +use log::trace; +use thiserror::Error; + +use crate::{ + asan_swap, + file::FileReader, + size_t, ssize_t, + symbols::{AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols}, +}; + +#[derive(Debug)] +struct FunctionOpen; + +impl Function for FunctionOpen { + const NAME: &CStr = c"open"; + type Func = unsafe extern "C" fn(*const c_char, c_int, c_int) -> c_int; +} + +#[derive(Debug)] +struct FunctionClose; + +impl Function for FunctionClose { + const NAME: &CStr = c"close"; + type Func = unsafe extern "C" fn(c_int) -> c_int; +} + +#[derive(Debug)] +struct FunctionRead; + +impl Function for FunctionRead { + const NAME: &CStr = c"read"; + type Func = unsafe extern "C" fn(c_int, *mut c_char, size_t) -> ssize_t; +} + +#[derive(Debug)] +struct FunctionErrnoLocation; + +impl Function for FunctionErrnoLocation { + const NAME: &CStr = c"__errno_location"; + type Func = unsafe extern "C" fn() -> *mut c_int; +} + +static OPEN_ADDR: AtomicGuestAddr = AtomicGuestAddr::new(); +static CLOSE_ADDR: AtomicGuestAddr = AtomicGuestAddr::new(); +static READ_ADDR: AtomicGuestAddr = AtomicGuestAddr::new(); +static GET_ERRNO_LOCATION_ADDR: AtomicGuestAddr = AtomicGuestAddr::new(); + +#[derive(Debug)] +pub struct LibcFileReader { + fd: c_int, + _phantom: PhantomData, +} + +impl LibcFileReader { + fn get_open() -> Result<::Func, LibcFileReaderError> { + let addr = OPEN_ADDR.try_get_or_insert_with(|| { + S::lookup(FunctionOpen::NAME).map_err(|e| LibcFileReaderError::FailedToFindSymbol(e)) + })?; + let f = + FunctionOpen::as_ptr(addr).map_err(|e| LibcFileReaderError::InvalidPointerType(e))?; + Ok(f) + } + + fn get_close() -> Result<::Func, LibcFileReaderError> { + let addr = CLOSE_ADDR.try_get_or_insert_with(|| { + S::lookup(FunctionClose::NAME).map_err(|e| LibcFileReaderError::FailedToFindSymbol(e)) + })?; + let f = + FunctionClose::as_ptr(addr).map_err(|e| LibcFileReaderError::InvalidPointerType(e))?; + Ok(f) + } + + fn get_read() -> Result<::Func, LibcFileReaderError> { + let addr = READ_ADDR.try_get_or_insert_with(|| { + S::lookup(FunctionRead::NAME).map_err(|e| LibcFileReaderError::FailedToFindSymbol(e)) + })?; + let f = + FunctionRead::as_ptr(addr).map_err(|e| LibcFileReaderError::InvalidPointerType(e))?; + Ok(f) + } + + fn get_errno_location() + -> Result<::Func, LibcFileReaderError> { + let addr = GET_ERRNO_LOCATION_ADDR.try_get_or_insert_with(|| { + S::lookup(FunctionErrnoLocation::NAME) + .map_err(|e| LibcFileReaderError::FailedToFindSymbol(e)) + })?; + let f = FunctionErrnoLocation::as_ptr(addr) + .map_err(|e| LibcFileReaderError::InvalidPointerType(e))?; + Ok(f) + } + + fn errno() -> Result> { + unsafe { asan_swap(false) }; + let errno_location = Self::get_errno_location()?; + unsafe { asan_swap(true) }; + let errno = unsafe { *errno_location() }; + Ok(errno) + } +} + +impl FileReader for LibcFileReader { + type Error = LibcFileReaderError; + fn new(path: &CStr) -> Result, Self::Error> { + let fn_open = Self::get_open()?; + unsafe { asan_swap(false) }; + let fd = unsafe { fn_open(path.as_ptr() as *const c_char, O_NONBLOCK | O_RDONLY, 0) }; + unsafe { asan_swap(true) }; + if fd < 0 { + let errno = Self::errno().unwrap(); + return Err(LibcFileReaderError::FailedToOpen(errno)); + } + Ok(LibcFileReader { + fd, + _phantom: PhantomData, + }) + } + fn read(&mut self, buf: &mut [u8]) -> Result { + let fn_read = Self::get_read()?; + unsafe { asan_swap(false) }; + let ret = unsafe { fn_read(self.fd, buf.as_mut_ptr() as *mut c_char, buf.len()) }; + unsafe { asan_swap(true) }; + if ret < 0 { + let errno = Self::errno().unwrap(); + return Err(LibcFileReaderError::FailedToRead(self.fd, errno)); + } + Ok(ret as usize) + } +} + +impl Drop for LibcFileReader { + fn drop(&mut self) { + let fn_close = Self::get_close().unwrap(); + unsafe { asan_swap(false) }; + let ret = unsafe { fn_close(self.fd) }; + unsafe { asan_swap(true) }; + if ret < 0 { + let errno = Self::errno().unwrap(); + panic!("Failed to close: {}, Errno: {}", self.fd, errno); + } + trace!("Closed fd: {}", self.fd); + } +} + +#[derive(Error, Debug, PartialEq)] +pub enum LibcFileReaderError { + #[error("Failed to find mmap functions")] + FailedToFindSymbol(S::Error), + #[error("Invalid pointer type: {0:?}")] + InvalidPointerType(FunctionPointerError), + #[error("Failed to read - fd: {0}, errno: {1}")] + FailedToRead(c_int, c_int), + #[error("Failed to open - errno: {0}")] + FailedToOpen(c_int), +} diff --git a/libafl_qemu/librasan/asan/src/file/linux.rs b/libafl_qemu/librasan/asan/src/file/linux.rs new file mode 100644 index 0000000000..d2e6e05f44 --- /dev/null +++ b/libafl_qemu/librasan/asan/src/file/linux.rs @@ -0,0 +1,36 @@ +use core::ffi::CStr; + +use rustix::{ + fd::OwnedFd, + fs::{Mode, OFlags, open}, + io::{Errno, read}, +}; +use thiserror::Error; + +use crate::file::FileReader; + +#[derive(Debug)] +pub struct LinuxFileReader { + fd: OwnedFd, +} + +impl FileReader for LinuxFileReader { + type Error = LinuxFileReaderError; + fn new(path: &'static CStr) -> Result { + let fd = open(path, OFlags::RDONLY | OFlags::NONBLOCK, Mode::empty()) + .map_err(LinuxFileReaderError::FailedToOpen)?; + + Ok(LinuxFileReader { fd }) + } + fn read(&mut self, buf: &mut [u8]) -> Result { + read(&self.fd, buf).map_err(LinuxFileReaderError::FailedToRead) + } +} + +#[derive(Error, Debug, PartialEq)] +pub enum LinuxFileReaderError { + #[error("Failed to open - errno: {0}")] + FailedToOpen(Errno), + #[error("Failed to read - errno: {0}")] + FailedToRead(Errno), +} diff --git a/libafl_qemu/librasan/asan/src/file/mod.rs b/libafl_qemu/librasan/asan/src/file/mod.rs new file mode 100644 index 0000000000..69d2f03a39 --- /dev/null +++ b/libafl_qemu/librasan/asan/src/file/mod.rs @@ -0,0 +1,14 @@ +use alloc::fmt::Debug; +use core::ffi::CStr; + +#[cfg(feature = "libc")] +pub mod libc; + +#[cfg(feature = "linux")] +pub mod linux; + +pub trait FileReader: Debug + Send + Sized { + type Error: Debug; + fn new(path: &'static CStr) -> Result; + fn read(&mut self, buf: &mut [u8]) -> Result; +} diff --git a/libafl_qemu/librasan/asan/src/hooks/mod.rs b/libafl_qemu/librasan/asan/src/hooks/mod.rs index e1c95ce8ca..fa4009997b 100644 --- a/libafl_qemu/librasan/asan/src/hooks/mod.rs +++ b/libafl_qemu/librasan/asan/src/hooks/mod.rs @@ -89,7 +89,7 @@ impl PatchedHook { } pub fn lookup(&self) -> Result { - S::lookup(self.name.as_ptr() as *const c_char) + unsafe { S::lookup_raw(self.name.as_ptr() as *const c_char) } } } diff --git a/libafl_qemu/librasan/asan/src/host/libc.rs b/libafl_qemu/librasan/asan/src/host/libc.rs index 97812acf8b..320a8a1fa2 100644 --- a/libafl_qemu/librasan/asan/src/host/libc.rs +++ b/libafl_qemu/librasan/asan/src/host/libc.rs @@ -12,9 +12,7 @@ use crate::{ GuestAddr, host::{Host, HostAction}, shadow::PoisonType, - symbols::{ - AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols, SymbolsLookupStr, - }, + symbols::{AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols}, }; #[derive(Debug)] @@ -139,7 +137,7 @@ impl LibcHost { fn get_syscall() -> Result<::Func, LibcHostError> { let addr = SYSCALL_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionSyscall::NAME).map_err(|e| LibcHostError::FailedToFindSymbol(e)) + S::lookup(FunctionSyscall::NAME).map_err(|e| LibcHostError::FailedToFindSymbol(e)) })?; let f = FunctionSyscall::as_ptr(addr).map_err(|e| LibcHostError::InvalidPointerType(e))?; Ok(f) diff --git a/libafl_qemu/librasan/asan/src/lib.rs b/libafl_qemu/librasan/asan/src/lib.rs index d24793385f..344494ba75 100644 --- a/libafl_qemu/librasan/asan/src/lib.rs +++ b/libafl_qemu/librasan/asan/src/lib.rs @@ -38,8 +38,12 @@ pub mod allocator; #[cfg(not(feature = "test"))] pub mod arch; +pub mod env; + pub mod exit; +pub mod file; + #[cfg(feature = "hooks")] pub mod hooks; diff --git a/libafl_qemu/librasan/asan/src/logger/libc.rs b/libafl_qemu/librasan/asan/src/logger/libc.rs index 0f2500b3da..7f6bfe5c14 100644 --- a/libafl_qemu/librasan/asan/src/logger/libc.rs +++ b/libafl_qemu/librasan/asan/src/logger/libc.rs @@ -7,7 +7,7 @@ use spin::Once; use crate::{ GuestAddr, asan_swap, - symbols::{Function, FunctionPointer, Symbols, SymbolsLookupStr}, + symbols::{Function, FunctionPointer, Symbols}, }; #[derive(Debug)] @@ -27,7 +27,7 @@ pub struct LibcLogger { impl LibcLogger { pub fn initialize(level: Level) { ONCE.call_once(|| { - let write = S::lookup_str(FunctionWrite::NAME).unwrap(); + let write = S::lookup(FunctionWrite::NAME).unwrap(); let logger = Box::leak(Box::new(LibcLogger { level, write })); log::set_logger(logger).unwrap(); log::set_max_level(LevelFilter::Trace); diff --git a/libafl_qemu/librasan/asan/src/maps/iterator.rs b/libafl_qemu/librasan/asan/src/maps/iterator.rs index e870bbb758..b7dd8203f4 100644 --- a/libafl_qemu/librasan/asan/src/maps/iterator.rs +++ b/libafl_qemu/librasan/asan/src/maps/iterator.rs @@ -3,7 +3,8 @@ use core::fmt::Debug; use crate::{ GuestAddr, - maps::{MapReader, decode::MapDecode, entry::MapEntry}, + file::FileReader, + maps::{decode::MapDecode, entry::MapEntry}, }; const BUFFER_SIZE: usize = 4096; @@ -21,25 +22,26 @@ enum MapState { } #[derive(Debug)] -pub struct MapIterator { +pub struct MapIterator { source: R, buffer: [u8; BUFFER_SIZE], buff_len: usize, state: MapState, } -impl MapIterator { - pub fn new(source: R) -> MapIterator { - MapIterator { +impl MapIterator { + pub fn new() -> Result, R::Error> { + let source = R::new(c"/proc/self/maps")?; + Ok(MapIterator { source, buffer: [0; BUFFER_SIZE], buff_len: 0, state: MapState::Base, - } + }) } } -impl Iterator for MapIterator { +impl Iterator for MapIterator { type Item = MapEntry; fn next(&mut self) -> Option { diff --git a/libafl_qemu/librasan/asan/src/maps/libc.rs b/libafl_qemu/librasan/asan/src/maps/libc.rs index e60460df6e..9f976b60c9 100644 --- a/libafl_qemu/librasan/asan/src/maps/libc.rs +++ b/libafl_qemu/librasan/asan/src/maps/libc.rs @@ -62,7 +62,7 @@ pub struct LibcMapReader { impl LibcMapReader { fn get_open() -> Result<::Func, LibcMapReaderError> { let addr = OPEN_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionOpen::NAME).map_err(|e| LibcMapReaderError::FailedToFindSymbol(e)) + S::lookup(FunctionOpen::NAME).map_err(|e| LibcMapReaderError::FailedToFindSymbol(e)) })?; let f = FunctionOpen::as_ptr(addr).map_err(|e| LibcMapReaderError::InvalidPointerType(e))?; @@ -71,7 +71,7 @@ impl LibcMapReader { fn get_close() -> Result<::Func, LibcMapReaderError> { let addr = CLOSE_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionClose::NAME) + S::lookup(FunctionClose::NAME) .map_err(|e| LibcMapReaderError::FailedToFindSymbol(e)) })?; let f = @@ -81,7 +81,7 @@ impl LibcMapReader { fn get_read() -> Result<::Func, LibcMapReaderError> { let addr = READ_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionRead::NAME).map_err(|e| LibcMapReaderError::FailedToFindSymbol(e)) + S::lookup(FunctionRead::NAME).map_err(|e| LibcMapReaderError::FailedToFindSymbol(e)) })?; let f = FunctionRead::as_ptr(addr).map_err(|e| LibcMapReaderError::InvalidPointerType(e))?; @@ -91,7 +91,7 @@ impl LibcMapReader { fn get_errno_location() -> Result<::Func, LibcMapReaderError> { let addr = GET_ERRNO_LOCATION_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionErrnoLocation::NAME) + S::lookup(FunctionErrnoLocation::NAME) .map_err(|e| LibcMapReaderError::FailedToFindSymbol(e)) })?; let f = FunctionErrnoLocation::as_ptr(addr) diff --git a/libafl_qemu/librasan/asan/src/maps/mod.rs b/libafl_qemu/librasan/asan/src/maps/mod.rs index 44047e22bb..a4a9199e02 100644 --- a/libafl_qemu/librasan/asan/src/maps/mod.rs +++ b/libafl_qemu/librasan/asan/src/maps/mod.rs @@ -6,10 +6,7 @@ use thiserror::Error; use crate::{ GuestAddr, - maps::{ - entry::{MapEntry, WriteableMapProtection}, - iterator::MapIterator, - }, + maps::entry::{MapEntry, WriteableMapProtection}, mmap::Mmap, }; @@ -18,28 +15,15 @@ pub mod entry; pub mod iterator; -#[cfg(feature = "libc")] -pub mod libc; - -#[cfg(feature = "linux")] -pub mod linux; - -pub trait MapReader: Sized { - type Error: Debug; - fn new() -> Result; - fn read(&mut self, buf: &mut [u8]) -> Result; - fn mappings() -> Result { - let reader = Self::new()?; - let maps = MapIterator::new(reader).collect::>(); - Ok(Maps { maps }) - } -} - pub struct Maps { maps: Vec, } impl Maps { + pub fn new(maps: Vec) -> Self { + Self { maps } + } + pub fn writeable( &self, addr: GuestAddr, diff --git a/libafl_qemu/librasan/asan/src/mmap/libc.rs b/libafl_qemu/librasan/asan/src/mmap/libc.rs index 84bf1661fc..11ec68037c 100644 --- a/libafl_qemu/librasan/asan/src/mmap/libc.rs +++ b/libafl_qemu/librasan/asan/src/mmap/libc.rs @@ -20,9 +20,7 @@ use thiserror::Error; use crate::{ GuestAddr, asan_swap, mmap::{Mmap, MmapProt}, - symbols::{ - AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols, SymbolsLookupStr, - }, + symbols::{AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols}, }; #[derive(Debug)] @@ -102,7 +100,7 @@ static MADVISE_ADDR: AtomicGuestAddr = AtomicGuestAddr::new(); impl LibcMmap { fn get_mmap() -> Result<::Func, LibcMapError> { let addr = MMAP_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionMmap::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) + S::lookup(FunctionMmap::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) })?; let f = FunctionMmap::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?; Ok(f) @@ -110,7 +108,7 @@ impl LibcMmap { fn get_munmap() -> Result<::Func, LibcMapError> { let addr = MUNMAP_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionMunmap::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) + S::lookup(FunctionMunmap::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) })?; let f = FunctionMunmap::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?; Ok(f) @@ -118,7 +116,7 @@ impl LibcMmap { fn get_mprotect() -> Result<::Func, LibcMapError> { let addr = MPROTECT_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionMprotect::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) + S::lookup(FunctionMprotect::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) })?; let f = FunctionMprotect::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?; Ok(f) @@ -126,8 +124,7 @@ impl LibcMmap { fn get_errno_location() -> Result<::Func, LibcMapError> { let addr = GET_ERRNO_LOCATION_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionErrnoLocation::NAME) - .map_err(|e| LibcMapError::FailedToFindSymbol(e)) + S::lookup(FunctionErrnoLocation::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) })?; let f = FunctionErrnoLocation::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?; @@ -136,7 +133,7 @@ impl LibcMmap { fn get_madvise() -> Result<::Func, LibcMapError> { let addr = MADVISE_ADDR.try_get_or_insert_with(|| { - S::lookup_str(FunctionMadvise::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) + S::lookup(FunctionMadvise::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e)) })?; let f = FunctionMadvise::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?; Ok(f) diff --git a/libafl_qemu/librasan/asan/src/patch/mod.rs b/libafl_qemu/librasan/asan/src/patch/mod.rs index ad18292206..3be99ba5f1 100644 --- a/libafl_qemu/librasan/asan/src/patch/mod.rs +++ b/libafl_qemu/librasan/asan/src/patch/mod.rs @@ -59,9 +59,7 @@ impl Patches { } pub fn is_patched(addr: GuestAddr) -> bool { - PATCHED - .get() - .map_or(false, |p| p.lock().contains_key(&addr)) + PATCHED.get().is_some_and(|p| p.lock().contains_key(&addr)) } } diff --git a/libafl_qemu/librasan/asan/src/symbols/dlsym.rs b/libafl_qemu/librasan/asan/src/symbols/dlsym.rs index 8103a6911b..f4f1dc931d 100644 --- a/libafl_qemu/librasan/asan/src/symbols/dlsym.rs +++ b/libafl_qemu/librasan/asan/src/symbols/dlsym.rs @@ -41,7 +41,7 @@ impl Symbols for DlSymSymbols { type Error = DlSymSymbolsError; #[allow(clippy::not_unsafe_ptr_arg_deref)] - fn lookup(name: *const c_char) -> Result { + unsafe fn lookup_raw(name: *const c_char) -> Result { if name.is_null() { Err(DlSymSymbolsError::NullName())?; } diff --git a/libafl_qemu/librasan/asan/src/symbols/mod.rs b/libafl_qemu/librasan/asan/src/symbols/mod.rs index fefd7a8079..29c8a95195 100644 --- a/libafl_qemu/librasan/asan/src/symbols/mod.rs +++ b/libafl_qemu/librasan/asan/src/symbols/mod.rs @@ -78,7 +78,11 @@ impl Default for AtomicGuestAddr { pub trait Symbols: Debug + Sized + Send { type Error: Debug; - fn lookup(name: *const c_char) -> Result; + unsafe fn lookup_raw(name: *const c_char) -> Result; + + fn lookup(name: &CStr) -> Result { + unsafe { Self::lookup_raw(name.as_ptr() as *const c_char) } + } } pub trait Function { @@ -86,16 +90,6 @@ pub trait Function { type Func: Copy; } -pub trait SymbolsLookupStr: Symbols { - fn lookup_str(name: &CStr) -> Result; -} - -impl SymbolsLookupStr for S { - fn lookup_str(name: &CStr) -> Result { - S::lookup(name.as_ptr() as *const c_char) - } -} - pub trait FunctionPointer: Function { fn as_ptr(addr: GuestAddr) -> Result; } diff --git a/libafl_qemu/librasan/asan/src/symbols/nop.rs b/libafl_qemu/librasan/asan/src/symbols/nop.rs index 53162338b9..39393c0366 100644 --- a/libafl_qemu/librasan/asan/src/symbols/nop.rs +++ b/libafl_qemu/librasan/asan/src/symbols/nop.rs @@ -10,7 +10,7 @@ pub struct NopSymbols; impl Symbols for NopSymbols { type Error = NopSymbolsError; - fn lookup(name: *const c_char) -> Result { + unsafe fn lookup_raw(name: *const c_char) -> Result { Err(NopSymbolsError::SymbolNotFound(name)) } } diff --git a/libafl_qemu/librasan/asan/src/test.rs b/libafl_qemu/librasan/asan/src/test.rs index d500a1fdfe..c74b7fade2 100644 --- a/libafl_qemu/librasan/asan/src/test.rs +++ b/libafl_qemu/librasan/asan/src/test.rs @@ -139,7 +139,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize { #[unsafe(no_mangle)] /// # Safety pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void { - TestSyms::lookup(name).unwrap() as *const c_void + unsafe { TestSyms::lookup_raw(name).unwrap() as *const c_void } } #[unsafe(no_mangle)] diff --git a/libafl_qemu/librasan/asan/tests/default_frontend_mock.rs b/libafl_qemu/librasan/asan/tests/default_frontend_mock.rs index b917749224..7d4a0ec27a 100644 --- a/libafl_qemu/librasan/asan/tests/default_frontend_mock.rs +++ b/libafl_qemu/librasan/asan/tests/default_frontend_mock.rs @@ -1,7 +1,7 @@ extern crate alloc; #[cfg(test)] -#[cfg(all(feature = "linux"))] +#[cfg(feature = "linux")] mod tests { use alloc::alloc::{GlobalAlloc, Layout}; diff --git a/libafl_qemu/librasan/asan/tests/env.rs b/libafl_qemu/librasan/asan/tests/env.rs new file mode 100644 index 0000000000..3f2999f8ce --- /dev/null +++ b/libafl_qemu/librasan/asan/tests/env.rs @@ -0,0 +1,39 @@ +#[cfg(test)] +mod tests { + use asan::{ + env::Env, + file::{libc::LibcFileReader, linux::LinuxFileReader}, + symbols::dlsym::{DlSymSymbols, LookupTypeNext}, + }; + #[test] + fn test_linux_env() { + /* RUST_LOG=debug PROFILE=dev cargo +nightly nextest run test_linux_env --no-capture */ + env_logger::init(); + let mut std_list = std::env::vars().collect::>(); + let envs = Env::::initialize().unwrap(); + let mut linux_list = envs + .into_iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect::>(); + + std_list.sort(); + linux_list.sort(); + assert_eq!(std_list, linux_list); + } + + #[test] + fn test_libc_env() { + /* RUST_LOG=debug PROFILE=dev cargo +nightly nextest run test_libc_env --no-capture */ + env_logger::init(); + let mut std_list = std::env::vars().collect::>(); + let envs = Env::>>::initialize().unwrap(); + let mut linux_list = envs + .into_iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect::>(); + + std_list.sort(); + linux_list.sort(); + assert_eq!(std_list, linux_list); + } +} diff --git a/libafl_qemu/librasan/asan/tests/hooks_free.rs b/libafl_qemu/librasan/asan/tests/hooks_free.rs index 02cc1fe0e0..2ad4810a88 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_free.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_free.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::ptr::null_mut; diff --git a/libafl_qemu/librasan/asan/tests/hooks_malloc.rs b/libafl_qemu/librasan/asan/tests/hooks_malloc.rs index f75dc35ecc..60372c100f 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_malloc.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_malloc.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ptr::null_mut, slice::from_raw_parts_mut}; diff --git a/libafl_qemu/librasan/asan/tests/hooks_malloc_usable_size.rs b/libafl_qemu/librasan/asan/tests/hooks_malloc_usable_size.rs index 392cf661ac..3bb9d8499a 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_malloc_usable_size.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_malloc_usable_size.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::ptr::null_mut; diff --git a/libafl_qemu/librasan/asan/tests/hooks_memalign.rs b/libafl_qemu/librasan/asan/tests/hooks_memalign.rs index 7e0b8bd0ef..adddbf5ac0 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_memalign.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_memalign.rs @@ -21,7 +21,7 @@ mod tests { #[test] fn memalign_power_of_two() { let addr = unsafe { memalign(8, 8) }; - assert_ne!(addr, 0 as *mut _); + assert_ne!(addr, std::ptr::null_mut()); assert_eq!(addr as usize & 7, 0); } diff --git a/libafl_qemu/librasan/asan/tests/hooks_memcpy.rs b/libafl_qemu/librasan/asan/tests/hooks_memcpy.rs index d4b8f4dc35..dcd01d260d 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_memcpy.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_memcpy.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ ffi::c_void, diff --git a/libafl_qemu/librasan/asan/tests/hooks_memmem.rs b/libafl_qemu/librasan/asan/tests/hooks_memmem.rs index f373316a06..c443dd9ffa 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_memmem.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_memmem.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ ffi::c_void, diff --git a/libafl_qemu/librasan/asan/tests/hooks_memmove.rs b/libafl_qemu/librasan/asan/tests/hooks_memmove.rs index 483a966f25..0c2af25827 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_memmove.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_memmove.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ ffi::c_void, diff --git a/libafl_qemu/librasan/asan/tests/hooks_mempcpy.rs b/libafl_qemu/librasan/asan/tests/hooks_mempcpy.rs index b403a04512..acbe696aa4 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_mempcpy.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_mempcpy.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ ffi::c_void, diff --git a/libafl_qemu/librasan/asan/tests/hooks_pvalloc.rs b/libafl_qemu/librasan/asan/tests/hooks_pvalloc.rs index 9cc5a440a8..59f2f2f9b5 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_pvalloc.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_pvalloc.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ptr::null_mut, slice::from_raw_parts_mut}; diff --git a/libafl_qemu/librasan/asan/tests/hooks_realloc.rs b/libafl_qemu/librasan/asan/tests/hooks_realloc.rs index 0bf57350e1..0929e5f56d 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_realloc.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_realloc.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ptr::null_mut, slice::from_raw_parts_mut}; diff --git a/libafl_qemu/librasan/asan/tests/hooks_reallocarray.rs b/libafl_qemu/librasan/asan/tests/hooks_reallocarray.rs index 62b41d6897..1c2031b873 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_reallocarray.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_reallocarray.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ptr::null_mut, slice::from_raw_parts_mut}; diff --git a/libafl_qemu/librasan/asan/tests/hooks_stpcpy.rs b/libafl_qemu/librasan/asan/tests/hooks_stpcpy.rs index 3458ae183b..1bfbb5aa0d 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_stpcpy.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_stpcpy.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ffi::c_char, ptr::null_mut}; diff --git a/libafl_qemu/librasan/asan/tests/hooks_stpncpy.rs b/libafl_qemu/librasan/asan/tests/hooks_stpncpy.rs index 53a47c838b..3a1c300aa7 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_stpncpy.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_stpncpy.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::{ffi::c_char, ptr::null_mut}; diff --git a/libafl_qemu/librasan/asan/tests/hooks_strncpy.rs b/libafl_qemu/librasan/asan/tests/hooks_strncpy.rs index 6ea0327ed1..9cc0969e91 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_strncpy.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_strncpy.rs @@ -48,7 +48,7 @@ mod tests { expected .as_bytes() .iter() - .zip(unsafe { from_raw_parts(dest.as_ptr() as *const u8, dest.len()) }) + .zip(unsafe { from_raw_parts(dest.as_ptr(), dest.len()) }) .for_each(|(x, y)| assert_eq!(*x, *y)); } @@ -69,7 +69,7 @@ mod tests { expected .as_bytes() .iter() - .zip(unsafe { from_raw_parts(dest.as_ptr() as *const u8, dest.len()) }) + .zip(unsafe { from_raw_parts(dest.as_ptr(), dest.len()) }) .for_each(|(x, y)| assert_eq!(*x, *y)); } } diff --git a/libafl_qemu/librasan/asan/tests/hooks_valloc.rs b/libafl_qemu/librasan/asan/tests/hooks_valloc.rs index 3c910ffdc9..ed759dbeb9 100644 --- a/libafl_qemu/librasan/asan/tests/hooks_valloc.rs +++ b/libafl_qemu/librasan/asan/tests/hooks_valloc.rs @@ -1,5 +1,5 @@ #[cfg(test)] -#[cfg(all(feature = "hooks"))] +#[cfg(feature = "hooks")] mod tests { use core::ptr::null_mut; diff --git a/libafl_qemu/librasan/asan/tests/libc_map_reader.rs b/libafl_qemu/librasan/asan/tests/libc_map_reader.rs index 8a957a237d..6e6b060ec5 100644 --- a/libafl_qemu/librasan/asan/tests/libc_map_reader.rs +++ b/libafl_qemu/librasan/asan/tests/libc_map_reader.rs @@ -2,10 +2,11 @@ #[cfg(feature = "libc")] mod tests { use asan::{ - maps::{MapReader, entry::MapEntry, iterator::MapIterator, libc::LibcMapReader}, + file::libc::LibcFileReader, + maps::{entry::MapEntry, iterator::MapIterator}, mmap::MmapProt, symbols::{ - SymbolsLookupStr, + Symbols, dlsym::{DlSymSymbols, LookupTypeNext}, }, }; @@ -15,13 +16,12 @@ mod tests { #[test] fn test_libc_map_reader() { - let reader = LibcMapReader::::new().unwrap(); - let iterator = MapIterator::new(reader); + let iterator = MapIterator::>::new().unwrap(); let maps = iterator.collect::>(); for entry in &maps { println!("{:?}", entry); } - let memcpy_addr = Syms::lookup_str(c"memcpy").unwrap(); + let memcpy_addr = Syms::lookup(c"memcpy").unwrap(); assert_ne!(maps.len(), 0); assert!(maps.iter().any(|e| e.contains(memcpy_addr))); let entry = maps diff --git a/libafl_qemu/librasan/asan/tests/linux_map_reader.rs b/libafl_qemu/librasan/asan/tests/linux_map_reader.rs index f3e6d3b420..5ccce86415 100644 --- a/libafl_qemu/librasan/asan/tests/linux_map_reader.rs +++ b/libafl_qemu/librasan/asan/tests/linux_map_reader.rs @@ -2,10 +2,11 @@ #[cfg(feature = "libc")] mod tests { use asan::{ - maps::{MapReader, entry::MapEntry, iterator::MapIterator, linux::LinuxMapReader}, + file::linux::LinuxFileReader, + maps::{entry::MapEntry, iterator::MapIterator}, mmap::MmapProt, symbols::{ - SymbolsLookupStr, + Symbols, dlsym::{DlSymSymbols, LookupTypeNext}, }, }; @@ -15,13 +16,12 @@ mod tests { #[test] fn test_linux_map_reader() { - let reader = LinuxMapReader::new().unwrap(); - let iterator = MapIterator::new(reader); + let iterator = MapIterator::::new().unwrap(); let maps = iterator.collect::>(); for entry in &maps { println!("{:?}", entry); } - let memcpy_addr = Syms::lookup_str(c"memcpy").unwrap(); + let memcpy_addr = Syms::lookup(c"memcpy").unwrap(); assert_ne!(maps.len(), 0); assert!(maps.iter().any(|e| e.contains(memcpy_addr))); let entry = maps diff --git a/libafl_qemu/librasan/asan/tests/patch_raw.rs b/libafl_qemu/librasan/asan/tests/patch_raw.rs index df72c48737..d7671c1f06 100644 --- a/libafl_qemu/librasan/asan/tests/patch_raw.rs +++ b/libafl_qemu/librasan/asan/tests/patch_raw.rs @@ -20,7 +20,7 @@ mod tests { assert_eq!(a4, 4); assert_eq!(a5, 5); assert_eq!(a6, 6); - return 0xdeadface; + 0xdeadface } #[unsafe(no_mangle)] @@ -31,7 +31,7 @@ mod tests { assert_eq!(a4, 4); assert_eq!(a5, 5); assert_eq!(a6, 6); - return 0xd00df00d; + 0xd00df00d } #[test] diff --git a/libafl_qemu/librasan/asan/tests/symbols_dlsym.rs b/libafl_qemu/librasan/asan/tests/symbols_dlsym.rs index 0a7f631e25..27b7b0fae3 100644 --- a/libafl_qemu/librasan/asan/tests/symbols_dlsym.rs +++ b/libafl_qemu/librasan/asan/tests/symbols_dlsym.rs @@ -6,7 +6,7 @@ mod tests { use asan::{ GuestAddr, symbols::{ - Function, SymbolsLookupStr, + Function, Symbols, dlsym::{DlSymSymbols, LookupTypeDefault}, }, }; @@ -29,14 +29,14 @@ mod tests { const NAME: &'static CStr = c"munmap"; } - type DLSYM = DlSymSymbols; + type DlSym = DlSymSymbols; #[test] fn test_dlsym() { use asan::symbols::FunctionPointer; - let mmap = DLSYM::lookup_str(c"mmap").unwrap(); - let mmap2 = DLSYM::lookup_str(c"mmap").unwrap(); + let mmap = DlSym::lookup(c"mmap").unwrap(); + let mmap2 = DlSym::lookup(c"mmap").unwrap(); assert_eq!(mmap, mmap2); let fnmmap = FunctionMmap::as_ptr(mmap).unwrap(); let mapping = unsafe { @@ -51,8 +51,8 @@ mod tests { }; let addr = mapping as GuestAddr; assert!(addr & 0xfff == 0); - let munmap = DLSYM::lookup_str(c"munmap").unwrap(); - let munmap2 = DLSYM::lookup_str(c"munmap").unwrap(); + let munmap = DlSym::lookup(c"munmap").unwrap(); + let munmap2 = DlSym::lookup(c"munmap").unwrap(); assert_eq!(munmap, munmap2); let fnmunmap = FunctionMunmap::as_ptr(munmap).unwrap(); let ret = unsafe { fnmunmap(mapping, 4096) }; diff --git a/libafl_qemu/librasan/gasan/src/lib.rs b/libafl_qemu/librasan/gasan/src/lib.rs index 0dd38ca208..2a2f223068 100644 --- a/libafl_qemu/librasan/gasan/src/lib.rs +++ b/libafl_qemu/librasan/gasan/src/lib.rs @@ -9,9 +9,11 @@ use asan::{ backend::{dlmalloc::DlmallocBackend, mimalloc::MimallocBackend}, frontend::{AllocatorFrontend, default::DefaultFrontend}, }, + env::Env, + file::libc::LibcFileReader, hooks::PatchedHooks, logger::libc::LibcLogger, - maps::{MapReader, libc::LibcMapReader}, + maps::{Maps, iterator::MapIterator}, mmap::libc::LibcMmap, patch::{Patches, raw::RawPatch}, shadow::{ @@ -24,7 +26,7 @@ use asan::{ }, tracking::{Tracking, guest_fast::GuestFastTracking}, }; -use log::{Level, debug, trace}; +use log::{Level, info, trace}; use spin::{Lazy, mutex::Mutex}; type Syms = DlSymSymbols; @@ -38,11 +40,17 @@ pub type GasanFrontend = pub type GasanSyms = DlSymSymbols; +pub type GasanEnv = Env>; + const PAGE_SIZE: usize = 4096; static FRONTEND: Lazy> = Lazy::new(|| { - LibcLogger::initialize::(Level::Info); - debug!("init"); + let level = GasanEnv::initialize() + .ok() + .and_then(|e| e.log_level()) + .unwrap_or(Level::Warn); + LibcLogger::initialize::(level); + info!("Gasan initializing..."); let backend = GasanBackend::new(DlmallocBackend::new(PAGE_SIZE)); let shadow = GuestShadow::::new().unwrap(); let tracking = GuestFastTracking::new().unwrap(); @@ -54,12 +62,17 @@ static FRONTEND: Lazy> = Lazy::new(|| { GasanFrontend::DEFAULT_QUARANTINE_SIZE, ) .unwrap(); - let mappings = LibcMapReader::::mappings().unwrap(); + let mappings = Maps::new( + MapIterator::>::new() + .unwrap() + .collect(), + ); Patches::init(mappings); for hook in PatchedHooks::default() { let target = hook.lookup::().unwrap(); Patches::apply::(target, hook.destination).unwrap(); } + info!("Gasan initialized."); Mutex::new(frontend) }); @@ -120,7 +133,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize { #[unsafe(no_mangle)] /// # Safety pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void { - GasanSyms::lookup(name).unwrap() as *const c_void + unsafe { GasanSyms::lookup_raw(name).unwrap() as *const c_void } } #[unsafe(no_mangle)] diff --git a/libafl_qemu/librasan/qasan/src/lib.rs b/libafl_qemu/librasan/qasan/src/lib.rs index 58906ac744..e5e78ccea8 100644 --- a/libafl_qemu/librasan/qasan/src/lib.rs +++ b/libafl_qemu/librasan/qasan/src/lib.rs @@ -9,10 +9,12 @@ use asan::{ backend::{dlmalloc::DlmallocBackend, mimalloc::MimallocBackend}, frontend::{AllocatorFrontend, default::DefaultFrontend}, }, + env::Env, + file::libc::LibcFileReader, hooks::PatchedHooks, host::{Host, libc::LibcHost}, logger::libc::LibcLogger, - maps::{MapReader, libc::LibcMapReader}, + maps::{Maps, iterator::MapIterator}, mmap::libc::LibcMmap, patch::{Patches, raw::RawPatch}, shadow::{Shadow, host::HostShadow}, @@ -22,7 +24,7 @@ use asan::{ }, tracking::{Tracking, host::HostTracking}, }; -use log::{Level, trace}; +use log::{Level, info, trace}; use spin::{Lazy, Mutex}; type Syms = DlSymSymbols; @@ -38,10 +40,17 @@ pub type QasanFrontend = pub type QasanSyms = DlSymSymbols; +pub type QasanEnv = Env>; + const PAGE_SIZE: usize = 4096; static FRONTEND: Lazy> = Lazy::new(|| { - LibcLogger::initialize::(Level::Info); + let level = QasanEnv::initialize() + .ok() + .and_then(|e| e.log_level()) + .unwrap_or(Level::Warn); + LibcLogger::initialize::(level); + info!("Qasan initializing..."); let backend = QasanBackend::new(DlmallocBackend::new(PAGE_SIZE)); let shadow = HostShadow::::new().unwrap(); let tracking = HostTracking::::new().unwrap(); @@ -53,12 +62,17 @@ static FRONTEND: Lazy> = Lazy::new(|| { QasanFrontend::DEFAULT_QUARANTINE_SIZE, ) .unwrap(); - let mappings = LibcMapReader::::mappings().unwrap(); + let mappings = Maps::new( + MapIterator::>::new() + .unwrap() + .collect(), + ); Patches::init(mappings); for hook in PatchedHooks::default() { let target = hook.lookup::().unwrap(); Patches::apply::(target, hook.destination).unwrap(); } + info!("Qasan initialized."); Mutex::new(frontend) }); @@ -119,7 +133,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize { #[unsafe(no_mangle)] /// # Safety pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void { - QasanSyms::lookup(name).unwrap() as *const c_void + unsafe { QasanSyms::lookup_raw(name).unwrap() as *const c_void } } #[unsafe(no_mangle)] diff --git a/libafl_qemu/librasan/zasan/Justfile b/libafl_qemu/librasan/zasan/Justfile index 77aa684bf3..da640ae9cb 100644 --- a/libafl_qemu/librasan/zasan/Justfile +++ b/libafl_qemu/librasan/zasan/Justfile @@ -7,7 +7,6 @@ ZASAN_SOURCE_DIR := source_directory() compile_zasan: #!/bin/sh . {{ DOTENV }} - RUSTFLAGS="--cfg rustix_use_experimental_asm" \ cargo \ build \ --package zasan \ diff --git a/libafl_qemu/librasan/zasan/src/lib.rs b/libafl_qemu/librasan/zasan/src/lib.rs index bf5c4bb5b3..37bf20038c 100644 --- a/libafl_qemu/librasan/zasan/src/lib.rs +++ b/libafl_qemu/librasan/zasan/src/lib.rs @@ -9,6 +9,8 @@ use asan::{ backend::dlmalloc::DlmallocBackend, frontend::{AllocatorFrontend, default::DefaultFrontend}, }, + env::Env, + file::linux::LinuxFileReader, logger::linux::LinuxLogger, mmap::linux::LinuxMmap, shadow::{ @@ -18,7 +20,7 @@ use asan::{ symbols::{Symbols, nop::NopSymbols}, tracking::{Tracking, guest_fast::GuestFastTracking}, }; -use log::{Level, trace}; +use log::{Level, info, trace}; use spin::{Lazy, Mutex}; pub type ZasanFrontend = DefaultFrontend< @@ -29,10 +31,17 @@ pub type ZasanFrontend = DefaultFrontend< pub type ZasanSyms = NopSymbols; +pub type ZasanEnv = Env; + const PAGE_SIZE: usize = 4096; static FRONTEND: Lazy> = Lazy::new(|| { - LinuxLogger::initialize(Level::Info); + let level = ZasanEnv::initialize() + .ok() + .and_then(|e| e.log_level()) + .unwrap_or(Level::Warn); + LinuxLogger::initialize(level); + info!("Zasan initializing..."); let backend = DlmallocBackend::::new(PAGE_SIZE); let shadow = GuestShadow::::new().unwrap(); let tracking = GuestFastTracking::new().unwrap(); @@ -44,6 +53,7 @@ static FRONTEND: Lazy> = Lazy::new(|| { ZasanFrontend::DEFAULT_QUARANTINE_SIZE, ) .unwrap(); + info!("Zasan initialized."); Mutex::new(frontend) }); @@ -104,7 +114,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize { #[unsafe(no_mangle)] /// # Safety pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void { - ZasanSyms::lookup(name).unwrap() as *const c_void + unsafe { ZasanSyms::lookup_raw(name).unwrap() as *const c_void } } #[unsafe(no_mangle)]