Prevent dropping variables in closure hooks (#549)

This commit is contained in:
Evan Richter 2022-02-24 03:18:46 -06:00 committed by GitHub
parent df84d39242
commit 679eadcc50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -108,6 +108,9 @@ where
let mut func: Box<dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64)> = let mut func: Box<dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64)> =
transmute(*ptr); transmute(*ptr);
(func)(&emulator, helpers, inprocess_get_state::<S>(), id); (func)(&emulator, helpers, inprocess_get_state::<S>(), id);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
_ => (), _ => (),
} }
@ -135,8 +138,13 @@ where
let mut func: Box< let mut func: Box<
dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64) -> Option<u64>, dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64) -> Option<u64>,
> = transmute(*ptr); > = transmute(*ptr);
(func)(&emulator, helpers, inprocess_get_state::<S>(), pc) let ret = (func)(&emulator, helpers, inprocess_get_state::<S>(), pc)
.map_or(SKIP_EXEC_HOOK, |id| id) .map_or(SKIP_EXEC_HOOK, |id| id);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
ret
} }
_ => SKIP_EXEC_HOOK, _ => SKIP_EXEC_HOOK,
} }
@ -162,6 +170,9 @@ where
let mut func: Box<dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64)> = let mut func: Box<dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64)> =
transmute(*ptr); transmute(*ptr);
(func)(&emulator, helpers, inprocess_get_state::<S>(), id); (func)(&emulator, helpers, inprocess_get_state::<S>(), id);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
_ => (), _ => (),
} }
@ -194,13 +205,18 @@ where
let mut func: Box< let mut func: Box<
dyn FnMut(&Emulator, &mut QT, Option<&mut S>, usize) -> Option<u64>, dyn FnMut(&Emulator, &mut QT, Option<&mut S>, usize) -> Option<u64>,
> = transmute(*ptr); > = transmute(*ptr);
(func)( let ret = (func)(
&emulator, &emulator,
helpers, helpers,
inprocess_get_state::<S>(), inprocess_get_state::<S>(),
size as usize, size as usize,
) )
.map_or(SKIP_EXEC_HOOK, |id| id) .map_or(SKIP_EXEC_HOOK, |id| id);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
ret
} }
_ => SKIP_EXEC_HOOK, _ => SKIP_EXEC_HOOK,
} }
@ -232,13 +248,18 @@ where
let mut func: Box< let mut func: Box<
dyn FnMut(&Emulator, &mut QT, Option<&mut S>, usize) -> Option<u64>, dyn FnMut(&Emulator, &mut QT, Option<&mut S>, usize) -> Option<u64>,
> = transmute(*ptr); > = transmute(*ptr);
(func)( let ret = (func)(
&emulator, &emulator,
helpers, helpers,
inprocess_get_state::<S>(), inprocess_get_state::<S>(),
size as usize, size as usize,
) )
.map_or(SKIP_EXEC_HOOK, |id| id) .map_or(SKIP_EXEC_HOOK, |id| id);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
ret
} }
_ => SKIP_EXEC_HOOK, _ => SKIP_EXEC_HOOK,
} }
@ -645,14 +666,19 @@ where
let mut func: Box< let mut func: Box<
dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, usize) -> Option<u64>, dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, usize) -> Option<u64>,
> = transmute(*ptr); > = transmute(*ptr);
(func)( let ret = (func)(
&emulator, &emulator,
helpers, helpers,
inprocess_get_state::<S>(), inprocess_get_state::<S>(),
pc, pc,
size as usize, size as usize,
) )
.map_or(SKIP_EXEC_HOOK, |id| id) .map_or(SKIP_EXEC_HOOK, |id| id);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
ret
} }
_ => SKIP_EXEC_HOOK, _ => SKIP_EXEC_HOOK,
} }
@ -678,6 +704,9 @@ where
let mut func: Box<dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u8, u8)> = let mut func: Box<dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u8, u8)> =
transmute(*ptr); transmute(*ptr);
(func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1); (func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
_ => (), _ => (),
} }
@ -706,6 +735,9 @@ where
dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u16, u16), dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u16, u16),
> = transmute(*ptr); > = transmute(*ptr);
(func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1); (func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
_ => (), _ => (),
} }
@ -734,6 +766,9 @@ where
dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u32, u32), dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u32, u32),
> = transmute(*ptr); > = transmute(*ptr);
(func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1); (func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
_ => (), _ => (),
} }
@ -762,6 +797,9 @@ where
dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u64, u64), dyn FnMut(&Emulator, &mut QT, Option<&mut S>, u64, u64, u64),
> = transmute(*ptr); > = transmute(*ptr);
(func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1); (func)(&emulator, helpers, inprocess_get_state::<S>(), id, v0, v1);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
_ => (), _ => (),
} }
@ -799,6 +837,9 @@ where
), ),
> = transmute(*ptr); > = transmute(*ptr);
(func)(&emu, hooks, inprocess_get_state::<S>(), tid); (func)(&emu, hooks, inprocess_get_state::<S>(), tid);
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
Hook::Once(ptr) => { Hook::Once(ptr) => {
let func: Box< let func: Box<
@ -907,6 +948,10 @@ where
a6, a6,
a7, a7,
); );
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
if r.skip_syscall { if r.skip_syscall {
res.skip_syscall = true; res.skip_syscall = true;
res.retval = r.retval; res.retval = r.retval;
@ -1009,6 +1054,9 @@ where
a6, a6,
a7, a7,
); );
// Forget the closure so that drop is not called on captured variables.
core::mem::forget(func);
} }
_ => (), _ => (),
} }