WorksButNotTested db1d38eeb6
LibAFL_QEMU/librasan: Add support for reading environment (#3241)
* Add support for reading environment

* Fix clippy

* Review fixes
2025-05-20 21:48:08 +02:00

199 lines
5.7 KiB
Rust

#![cfg_attr(target_arch = "arm", feature(arm_target_feature))]
#[cfg(test)]
#[cfg(feature = "libc")]
#[cfg(not(target_arch = "arm"))]
mod tests {
use asan::{
GuestAddr,
mmap::{Mmap, MmapProt, linux::LinuxMmap},
patch::{Patch, raw::RawPatch},
};
use libc::{_SC_PAGESIZE, sysconf};
use log::info;
#[unsafe(no_mangle)]
extern "C" fn test1(a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize) -> usize {
assert_eq!(a1, 1);
assert_eq!(a2, 2);
assert_eq!(a3, 3);
assert_eq!(a4, 4);
assert_eq!(a5, 5);
assert_eq!(a6, 6);
0xdeadface
}
#[unsafe(no_mangle)]
extern "C" fn test2(a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize) -> usize {
assert_eq!(a1, 1);
assert_eq!(a2, 2);
assert_eq!(a3, 3);
assert_eq!(a4, 4);
assert_eq!(a5, 5);
assert_eq!(a6, 6);
0xd00df00d
}
#[test]
fn test_patch() {
let ret1 = test1(1, 2, 3, 4, 5, 6);
assert_eq!(ret1, 0xdeadface);
let ret2 = test2(1, 2, 3, 4, 5, 6);
assert_eq!(ret2, 0xd00df00d);
let ptest1 = test1 as *const () as GuestAddr;
let ptest2 = test2 as *const () as GuestAddr;
info!("pfn: {:#x}", ptest1);
let aligned_pfn = ptest1 & !0xfff;
let page_size = unsafe { sysconf(_SC_PAGESIZE) as usize };
info!("aligned_pfn: {:#x}", aligned_pfn);
info!("page_size: {:#x}", page_size);
LinuxMmap::protect(
aligned_pfn,
page_size * 2,
MmapProt::READ | MmapProt::WRITE | MmapProt::EXEC,
)
.unwrap();
RawPatch::patch(ptest1, ptest2).unwrap();
let ret = test1(1, 2, 3, 4, 5, 6);
assert_eq!(ret, 0xd00df00d);
LinuxMmap::protect(aligned_pfn, page_size * 2, MmapProt::READ | MmapProt::EXEC).unwrap();
}
}
#[cfg(test)]
#[cfg(feature = "libc")]
#[cfg(target_arch = "arm")]
mod tests {
use asan::{
GuestAddr,
mmap::{Mmap, MmapProt, linux::LinuxMmap},
patch::{Patch, raw::RawPatch},
};
use libc::{_SC_PAGESIZE, sysconf};
use log::info;
macro_rules! define_test_function {
($fn_name:ident, $ret_val:expr) => {
define_test_function!([], $fn_name, $ret_val);
};
($attr:meta, $fn_name:ident, $ret_val:expr) => {
define_test_function!([$attr], $fn_name, $ret_val);
};
([$($attr:meta)*], $fn_name:ident, $ret_val:expr) => {
#[unsafe(no_mangle)]
$(#[$attr])*
extern "C" fn $fn_name(
a1: usize,
a2: usize,
a3: usize,
a4: usize,
a5: usize,
a6: usize,
) -> usize {
assert_eq!(a1, 1);
assert_eq!(a2, 2);
assert_eq!(a3, 3);
assert_eq!(a4, 4);
assert_eq!(a5, 5);
assert_eq!(a6, 6);
return $ret_val;
}
};
}
macro_rules! define_test {
(
$fn_name:ident,
$test_fn1:ident,
$test_fn2:ident,
$test_ret_val1:expr,
$test_ret_val2:expr
) => {
#[test]
fn $fn_name() {
#[allow(unused_unsafe)]
unsafe {
let ret1 = $test_fn1(1, 2, 3, 4, 5, 6);
assert_eq!(ret1, $test_ret_val1);
let ret2 = $test_fn2(1, 2, 3, 4, 5, 6);
assert_eq!(ret2, $test_ret_val2);
let ptest1 = $test_fn1 as *const () as GuestAddr;
let ptest2 = $test_fn2 as *const () as GuestAddr;
info!("pfn: {:#x}", ptest1);
let aligned_pfn = ptest1 & !0xfff;
let page_size = unsafe { sysconf(_SC_PAGESIZE) as usize };
info!("aligned_pfn: {:#x}", aligned_pfn);
info!("page_size: {:#x}", page_size);
LinuxMmap::protect(
aligned_pfn,
page_size * 2,
MmapProt::READ | MmapProt::WRITE | MmapProt::EXEC,
)
.unwrap();
RawPatch::patch(ptest1, ptest2).unwrap();
let ret = $test_fn1(1, 2, 3, 4, 5, 6);
assert_eq!(ret, $test_ret_val2);
LinuxMmap::protect(aligned_pfn, page_size * 2, MmapProt::READ | MmapProt::EXEC)
.unwrap();
}
}
};
}
define_test_function!(arm_patch_target, 0xdeadface);
define_test_function!(patched_arm_to_arm, 0xd00df00d);
define_test_function!(patched_arm_to_thumb, 0xfeeddeaf);
define_test_function!(
target_feature(enable = "thumb-mode"),
thumb_patch_target,
0xcafebabe
);
define_test_function!(
target_feature(enable = "thumb-mode"),
patched_thumb_to_thumb,
0xbeeffade
);
define_test_function!(
target_feature(enable = "thumb-mode"),
patched_thumb_to_arm,
0xdeedcede
);
define_test!(
test_patch_arm_to_arm,
patched_arm_to_arm,
arm_patch_target,
0xd00df00d,
0xdeadface
);
define_test!(
test_patch_arm_to_thumb,
patched_arm_to_thumb,
thumb_patch_target,
0xfeeddeaf,
0xcafebabe
);
define_test!(
test_patch_thumb_to_arm,
patched_thumb_to_arm,
arm_patch_target,
0xdeedcede,
0xdeadface
);
define_test!(
test_patch_thumb_to_thumb,
patched_thumb_to_thumb,
thumb_patch_target,
0xbeeffade,
0xcafebabe
);
}