From 338653878d89afb5fab99d2e1aa8575aac21feea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Cabrera?= Date: Thu, 30 Nov 2023 15:53:39 -0500 Subject: [PATCH] winch: Tighten fuzzing criteria (#7621) This commit tightens the fuzzing criteria for Winch. The previous implementation only accounted for unsupported instructions. However, unsupported types can also cause the fuzzer to crash. Winch currently doesn't support `v128` and most of the `Ref` types. --- fuzz/fuzz_targets/differential.rs | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/fuzz/fuzz_targets/differential.rs b/fuzz/fuzz_targets/differential.rs index a884a8430c..6489237689 100644 --- a/fuzz/fuzz_targets/differential.rs +++ b/fuzz/fuzz_targets/differential.rs @@ -5,6 +5,7 @@ use libfuzzer_sys::fuzz_target; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; use std::sync::Once; +use wasmparser::ValType; use wasmtime_fuzzing::generators::CompilerStrategy; use wasmtime_fuzzing::generators::{Config, DiffValue, DiffValueType, SingleInstModule}; use wasmtime_fuzzing::oracles::diff_wasmtime::WasmtimeInstance; @@ -283,12 +284,28 @@ impl RuntimeStats { fn winch_supports_module(module: &[u8]) -> bool { use wasmparser::{Operator::*, Parser, Payload}; + fn is_type_supported(ty: &ValType) -> bool { + match ty { + ValType::V128 => false, + ValType::Ref(r) => r.is_func_ref(), + _ => true, + } + } + let mut supported = true; let mut parser = Parser::new(0).parse_all(module); 'main: while let Some(payload) = parser.next() { match payload.unwrap() { Payload::CodeSectionEntry(body) => { + let local_reader = body.get_locals_reader().unwrap(); + for local in local_reader { + let (_, ty) = local.unwrap(); + if !is_type_supported(&ty) { + supported = false; + break 'main; + } + } let op_reader = body.get_operators_reader().unwrap(); for op in op_reader { match op.unwrap() { @@ -419,6 +436,37 @@ fn winch_supports_module(module: &[u8]) -> bool { } } } + Payload::TypeSection(section) => { + for ty in section.into_iter_err_on_gc_types() { + if let Ok(t) = ty { + for p in t.params().iter().chain(t.results()) { + if !is_type_supported(p) { + supported = false; + break 'main; + } + } + } else { + supported = false; + break 'main; + } + } + } + Payload::GlobalSection(section) => { + for global in section { + if !is_type_supported(&global.unwrap().ty.content_type) { + supported = false; + break 'main; + } + } + } + Payload::TableSection(section) => { + for t in section { + if !t.unwrap().ty.element_type.is_func_ref() { + supported = false; + break 'main; + } + } + } _ => {} } }