Skip to content

Commit c0e8f43

Browse files
Add single-threaded feature to librasan
1 parent d7eb3bd commit c0e8f43

File tree

17 files changed

+201
-67
lines changed

17 files changed

+201
-67
lines changed

libafl_qemu/librasan/asan/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ libc = ["dep:libc"]
4242
linux = ["dep:rustix"]
4343
## Enable the `baby_mimalloc` allocator
4444
mimalloc = ["dep:baby-mimalloc"]
45+
## Support single-threaded targets by using dummy synchronization primitives
46+
single-threaded = ["dep:nospin"]
4547
## Disable the magic used to support `no_std` environments for running unit and integration tests
4648
test = []
4749
## Enable support for memory tracking
@@ -59,11 +61,15 @@ log = { version = "0.4.22", default-features = false, features = [
5961
"release_max_level_info",
6062
] }
6163
libc = { version = "0.2.169", default-features = false, optional = true }
64+
nospin = { version = "0.2.4", default-features = false, optional = true, features = [
65+
"lazy",
66+
"mutex",
67+
"once",
68+
] }
6269
nostd-musl = { version = "0.1.5", default-features = false, features = [
6370
"optimized-assembly",
6471
] }
6572
nostd-printf = { version = "0.1.4", default-features = false }
66-
6773
readonly = { version = "0.2.12", default-features = false }
6874
rustix = { version = "1.0.0", default-features = false, features = [
6975
"fs",

libafl_qemu/librasan/asan/src/allocator/backend/dlmalloc.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ use core::{marker::PhantomData, mem::forget, ptr::null_mut};
1010

1111
use dlmalloc::{Allocator, Dlmalloc};
1212
use log::debug;
13+
#[cfg(feature = "single-threaded")]
14+
use nospin::Mutex;
15+
#[cfg(not(feature = "single-threaded"))]
1316
use spin::Mutex;
1417

1518
use crate::mmap::Mmap;

libafl_qemu/librasan/asan/src/allocator/backend/mimalloc.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use alloc::alloc::{GlobalAlloc, Layout};
22

33
use baby_mimalloc::Mimalloc;
4+
#[cfg(feature = "single-threaded")]
5+
use nospin::Mutex;
6+
#[cfg(not(feature = "single-threaded"))]
47
use spin::Mutex;
58

69
pub struct MimallocBackend<G: GlobalAlloc> {

libafl_qemu/librasan/asan/src/logger/libc.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ use core::ffi::{CStr, c_int, c_void};
33

44
use libc::{STDERR_FILENO, size_t, ssize_t};
55
use log::{Level, LevelFilter, Log, Metadata, Record};
6+
#[cfg(feature = "single-threaded")]
7+
use nospin::Once;
8+
#[cfg(not(feature = "single-threaded"))]
69
use spin::Once;
710

811
use crate::{

libafl_qemu/librasan/asan/src/logger/linux.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use alloc::{boxed::Box, format};
22

33
use log::{Level, LevelFilter, Log, Metadata, Record};
4+
#[cfg(feature = "single-threaded")]
5+
use nospin::Once;
46
use rustix::{io::write, stdio::stderr};
7+
#[cfg(not(feature = "single-threaded"))]
58
use spin::Once;
69

710
static ONCE: Once<&'static LinuxLogger> = Once::new();

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ pub mod raw;
66
use alloc::fmt::Debug;
77

88
use log::trace;
9+
#[cfg(feature = "single-threaded")]
10+
use nospin::{Mutex, Once};
11+
#[cfg(not(feature = "single-threaded"))]
912
use spin::{Mutex, Once};
1013
use thiserror::Error;
1114

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[cfg(feature = "single-threaded")]
2+
pub mod single_threaded;
3+
4+
#[cfg(not(feature = "single-threaded"))]
5+
pub mod multi_threaded;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use alloc::fmt::Debug;
2+
use core::{
3+
ffi::c_void,
4+
ptr::null_mut,
5+
sync::atomic::{AtomicPtr, Ordering},
6+
};
7+
8+
use crate::GuestAddr;
9+
10+
pub struct AtomicGuestAddr {
11+
addr: AtomicPtr<c_void>,
12+
}
13+
14+
impl AtomicGuestAddr {
15+
pub const fn new() -> Self {
16+
AtomicGuestAddr {
17+
addr: AtomicPtr::new(null_mut()),
18+
}
19+
}
20+
21+
pub fn load(&self) -> Option<GuestAddr> {
22+
let addr = self.addr.load(Ordering::SeqCst) as GuestAddr;
23+
match addr {
24+
GuestAddr::MIN => None,
25+
_ => Some(addr),
26+
}
27+
}
28+
29+
pub fn store(&self, addr: GuestAddr) {
30+
self.addr.store(addr as *mut c_void, Ordering::SeqCst);
31+
}
32+
33+
pub fn get_or_insert_with<F>(&self, f: F) -> GuestAddr
34+
where
35+
F: FnOnce() -> GuestAddr,
36+
{
37+
if let Some(addr) = self.load() {
38+
addr
39+
} else {
40+
let addr = f();
41+
self.store(addr);
42+
addr
43+
}
44+
}
45+
46+
pub fn try_get_or_insert_with<F, E>(&self, f: F) -> Result<GuestAddr, E>
47+
where
48+
F: FnOnce() -> Result<GuestAddr, E>,
49+
E: Debug,
50+
{
51+
if let Some(addr) = self.load() {
52+
Ok(addr)
53+
} else {
54+
let addr = f()?;
55+
self.store(addr);
56+
Ok(addr)
57+
}
58+
}
59+
}
60+
61+
impl Default for AtomicGuestAddr {
62+
fn default() -> Self {
63+
Self::new()
64+
}
65+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use alloc::fmt::Debug;
2+
use core::cell::UnsafeCell;
3+
4+
use crate::GuestAddr;
5+
6+
pub struct AtomicGuestAddr {
7+
addr: UnsafeCell<GuestAddr>,
8+
}
9+
10+
unsafe impl Sync for AtomicGuestAddr {}
11+
12+
impl AtomicGuestAddr {
13+
pub const fn new() -> Self {
14+
AtomicGuestAddr {
15+
addr: UnsafeCell::new(GuestAddr::MIN),
16+
}
17+
}
18+
19+
pub fn load(&self) -> Option<GuestAddr> {
20+
let addr = unsafe { *self.addr.get() };
21+
match addr {
22+
GuestAddr::MIN => None,
23+
_ => Some(addr),
24+
}
25+
}
26+
27+
pub fn store(&self, addr: GuestAddr) {
28+
unsafe { *self.addr.get() = addr };
29+
}
30+
31+
pub fn get_or_insert_with<F>(&self, f: F) -> GuestAddr
32+
where
33+
F: FnOnce() -> GuestAddr,
34+
{
35+
if let Some(addr) = self.load() {
36+
addr
37+
} else {
38+
let addr = f();
39+
self.store(addr);
40+
addr
41+
}
42+
}
43+
44+
pub fn try_get_or_insert_with<F, E>(&self, f: F) -> Result<GuestAddr, E>
45+
where
46+
F: FnOnce() -> Result<GuestAddr, E>,
47+
E: Debug,
48+
{
49+
if let Some(addr) = self.load() {
50+
Ok(addr)
51+
} else {
52+
let addr = f()?;
53+
self.store(addr);
54+
Ok(addr)
55+
}
56+
}
57+
}
58+
59+
impl Default for AtomicGuestAddr {
60+
fn default() -> Self {
61+
Self::new()
62+
}
63+
}

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

Lines changed: 8 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,24 @@
44
//! conventional symbol lookup is not possible, e.g. if libc is statically
55
//! linked
66
use alloc::fmt::Debug;
7-
use core::{
8-
ffi::{CStr, c_char, c_void},
9-
ptr::null_mut,
10-
sync::atomic::{AtomicPtr, Ordering},
11-
};
7+
use core::ffi::{CStr, c_char, c_void};
128

139
use thiserror::Error;
1410

1511
use crate::{GuestAddr, patch::Patches};
1612

13+
pub mod atomic_guest_addr;
14+
15+
#[cfg(not(feature = "single-threaded"))]
16+
pub use atomic_guest_addr::multi_threaded::AtomicGuestAddr;
17+
#[cfg(feature = "single-threaded")]
18+
pub use atomic_guest_addr::single_threaded::AtomicGuestAddr;
19+
1720
#[cfg(feature = "libc")]
1821
pub mod dlsym;
1922

2023
pub mod nop;
2124

22-
pub struct AtomicGuestAddr {
23-
addr: AtomicPtr<c_void>,
24-
}
25-
26-
impl AtomicGuestAddr {
27-
pub const fn new() -> Self {
28-
AtomicGuestAddr {
29-
addr: AtomicPtr::new(null_mut()),
30-
}
31-
}
32-
33-
pub fn load(&self) -> Option<GuestAddr> {
34-
let addr = self.addr.load(Ordering::SeqCst) as GuestAddr;
35-
match addr {
36-
GuestAddr::MIN => None,
37-
_ => Some(addr),
38-
}
39-
}
40-
41-
pub fn store(&self, addr: GuestAddr) {
42-
self.addr.store(addr as *mut c_void, Ordering::SeqCst);
43-
}
44-
45-
pub fn get_or_insert_with<F>(&self, f: F) -> GuestAddr
46-
where
47-
F: FnOnce() -> GuestAddr,
48-
{
49-
if let Some(addr) = self.load() {
50-
addr
51-
} else {
52-
let addr = f();
53-
self.store(addr);
54-
addr
55-
}
56-
}
57-
58-
pub fn try_get_or_insert_with<F, E>(&self, f: F) -> Result<GuestAddr, E>
59-
where
60-
F: FnOnce() -> Result<GuestAddr, E>,
61-
E: Debug,
62-
{
63-
if let Some(addr) = self.load() {
64-
Ok(addr)
65-
} else {
66-
let addr = f()?;
67-
self.store(addr);
68-
Ok(addr)
69-
}
70-
}
71-
}
72-
73-
impl Default for AtomicGuestAddr {
74-
fn default() -> Self {
75-
Self::new()
76-
}
77-
}
78-
7925
pub trait Symbols: Debug + Sized + Send {
8026
type Error: Debug;
8127
fn lookup(name: *const c_char) -> Result<GuestAddr, Self::Error>;

libafl_qemu/librasan/asan/src/test.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use core::{
44
};
55

66
use log::{Level, error, trace};
7+
#[cfg(feature = "single-threaded")]
8+
use nospin::{Lazy, Mutex};
9+
#[cfg(not(feature = "single-threaded"))]
710
use spin::{Lazy, Mutex};
811

912
use crate::{

libafl_qemu/librasan/gasan/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ rust-version.workspace = true
88
crate-type = ["staticlib"]
99

1010
[features]
11-
default = []
11+
default = ["single-threaded"]
12+
## Support single-threaded targets by using dummy synchronization primitives
13+
single-threaded = ["dep:nospin", "asan/single-threaded"]
1214
test = ["asan/test", "dummy_libc/test"]
1315

1416
[dependencies]
@@ -25,6 +27,11 @@ dummy_libc = { path = "../dummy_libc", default-features = false }
2527
log = { version = "0.4.22", default-features = false, features = [
2628
"release_max_level_info",
2729
] }
30+
nospin = { version = "0.2.4", default-features = false, optional = true, features = [
31+
"lazy",
32+
"mutex",
33+
"once",
34+
] }
2835
spin = { version = "0.9.8", default-features = false, features = [
2936
"lazy",
3037
"mutex",

libafl_qemu/librasan/gasan/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ use asan::{
2525
tracking::{Tracking, guest_fast::GuestFastTracking},
2626
};
2727
use log::{Level, debug, trace};
28-
use spin::{Lazy, mutex::Mutex};
28+
#[cfg(feature = "single-threaded")]
29+
use nospin::{Lazy, Mutex};
30+
#[cfg(not(feature = "single-threaded"))]
31+
use spin::{Lazy, Mutex};
2932

3033
type Syms = DlSymSymbols<LookupTypeNext>;
3134

libafl_qemu/librasan/qasan/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ rust-version.workspace = true
88
crate-type = ["staticlib"]
99

1010
[features]
11-
default = []
11+
default = ["single-threaded"]
12+
## Support single-threaded targets by using dummy synchronization primitives
13+
single-threaded = ["dep:nospin", "asan/single-threaded"]
1214
test = ["asan/test", "dummy_libc/test"]
1315

1416
[dependencies]
@@ -26,6 +28,11 @@ libc = { version = "0.2.169", default-features = false }
2628
log = { version = "0.4.22", default-features = false, features = [
2729
"release_max_level_info",
2830
] }
31+
nospin = { version = "0.2.4", default-features = false, optional = true, features = [
32+
"lazy",
33+
"mutex",
34+
"once",
35+
] }
2936
spin = { version = "0.9.8", default-features = false, features = [
3037
"lazy",
3138
"mutex",

libafl_qemu/librasan/qasan/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ use asan::{
2323
tracking::{Tracking, host::HostTracking},
2424
};
2525
use log::{Level, trace};
26+
#[cfg(feature = "single-threaded")]
27+
use nospin::{Lazy, Mutex};
28+
#[cfg(not(feature = "single-threaded"))]
2629
use spin::{Lazy, Mutex};
2730

2831
type Syms = DlSymSymbols<LookupTypeNext>;

0 commit comments

Comments
 (0)