mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 13:48:26 +00:00
Fix use-after free with NativeFunc
This commit is contained in:
4
lib/api/src/externals/function.rs
vendored
4
lib/api/src/externals/function.rs
vendored
@@ -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(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(¶ms_list)?
|
(*ctx).ctx.call(¶ms_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(¶ms_list)?
|
(*ctx).ctx.call(¶ms_list)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user