LibAFL_QEMU/librasan: Add support for reading environment (#3241)
* Add support for reading environment * Fix clippy * Review fixes
This commit is contained in:
parent
d7eb3bd234
commit
db1d38eeb6
@ -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 \
|
||||
|
119
libafl_qemu/librasan/asan/src/env/mod.rs
vendored
Normal file
119
libafl_qemu/librasan/asan/src/env/mod.rs
vendored
Normal file
@ -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<AHasher>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Env<R: FileReader> {
|
||||
envs: HashMap<String, String, Hasher>,
|
||||
phantom: PhantomData<R>,
|
||||
}
|
||||
|
||||
impl<R: FileReader> Env<R> {
|
||||
/* 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<Env<R>, EnvError<R>> {
|
||||
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::<String, String, Hasher>::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<Level> {
|
||||
self.get("RUST_LOG").and_then(|s| s.parse().ok())
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: FileReader> IntoIterator for Env<R> {
|
||||
type Item = (String, String);
|
||||
type IntoIter = hashbrown::hash_map::IntoIter<String, String>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.envs.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum EnvError<R: FileReader> {
|
||||
#[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),
|
||||
}
|
161
libafl_qemu/librasan/asan/src/file/libc.rs
Normal file
161
libafl_qemu/librasan/asan/src/file/libc.rs
Normal file
@ -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<S: Symbols> {
|
||||
fd: c_int,
|
||||
_phantom: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S: Symbols> LibcFileReader<S> {
|
||||
fn get_open() -> Result<<FunctionOpen as Function>::Func, LibcFileReaderError<S>> {
|
||||
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<<FunctionClose as Function>::Func, LibcFileReaderError<S>> {
|
||||
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<<FunctionRead as Function>::Func, LibcFileReaderError<S>> {
|
||||
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<<FunctionErrnoLocation as Function>::Func, LibcFileReaderError<S>> {
|
||||
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<c_int, LibcFileReaderError<S>> {
|
||||
unsafe { asan_swap(false) };
|
||||
let errno_location = Self::get_errno_location()?;
|
||||
unsafe { asan_swap(true) };
|
||||
let errno = unsafe { *errno_location() };
|
||||
Ok(errno)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Symbols> FileReader for LibcFileReader<S> {
|
||||
type Error = LibcFileReaderError<S>;
|
||||
fn new(path: &CStr) -> Result<LibcFileReader<S>, 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<usize, Self::Error> {
|
||||
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<S: Symbols> Drop for LibcFileReader<S> {
|
||||
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<S: Symbols> {
|
||||
#[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),
|
||||
}
|
36
libafl_qemu/librasan/asan/src/file/linux.rs
Normal file
36
libafl_qemu/librasan/asan/src/file/linux.rs
Normal file
@ -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<LinuxFileReader, Self::Error> {
|
||||
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<usize, Self::Error> {
|
||||
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),
|
||||
}
|
14
libafl_qemu/librasan/asan/src/file/mod.rs
Normal file
14
libafl_qemu/librasan/asan/src/file/mod.rs
Normal file
@ -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<Self, Self::Error>;
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
|
||||
}
|
@ -89,7 +89,7 @@ impl PatchedHook {
|
||||
}
|
||||
|
||||
pub fn lookup<S: Symbols>(&self) -> Result<GuestAddr, S::Error> {
|
||||
S::lookup(self.name.as_ptr() as *const c_char)
|
||||
unsafe { S::lookup_raw(self.name.as_ptr() as *const c_char) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<S: Symbols> LibcHost<S> {
|
||||
|
||||
fn get_syscall() -> Result<<FunctionSyscall as Function>::Func, LibcHostError<S>> {
|
||||
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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<S: Symbols>(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);
|
||||
|
@ -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<R: MapReader> {
|
||||
pub struct MapIterator<R: FileReader> {
|
||||
source: R,
|
||||
buffer: [u8; BUFFER_SIZE],
|
||||
buff_len: usize,
|
||||
state: MapState,
|
||||
}
|
||||
|
||||
impl<R: MapReader> MapIterator<R> {
|
||||
pub fn new(source: R) -> MapIterator<R> {
|
||||
MapIterator {
|
||||
impl<R: FileReader> MapIterator<R> {
|
||||
pub fn new() -> Result<MapIterator<R>, R::Error> {
|
||||
let source = R::new(c"/proc/self/maps")?;
|
||||
Ok(MapIterator {
|
||||
source,
|
||||
buffer: [0; BUFFER_SIZE],
|
||||
buff_len: 0,
|
||||
state: MapState::Base,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: MapReader> Iterator for MapIterator<R> {
|
||||
impl<R: FileReader> Iterator for MapIterator<R> {
|
||||
type Item = MapEntry;
|
||||
|
||||
fn next(&mut self) -> Option<MapEntry> {
|
||||
|
@ -62,7 +62,7 @@ pub struct LibcMapReader<S: Symbols> {
|
||||
impl<S: Symbols> LibcMapReader<S> {
|
||||
fn get_open() -> Result<<FunctionOpen as Function>::Func, LibcMapReaderError<S>> {
|
||||
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<S: Symbols> LibcMapReader<S> {
|
||||
|
||||
fn get_close() -> Result<<FunctionClose as Function>::Func, LibcMapReaderError<S>> {
|
||||
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<S: Symbols> LibcMapReader<S> {
|
||||
|
||||
fn get_read() -> Result<<FunctionRead as Function>::Func, LibcMapReaderError<S>> {
|
||||
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<S: Symbols> LibcMapReader<S> {
|
||||
fn get_errno_location()
|
||||
-> Result<<FunctionErrnoLocation as Function>::Func, LibcMapReaderError<S>> {
|
||||
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)
|
||||
|
@ -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<Self, Self::Error>;
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
|
||||
fn mappings() -> Result<Maps, Self::Error> {
|
||||
let reader = Self::new()?;
|
||||
let maps = MapIterator::new(reader).collect::<Vec<MapEntry>>();
|
||||
Ok(Maps { maps })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Maps {
|
||||
maps: Vec<MapEntry>,
|
||||
}
|
||||
|
||||
impl Maps {
|
||||
pub fn new(maps: Vec<MapEntry>) -> Self {
|
||||
Self { maps }
|
||||
}
|
||||
|
||||
pub fn writeable<M: Mmap>(
|
||||
&self,
|
||||
addr: GuestAddr,
|
||||
|
@ -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<S: Symbols> LibcMmap<S> {
|
||||
fn get_mmap() -> Result<<FunctionMmap as Function>::Func, LibcMapError<S>> {
|
||||
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<S: Symbols> LibcMmap<S> {
|
||||
|
||||
fn get_munmap() -> Result<<FunctionMunmap as Function>::Func, LibcMapError<S>> {
|
||||
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<S: Symbols> LibcMmap<S> {
|
||||
|
||||
fn get_mprotect() -> Result<<FunctionMprotect as Function>::Func, LibcMapError<S>> {
|
||||
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<S: Symbols> LibcMmap<S> {
|
||||
|
||||
fn get_errno_location() -> Result<<FunctionErrnoLocation as Function>::Func, LibcMapError<S>> {
|
||||
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<S: Symbols> LibcMmap<S> {
|
||||
|
||||
fn get_madvise() -> Result<<FunctionMadvise as Function>::Func, LibcMapError<S>> {
|
||||
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)
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ impl<L: LookupType> Symbols for DlSymSymbols<L> {
|
||||
type Error = DlSymSymbolsError;
|
||||
|
||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||
fn lookup(name: *const c_char) -> Result<GuestAddr, Self::Error> {
|
||||
unsafe fn lookup_raw(name: *const c_char) -> Result<GuestAddr, Self::Error> {
|
||||
if name.is_null() {
|
||||
Err(DlSymSymbolsError::NullName())?;
|
||||
}
|
||||
|
@ -78,7 +78,11 @@ impl Default for AtomicGuestAddr {
|
||||
|
||||
pub trait Symbols: Debug + Sized + Send {
|
||||
type Error: Debug;
|
||||
fn lookup(name: *const c_char) -> Result<GuestAddr, Self::Error>;
|
||||
unsafe fn lookup_raw(name: *const c_char) -> Result<GuestAddr, Self::Error>;
|
||||
|
||||
fn lookup(name: &CStr) -> Result<GuestAddr, Self::Error> {
|
||||
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<GuestAddr, Self::Error>;
|
||||
}
|
||||
|
||||
impl<S: Symbols> SymbolsLookupStr for S {
|
||||
fn lookup_str(name: &CStr) -> Result<GuestAddr, Self::Error> {
|
||||
S::lookup(name.as_ptr() as *const c_char)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FunctionPointer: Function {
|
||||
fn as_ptr(addr: GuestAddr) -> Result<Self::Func, FunctionPointerError>;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ pub struct NopSymbols;
|
||||
impl Symbols for NopSymbols {
|
||||
type Error = NopSymbolsError;
|
||||
|
||||
fn lookup(name: *const c_char) -> Result<GuestAddr, Self::Error> {
|
||||
unsafe fn lookup_raw(name: *const c_char) -> Result<GuestAddr, Self::Error> {
|
||||
Err(NopSymbolsError::SymbolNotFound(name))
|
||||
}
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "linux"))]
|
||||
#[cfg(feature = "linux")]
|
||||
mod tests {
|
||||
use alloc::alloc::{GlobalAlloc, Layout};
|
||||
|
||||
|
39
libafl_qemu/librasan/asan/tests/env.rs
Normal file
39
libafl_qemu/librasan/asan/tests/env.rs
Normal file
@ -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::<Vec<(String, String)>>();
|
||||
let envs = Env::<LinuxFileReader>::initialize().unwrap();
|
||||
let mut linux_list = envs
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone()))
|
||||
.collect::<Vec<(String, String)>>();
|
||||
|
||||
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::<Vec<(String, String)>>();
|
||||
let envs = Env::<LibcFileReader<DlSymSymbols<LookupTypeNext>>>::initialize().unwrap();
|
||||
let mut linux_list = envs
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone()))
|
||||
.collect::<Vec<(String, String)>>();
|
||||
|
||||
std_list.sort();
|
||||
linux_list.sort();
|
||||
assert_eq!(std_list, linux_list);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::ptr::null_mut;
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::ptr::null_mut;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::{
|
||||
ffi::c_void,
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::{
|
||||
ffi::c_void,
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::{
|
||||
ffi::c_void,
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::{
|
||||
ffi::c_void,
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::{ffi::c_char, ptr::null_mut};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::{ffi::c_char, ptr::null_mut};
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[cfg(test)]
|
||||
#[cfg(all(feature = "hooks"))]
|
||||
#[cfg(feature = "hooks")]
|
||||
mod tests {
|
||||
use core::ptr::null_mut;
|
||||
|
||||
|
@ -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::<Syms>::new().unwrap();
|
||||
let iterator = MapIterator::new(reader);
|
||||
let iterator = MapIterator::<LibcFileReader<Syms>>::new().unwrap();
|
||||
let maps = iterator.collect::<Vec<MapEntry>>();
|
||||
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
|
||||
|
@ -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::<LinuxFileReader>::new().unwrap();
|
||||
let maps = iterator.collect::<Vec<MapEntry>>();
|
||||
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
|
||||
|
@ -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]
|
||||
|
@ -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<LookupTypeDefault>;
|
||||
type DlSym = DlSymSymbols<LookupTypeDefault>;
|
||||
|
||||
#[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) };
|
||||
|
@ -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<LookupTypeNext>;
|
||||
@ -38,11 +40,17 @@ pub type GasanFrontend =
|
||||
|
||||
pub type GasanSyms = DlSymSymbols<LookupTypeNext>;
|
||||
|
||||
pub type GasanEnv = Env<LibcFileReader<GasanSyms>>;
|
||||
|
||||
const PAGE_SIZE: usize = 4096;
|
||||
|
||||
static FRONTEND: Lazy<Mutex<GasanFrontend>> = Lazy::new(|| {
|
||||
LibcLogger::initialize::<GasanSyms>(Level::Info);
|
||||
debug!("init");
|
||||
let level = GasanEnv::initialize()
|
||||
.ok()
|
||||
.and_then(|e| e.log_level())
|
||||
.unwrap_or(Level::Warn);
|
||||
LibcLogger::initialize::<GasanSyms>(level);
|
||||
info!("Gasan initializing...");
|
||||
let backend = GasanBackend::new(DlmallocBackend::new(PAGE_SIZE));
|
||||
let shadow = GuestShadow::<GasanMmap, DefaultShadowLayout>::new().unwrap();
|
||||
let tracking = GuestFastTracking::new().unwrap();
|
||||
@ -54,12 +62,17 @@ static FRONTEND: Lazy<Mutex<GasanFrontend>> = Lazy::new(|| {
|
||||
GasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
||||
)
|
||||
.unwrap();
|
||||
let mappings = LibcMapReader::<GasanSyms>::mappings().unwrap();
|
||||
let mappings = Maps::new(
|
||||
MapIterator::<LibcFileReader<Syms>>::new()
|
||||
.unwrap()
|
||||
.collect(),
|
||||
);
|
||||
Patches::init(mappings);
|
||||
for hook in PatchedHooks::default() {
|
||||
let target = hook.lookup::<GasanSyms>().unwrap();
|
||||
Patches::apply::<RawPatch, GasanMmap>(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)]
|
||||
|
@ -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<LookupTypeNext>;
|
||||
@ -38,10 +40,17 @@ pub type QasanFrontend =
|
||||
|
||||
pub type QasanSyms = DlSymSymbols<LookupTypeNext>;
|
||||
|
||||
pub type QasanEnv = Env<LibcFileReader<QasanSyms>>;
|
||||
|
||||
const PAGE_SIZE: usize = 4096;
|
||||
|
||||
static FRONTEND: Lazy<Mutex<QasanFrontend>> = Lazy::new(|| {
|
||||
LibcLogger::initialize::<QasanSyms>(Level::Info);
|
||||
let level = QasanEnv::initialize()
|
||||
.ok()
|
||||
.and_then(|e| e.log_level())
|
||||
.unwrap_or(Level::Warn);
|
||||
LibcLogger::initialize::<QasanSyms>(level);
|
||||
info!("Qasan initializing...");
|
||||
let backend = QasanBackend::new(DlmallocBackend::new(PAGE_SIZE));
|
||||
let shadow = HostShadow::<QasanHost>::new().unwrap();
|
||||
let tracking = HostTracking::<QasanHost>::new().unwrap();
|
||||
@ -53,12 +62,17 @@ static FRONTEND: Lazy<Mutex<QasanFrontend>> = Lazy::new(|| {
|
||||
QasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
||||
)
|
||||
.unwrap();
|
||||
let mappings = LibcMapReader::<QasanSyms>::mappings().unwrap();
|
||||
let mappings = Maps::new(
|
||||
MapIterator::<LibcFileReader<Syms>>::new()
|
||||
.unwrap()
|
||||
.collect(),
|
||||
);
|
||||
Patches::init(mappings);
|
||||
for hook in PatchedHooks::default() {
|
||||
let target = hook.lookup::<QasanSyms>().unwrap();
|
||||
Patches::apply::<RawPatch, QasanMmap>(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)]
|
||||
|
@ -7,7 +7,6 @@ ZASAN_SOURCE_DIR := source_directory()
|
||||
compile_zasan:
|
||||
#!/bin/sh
|
||||
. {{ DOTENV }}
|
||||
RUSTFLAGS="--cfg rustix_use_experimental_asm" \
|
||||
cargo \
|
||||
build \
|
||||
--package zasan \
|
||||
|
@ -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<LinuxFileReader>;
|
||||
|
||||
const PAGE_SIZE: usize = 4096;
|
||||
|
||||
static FRONTEND: Lazy<Mutex<ZasanFrontend>> = 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::<LinuxMmap>::new(PAGE_SIZE);
|
||||
let shadow = GuestShadow::<LinuxMmap, DefaultShadowLayout>::new().unwrap();
|
||||
let tracking = GuestFastTracking::new().unwrap();
|
||||
@ -44,6 +53,7 @@ static FRONTEND: Lazy<Mutex<ZasanFrontend>> = 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)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user