Fix use-after free with NativeFunc

This commit is contained in:
Mark McCaskey
2020-12-08 12:13:17 -08:00
parent d90be1eb61
commit eb8b486388
3 changed files with 27 additions and 47 deletions

View File

@@ -673,9 +673,7 @@ impl Function {
Ok(NativeFunc::new( Ok(NativeFunc::new(
self.store.clone(), self.store.clone(),
self.exported.vm_function.address, self.exported.clone(),
self.exported.vm_function.vmctx,
self.exported.vm_function.kind,
self.definition.clone(), self.definition.clone(),
)) ))
} }

View File

@@ -27,10 +27,7 @@ use wasmer_vm::{
pub struct NativeFunc<Args = (), Rets = ()> { pub struct NativeFunc<Args = (), Rets = ()> {
definition: FunctionDefinition, definition: FunctionDefinition,
store: Store, store: Store,
address: *const VMFunctionBody, exported: ExportFunction,
vmctx: VMFunctionEnvironment,
arg_kind: VMFunctionKind,
// exported: ExportFunction,
_phantom: PhantomData<(Args, Rets)>, _phantom: PhantomData<(Args, Rets)>,
} }
@@ -43,20 +40,28 @@ where
{ {
pub(crate) fn new( pub(crate) fn new(
store: Store, store: Store,
address: *const VMFunctionBody, exported: ExportFunction,
vmctx: VMFunctionEnvironment,
arg_kind: VMFunctionKind,
definition: FunctionDefinition, definition: FunctionDefinition,
) -> Self { ) -> Self {
Self { Self {
definition, definition,
store, store,
address, exported,
vmctx,
arg_kind,
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
pub(crate) fn vmctx(&self) -> VMFunctionEnvironment {
self.exported.vm_function.vmctx
}
pub(crate) fn address(&self) -> *const VMFunctionBody {
self.exported.vm_function.address
}
pub(crate) fn arg_kind(&self) -> VMFunctionKind {
self.exported.vm_function.kind
}
} }
/* /*
@@ -84,19 +89,7 @@ where
Rets: WasmTypeList, Rets: WasmTypeList,
{ {
fn from(other: &NativeFunc<Args, Rets>) -> Self { fn from(other: &NativeFunc<Args, Rets>) -> Self {
let signature = FunctionType::new(Args::wasm_types(), Rets::wasm_types()); other.exported.clone()
Self {
// TODO:
import_init_function_ptr: None,
vm_function: VMExportFunction {
address: other.address,
vmctx: other.vmctx,
signature,
kind: other.arg_kind,
call_trampoline: None,
instance_allocator: None,
},
}
} }
} }
@@ -106,22 +99,10 @@ where
Rets: WasmTypeList, Rets: WasmTypeList,
{ {
fn from(other: NativeFunc<Args, Rets>) -> Self { fn from(other: NativeFunc<Args, Rets>) -> Self {
let signature = FunctionType::new(Args::wasm_types(), Rets::wasm_types());
Self { Self {
store: other.store, store: other.store,
definition: other.definition, definition: other.definition,
exported: ExportFunction { exported: other.exported.clone(),
// TODO:
import_init_function_ptr: None,
vm_function: VMExportFunction {
address: other.address,
vmctx: other.vmctx,
signature,
kind: other.arg_kind,
call_trampoline: None,
instance_allocator: None,
},
},
} }
} }
} }
@@ -158,9 +139,9 @@ macro_rules! impl_native_traits {
}; };
unsafe { unsafe {
wasmer_vm::wasmer_call_trampoline( wasmer_vm::wasmer_call_trampoline(
self.vmctx, self.vmctx(),
trampoline, trampoline,
self.address, self.address(),
args_rets.as_mut_ptr() as *mut u8, args_rets.as_mut_ptr() as *mut u8,
) )
}?; }?;
@@ -182,7 +163,7 @@ macro_rules! impl_native_traits {
// //
// let results = unsafe { // let results = unsafe {
// wasmer_vm::catch_traps_with_result(self.vmctx, || { // wasmer_vm::catch_traps_with_result(self.vmctx, || {
// let f = std::mem::transmute::<_, unsafe extern "C" fn( *mut VMContext, $( $x, )*) -> Rets::CStruct>(self.address); // let f = std::mem::transmute::<_, unsafe extern "C" fn( *mut VMContext, $( $x, )*) -> Rets::CStruct>(self.address());
// // We always pass the vmctx // // We always pass the vmctx
// f( self.vmctx, $( $x, )* ) // f( self.vmctx, $( $x, )* )
// }).map_err(RuntimeError::from_trap)? // }).map_err(RuntimeError::from_trap)?
@@ -193,12 +174,12 @@ macro_rules! impl_native_traits {
FunctionDefinition::Host(HostFunctionDefinition { FunctionDefinition::Host(HostFunctionDefinition {
has_env has_env
}) => { }) => {
match self.arg_kind { match self.arg_kind() {
VMFunctionKind::Static => { VMFunctionKind::Static => {
let results = catch_unwind(AssertUnwindSafe(|| unsafe { let results = catch_unwind(AssertUnwindSafe(|| unsafe {
let f = std::mem::transmute::<_, unsafe extern "C" fn( VMFunctionEnvironment, $( $x, )*) -> Rets::CStruct>(self.address); let f = std::mem::transmute::<_, unsafe extern "C" fn( VMFunctionEnvironment, $( $x, )*) -> Rets::CStruct>(self.address());
// We always pass the vmctx // We always pass the vmctx
f( self.vmctx, $( $x, )* ) f( self.vmctx(), $( $x, )* )
})).map_err(|e| RuntimeError::new(format!("{:?}", e)))?; })).map_err(|e| RuntimeError::new(format!("{:?}", e)))?;
Ok(Rets::from_c_struct(results)) Ok(Rets::from_c_struct(results))
}, },
@@ -207,13 +188,13 @@ macro_rules! impl_native_traits {
let results = if !has_env { let results = if !has_env {
type VMContextWithoutEnv = VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv>; type VMContextWithoutEnv = VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv>;
unsafe { unsafe {
let ctx = self.vmctx.host_env as *mut VMContextWithoutEnv; let ctx = self.vmctx().host_env as *mut VMContextWithoutEnv;
(*ctx).ctx.call(&params_list)? (*ctx).ctx.call(&params_list)?
} }
} else { } else {
type VMContextWithEnv = VMDynamicFunctionContext<VMDynamicFunctionWithEnv<std::ffi::c_void>>; type VMContextWithEnv = VMDynamicFunctionContext<VMDynamicFunctionWithEnv<std::ffi::c_void>>;
unsafe { unsafe {
let ctx = self.vmctx.host_env as *mut VMContextWithEnv; let ctx = self.vmctx().host_env as *mut VMContextWithEnv;
(*ctx).ctx.call(&params_list)? (*ctx).ctx.call(&params_list)?
} }
}; };

View File

@@ -933,6 +933,7 @@ impl Drop for InstanceAllocator {
// > "acquire" operation before deleting the object. // > "acquire" operation before deleting the object.
// //
// [1]: https://www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html // [1]: https://www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html
dbg!("Freeing instance allocator");
atomic::fence(atomic::Ordering::Acquire); atomic::fence(atomic::Ordering::Acquire);
// Now we can deallocate the instance. Note that we don't // Now we can deallocate the instance. Note that we don't