-
-
Notifications
You must be signed in to change notification settings - Fork 476
Expand file tree
/
Copy pathguest_shadow.rs
More file actions
95 lines (83 loc) · 2.68 KB
/
Copy pathguest_shadow.rs
File metadata and controls
95 lines (83 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#![no_main]
use std::sync::{LazyLock, Mutex, MutexGuard};
use libafl_asan::{
GuestAddr,
mmap::libc::LibcMmap,
shadow::{
PoisonType, Shadow,
guest::{GuestShadow, GuestShadowError},
layout::DefaultShadowLayout,
},
symbols::dlsym::{DlSymSymbols, LookupTypeNext},
};
use libfuzzer_sys::fuzz_target;
use log::info;
type GS = GuestShadow<LibcMmap<DlSymSymbols<LookupTypeNext>>, DefaultShadowLayout>;
static INIT_ONCE: LazyLock<Mutex<GS>> = LazyLock::new(|| {
env_logger::init();
Mutex::new(
GuestShadow::<LibcMmap<DlSymSymbols<LookupTypeNext>>, DefaultShadowLayout>::new().unwrap(),
)
});
fn get_shadow() -> MutexGuard<'static, GS> {
INIT_ONCE.lock().unwrap()
}
const MAX_LENGTH: usize = 0x3ff;
const MAX_ADDR: GuestAddr = GS::HIGH_MEM_LIMIT;
const MAX_OFFSET: usize = 0x7ff;
fuzz_target!(|data: Vec<GuestAddr>| {
let mut shadow = get_shadow();
if data.len() < 4 {
return;
}
info!("data: {data:x?}");
let start = data[0] & MAX_ADDR;
let len = data[1] & MAX_LENGTH;
let test_offset = data[2] & MAX_OFFSET;
let test_len = data[3] & MAX_LENGTH;
let result = shadow.poison(start, len, PoisonType::AsanUser);
if !GS::is_memory(start, len) {
assert_eq!(result, Err(GuestShadowError::InvalidMemoryAddress(start)));
return;
} else if !GS::is_end_aligned(start, len) {
assert_eq!(
result,
Err(GuestShadowError::UnalignedEndAddress(start, len,))
);
return;
} else {
assert_eq!(result, Ok(()));
}
let test_start = if test_offset > MAX_LENGTH {
start.saturating_add(test_offset - MAX_LENGTH) & MAX_ADDR
} else {
start.saturating_sub(test_offset)
};
let test_result = shadow.is_poison(test_start, test_len);
if !GS::is_memory(test_start, test_len) {
assert_eq!(
test_result,
Err(GuestShadowError::InvalidMemoryAddress(test_start))
);
} else if len == 0 || test_len == 0 {
assert_eq!(test_result, Ok(false));
} else {
let end = start + len;
let test_end = test_start + test_len;
let overlaps = !(test_end <= start || test_start >= end);
assert_eq!(test_result, Ok(overlaps));
}
let start_aligned = GS::align_down(start);
shadow
.unpoison(start_aligned, len + start - start_aligned)
.unwrap();
let retest_result = shadow.is_poison(test_start, test_len);
if !GS::is_memory(test_start, test_len) {
assert_eq!(
retest_result,
Err(GuestShadowError::InvalidMemoryAddress(test_start))
);
} else {
assert_eq!(retest_result, Ok(false));
}
});