Fix libafl_qemu hooks references (#1825)

* fix libafl_qemu hooks references

* restrict the fatptr transmutation
This commit is contained in:
Rubens Brandão 2024-02-02 17:52:58 -03:00 committed by GitHub
parent 5c18dca792
commit 241b93036e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 37 deletions

View File

@ -523,7 +523,8 @@ impl Drop for GuestMaps {
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct FatPtr(pub *const c_void, pub *const c_void); pub(crate) struct FatPtr(pub *const c_void, pub *const c_void);
static mut GDB_COMMANDS: Vec<FatPtr> = vec![]; #[allow(clippy::vec_box)]
static mut GDB_COMMANDS: Vec<Box<FatPtr>> = vec![];
extern "C" fn gdb_cmd(data: *const (), buf: *const u8, len: usize) -> i32 { extern "C" fn gdb_cmd(data: *const (), buf: *const u8, len: usize) -> i32 {
unsafe { unsafe {
@ -1698,11 +1699,9 @@ impl Emulator {
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) { pub fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) {
unsafe { unsafe {
GDB_COMMANDS.push(core::mem::transmute(callback)); let fat: Box<FatPtr> = Box::new(transmute(callback));
libafl_qemu_add_gdb_cmd( libafl_qemu_add_gdb_cmd(gdb_cmd, &*fat as *const _ as *const ());
gdb_cmd, GDB_COMMANDS.push(fat);
GDB_COMMANDS.last().unwrap() as *const _ as *const (),
);
} }
} }

View File

@ -25,18 +25,18 @@ use crate::{
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) enum Hook { pub(crate) enum Hook {
Function(*const c_void), Function(*const c_void),
Closure(FatPtr), Closure(Box<FatPtr>),
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
Once(FatPtr), Once(Box<FatPtr>),
Empty, Empty,
} }
*/ */
// all kinds of hooks // all kinds of hooks
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub(crate) enum HookRepr { pub(crate) enum HookRepr {
Function(*const c_void), Function(*const c_void),
Closure(FatPtr), Closure(Box<FatPtr>),
Empty, Empty,
} }
@ -77,7 +77,7 @@ macro_rules! hook_to_repr {
($h:expr) => { ($h:expr) => {
match $h { match $h {
Hook::Function(f) => HookRepr::Function(f as *const libc::c_void), Hook::Function(f) => HookRepr::Function(f as *const libc::c_void),
Hook::Closure(c) => HookRepr::Closure(transmute(c)), Hook::Closure(c) => HookRepr::Closure(Box::new(transmute(c))),
Hook::Raw(_) => HookRepr::Empty, // managed by emu Hook::Raw(_) => HookRepr::Empty, // managed by emu
Hook::Empty => HookRepr::Empty, Hook::Empty => HookRepr::Empty,
} }
@ -242,13 +242,13 @@ macro_rules! create_exec_wrapper {
} }
} }
static mut GENERIC_HOOKS: Vec<(InstructionHookId, FatPtr)> = vec![]; static mut GENERIC_HOOKS: Vec<(InstructionHookId, Box<FatPtr>)> = vec![];
create_wrapper!(generic, (pc: GuestAddr)); create_wrapper!(generic, (pc: GuestAddr));
static mut BACKDOOR_HOOKS: Vec<(BackdoorHookId, FatPtr)> = vec![]; static mut BACKDOOR_HOOKS: Vec<(BackdoorHookId, Box<FatPtr>)> = vec![];
create_wrapper!(backdoor, (pc: GuestAddr)); create_wrapper!(backdoor, (pc: GuestAddr));
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
static mut PRE_SYSCALL_HOOKS: Vec<(PreSyscallHookId, FatPtr)> = vec![]; static mut PRE_SYSCALL_HOOKS: Vec<(PreSyscallHookId, Box<FatPtr>)> = vec![];
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
create_wrapper!(pre_syscall, (sys_num: i32, create_wrapper!(pre_syscall, (sys_num: i32,
a0: GuestAddr, a0: GuestAddr,
@ -260,7 +260,7 @@ create_wrapper!(pre_syscall, (sys_num: i32,
a6: GuestAddr, a6: GuestAddr,
a7: GuestAddr), SyscallHookResult); a7: GuestAddr), SyscallHookResult);
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
static mut POST_SYSCALL_HOOKS: Vec<(PostSyscallHookId, FatPtr)> = vec![]; static mut POST_SYSCALL_HOOKS: Vec<(PostSyscallHookId, Box<FatPtr>)> = vec![];
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32, create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32,
a0: GuestAddr, a0: GuestAddr,
@ -272,7 +272,7 @@ create_wrapper!(post_syscall, (res: GuestAddr, sys_num: i32,
a6: GuestAddr, a6: GuestAddr,
a7: GuestAddr), GuestAddr); a7: GuestAddr), GuestAddr);
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
static mut NEW_THREAD_HOOKS: Vec<(NewThreadHookId, FatPtr)> = vec![]; static mut NEW_THREAD_HOOKS: Vec<(NewThreadHookId, Box<FatPtr>)> = vec![];
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
create_wrapper!(new_thread, (tid: u32), bool); create_wrapper!(new_thread, (tid: u32), bool);
@ -459,15 +459,14 @@ where
invalidate_block: bool, invalidate_block: bool,
) -> InstructionHookId { ) -> InstructionHookId {
unsafe { unsafe {
let fat: FatPtr = transmute(hook); let mut fat: Box<FatPtr> = Box::new(transmute(hook));
GENERIC_HOOKS.push((InstructionHookId(0), fat));
let id = self.emulator.set_hook( let id = self.emulator.set_hook(
&mut ((*addr_of_mut!(GENERIC_HOOKS)).last_mut().unwrap().1), transmute::<&mut FatPtr, &mut FatPtr>(&mut *fat), //transmute satisfy the lifetime
addr, addr,
closure_generic_hook_wrapper::<QT, S>, closure_generic_hook_wrapper::<QT, S>,
invalidate_block, invalidate_block,
); );
GENERIC_HOOKS.last_mut().unwrap().0 = id; GENERIC_HOOKS.push((id, fat));
id id
} }
} }
@ -896,13 +895,12 @@ where
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>, hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, GuestAddr)>,
) -> BackdoorHookId { ) -> BackdoorHookId {
unsafe { unsafe {
let fat: FatPtr = transmute(hook); let mut fat: Box<FatPtr> = Box::new(transmute(hook));
BACKDOOR_HOOKS.push((BackdoorHookId(0), fat));
let id = self.emulator.add_backdoor_hook( let id = self.emulator.add_backdoor_hook(
&mut ((*addr_of_mut!(BACKDOOR_HOOKS)).last_mut().unwrap().1), transmute::<&mut FatPtr, &mut FatPtr>(&mut *fat), //transmute satisfy the lifetime
closure_backdoor_hook_wrapper::<QT, S>, closure_backdoor_hook_wrapper::<QT, S>,
); );
BACKDOOR_HOOKS.last_mut().unwrap().0 = id; BACKDOOR_HOOKS.push((id, fat));
id id
} }
} }
@ -1010,13 +1008,12 @@ where
>, >,
) -> PreSyscallHookId { ) -> PreSyscallHookId {
unsafe { unsafe {
let fat: FatPtr = transmute(hook); let mut fat: Box<FatPtr> = Box::new(transmute(hook));
PRE_SYSCALL_HOOKS.push((PreSyscallHookId(0), fat));
let id = self.emulator.add_pre_syscall_hook( let id = self.emulator.add_pre_syscall_hook(
&mut ((*addr_of_mut!(PRE_SYSCALL_HOOKS)).last_mut().unwrap().1), transmute::<&mut FatPtr, &mut FatPtr>(&mut *fat), //transmute satisfy the lifetime
closure_pre_syscall_hook_wrapper::<QT, S>, closure_pre_syscall_hook_wrapper::<QT, S>,
); );
PRE_SYSCALL_HOOKS.last_mut().unwrap().0 = id; PRE_SYSCALL_HOOKS.push((id, fat));
id id
} }
} }
@ -1129,13 +1126,12 @@ where
>, >,
) -> PostSyscallHookId { ) -> PostSyscallHookId {
unsafe { unsafe {
let fat: FatPtr = transmute(hook); let mut fat: Box<FatPtr> = Box::new(transmute(hook));
POST_SYSCALL_HOOKS.push((PostSyscallHookId(0), fat));
let id = self.emulator.add_post_syscall_hook( let id = self.emulator.add_post_syscall_hook(
&mut ((*addr_of_mut!(POST_SYSCALL_HOOKS)).last_mut().unwrap().1), transmute::<&mut FatPtr, &mut FatPtr>(&mut *fat), //transmute satisfy the lifetime
closure_post_syscall_hook_wrapper::<QT, S>, closure_post_syscall_hook_wrapper::<QT, S>,
); );
POST_SYSCALL_HOOKS.last_mut().unwrap().0 = id; POST_SYSCALL_HOOKS.push((id, fat));
id id
} }
} }
@ -1177,13 +1173,12 @@ where
hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>, hook: Box<dyn for<'a> FnMut(&'a mut Self, Option<&'a mut S>, u32) -> bool>,
) -> NewThreadHookId { ) -> NewThreadHookId {
unsafe { unsafe {
let fat: FatPtr = transmute(hook); let mut fat: Box<FatPtr> = Box::new(transmute(hook));
NEW_THREAD_HOOKS.push((NewThreadHookId(0), fat));
let id = self.emulator.add_new_thread_hook( let id = self.emulator.add_new_thread_hook(
&mut (*addr_of_mut!(NEW_THREAD_HOOKS)).last_mut().unwrap().1, transmute::<&mut FatPtr, &mut FatPtr>(&mut *fat), //transmute satisfy the lifetime
closure_new_thread_hook_wrapper::<QT, S>, closure_new_thread_hook_wrapper::<QT, S>,
); );
NEW_THREAD_HOOKS.last_mut().unwrap().0 = id; NEW_THREAD_HOOKS.push((id, fat));
id id
} }
} }
@ -1200,7 +1195,7 @@ where
pub fn crash_closure(&self, hook: Box<dyn FnMut(&mut Self, i32)>) { pub fn crash_closure(&self, hook: Box<dyn FnMut(&mut Self, i32)>) {
unsafe { unsafe {
self.emulator.set_crash_hook(crash_hook_wrapper::<QT, S>); self.emulator.set_crash_hook(crash_hook_wrapper::<QT, S>);
CRASH_HOOKS.push(HookRepr::Closure(transmute(hook))); CRASH_HOOKS.push(HookRepr::Closure(Box::new(transmute(hook))));
} }
} }
} }