Skip to content

Commit 869edd0

Browse files
WorksButNotTestedYour Name
and
Your Name
authored
Various updates to librasan (#3106)
* Add rawmemchr * Add stpncpy * Add strchrnul * Fix strcat * Added strncat * Add wcschr * Minor tweak * Add wcsncmp * Add wcsnlen * Add wcsrchr * Add wmemchr * Fix asan load/store sizes for wide string functions * Refactor patches * Rename tracking functions to prevent collision with allocator * Change return type of asan_sym to make it consistent with the other native functions * Fix mutex re-entrancy issue in Patches by splitting locks * Fix tests on 32-bit platforms --------- Co-authored-by: Your Name <[email protected]>
1 parent 58607dc commit 869edd0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1319
-190
lines changed

libafl_qemu/librasan/asan/src/allocator/frontend/default.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl<B: GlobalAlloc + Send, S: Shadow, T: Tracking> AllocatorFrontend for Defaul
9494
);
9595

9696
self.tracking
97-
.alloc(data, len)
97+
.track(data, len)
9898
.map_err(|e| DefaultFrontendError::TrackingError(e))?;
9999
self.shadow
100100
.poison(orig, data - orig, PoisonType::AsanHeapLeftRz)
@@ -130,7 +130,7 @@ impl<B: GlobalAlloc + Send, S: Shadow, T: Tracking> AllocatorFrontend for Defaul
130130
)
131131
.map_err(|e| DefaultFrontendError::ShadowError(e))?;
132132
self.tracking
133-
.dealloc(addr)
133+
.untrack(addr)
134134
.map_err(|e| DefaultFrontendError::TrackingError(e))?;
135135
self.quaratine_used += alloc.backend_len;
136136
self.quarantine.push_back(alloc);

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::ffi::{CStr, c_char, c_int};
1+
use core::ffi::{CStr, c_char, c_int, c_void};
22

33
use libc::{SIGABRT, pid_t};
44

@@ -32,15 +32,15 @@ impl Function for FunctionExit {
3232
}
3333

3434
unsafe extern "C" {
35-
fn asan_sym(name: *const c_char) -> GuestAddr;
35+
fn asan_sym(name: *const c_char) -> *const c_void;
3636
}
3737

3838
pub fn abort() -> ! {
3939
let getpid_addr = unsafe { asan_sym(FunctionGetpid::NAME.as_ptr() as *const c_char) };
40-
let fn_getpid = FunctionGetpid::as_ptr(getpid_addr).unwrap();
40+
let fn_getpid = FunctionGetpid::as_ptr(getpid_addr as GuestAddr).unwrap();
4141

4242
let kill_addr = unsafe { asan_sym(FunctionKill::NAME.as_ptr() as *const c_char) };
43-
let fn_kill = FunctionKill::as_ptr(kill_addr).unwrap();
43+
let fn_kill = FunctionKill::as_ptr(kill_addr as GuestAddr).unwrap();
4444

4545
unsafe { asan_swap(false) };
4646
let pid = unsafe { fn_getpid() };
@@ -50,7 +50,7 @@ pub fn abort() -> ! {
5050

5151
pub fn exit(status: c_int) -> ! {
5252
let exit_addr = unsafe { asan_sym(FunctionExit::NAME.as_ptr() as *const c_char) };
53-
let fn_exit = FunctionExit::as_ptr(exit_addr).unwrap();
53+
let fn_exit = FunctionExit::as_ptr(exit_addr as GuestAddr).unwrap();
5454
unsafe { asan_swap(false) };
5555
unsafe { fn_exit(status) };
5656
}

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use libc::FILE;
44
use log::trace;
55

66
use crate::{
7-
asan_load, asan_panic, asan_store, asan_swap, asan_sym,
7+
GuestAddr, asan_load, asan_panic, asan_store, asan_swap, asan_sym,
88
symbols::{AtomicGuestAddr, Function, FunctionPointer},
99
};
1010

@@ -36,8 +36,9 @@ pub unsafe extern "C" fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) ->
3636

3737
asan_store(buf as *const c_void, n as usize);
3838
asan_load(stream as *const c_void, size_of::<FILE>());
39-
let addr = FGETS_ADDR
40-
.get_or_insert_with(|| asan_sym(FunctionFgets::NAME.as_ptr() as *const c_char));
39+
let addr = FGETS_ADDR.get_or_insert_with(|| {
40+
asan_sym(FunctionFgets::NAME.as_ptr() as *const c_char) as GuestAddr
41+
});
4142
let fn_fgets = FunctionFgets::as_ptr(addr).unwrap();
4243
asan_swap(false);
4344
let ret = fn_fgets(buf, n, stream);

libafl_qemu/librasan/asan/src/hooks/mmap/libc.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use libc::{c_int, c_void};
44
use log::trace;
55

66
use crate::{
7-
asan_swap, asan_sym, asan_track, asan_unpoison, off_t, size_t,
7+
GuestAddr, asan_swap, asan_sym, asan_track, asan_unpoison, off_t, size_t,
88
symbols::{AtomicGuestAddr, Function, FunctionPointer},
99
};
1010

@@ -41,8 +41,9 @@ pub unsafe extern "C" fn mmap(
4141
"mmap - addr: {:p}, len: {:#x}, prot: {:#x}, flags: {:#x}, fd: {:#x}, offset: {:#x}",
4242
addr, len, prot, flags, fd, offset
4343
);
44-
let mmap_addr =
45-
MMAP_ADDR.get_or_insert_with(|| asan_sym(FunctionMmap::NAME.as_ptr() as *const c_char));
44+
let mmap_addr = MMAP_ADDR.get_or_insert_with(|| {
45+
asan_sym(FunctionMmap::NAME.as_ptr() as *const c_char) as GuestAddr
46+
});
4647
asan_swap(false);
4748
let fn_mmap = FunctionMmap::as_ptr(mmap_addr).unwrap();
4849
asan_swap(true);

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

+69-6
Original file line numberDiff line numberDiff line change
@@ -28,45 +28,54 @@ pub mod mmap;
2828
pub mod munmap;
2929
pub mod posix_memalign;
3030
pub mod pvalloc;
31+
pub mod rawmemchr;
3132
pub mod read;
3233
pub mod realloc;
3334
pub mod reallocarray;
3435
pub mod stpcpy;
36+
pub mod stpncpy;
3537
pub mod strcasecmp;
3638
pub mod strcasestr;
3739
pub mod strcat;
3840
pub mod strchr;
41+
pub mod strchrnul;
3942
pub mod strcmp;
4043
pub mod strcpy;
4144
pub mod strdup;
4245
pub mod strlen;
4346
pub mod strncasecmp;
47+
pub mod strncat;
4448
pub mod strncmp;
4549
pub mod strncpy;
4650
pub mod strndup;
4751
pub mod strnlen;
4852
pub mod strrchr;
4953
pub mod strstr;
5054
pub mod valloc;
55+
pub mod wcschr;
5156
pub mod wcscmp;
5257
pub mod wcscpy;
5358
pub mod wcslen;
59+
pub mod wcsncmp;
60+
pub mod wcsnlen;
61+
pub mod wcsrchr;
62+
pub mod wmemchr;
5463
pub mod write;
5564

5665
#[cfg(feature = "libc")]
5766
pub mod fgets;
5867

59-
use alloc::vec::Vec;
68+
use alloc::vec::{IntoIter, Vec};
6069
use core::ffi::{CStr, c_char, c_int, c_void};
6170

62-
use crate::{GuestAddr, hooks, size_t, wchar_t};
71+
use crate::{GuestAddr, hooks, size_t, symbols::Symbols, wchar_t};
6372

6473
unsafe extern "C" {
6574
pub fn asprintf(strp: *mut *mut c_char, fmt: *const c_char, ...) -> c_int;
6675
pub fn vasprintf(strp: *mut *mut c_char, fmt: *const c_char, va: *const c_void) -> c_int;
6776
}
6877

69-
#[derive(Clone)]
78+
#[derive(Debug, Clone)]
7079
pub struct PatchedHook {
7180
pub name: &'static CStr,
7281
pub destination: GuestAddr,
@@ -79,8 +88,27 @@ impl PatchedHook {
7988
Self { name, destination }
8089
}
8190

82-
pub fn all() -> Vec<Self> {
83-
[
91+
pub fn lookup<S: Symbols>(&self) -> Result<GuestAddr, S::Error> {
92+
S::lookup(self.name.as_ptr() as *const c_char)
93+
}
94+
}
95+
96+
pub struct PatchedHooks {
97+
hooks: Vec<PatchedHook>,
98+
}
99+
100+
impl IntoIterator for PatchedHooks {
101+
type Item = PatchedHook;
102+
type IntoIter = IntoIter<Self::Item>;
103+
104+
fn into_iter(self) -> Self::IntoIter {
105+
self.hooks.into_iter()
106+
}
107+
}
108+
109+
impl Default for PatchedHooks {
110+
fn default() -> Self {
111+
Self { hooks: [
84112
PatchedHook::new::<unsafe extern "C" fn(size_t, size_t) -> *mut c_void>(
85113
c"aligned_alloc",
86114
hooks::aligned_alloc::aligned_alloc,
@@ -124,10 +152,17 @@ impl PatchedHook {
124152
c"memrchr",
125153
hooks::memrchr::memrchr,
126154
),
155+
PatchedHook::new::<unsafe extern "C" fn(*const c_void, c_int) -> *mut c_void>(
156+
c"rawmemchr",
157+
hooks::rawmemchr::rawmemchr,
158+
),
127159
PatchedHook::new::<unsafe extern "C" fn(*mut c_char, *const c_char) -> *mut c_char>(
128160
c"stpcpy",
129161
hooks::stpcpy::stpcpy,
130162
),
163+
PatchedHook::new::<
164+
unsafe extern "C" fn(*mut c_char, *const c_char, size_t) -> *mut c_char,
165+
>(c"stpncpy", hooks::stpncpy::stpncpy),
131166
PatchedHook::new::<unsafe extern "C" fn(*const c_char, *const c_char) -> c_int>(
132167
c"strcasecmp",
133168
hooks::strcasecmp::strcasecmp,
@@ -144,6 +179,10 @@ impl PatchedHook {
144179
c"strchr",
145180
hooks::strchr::strchr,
146181
),
182+
PatchedHook::new::<unsafe extern "C" fn(*const c_char, c_int) -> *mut c_char>(
183+
c"strchrnul",
184+
hooks::strchrnul::strchrnul,
185+
),
147186
PatchedHook::new::<unsafe extern "C" fn(*const c_char, *const c_char) -> c_int>(
148187
c"strcmp",
149188
hooks::strcmp::strcmp,
@@ -164,6 +203,9 @@ impl PatchedHook {
164203
c"strncasecmp",
165204
hooks::strncasecmp::strncasecmp,
166205
),
206+
PatchedHook::new::<
207+
unsafe extern "C" fn(*mut c_char, *const c_char, size_t) -> *mut c_char,
208+
>(c"strncat", hooks::strncat::strncat),
167209
PatchedHook::new::<unsafe extern "C" fn(*const c_char, *const c_char, size_t) -> c_int>(
168210
c"strncmp",
169211
hooks::strncmp::strncmp,
@@ -190,6 +232,10 @@ impl PatchedHook {
190232
PatchedHook::new::<
191233
unsafe extern "C" fn(*mut *mut c_char, *const c_char, *const c_void) -> c_int,
192234
>(c"vasprintf", hooks::vasprintf),
235+
PatchedHook::new::<unsafe extern "C" fn(*const wchar_t, c_int) -> *mut wchar_t>(
236+
c"wcschr",
237+
hooks::wcschr::wcschr,
238+
),
193239
PatchedHook::new::<unsafe extern "C" fn(*const wchar_t, *const wchar_t) -> c_int>(
194240
c"wcscmp",
195241
hooks::wcscmp::wcscmp,
@@ -202,7 +248,24 @@ impl PatchedHook {
202248
c"wcslen",
203249
hooks::wcslen::wcslen,
204250
),
251+
PatchedHook::new::<unsafe extern "C" fn (*const wchar_t, *const wchar_t, size_t) -> c_int>(
252+
c"wcsncmp",
253+
hooks::wcsncmp::wcsncmp,
254+
),
255+
PatchedHook::new::<unsafe extern "C" fn ( *const wchar_t, size_t) -> size_t>(
256+
c"wcsnlen",
257+
hooks::wcsnlen::wcsnlen,
258+
),
259+
PatchedHook::new::<unsafe extern "C" fn ( *const wchar_t, c_int) -> *mut wchar_t >(
260+
c"wcsrchr",
261+
hooks::wcsrchr::wcsrchr,
262+
),
263+
PatchedHook::new::<unsafe extern "C" fn ( *const wchar_t, wchar_t, size_t) -> *mut wchar_t>(
264+
c"wmemchr",
265+
hooks::wmemchr::wmemchr,
266+
),
267+
205268
]
206-
.to_vec()
269+
.to_vec() }
207270
}
208271
}

libafl_qemu/librasan/asan/src/hooks/munmap/libc.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use libc::{c_int, c_void};
44
use log::trace;
55

66
use crate::{
7-
asan_swap, asan_sym, asan_untrack, size_t,
7+
GuestAddr, asan_swap, asan_sym, asan_untrack, size_t,
88
symbols::{AtomicGuestAddr, Function, FunctionPointer},
99
};
1010

@@ -24,8 +24,9 @@ static MUNMAP_ADDR: AtomicGuestAddr = AtomicGuestAddr::new();
2424
pub unsafe extern "C" fn munmap(addr: *mut c_void, len: size_t) -> c_int {
2525
unsafe {
2626
trace!("munmap - addr: {:p}, len: {:#x}", addr, len);
27-
let mmap_addr = MUNMAP_ADDR
28-
.get_or_insert_with(|| asan_sym(FunctionMunmap::NAME.as_ptr() as *const c_char));
27+
let mmap_addr = MUNMAP_ADDR.get_or_insert_with(|| {
28+
asan_sym(FunctionMunmap::NAME.as_ptr() as *const c_char) as GuestAddr
29+
});
2930
asan_swap(false);
3031
let fn_munmap = FunctionMunmap::as_ptr(mmap_addr).unwrap();
3132
asan_swap(true);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use core::ffi::{c_char, c_int, c_void};
2+
3+
use log::trace;
4+
5+
use crate::{asan_load, asan_panic};
6+
7+
/// # Safety
8+
/// See man pages
9+
#[unsafe(export_name = "patch_rawmemchr")]
10+
pub unsafe extern "C" fn rawmemchr(s: *const c_void, c: c_int) -> *mut c_void {
11+
unsafe {
12+
trace!("rawmemchr - s: {:p}, c: {:#x}", s, c);
13+
14+
if s.is_null() {
15+
asan_panic(c"rawmemchr - s is null".as_ptr() as *const c_char);
16+
}
17+
18+
let mut len = 0;
19+
let pc = s as *const c_char;
20+
while *pc.add(len) != c as c_char {
21+
len += 1;
22+
}
23+
asan_load(s, len);
24+
s.add(len) as *mut c_void
25+
}
26+
}

libafl_qemu/librasan/asan/src/hooks/read/libc.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use libc::{SYS_read, c_int, c_void};
44
use log::trace;
55

66
use crate::{
7-
asan_panic, asan_store, asan_swap, asan_sym, size_t, ssize_t,
7+
GuestAddr, asan_panic, asan_store, asan_swap, asan_sym, size_t, ssize_t,
88
symbols::{AtomicGuestAddr, Function, FunctionPointer},
99
};
1010

@@ -30,8 +30,9 @@ pub unsafe extern "C" fn read(fd: c_int, buf: *mut c_void, count: size_t) -> ssi
3030
}
3131

3232
asan_store(buf, count);
33-
let addr = SYSCALL_ADDR
34-
.get_or_insert_with(|| asan_sym(FunctionSyscall::NAME.as_ptr() as *const c_char));
33+
let addr = SYSCALL_ADDR.get_or_insert_with(|| {
34+
asan_sym(FunctionSyscall::NAME.as_ptr() as *const c_char) as GuestAddr
35+
});
3536
let fn_syscall = FunctionSyscall::as_ptr(addr).unwrap();
3637
asan_swap(false);
3738
let ret = fn_syscall(SYS_read, fd, buf, count);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use core::{
2+
cmp::min,
3+
ffi::{c_char, c_void},
4+
ptr::{copy, write_bytes},
5+
};
6+
7+
use log::trace;
8+
9+
use crate::{asan_load, asan_panic, asan_store, size_t};
10+
11+
/// # Safety
12+
/// See man pages
13+
#[unsafe(export_name = "patch_stpncpy")]
14+
pub unsafe extern "C" fn stpncpy(
15+
dst: *mut c_char,
16+
src: *const c_char,
17+
dsize: size_t,
18+
) -> *mut c_char {
19+
unsafe {
20+
trace!(
21+
"stpncpy - dst: {:p}, src: {:p}, dsize: {:#x}",
22+
dst, src, dsize
23+
);
24+
25+
if dsize == 0 {
26+
return dst;
27+
}
28+
29+
if dst.is_null() {
30+
asan_panic(c"stpncpy - dst is null".as_ptr() as *const c_char);
31+
}
32+
33+
if src.is_null() {
34+
asan_panic(c"stpncpy - src is null".as_ptr() as *const c_char);
35+
}
36+
37+
let mut len = 0;
38+
while *src.add(len) != 0 {
39+
len += 1;
40+
}
41+
asan_load(src as *const c_void, len + 1);
42+
asan_store(dst as *const c_void, dsize);
43+
44+
let dlen = min(len + 1, dsize);
45+
copy(src, dst, dlen);
46+
write_bytes(dst.add(dlen), 0, dsize - dlen);
47+
dst.add(dsize)
48+
}
49+
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use core::{
55

66
use log::trace;
77

8-
use crate::{asan_load, asan_panic};
8+
use crate::{asan_load, asan_panic, asan_store};
99

1010
/// # Safety
1111
/// See man pages
@@ -30,7 +30,7 @@ pub unsafe extern "C" fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_cha
3030
while *ct.add(ct_len) != 0 {
3131
ct_len += 1;
3232
}
33-
asan_load(s as *const c_void, s_len + 1);
33+
asan_store(s.add(s_len) as *const c_void, ct_len + 1);
3434
asan_load(ct as *const c_void, ct_len + 1);
3535
copy(ct, s.add(s_len), ct_len + 1);
3636
s

0 commit comments

Comments
 (0)