Update wasmi used in differential fuzzing (#5104)

* Update `wasmi` used in differential fuzzing

Closes #4818
Closes #5102

* Add audits
This commit is contained in:
Alex Crichton
2022-10-24 11:41:40 -05:00
committed by GitHub
parent 37c3342374
commit 95f02eb67d
6 changed files with 163 additions and 134 deletions

90
Cargo.lock generated
View File

@@ -1450,6 +1450,12 @@ dependencies = [
"serde",
]
[[package]]
name = "indexmap-nostd"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590"
[[package]]
name = "indicatif"
version = "0.13.0"
@@ -1612,7 +1618,7 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin",
"spin 0.5.2",
]
[[package]]
@@ -1740,9 +1746,9 @@ dependencies = [
[[package]]
name = "memory_units"
version = "0.3.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
[[package]]
name = "miette"
@@ -1816,17 +1822,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-bigint"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
dependencies = [
"autocfg 1.1.0",
"num-integer",
"num-traits",
]
[[package]]
name = "num-bigint-dig"
version = "0.7.0"
@@ -1867,18 +1862,6 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg 1.1.0",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
@@ -2029,12 +2012,6 @@ dependencies = [
"sha2 0.9.9",
]
[[package]]
name = "parity-wasm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92"
[[package]]
name = "parking_lot"
version = "0.11.2"
@@ -2716,6 +2693,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
[[package]]
name = "spki"
version = "0.4.1"
@@ -3318,26 +3301,32 @@ dependencies = [
[[package]]
name = "wasmi"
version = "0.11.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a3cb58f98e4d6c944af18c2c9002f22d0b928dfbb8b6c2b7d78a8573a5216bf"
checksum = "7428e8361e19d3affa9221ad674014b4a29381b07c755aab9b1cd4f74610221a"
dependencies = [
"spin 0.9.4",
"wasmi_arena",
"wasmi_core",
"wasmparser-nostd",
]
[[package]]
name = "wasmi_arena"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ea379cbb0b41f3a9f0bf7b47036d036aae7f43383d8cc487d4deccf40dee0a"
[[package]]
name = "wasmi_core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c9559a70c22f27793520b9e098baea45915088fb5093dd7041fcfe238b95d4e"
dependencies = [
"downcast-rs",
"libm",
"memory_units",
"num-rational",
"num-traits",
"parity-wasm",
"wasmi-validation",
]
[[package]]
name = "wasmi-validation"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "165343ecd6c018fc09ebcae280752702c9a2ef3e6f8d02f1cfcbdb53ef6d7937"
dependencies = [
"parity-wasm",
]
[[package]]
@@ -3349,6 +3338,15 @@ dependencies = [
"indexmap",
]
[[package]]
name = "wasmparser-nostd"
version = "0.91.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c37f310b5a62bfd5ae7c0f1d8e6f98af16a5d6d84ba764e9c36439ec14e318b"
dependencies = [
"indexmap-nostd",
]
[[package]]
name = "wasmprinter"
version = "0.2.41"

View File

@@ -25,7 +25,7 @@ wasm-encoder = { workspace = true }
wasm-smith = { workspace = true }
wasm-mutate = { workspace = true }
wasm-spec-interpreter = { path = "./wasm-spec-interpreter", optional = true }
wasmi = "0.11.0"
wasmi = "0.19.0"
# We rely on precompiled v8 binaries, but rusty-v8 doesn't have a precompiled
# binary for MinGW which is built on our CI. It does have one for Windows-msvc,

View File

@@ -6,16 +6,15 @@ use anyhow::{Context, Error, Result};
use wasmtime::{Trap, TrapCode};
/// A wrapper for `wasmi` as a [`DiffEngine`].
pub struct WasmiEngine;
pub struct WasmiEngine {
engine: wasmi::Engine,
}
impl WasmiEngine {
pub(crate) fn new(config: &mut Config) -> Self {
let config = &mut config.module_config.config;
config.reference_types_enabled = false;
config.simd_enabled = false;
config.multi_value_enabled = false;
config.saturating_float_to_int_enabled = false;
config.sign_extension_enabled = false;
config.memory64_enabled = false;
config.bulk_memory_enabled = false;
config.threads_enabled = false;
@@ -24,7 +23,9 @@ impl WasmiEngine {
config.max_tables = config.max_tables.min(1);
config.min_tables = config.min_tables.min(1);
Self
Self {
engine: wasmi::Engine::default(),
}
}
}
@@ -34,11 +35,14 @@ impl DiffEngine for WasmiEngine {
}
fn instantiate(&mut self, wasm: &[u8]) -> Result<Box<dyn DiffInstance>> {
let module = wasmi::Module::from_buffer(wasm).context("unable to validate Wasm module")?;
let instance = wasmi::ModuleInstance::new(&module, &wasmi::ImportsBuilder::default())
let module =
wasmi::Module::new(&self.engine, wasm).context("unable to validate Wasm module")?;
let mut store = wasmi::Store::new(&self.engine, ());
let instance = wasmi::Linker::<()>::new()
.instantiate(&mut store, &module)
.and_then(|i| i.start(&mut store))
.context("unable to instantiate module in wasmi")?;
let instance = instance.run_start(&mut wasmi::NopExternals)?;
Ok(Box::new(WasmiInstance { module, instance }))
Ok(Box::new(WasmiInstance { store, instance }))
}
fn assert_error_match(&self, trap: &Trap, err: &Error) {
@@ -69,38 +73,38 @@ impl DiffEngine for WasmiEngine {
Some(other) => panic!("unexpected wasmi error: {}", other),
None => err
.downcast_ref::<wasmi::Trap>()
.downcast_ref::<wasmi::core::Trap>()
.expect(&format!("not a trap: {:?}", err)),
};
match wasmi.kind() {
wasmi::TrapKind::StackOverflow => {
match wasmi.as_code() {
Some(wasmi::core::TrapCode::StackOverflow) => {
assert_eq!(trap.trap_code(), Some(TrapCode::StackOverflow))
}
wasmi::TrapKind::MemoryAccessOutOfBounds => {
Some(wasmi::core::TrapCode::MemoryAccessOutOfBounds) => {
assert_eq!(trap.trap_code(), Some(TrapCode::MemoryOutOfBounds))
}
wasmi::TrapKind::Unreachable => {
Some(wasmi::core::TrapCode::Unreachable) => {
assert_eq!(trap.trap_code(), Some(TrapCode::UnreachableCodeReached))
}
wasmi::TrapKind::TableAccessOutOfBounds => {
Some(wasmi::core::TrapCode::TableAccessOutOfBounds) => {
assert_eq!(trap.trap_code(), Some(TrapCode::TableOutOfBounds))
}
wasmi::TrapKind::ElemUninitialized => {
Some(wasmi::core::TrapCode::ElemUninitialized) => {
assert_eq!(trap.trap_code(), Some(TrapCode::IndirectCallToNull))
}
wasmi::TrapKind::DivisionByZero => {
Some(wasmi::core::TrapCode::DivisionByZero) => {
assert_eq!(trap.trap_code(), Some(TrapCode::IntegerDivisionByZero))
}
wasmi::TrapKind::IntegerOverflow => {
Some(wasmi::core::TrapCode::IntegerOverflow) => {
assert_eq!(trap.trap_code(), Some(TrapCode::IntegerOverflow))
}
wasmi::TrapKind::InvalidConversionToInt => {
Some(wasmi::core::TrapCode::InvalidConversionToInt) => {
assert_eq!(trap.trap_code(), Some(TrapCode::BadConversionToInteger))
}
wasmi::TrapKind::UnexpectedSignature => {
Some(wasmi::core::TrapCode::UnexpectedSignature) => {
assert_eq!(trap.trap_code(), Some(TrapCode::BadSignature))
}
wasmi::TrapKind::Host(_) => unreachable!(),
None => unreachable!(),
}
}
@@ -108,13 +112,13 @@ impl DiffEngine for WasmiEngine {
let trap = match err.downcast_ref::<wasmi::Error>() {
Some(wasmi::Error::Trap(trap)) => trap,
Some(_) => return false,
None => match err.downcast_ref::<wasmi::Trap>() {
None => match err.downcast_ref::<wasmi::core::Trap>() {
Some(trap) => trap,
None => return false,
},
};
match trap.kind() {
wasmi::TrapKind::StackOverflow => true,
match trap.as_code() {
Some(wasmi::core::TrapCode::StackOverflow) => true,
_ => false,
}
}
@@ -122,9 +126,8 @@ impl DiffEngine for WasmiEngine {
/// A wrapper for `wasmi` Wasm instances.
struct WasmiInstance {
#[allow(dead_code)] // reason = "the module must live as long as its reference"
module: wasmi::Module,
instance: wasmi::ModuleRef,
store: wasmi::Store<()>,
instance: wasmi::Instance,
}
impl DiffInstance for WasmiInstance {
@@ -136,57 +139,48 @@ impl DiffInstance for WasmiInstance {
&mut self,
function_name: &str,
arguments: &[DiffValue],
_results: &[DiffValueType],
result_tys: &[DiffValueType],
) -> Result<Option<Vec<DiffValue>>> {
let arguments: Vec<_> = arguments.iter().map(wasmi::RuntimeValue::from).collect();
let export = self
let function = match self
.instance
.export_by_name(function_name)
.context(format!(
"unable to find function '{}' in wasmi instance",
function_name
))?;
let function = export.as_func().context("wasmi export is not a function")?;
let result = wasmi::FuncInstance::invoke(&function, &arguments, &mut wasmi::NopExternals)
.context("failed while invoking function in wasmi")?;
Ok(Some(if let Some(result) = result {
vec![result.into()]
} else {
vec![]
}))
.get_export(&self.store, function_name)
.unwrap()
{
wasmi::Extern::Func(f) => f,
_ => unreachable!(),
};
let arguments: Vec<_> = arguments.iter().map(|x| x.into()).collect();
let mut results = vec![wasmi::core::Value::I32(0); result_tys.len()];
function
.call(&mut self.store, &arguments, &mut results)
.context("wasmi function trap")?;
Ok(Some(results.into_iter().map(|x| x.into()).collect()))
}
fn get_global(&mut self, name: &str, _ty: DiffValueType) -> Option<DiffValue> {
match self.instance.export_by_name(name) {
Some(wasmi::ExternVal::Global(g)) => Some(g.get().into()),
match self.instance.get_export(&self.store, name).unwrap() {
wasmi::Extern::Global(g) => Some(g.get(&self.store).into()),
_ => unreachable!(),
}
}
fn get_memory(&mut self, name: &str, shared: bool) -> Option<Vec<u8>> {
assert!(!shared);
match self.instance.export_by_name(name) {
Some(wasmi::ExternVal::Memory(m)) => {
// `wasmi` memory may be stored non-contiguously; copy
// it out to a contiguous chunk.
let mut buffer: Vec<u8> = vec![0; m.current_size().0 * 65536];
m.get_into(0, &mut buffer[..])
.expect("can access wasmi memory");
Some(buffer)
}
match self.instance.get_export(&self.store, name).unwrap() {
wasmi::Extern::Memory(m) => Some(m.data(&self.store).to_vec()),
_ => unreachable!(),
}
}
}
impl From<&DiffValue> for wasmi::RuntimeValue {
impl From<&DiffValue> for wasmi::core::Value {
fn from(v: &DiffValue) -> Self {
use wasmi::RuntimeValue::*;
use wasmi::core::Value::*;
match *v {
DiffValue::I32(n) => I32(n),
DiffValue::I64(n) => I64(n),
DiffValue::F32(n) => F32(wasmi::nan_preserving_float::F32::from_bits(n)),
DiffValue::F64(n) => F64(wasmi::nan_preserving_float::F64::from_bits(n)),
DiffValue::F32(n) => F32(wasmi::core::F32::from_bits(n)),
DiffValue::F64(n) => F64(wasmi::core::F64::from_bits(n)),
DiffValue::V128(_) | DiffValue::FuncRef { .. } | DiffValue::ExternRef { .. } => {
unimplemented!()
}
@@ -194,9 +188,9 @@ impl From<&DiffValue> for wasmi::RuntimeValue {
}
}
impl Into<DiffValue> for wasmi::RuntimeValue {
impl Into<DiffValue> for wasmi::core::Value {
fn into(self) -> DiffValue {
use wasmi::RuntimeValue::*;
use wasmi::core::Value::*;
match self {
I32(n) => DiffValue::I32(n),
I64(n) => DiffValue::I64(n),

View File

@@ -176,6 +176,16 @@ criteria = "safe-to-deploy"
version = "2.2.1"
notes = "I am the author of this crate."
[[audits.indexmap-nostd]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-run"
version = "0.4.0"
notes = """
I've verified that this is a sliced-down version of the `indexmap` crate which
is otherwise certified. This doesn't contain unnecessary `unsafe` and
additionally doesn't reach for ambient capabilities.
"""
[[audits.is-terminal]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
@@ -220,6 +230,15 @@ Contains unsafe blocks but are encapsulated and required for the operation at
hand.
"""
[[audits.memory_units]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-run"
delta = "0.3.0 -> 0.4.0"
notes = """
This bump only changed from a function to an associated `const` and trivially
contains no significant changes.
"""
[[audits.peeking_take_while]]
who = "Nick Fitzgerald <fitzgen@gmail.com>"
criteria = "safe-to-deploy"
@@ -256,6 +275,18 @@ criteria = "safe-to-deploy"
delta = "0.9.9 -> 0.10.2"
notes = "This upgrade is mostly a code refactor, as far as I can tell. No new uses of unsafe nor any new ambient capabilities usage."
[[audits.spin]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-run"
version = "0.9.4"
notes = """
I've verified the contents of this crate and that while they contain `unsafe`
it's exclusively around implementing atomic primitive where some `unsafe` is to
be expected. Otherwise this crate does not unduly access ambient capabilities
and does what it says on the tin, providing spin-based synchronization
primitives.
"""
[[audits.system-interface]]
who = "Dan Gohman <dev@sunfishcode.online>"
criteria = "safe-to-deploy"
@@ -352,6 +383,27 @@ criteria = "safe-to-deploy"
version = "0.11.6"
notes = "The Bytecode Alliance is the author of this crate."
[[audits.wasmi_arena]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-run"
version = "0.1.0"
notes = """
This crate contains no `unsafe` code and doesn't reach in unnecessarily to the
standard library or anything like that. This only contains a few data structures
used by `wasmi` and various idiomatic Rust trait implementations.
"""
[[audits.wasmi_core]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-run"
version = "0.4.0"
notes = """
This crate contains no `unsafe` code and otherwise is only the bits and bobs for
the internals of a wasm implementation. Reading over this crate there is no
unexpected usage of the filesystem or things like that and otherwise is mostly
plumbing for all the integer operations in core wasm.
"""
[[audits.wasmparser]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"
@@ -388,6 +440,17 @@ criteria = "safe-to-deploy"
version = "0.92.0"
notes = "The Bytecode Alliance is the author of this crate."
[[audits.wasmparser-nostd]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-run"
version = "0.91.0"
notes = """
I have certified that this crate is a one-to-one fork of `wasmparser` with
updates exclusively for the usage on targets without the standard library.
This crate is otherwise primarily authored by the Bytecode Alliance and
otherwise certified.
"""
[[audits.wasmprinter]]
who = "Alex Crichton <alex@alexcrichton.com>"
criteria = "safe-to-deploy"

View File

@@ -578,10 +578,6 @@ criteria = "safe-to-deploy"
version = "0.9.0"
criteria = "safe-to-deploy"
[[exemptions.parity-wasm]]
version = "0.42.2"
criteria = "safe-to-run"
[[exemptions.parking_lot]]
version = "0.11.2"
criteria = "safe-to-deploy"
@@ -1031,11 +1027,7 @@ version = "0.2.80"
criteria = "safe-to-run"
[[exemptions.wasmi]]
version = "0.11.0"
criteria = "safe-to-run"
[[exemptions.wasmi-validation]]
version = "0.4.1"
version = "0.19.0"
criteria = "safe-to-run"
[[exemptions.web-sys]]

View File

@@ -200,18 +200,6 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.5.4 -> 0.5.7"
[[audits.mozilla.audits.num-bigint]]
who = "Josh Stone <jistone@redhat.com>"
criteria = "safe-to-deploy"
version = "0.2.6"
notes = "All code written or reviewed by Josh Stone."
[[audits.mozilla.audits.num-bigint]]
who = "Josh Stone <jistone@redhat.com>"
criteria = "safe-to-deploy"
version = "0.4.3"
notes = "All code written or reviewed by Josh Stone."
[[audits.mozilla.audits.num-integer]]
who = "Josh Stone <jistone@redhat.com>"
criteria = "safe-to-deploy"
@@ -224,12 +212,6 @@ criteria = "safe-to-deploy"
version = "0.1.43"
notes = "All code written or reviewed by Josh Stone."
[[audits.mozilla.audits.num-rational]]
who = "Josh Stone <jistone@redhat.com>"
criteria = "safe-to-deploy"
version = "0.4.1"
notes = "All code written or reviewed by Josh Stone."
[[audits.mozilla.audits.num-traits]]
who = "Josh Stone <jistone@redhat.com>"
criteria = "safe-to-deploy"