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:
|
clippy:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
cargo clippy
|
cargo clippy -F test
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
@ -52,6 +52,8 @@ build_i386_dev:
|
|||||||
|
|
||||||
build_ppc_dev:
|
build_ppc_dev:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
RUSTC_BOOTSTRAP=1 \
|
||||||
|
RUSTFLAGS="--cfg rustix_use_experimental_asm" \
|
||||||
ARCH=ppc PROFILE=dev just build
|
ARCH=ppc PROFILE=dev just build
|
||||||
|
|
||||||
build_arm_release:
|
build_arm_release:
|
||||||
@ -72,6 +74,8 @@ build_i386_release:
|
|||||||
|
|
||||||
build_ppc_release:
|
build_ppc_release:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
RUSTC_BOOTSTRAP=1 \
|
||||||
|
RUSTFLAGS="--cfg rustix_use_experimental_asm" \
|
||||||
ARCH=ppc PROFILE=release just build
|
ARCH=ppc PROFILE=release just build
|
||||||
|
|
||||||
build_everything_dev: \
|
build_everything_dev: \
|
||||||
@ -92,6 +96,8 @@ build_everything: build_everything_dev build_everything_release
|
|||||||
|
|
||||||
test_arm:
|
test_arm:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
RUSTC_BOOTSTRAP=1 \
|
||||||
|
RUSTFLAGS="--cfg rustix_use_experimental_asm" \
|
||||||
ARCH=arm \
|
ARCH=arm \
|
||||||
PROFILE=dev \
|
PROFILE=dev \
|
||||||
RUSTLOG=debug \
|
RUSTLOG=debug \
|
||||||
@ -124,6 +130,8 @@ test_i386:
|
|||||||
|
|
||||||
test_ppc:
|
test_ppc:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
RUSTC_BOOTSTRAP=1 \
|
||||||
|
RUSTFLAGS="--cfg rustix_use_experimental_asm" \
|
||||||
ARCH=ppc \
|
ARCH=ppc \
|
||||||
PROFILE=dev \
|
PROFILE=dev \
|
||||||
RUSTLOG=debug \
|
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> {
|
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,
|
GuestAddr,
|
||||||
host::{Host, HostAction},
|
host::{Host, HostAction},
|
||||||
shadow::PoisonType,
|
shadow::PoisonType,
|
||||||
symbols::{
|
symbols::{AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols},
|
||||||
AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols, SymbolsLookupStr,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -139,7 +137,7 @@ impl<S: Symbols> LibcHost<S> {
|
|||||||
|
|
||||||
fn get_syscall() -> Result<<FunctionSyscall as Function>::Func, LibcHostError<S>> {
|
fn get_syscall() -> Result<<FunctionSyscall as Function>::Func, LibcHostError<S>> {
|
||||||
let addr = SYSCALL_ADDR.try_get_or_insert_with(|| {
|
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))?;
|
let f = FunctionSyscall::as_ptr(addr).map_err(|e| LibcHostError::InvalidPointerType(e))?;
|
||||||
Ok(f)
|
Ok(f)
|
||||||
|
@ -38,8 +38,12 @@ pub mod allocator;
|
|||||||
#[cfg(not(feature = "test"))]
|
#[cfg(not(feature = "test"))]
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
|
|
||||||
|
pub mod env;
|
||||||
|
|
||||||
pub mod exit;
|
pub mod exit;
|
||||||
|
|
||||||
|
pub mod file;
|
||||||
|
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
pub mod hooks;
|
pub mod hooks;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use spin::Once;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
GuestAddr, asan_swap,
|
GuestAddr, asan_swap,
|
||||||
symbols::{Function, FunctionPointer, Symbols, SymbolsLookupStr},
|
symbols::{Function, FunctionPointer, Symbols},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -27,7 +27,7 @@ pub struct LibcLogger {
|
|||||||
impl LibcLogger {
|
impl LibcLogger {
|
||||||
pub fn initialize<S: Symbols>(level: Level) {
|
pub fn initialize<S: Symbols>(level: Level) {
|
||||||
ONCE.call_once(|| {
|
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 }));
|
let logger = Box::leak(Box::new(LibcLogger { level, write }));
|
||||||
log::set_logger(logger).unwrap();
|
log::set_logger(logger).unwrap();
|
||||||
log::set_max_level(LevelFilter::Trace);
|
log::set_max_level(LevelFilter::Trace);
|
||||||
|
@ -3,7 +3,8 @@ use core::fmt::Debug;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
maps::{MapReader, decode::MapDecode, entry::MapEntry},
|
file::FileReader,
|
||||||
|
maps::{decode::MapDecode, entry::MapEntry},
|
||||||
};
|
};
|
||||||
|
|
||||||
const BUFFER_SIZE: usize = 4096;
|
const BUFFER_SIZE: usize = 4096;
|
||||||
@ -21,25 +22,26 @@ enum MapState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MapIterator<R: MapReader> {
|
pub struct MapIterator<R: FileReader> {
|
||||||
source: R,
|
source: R,
|
||||||
buffer: [u8; BUFFER_SIZE],
|
buffer: [u8; BUFFER_SIZE],
|
||||||
buff_len: usize,
|
buff_len: usize,
|
||||||
state: MapState,
|
state: MapState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: MapReader> MapIterator<R> {
|
impl<R: FileReader> MapIterator<R> {
|
||||||
pub fn new(source: R) -> MapIterator<R> {
|
pub fn new() -> Result<MapIterator<R>, R::Error> {
|
||||||
MapIterator {
|
let source = R::new(c"/proc/self/maps")?;
|
||||||
|
Ok(MapIterator {
|
||||||
source,
|
source,
|
||||||
buffer: [0; BUFFER_SIZE],
|
buffer: [0; BUFFER_SIZE],
|
||||||
buff_len: 0,
|
buff_len: 0,
|
||||||
state: MapState::Base,
|
state: MapState::Base,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: MapReader> Iterator for MapIterator<R> {
|
impl<R: FileReader> Iterator for MapIterator<R> {
|
||||||
type Item = MapEntry;
|
type Item = MapEntry;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<MapEntry> {
|
fn next(&mut self) -> Option<MapEntry> {
|
||||||
|
@ -62,7 +62,7 @@ pub struct LibcMapReader<S: Symbols> {
|
|||||||
impl<S: Symbols> LibcMapReader<S> {
|
impl<S: Symbols> LibcMapReader<S> {
|
||||||
fn get_open() -> Result<<FunctionOpen as Function>::Func, LibcMapReaderError<S>> {
|
fn get_open() -> Result<<FunctionOpen as Function>::Func, LibcMapReaderError<S>> {
|
||||||
let addr = OPEN_ADDR.try_get_or_insert_with(|| {
|
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 =
|
let f =
|
||||||
FunctionOpen::as_ptr(addr).map_err(|e| LibcMapReaderError::InvalidPointerType(e))?;
|
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>> {
|
fn get_close() -> Result<<FunctionClose as Function>::Func, LibcMapReaderError<S>> {
|
||||||
let addr = CLOSE_ADDR.try_get_or_insert_with(|| {
|
let addr = CLOSE_ADDR.try_get_or_insert_with(|| {
|
||||||
S::lookup_str(FunctionClose::NAME)
|
S::lookup(FunctionClose::NAME)
|
||||||
.map_err(|e| LibcMapReaderError::FailedToFindSymbol(e))
|
.map_err(|e| LibcMapReaderError::FailedToFindSymbol(e))
|
||||||
})?;
|
})?;
|
||||||
let f =
|
let f =
|
||||||
@ -81,7 +81,7 @@ impl<S: Symbols> LibcMapReader<S> {
|
|||||||
|
|
||||||
fn get_read() -> Result<<FunctionRead as Function>::Func, LibcMapReaderError<S>> {
|
fn get_read() -> Result<<FunctionRead as Function>::Func, LibcMapReaderError<S>> {
|
||||||
let addr = READ_ADDR.try_get_or_insert_with(|| {
|
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 =
|
let f =
|
||||||
FunctionRead::as_ptr(addr).map_err(|e| LibcMapReaderError::InvalidPointerType(e))?;
|
FunctionRead::as_ptr(addr).map_err(|e| LibcMapReaderError::InvalidPointerType(e))?;
|
||||||
@ -91,7 +91,7 @@ impl<S: Symbols> LibcMapReader<S> {
|
|||||||
fn get_errno_location()
|
fn get_errno_location()
|
||||||
-> Result<<FunctionErrnoLocation as Function>::Func, LibcMapReaderError<S>> {
|
-> Result<<FunctionErrnoLocation as Function>::Func, LibcMapReaderError<S>> {
|
||||||
let addr = GET_ERRNO_LOCATION_ADDR.try_get_or_insert_with(|| {
|
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))
|
.map_err(|e| LibcMapReaderError::FailedToFindSymbol(e))
|
||||||
})?;
|
})?;
|
||||||
let f = FunctionErrnoLocation::as_ptr(addr)
|
let f = FunctionErrnoLocation::as_ptr(addr)
|
||||||
|
@ -6,10 +6,7 @@ use thiserror::Error;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
maps::{
|
maps::entry::{MapEntry, WriteableMapProtection},
|
||||||
entry::{MapEntry, WriteableMapProtection},
|
|
||||||
iterator::MapIterator,
|
|
||||||
},
|
|
||||||
mmap::Mmap,
|
mmap::Mmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,28 +15,15 @@ pub mod entry;
|
|||||||
|
|
||||||
pub mod iterator;
|
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 {
|
pub struct Maps {
|
||||||
maps: Vec<MapEntry>,
|
maps: Vec<MapEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Maps {
|
impl Maps {
|
||||||
|
pub fn new(maps: Vec<MapEntry>) -> Self {
|
||||||
|
Self { maps }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn writeable<M: Mmap>(
|
pub fn writeable<M: Mmap>(
|
||||||
&self,
|
&self,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
|
@ -20,9 +20,7 @@ use thiserror::Error;
|
|||||||
use crate::{
|
use crate::{
|
||||||
GuestAddr, asan_swap,
|
GuestAddr, asan_swap,
|
||||||
mmap::{Mmap, MmapProt},
|
mmap::{Mmap, MmapProt},
|
||||||
symbols::{
|
symbols::{AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols},
|
||||||
AtomicGuestAddr, Function, FunctionPointer, FunctionPointerError, Symbols, SymbolsLookupStr,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -102,7 +100,7 @@ static MADVISE_ADDR: AtomicGuestAddr = AtomicGuestAddr::new();
|
|||||||
impl<S: Symbols> LibcMmap<S> {
|
impl<S: Symbols> LibcMmap<S> {
|
||||||
fn get_mmap() -> Result<<FunctionMmap as Function>::Func, LibcMapError<S>> {
|
fn get_mmap() -> Result<<FunctionMmap as Function>::Func, LibcMapError<S>> {
|
||||||
let addr = MMAP_ADDR.try_get_or_insert_with(|| {
|
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))?;
|
let f = FunctionMmap::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?;
|
||||||
Ok(f)
|
Ok(f)
|
||||||
@ -110,7 +108,7 @@ impl<S: Symbols> LibcMmap<S> {
|
|||||||
|
|
||||||
fn get_munmap() -> Result<<FunctionMunmap as Function>::Func, LibcMapError<S>> {
|
fn get_munmap() -> Result<<FunctionMunmap as Function>::Func, LibcMapError<S>> {
|
||||||
let addr = MUNMAP_ADDR.try_get_or_insert_with(|| {
|
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))?;
|
let f = FunctionMunmap::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?;
|
||||||
Ok(f)
|
Ok(f)
|
||||||
@ -118,7 +116,7 @@ impl<S: Symbols> LibcMmap<S> {
|
|||||||
|
|
||||||
fn get_mprotect() -> Result<<FunctionMprotect as Function>::Func, LibcMapError<S>> {
|
fn get_mprotect() -> Result<<FunctionMprotect as Function>::Func, LibcMapError<S>> {
|
||||||
let addr = MPROTECT_ADDR.try_get_or_insert_with(|| {
|
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))?;
|
let f = FunctionMprotect::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?;
|
||||||
Ok(f)
|
Ok(f)
|
||||||
@ -126,8 +124,7 @@ impl<S: Symbols> LibcMmap<S> {
|
|||||||
|
|
||||||
fn get_errno_location() -> Result<<FunctionErrnoLocation as Function>::Func, LibcMapError<S>> {
|
fn get_errno_location() -> Result<<FunctionErrnoLocation as Function>::Func, LibcMapError<S>> {
|
||||||
let addr = GET_ERRNO_LOCATION_ADDR.try_get_or_insert_with(|| {
|
let addr = GET_ERRNO_LOCATION_ADDR.try_get_or_insert_with(|| {
|
||||||
S::lookup_str(FunctionErrnoLocation::NAME)
|
S::lookup(FunctionErrnoLocation::NAME).map_err(|e| LibcMapError::FailedToFindSymbol(e))
|
||||||
.map_err(|e| LibcMapError::FailedToFindSymbol(e))
|
|
||||||
})?;
|
})?;
|
||||||
let f =
|
let f =
|
||||||
FunctionErrnoLocation::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?;
|
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>> {
|
fn get_madvise() -> Result<<FunctionMadvise as Function>::Func, LibcMapError<S>> {
|
||||||
let addr = MADVISE_ADDR.try_get_or_insert_with(|| {
|
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))?;
|
let f = FunctionMadvise::as_ptr(addr).map_err(|e| LibcMapError::InvalidPointerType(e))?;
|
||||||
Ok(f)
|
Ok(f)
|
||||||
|
@ -59,9 +59,7 @@ impl Patches {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_patched(addr: GuestAddr) -> bool {
|
pub fn is_patched(addr: GuestAddr) -> bool {
|
||||||
PATCHED
|
PATCHED.get().is_some_and(|p| p.lock().contains_key(&addr))
|
||||||
.get()
|
|
||||||
.map_or(false, |p| p.lock().contains_key(&addr))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ impl<L: LookupType> Symbols for DlSymSymbols<L> {
|
|||||||
type Error = DlSymSymbolsError;
|
type Error = DlSymSymbolsError;
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
#[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() {
|
if name.is_null() {
|
||||||
Err(DlSymSymbolsError::NullName())?;
|
Err(DlSymSymbolsError::NullName())?;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,11 @@ impl Default for AtomicGuestAddr {
|
|||||||
|
|
||||||
pub trait Symbols: Debug + Sized + Send {
|
pub trait Symbols: Debug + Sized + Send {
|
||||||
type Error: Debug;
|
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 {
|
pub trait Function {
|
||||||
@ -86,16 +90,6 @@ pub trait Function {
|
|||||||
type Func: Copy;
|
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 {
|
pub trait FunctionPointer: Function {
|
||||||
fn as_ptr(addr: GuestAddr) -> Result<Self::Func, FunctionPointerError>;
|
fn as_ptr(addr: GuestAddr) -> Result<Self::Func, FunctionPointerError>;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ pub struct NopSymbols;
|
|||||||
impl Symbols for NopSymbols {
|
impl Symbols for NopSymbols {
|
||||||
type Error = NopSymbolsError;
|
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))
|
Err(NopSymbolsError::SymbolNotFound(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
/// # Safety
|
/// # Safety
|
||||||
pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void {
|
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)]
|
#[unsafe(no_mangle)]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "linux"))]
|
#[cfg(feature = "linux")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use alloc::alloc::{GlobalAlloc, Layout};
|
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(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn memalign_power_of_two() {
|
fn memalign_power_of_two() {
|
||||||
let addr = unsafe { memalign(8, 8) };
|
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);
|
assert_eq!(addr as usize & 7, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
use core::{ptr::null_mut, slice::from_raw_parts_mut};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{ffi::c_char, ptr::null_mut};
|
use core::{ffi::c_char, ptr::null_mut};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{ffi::c_char, ptr::null_mut};
|
use core::{ffi::c_char, ptr::null_mut};
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ mod tests {
|
|||||||
expected
|
expected
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.iter()
|
.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));
|
.for_each(|(x, y)| assert_eq!(*x, *y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ mod tests {
|
|||||||
expected
|
expected
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.iter()
|
.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));
|
.for_each(|(x, y)| assert_eq!(*x, *y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "hooks"))]
|
#[cfg(feature = "hooks")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
#[cfg(feature = "libc")]
|
#[cfg(feature = "libc")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use asan::{
|
use asan::{
|
||||||
maps::{MapReader, entry::MapEntry, iterator::MapIterator, libc::LibcMapReader},
|
file::libc::LibcFileReader,
|
||||||
|
maps::{entry::MapEntry, iterator::MapIterator},
|
||||||
mmap::MmapProt,
|
mmap::MmapProt,
|
||||||
symbols::{
|
symbols::{
|
||||||
SymbolsLookupStr,
|
Symbols,
|
||||||
dlsym::{DlSymSymbols, LookupTypeNext},
|
dlsym::{DlSymSymbols, LookupTypeNext},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -15,13 +16,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_libc_map_reader() {
|
fn test_libc_map_reader() {
|
||||||
let reader = LibcMapReader::<Syms>::new().unwrap();
|
let iterator = MapIterator::<LibcFileReader<Syms>>::new().unwrap();
|
||||||
let iterator = MapIterator::new(reader);
|
|
||||||
let maps = iterator.collect::<Vec<MapEntry>>();
|
let maps = iterator.collect::<Vec<MapEntry>>();
|
||||||
for entry in &maps {
|
for entry in &maps {
|
||||||
println!("{:?}", entry);
|
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_ne!(maps.len(), 0);
|
||||||
assert!(maps.iter().any(|e| e.contains(memcpy_addr)));
|
assert!(maps.iter().any(|e| e.contains(memcpy_addr)));
|
||||||
let entry = maps
|
let entry = maps
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
#[cfg(feature = "libc")]
|
#[cfg(feature = "libc")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use asan::{
|
use asan::{
|
||||||
maps::{MapReader, entry::MapEntry, iterator::MapIterator, linux::LinuxMapReader},
|
file::linux::LinuxFileReader,
|
||||||
|
maps::{entry::MapEntry, iterator::MapIterator},
|
||||||
mmap::MmapProt,
|
mmap::MmapProt,
|
||||||
symbols::{
|
symbols::{
|
||||||
SymbolsLookupStr,
|
Symbols,
|
||||||
dlsym::{DlSymSymbols, LookupTypeNext},
|
dlsym::{DlSymSymbols, LookupTypeNext},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -15,13 +16,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_linux_map_reader() {
|
fn test_linux_map_reader() {
|
||||||
let reader = LinuxMapReader::new().unwrap();
|
let iterator = MapIterator::<LinuxFileReader>::new().unwrap();
|
||||||
let iterator = MapIterator::new(reader);
|
|
||||||
let maps = iterator.collect::<Vec<MapEntry>>();
|
let maps = iterator.collect::<Vec<MapEntry>>();
|
||||||
for entry in &maps {
|
for entry in &maps {
|
||||||
println!("{:?}", entry);
|
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_ne!(maps.len(), 0);
|
||||||
assert!(maps.iter().any(|e| e.contains(memcpy_addr)));
|
assert!(maps.iter().any(|e| e.contains(memcpy_addr)));
|
||||||
let entry = maps
|
let entry = maps
|
||||||
|
@ -20,7 +20,7 @@ mod tests {
|
|||||||
assert_eq!(a4, 4);
|
assert_eq!(a4, 4);
|
||||||
assert_eq!(a5, 5);
|
assert_eq!(a5, 5);
|
||||||
assert_eq!(a6, 6);
|
assert_eq!(a6, 6);
|
||||||
return 0xdeadface;
|
0xdeadface
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
@ -31,7 +31,7 @@ mod tests {
|
|||||||
assert_eq!(a4, 4);
|
assert_eq!(a4, 4);
|
||||||
assert_eq!(a5, 5);
|
assert_eq!(a5, 5);
|
||||||
assert_eq!(a6, 6);
|
assert_eq!(a6, 6);
|
||||||
return 0xd00df00d;
|
0xd00df00d
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -6,7 +6,7 @@ mod tests {
|
|||||||
use asan::{
|
use asan::{
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
symbols::{
|
symbols::{
|
||||||
Function, SymbolsLookupStr,
|
Function, Symbols,
|
||||||
dlsym::{DlSymSymbols, LookupTypeDefault},
|
dlsym::{DlSymSymbols, LookupTypeDefault},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -29,14 +29,14 @@ mod tests {
|
|||||||
const NAME: &'static CStr = c"munmap";
|
const NAME: &'static CStr = c"munmap";
|
||||||
}
|
}
|
||||||
|
|
||||||
type DLSYM = DlSymSymbols<LookupTypeDefault>;
|
type DlSym = DlSymSymbols<LookupTypeDefault>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dlsym() {
|
fn test_dlsym() {
|
||||||
use asan::symbols::FunctionPointer;
|
use asan::symbols::FunctionPointer;
|
||||||
|
|
||||||
let mmap = DLSYM::lookup_str(c"mmap").unwrap();
|
let mmap = DlSym::lookup(c"mmap").unwrap();
|
||||||
let mmap2 = DLSYM::lookup_str(c"mmap").unwrap();
|
let mmap2 = DlSym::lookup(c"mmap").unwrap();
|
||||||
assert_eq!(mmap, mmap2);
|
assert_eq!(mmap, mmap2);
|
||||||
let fnmmap = FunctionMmap::as_ptr(mmap).unwrap();
|
let fnmmap = FunctionMmap::as_ptr(mmap).unwrap();
|
||||||
let mapping = unsafe {
|
let mapping = unsafe {
|
||||||
@ -51,8 +51,8 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let addr = mapping as GuestAddr;
|
let addr = mapping as GuestAddr;
|
||||||
assert!(addr & 0xfff == 0);
|
assert!(addr & 0xfff == 0);
|
||||||
let munmap = DLSYM::lookup_str(c"munmap").unwrap();
|
let munmap = DlSym::lookup(c"munmap").unwrap();
|
||||||
let munmap2 = DLSYM::lookup_str(c"munmap").unwrap();
|
let munmap2 = DlSym::lookup(c"munmap").unwrap();
|
||||||
assert_eq!(munmap, munmap2);
|
assert_eq!(munmap, munmap2);
|
||||||
let fnmunmap = FunctionMunmap::as_ptr(munmap).unwrap();
|
let fnmunmap = FunctionMunmap::as_ptr(munmap).unwrap();
|
||||||
let ret = unsafe { fnmunmap(mapping, 4096) };
|
let ret = unsafe { fnmunmap(mapping, 4096) };
|
||||||
|
@ -9,9 +9,11 @@ use asan::{
|
|||||||
backend::{dlmalloc::DlmallocBackend, mimalloc::MimallocBackend},
|
backend::{dlmalloc::DlmallocBackend, mimalloc::MimallocBackend},
|
||||||
frontend::{AllocatorFrontend, default::DefaultFrontend},
|
frontend::{AllocatorFrontend, default::DefaultFrontend},
|
||||||
},
|
},
|
||||||
|
env::Env,
|
||||||
|
file::libc::LibcFileReader,
|
||||||
hooks::PatchedHooks,
|
hooks::PatchedHooks,
|
||||||
logger::libc::LibcLogger,
|
logger::libc::LibcLogger,
|
||||||
maps::{MapReader, libc::LibcMapReader},
|
maps::{Maps, iterator::MapIterator},
|
||||||
mmap::libc::LibcMmap,
|
mmap::libc::LibcMmap,
|
||||||
patch::{Patches, raw::RawPatch},
|
patch::{Patches, raw::RawPatch},
|
||||||
shadow::{
|
shadow::{
|
||||||
@ -24,7 +26,7 @@ use asan::{
|
|||||||
},
|
},
|
||||||
tracking::{Tracking, guest_fast::GuestFastTracking},
|
tracking::{Tracking, guest_fast::GuestFastTracking},
|
||||||
};
|
};
|
||||||
use log::{Level, debug, trace};
|
use log::{Level, info, trace};
|
||||||
use spin::{Lazy, mutex::Mutex};
|
use spin::{Lazy, mutex::Mutex};
|
||||||
|
|
||||||
type Syms = DlSymSymbols<LookupTypeNext>;
|
type Syms = DlSymSymbols<LookupTypeNext>;
|
||||||
@ -38,11 +40,17 @@ pub type GasanFrontend =
|
|||||||
|
|
||||||
pub type GasanSyms = DlSymSymbols<LookupTypeNext>;
|
pub type GasanSyms = DlSymSymbols<LookupTypeNext>;
|
||||||
|
|
||||||
|
pub type GasanEnv = Env<LibcFileReader<GasanSyms>>;
|
||||||
|
|
||||||
const PAGE_SIZE: usize = 4096;
|
const PAGE_SIZE: usize = 4096;
|
||||||
|
|
||||||
static FRONTEND: Lazy<Mutex<GasanFrontend>> = Lazy::new(|| {
|
static FRONTEND: Lazy<Mutex<GasanFrontend>> = Lazy::new(|| {
|
||||||
LibcLogger::initialize::<GasanSyms>(Level::Info);
|
let level = GasanEnv::initialize()
|
||||||
debug!("init");
|
.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 backend = GasanBackend::new(DlmallocBackend::new(PAGE_SIZE));
|
||||||
let shadow = GuestShadow::<GasanMmap, DefaultShadowLayout>::new().unwrap();
|
let shadow = GuestShadow::<GasanMmap, DefaultShadowLayout>::new().unwrap();
|
||||||
let tracking = GuestFastTracking::new().unwrap();
|
let tracking = GuestFastTracking::new().unwrap();
|
||||||
@ -54,12 +62,17 @@ static FRONTEND: Lazy<Mutex<GasanFrontend>> = Lazy::new(|| {
|
|||||||
GasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
GasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mappings = LibcMapReader::<GasanSyms>::mappings().unwrap();
|
let mappings = Maps::new(
|
||||||
|
MapIterator::<LibcFileReader<Syms>>::new()
|
||||||
|
.unwrap()
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
Patches::init(mappings);
|
Patches::init(mappings);
|
||||||
for hook in PatchedHooks::default() {
|
for hook in PatchedHooks::default() {
|
||||||
let target = hook.lookup::<GasanSyms>().unwrap();
|
let target = hook.lookup::<GasanSyms>().unwrap();
|
||||||
Patches::apply::<RawPatch, GasanMmap>(target, hook.destination).unwrap();
|
Patches::apply::<RawPatch, GasanMmap>(target, hook.destination).unwrap();
|
||||||
}
|
}
|
||||||
|
info!("Gasan initialized.");
|
||||||
Mutex::new(frontend)
|
Mutex::new(frontend)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -120,7 +133,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
/// # Safety
|
/// # Safety
|
||||||
pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void {
|
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)]
|
#[unsafe(no_mangle)]
|
||||||
|
@ -9,10 +9,12 @@ use asan::{
|
|||||||
backend::{dlmalloc::DlmallocBackend, mimalloc::MimallocBackend},
|
backend::{dlmalloc::DlmallocBackend, mimalloc::MimallocBackend},
|
||||||
frontend::{AllocatorFrontend, default::DefaultFrontend},
|
frontend::{AllocatorFrontend, default::DefaultFrontend},
|
||||||
},
|
},
|
||||||
|
env::Env,
|
||||||
|
file::libc::LibcFileReader,
|
||||||
hooks::PatchedHooks,
|
hooks::PatchedHooks,
|
||||||
host::{Host, libc::LibcHost},
|
host::{Host, libc::LibcHost},
|
||||||
logger::libc::LibcLogger,
|
logger::libc::LibcLogger,
|
||||||
maps::{MapReader, libc::LibcMapReader},
|
maps::{Maps, iterator::MapIterator},
|
||||||
mmap::libc::LibcMmap,
|
mmap::libc::LibcMmap,
|
||||||
patch::{Patches, raw::RawPatch},
|
patch::{Patches, raw::RawPatch},
|
||||||
shadow::{Shadow, host::HostShadow},
|
shadow::{Shadow, host::HostShadow},
|
||||||
@ -22,7 +24,7 @@ use asan::{
|
|||||||
},
|
},
|
||||||
tracking::{Tracking, host::HostTracking},
|
tracking::{Tracking, host::HostTracking},
|
||||||
};
|
};
|
||||||
use log::{Level, trace};
|
use log::{Level, info, trace};
|
||||||
use spin::{Lazy, Mutex};
|
use spin::{Lazy, Mutex};
|
||||||
|
|
||||||
type Syms = DlSymSymbols<LookupTypeNext>;
|
type Syms = DlSymSymbols<LookupTypeNext>;
|
||||||
@ -38,10 +40,17 @@ pub type QasanFrontend =
|
|||||||
|
|
||||||
pub type QasanSyms = DlSymSymbols<LookupTypeNext>;
|
pub type QasanSyms = DlSymSymbols<LookupTypeNext>;
|
||||||
|
|
||||||
|
pub type QasanEnv = Env<LibcFileReader<QasanSyms>>;
|
||||||
|
|
||||||
const PAGE_SIZE: usize = 4096;
|
const PAGE_SIZE: usize = 4096;
|
||||||
|
|
||||||
static FRONTEND: Lazy<Mutex<QasanFrontend>> = Lazy::new(|| {
|
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 backend = QasanBackend::new(DlmallocBackend::new(PAGE_SIZE));
|
||||||
let shadow = HostShadow::<QasanHost>::new().unwrap();
|
let shadow = HostShadow::<QasanHost>::new().unwrap();
|
||||||
let tracking = HostTracking::<QasanHost>::new().unwrap();
|
let tracking = HostTracking::<QasanHost>::new().unwrap();
|
||||||
@ -53,12 +62,17 @@ static FRONTEND: Lazy<Mutex<QasanFrontend>> = Lazy::new(|| {
|
|||||||
QasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
QasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mappings = LibcMapReader::<QasanSyms>::mappings().unwrap();
|
let mappings = Maps::new(
|
||||||
|
MapIterator::<LibcFileReader<Syms>>::new()
|
||||||
|
.unwrap()
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
Patches::init(mappings);
|
Patches::init(mappings);
|
||||||
for hook in PatchedHooks::default() {
|
for hook in PatchedHooks::default() {
|
||||||
let target = hook.lookup::<QasanSyms>().unwrap();
|
let target = hook.lookup::<QasanSyms>().unwrap();
|
||||||
Patches::apply::<RawPatch, QasanMmap>(target, hook.destination).unwrap();
|
Patches::apply::<RawPatch, QasanMmap>(target, hook.destination).unwrap();
|
||||||
}
|
}
|
||||||
|
info!("Qasan initialized.");
|
||||||
Mutex::new(frontend)
|
Mutex::new(frontend)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -119,7 +133,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
/// # Safety
|
/// # Safety
|
||||||
pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void {
|
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)]
|
#[unsafe(no_mangle)]
|
||||||
|
@ -7,7 +7,6 @@ ZASAN_SOURCE_DIR := source_directory()
|
|||||||
compile_zasan:
|
compile_zasan:
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. {{ DOTENV }}
|
. {{ DOTENV }}
|
||||||
RUSTFLAGS="--cfg rustix_use_experimental_asm" \
|
|
||||||
cargo \
|
cargo \
|
||||||
build \
|
build \
|
||||||
--package zasan \
|
--package zasan \
|
||||||
|
@ -9,6 +9,8 @@ use asan::{
|
|||||||
backend::dlmalloc::DlmallocBackend,
|
backend::dlmalloc::DlmallocBackend,
|
||||||
frontend::{AllocatorFrontend, default::DefaultFrontend},
|
frontend::{AllocatorFrontend, default::DefaultFrontend},
|
||||||
},
|
},
|
||||||
|
env::Env,
|
||||||
|
file::linux::LinuxFileReader,
|
||||||
logger::linux::LinuxLogger,
|
logger::linux::LinuxLogger,
|
||||||
mmap::linux::LinuxMmap,
|
mmap::linux::LinuxMmap,
|
||||||
shadow::{
|
shadow::{
|
||||||
@ -18,7 +20,7 @@ use asan::{
|
|||||||
symbols::{Symbols, nop::NopSymbols},
|
symbols::{Symbols, nop::NopSymbols},
|
||||||
tracking::{Tracking, guest_fast::GuestFastTracking},
|
tracking::{Tracking, guest_fast::GuestFastTracking},
|
||||||
};
|
};
|
||||||
use log::{Level, trace};
|
use log::{Level, info, trace};
|
||||||
use spin::{Lazy, Mutex};
|
use spin::{Lazy, Mutex};
|
||||||
|
|
||||||
pub type ZasanFrontend = DefaultFrontend<
|
pub type ZasanFrontend = DefaultFrontend<
|
||||||
@ -29,10 +31,17 @@ pub type ZasanFrontend = DefaultFrontend<
|
|||||||
|
|
||||||
pub type ZasanSyms = NopSymbols;
|
pub type ZasanSyms = NopSymbols;
|
||||||
|
|
||||||
|
pub type ZasanEnv = Env<LinuxFileReader>;
|
||||||
|
|
||||||
const PAGE_SIZE: usize = 4096;
|
const PAGE_SIZE: usize = 4096;
|
||||||
|
|
||||||
static FRONTEND: Lazy<Mutex<ZasanFrontend>> = Lazy::new(|| {
|
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 backend = DlmallocBackend::<LinuxMmap>::new(PAGE_SIZE);
|
||||||
let shadow = GuestShadow::<LinuxMmap, DefaultShadowLayout>::new().unwrap();
|
let shadow = GuestShadow::<LinuxMmap, DefaultShadowLayout>::new().unwrap();
|
||||||
let tracking = GuestFastTracking::new().unwrap();
|
let tracking = GuestFastTracking::new().unwrap();
|
||||||
@ -44,6 +53,7 @@ static FRONTEND: Lazy<Mutex<ZasanFrontend>> = Lazy::new(|| {
|
|||||||
ZasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
ZasanFrontend::DEFAULT_QUARANTINE_SIZE,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
info!("Zasan initialized.");
|
||||||
Mutex::new(frontend)
|
Mutex::new(frontend)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -104,7 +114,7 @@ pub unsafe extern "C" fn asan_get_size(addr: *const c_void) -> usize {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
/// # Safety
|
/// # Safety
|
||||||
pub unsafe extern "C" fn asan_sym(name: *const c_char) -> *const c_void {
|
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)]
|
#[unsafe(no_mangle)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user