Skip to content

Commit 0154a3b

Browse files
WorksButNotTestedYour Name
andauthored
Added heap feature (#3074)
* Added heap feature * Rename feature and add some more docs * Use document-features crate * Expose the patching API for more flexibility --------- Co-authored-by: Your Name <you@example.com>
1 parent e728df9 commit 0154a3b

File tree

8 files changed

+57
-33
lines changed

8 files changed

+57
-33
lines changed

libafl_qemu/librasan/asan/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ rust-version.workspace = true
88
crate-type = ["rlib"]
99

1010
[features]
11+
#! # Features
1112
default = [
1213
"dlmalloc",
14+
"document-features",
15+
"global_allocator",
1316
"guest",
1417
"hooks",
1518
"host",
@@ -19,21 +22,35 @@ default = [
1922
"test",
2023
"tracking",
2124
]
25+
## Enable support for the `dlmalloc` allocator backend
2226
dlmalloc = ["dep:dlmalloc"]
27+
## Enable documentation of features
28+
document-features = ["dep:document-features"]
29+
## Configure a global allocator (using dlmalloc or mimalloc as configured)
30+
global_allocator = []
31+
## Enable support for shadow memory and tracking in the guest
2332
guest = []
33+
## Enable support for hooking functions in the guest
2434
hooks = []
35+
## Enable support for shadow memory and tracking in the host
2536
host = ["dep:syscalls"]
37+
## Enable use of the `libc` library to support creation of mappings, read/write, logging etc (more OS agnostic)
2638
libc = ["dep:libc"]
39+
## Enable the use of direct syscalls (supported by `rustix`) to interact with the operating system (Linux specific).
2740
linux = ["dep:rustix"]
41+
## Enable the `baby_mimalloc` allocator
2842
mimalloc = ["dep:baby-mimalloc"]
43+
## Disable the magic used to support `no_std` environments for running unit and integration tests
2944
test = []
45+
## Enable support for memory tracking
3046
tracking = []
3147

3248
[dependencies]
3349
baby-mimalloc = { version = "0.2.1", default-features = false, features = [
3450
"spin_mutex",
3551
], optional = true }
3652
bitflags = { version = "2.8.0", default-features = false }
53+
document-features = { version = "0.2.11", optional = true }
3754
dlmalloc = { version = "0.2.7", default-features = false, optional = true }
3855
itertools = { version = "0.14.0", default-features = false }
3956
log = { version = "0.4.22", default-features = false, features = [

libafl_qemu/librasan/asan/src/hooks/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub struct PatchedHook {
7373
}
7474

7575
impl PatchedHook {
76-
const fn new<F: Copy>(name: &'static CStr, func: F) -> Self {
76+
pub const fn new<F: Copy>(name: &'static CStr, func: F) -> Self {
7777
let pf = (&func) as *const F as *const GuestAddr;
7878
let destination = unsafe { *pf };
7979
Self { name, destination }

libafl_qemu/librasan/asan/src/lib.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,9 @@
2929
//! The componentized nature of the design is intended to permit the user to
3030
//! adapt `asan` to their needs with minimal modification by selecting and
3131
//! combining alternative implementations of the various key components.
32-
//!
33-
//! ## Features
34-
//! - `dlmalloc` - Enable support for the dlmalloc allocator backend.
35-
//! - `guest` - Enable support for shadow memory and tracking in the guest
36-
//! - `hooks` - Enable support for hooking functions in the guest
37-
//! - `host` - Enable support for shadow memory and tracking in the host
38-
//! - `libc` - Enable use of the `libc` library to support creation of mappings,
39-
//! read/write, logging etc (more OS agnostic)
40-
//! - `linux` - Enable the use of direct syscalls (supported by `rustix`) to
41-
//! interact with the operating system (Linux specific).
42-
//! - `test` - Disable the magic used to support `no_std` environments for
43-
//! running unit and integration tests
44-
//! - `tracking` - Enable support for memory tracking.
4532
#![cfg_attr(not(feature = "test"), no_std)]
4633
#![cfg_attr(target_arch = "powerpc", feature(asm_experimental_arch))]
34+
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
4735

4836
pub mod allocator;
4937

libafl_qemu/librasan/asan/src/mem.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,34 @@ use core::{
33
slice::{from_raw_parts, from_raw_parts_mut},
44
};
55

6-
#[cfg(feature = "dlmalloc")]
6+
#[cfg(all(feature = "global_allocator", feature = "dlmalloc"))]
77
use crate::allocator::backend::dlmalloc::DlmallocBackend;
88

9-
#[cfg(all(feature = "linux", not(feature = "libc")))]
9+
#[cfg(all(feature = "global_allocator", feature = "linux", not(feature = "libc")))]
1010
type Mmap = crate::mmap::linux::LinuxMmap;
1111

1212
#[cfg(feature = "libc")]
1313
type Mmap = crate::mmap::libc::LibcMmap<
1414
crate::symbols::dlsym::DlSymSymbols<crate::symbols::dlsym::LookupTypeNext>,
1515
>;
1616

17+
#[cfg(all(feature = "global_allocator"))]
1718
const PAGE_SIZE: usize = 4096;
1819

1920
#[global_allocator]
20-
#[cfg(all(feature = "dlmalloc", not(feature = "mimalloc")))]
21+
#[cfg(all(
22+
feature = "global_allocator",
23+
feature = "dlmalloc",
24+
not(feature = "mimalloc")
25+
))]
2126
static GLOBAL_ALLOCATOR: DlmallocBackend<Mmap> = DlmallocBackend::new(PAGE_SIZE);
2227

2328
#[global_allocator]
24-
#[cfg(all(feature = "dlmalloc", feature = "mimalloc"))]
29+
#[cfg(all(
30+
feature = "global_allocator",
31+
feature = "dlmalloc",
32+
feature = "mimalloc"
33+
))]
2534
static GLOBAL_ALLOCATOR: baby_mimalloc::MimallocMutexWrapper<DlmallocBackend<Mmap>> =
2635
baby_mimalloc::MimallocMutexWrapper::with_os_allocator(DlmallocBackend::new(PAGE_SIZE));
2736

libafl_qemu/librasan/asan/src/patch/hooks.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,32 @@ impl PatchedHooks {
2323
pub fn init<S: Symbols, P: Patch, R: MapReader, M: Mmap>()
2424
-> Result<(), PatchesError<S, P, R, M>> {
2525
debug!("Installing patches");
26-
let reader = R::new().map_err(|e| PatchesError::MapReaderError(e))?;
27-
let mappings = MapIterator::new(reader).collect::<Vec<MapEntry>>();
26+
let mappings = Self::get_mappings()?;
2827
mappings.iter().for_each(|m| trace!("{m:?}"));
29-
let patches = PatchedHook::all()
30-
.into_iter()
31-
.map(|p| Self::apply_patch(p, &mappings))
32-
.collect::<Result<BTreeMap<GuestAddr, PatchedHook>, PatchesError<S, P, R, M>>>()?;
33-
PATCHED.lock().replace(patches);
28+
for patch in PatchedHook::all() {
29+
Self::patch(patch, &mappings)?;
30+
}
3431
debug!("Patching complete");
3532
Ok(())
3633
}
3734

38-
fn apply_patch<S: Symbols, P: Patch, R: MapReader, M: Mmap>(
39-
p: PatchedHook,
35+
pub fn get_mappings<S: Symbols, P: Patch, R: MapReader, M: Mmap>()
36+
-> Result<Vec<MapEntry>, PatchesError<S, P, R, M>> {
37+
let reader = R::new().map_err(|e| PatchesError::MapReaderError(e))?;
38+
Ok(MapIterator::new(reader).collect::<Vec<MapEntry>>())
39+
}
40+
41+
pub fn patch<S: Symbols, P: Patch, R: MapReader, M: Mmap>(
42+
patch: PatchedHook,
4043
mappings: &[MapEntry],
41-
) -> Result<(GuestAddr, PatchedHook), PatchesError<S, P, R, M>> {
42-
trace!("patch: {:?}, destination: {:#x}", p.name, p.destination);
43-
let target = S::lookup(p.name.as_ptr() as *const c_char)
44+
) -> Result<(), PatchesError<S, P, R, M>> {
45+
trace!(
46+
"patch: {:?}, destination: {:#x}",
47+
patch.name, patch.destination
48+
);
49+
let target = S::lookup(patch.name.as_ptr() as *const c_char)
4450
.map_err(|e| PatchesError::SymbolsError(e))?;
45-
trace!("patching: {:#x} -> {:#x}", target, p.destination);
51+
trace!("patching: {:#x} -> {:#x}", target, patch.destination);
4652
let mapping = mappings
4753
.iter()
4854
.filter(|m| m.contains(target))
@@ -51,9 +57,10 @@ impl PatchedHooks {
5157
let prot = mapping
5258
.writeable::<M>()
5359
.map_err(|e| PatchesError::MmapError(e))?;
54-
P::patch(target, p.destination).map_err(|e| PatchesError::PatchError(e))?;
60+
P::patch(target, patch.destination).map_err(|e| PatchesError::PatchError(e))?;
5561
drop(prot);
56-
Ok((target, p))
62+
PATCHED.lock().get_or_insert_default().insert(target, patch);
63+
Ok(())
5764
}
5865

5966
pub fn check_patched(addr: GuestAddr) -> Result<(), PatchesCheckError> {

libafl_qemu/librasan/gasan/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ test = ["asan/test", "dummy_libc/test"]
1414
[dependencies]
1515
asan = { path = "../asan", default-features = false, features = [
1616
"dlmalloc",
17+
"global_allocator",
1718
"guest",
1819
"hooks",
1920
"libc",

libafl_qemu/librasan/qasan/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ test = ["asan/test", "dummy_libc/test"]
1414
[dependencies]
1515
asan = { path = "../asan", default-features = false, features = [
1616
"dlmalloc",
17+
"global_allocator",
1718
"hooks",
1819
"host",
1920
"libc",

libafl_qemu/librasan/zasan/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ test = ["asan/test"]
1414
[dependencies]
1515
asan = { path = "../asan", default-features = false, features = [
1616
"dlmalloc",
17+
"global_allocator",
1718
"guest",
1819
"hooks",
1920
"host",

0 commit comments

Comments
 (0)