mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-13 04:46:04 +00:00
Merge #1128
1128: fix(runtime-core) Avoid crashing when missing host functions are allowed r=Hywan a=Hywan Fix #1118. #1121 can be merged after This PR fixes 2 things: * When droping the import backing, check that `vm::FuncCtx` isn't null before dropping it, * Use an `always_trap` as a placeholder host function when a host function is missing. Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
This commit is contained in:
commit
be29b2e007
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
|
||||||
|
- [#1128](https://github.com/wasmerio/wasmer/pull/1128) Fix a crash when a host function is missing and the `allow_missing_functions` flag is enabled
|
||||||
- [#1097](https://github.com/wasmerio/wasmer/pull/1097) Move inline breakpoint outside of runtime backend
|
- [#1097](https://github.com/wasmerio/wasmer/pull/1097) Move inline breakpoint outside of runtime backend
|
||||||
- [#1095](https://github.com/wasmerio/wasmer/pull/1095) Update to cranelift 0.52.
|
- [#1095](https://github.com/wasmerio/wasmer/pull/1095) Update to cranelift 0.52.
|
||||||
- [#1092](https://github.com/wasmerio/wasmer/pull/1092) Add `get_utf8_string_with_nul` to `WasmPtr` to read nul-terminated strings from memory.
|
- [#1092](https://github.com/wasmerio/wasmer/pull/1092) Add `get_utf8_string_with_nul` to `WasmPtr` to read nul-terminated strings from memory.
|
||||||
|
@ -8,6 +8,7 @@ use crate::{
|
|||||||
sig_registry::SigRegistry,
|
sig_registry::SigRegistry,
|
||||||
structures::{BoxedMap, Map, SliceMap, TypedIndex},
|
structures::{BoxedMap, Map, SliceMap, TypedIndex},
|
||||||
table::Table,
|
table::Table,
|
||||||
|
typed_func::{always_trap, Func},
|
||||||
types::{
|
types::{
|
||||||
ImportedFuncIndex, ImportedGlobalIndex, ImportedMemoryIndex, ImportedTableIndex,
|
ImportedFuncIndex, ImportedGlobalIndex, ImportedMemoryIndex, ImportedTableIndex,
|
||||||
Initializer, LocalFuncIndex, LocalGlobalIndex, LocalMemoryIndex, LocalOrImport,
|
Initializer, LocalFuncIndex, LocalGlobalIndex, LocalMemoryIndex, LocalOrImport,
|
||||||
@ -15,11 +16,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{fmt::Debug, ptr::NonNull, slice};
|
||||||
fmt::Debug,
|
|
||||||
ptr::{self, NonNull},
|
|
||||||
slice,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Size of the array for internal instance usage
|
/// Size of the array for internal instance usage
|
||||||
pub const INTERNALS_SIZE: usize = 256;
|
pub const INTERNALS_SIZE: usize = 256;
|
||||||
@ -563,7 +560,11 @@ impl Drop for ImportBacking {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Properly drop the `vm::FuncCtx` in `vm::ImportedFunc`.
|
// Properly drop the `vm::FuncCtx` in `vm::ImportedFunc`.
|
||||||
for (_imported_func_index, imported_func) in (*self.vm_functions).iter_mut() {
|
for (_imported_func_index, imported_func) in (*self.vm_functions).iter_mut() {
|
||||||
let _: Box<vm::FuncCtx> = unsafe { Box::from_raw(imported_func.func_ctx.as_ptr()) };
|
let func_ctx_ptr = imported_func.func_ctx.as_ptr();
|
||||||
|
|
||||||
|
if !func_ctx_ptr.is_null() {
|
||||||
|
let _: Box<vm::FuncCtx> = unsafe { Box::from_raw(func_ctx_ptr) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -650,9 +651,18 @@ fn import_functions(
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if imports.allow_missing_functions {
|
if imports.allow_missing_functions {
|
||||||
|
let always_trap = Func::new(always_trap);
|
||||||
|
|
||||||
functions.push(vm::ImportedFunc {
|
functions.push(vm::ImportedFunc {
|
||||||
func: ptr::null(),
|
func: always_trap.get_vm_func().as_ptr(),
|
||||||
func_ctx: unsafe { NonNull::new_unchecked(ptr::null_mut()) }, // TODO: Non-sense…
|
func_ctx: NonNull::new(Box::into_raw(Box::new(vm::FuncCtx {
|
||||||
|
// ^^^^^^^^ `vm::FuncCtx` is purposely leaked.
|
||||||
|
// It is dropped by the specific `Drop`
|
||||||
|
// implementation of `ImportBacking`.
|
||||||
|
vmctx: NonNull::new(vmctx).expect("`vmctx` must not be null."),
|
||||||
|
func_env: None,
|
||||||
|
})))
|
||||||
|
.unwrap(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
link_errors.push(LinkError::ImportNotFound {
|
link_errors.push(LinkError::ImportNotFound {
|
||||||
|
@ -258,11 +258,6 @@ where
|
|||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying func pointer.
|
|
||||||
pub fn get_vm_func(&self) -> NonNull<vm::Func> {
|
|
||||||
self.func
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Args, Rets> Func<'a, Args, Rets, Host>
|
impl<'a, Args, Rets> Func<'a, Args, Rets, Host>
|
||||||
@ -303,6 +298,11 @@ where
|
|||||||
pub fn returns(&self) -> &'static [Type] {
|
pub fn returns(&self) -> &'static [Type] {
|
||||||
Rets::types()
|
Rets::types()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the underlying func pointer.
|
||||||
|
pub fn get_vm_func(&self) -> NonNull<vm::Func> {
|
||||||
|
self.func
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WasmTypeList for Infallible {
|
impl WasmTypeList for Infallible {
|
||||||
@ -733,6 +733,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Function that always fails. It can be used as a placeholder when a
|
||||||
|
/// host function is missing for instance.
|
||||||
|
pub(crate) fn always_trap() -> Result<(), &'static str> {
|
||||||
|
Err("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -30,9 +30,9 @@ fn error_propagation() {
|
|||||||
|
|
||||||
let instance = module
|
let instance = module
|
||||||
.instantiate(&imports! {
|
.instantiate(&imports! {
|
||||||
"env" => {
|
"env" => {
|
||||||
"ret_err" => Func::new(ret_err),
|
"ret_err" => Func::new(ret_err),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user