From d20f1a99f87d0477ada1a112a1d55d6ed47eadf9 Mon Sep 17 00:00:00 2001 From: Diego <96022404+dzfrias@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:41:47 -0700 Subject: [PATCH] LibWasm: Validate imports --- .../AbstractMachine/AbstractMachine.cpp | 48 ++++++++++++++++++- Userland/Libraries/LibWasm/Types.h | 5 ++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp index 0e7fc3bb431..68cad9c1449 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -155,7 +156,52 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector> elements; ModuleInstance auxiliary_instance; - // FIXME: Check that imports/extern match + module.for_each_section_of_type([&](ImportSection const& section) { + for (auto [i, import_] : enumerate(section.imports())) { + auto extern_ = externs.at(i); + auto is_valid = import_.description().visit( + [&](MemoryType const& mem_type) -> bool { + if (!extern_.has()) + return false; + auto other_mem_type = m_store.get(extern_.get())->type(); + return other_mem_type.limits().is_subset_of(mem_type.limits()); + }, + [&](TableType const& table_type) -> bool { + if (!extern_.has()) + return false; + auto other_table_type = m_store.get(extern_.get())->type(); + return table_type.element_type() == other_table_type.element_type() + && other_table_type.limits().is_subset_of(table_type.limits()); + }, + [&](GlobalType const& global_type) -> bool { + if (!extern_.has()) + return false; + auto other_global_type = m_store.get(extern_.get())->type(); + return global_type.type() == other_global_type.type() + && global_type.is_mutable() == other_global_type.is_mutable(); + }, + [&](FunctionType const& type) -> bool { + if (!extern_.has()) + return false; + auto other_type = m_store.get(extern_.get())->visit([&](WasmFunction const& wasm_func) { return wasm_func.type(); }, [&](HostFunction const& host_func) { return host_func.type(); }); + return type.results() == other_type.results() + && type.parameters() == other_type.parameters(); + }, + [&](TypeIndex type_index) -> bool { + if (!extern_.has()) + return false; + auto other_type = m_store.get(extern_.get())->visit([&](WasmFunction const& wasm_func) { return wasm_func.type(); }, [&](HostFunction const& host_func) { return host_func.type(); }); + auto& type = module.type(type_index); + return type.results() == other_type.results() + && type.parameters() == other_type.parameters(); + }); + if (!is_valid) + instantiation_result = InstantiationError { "Import and extern do not match" }; + } + }); + + if (instantiation_result.has_value()) + return instantiation_result.release_value(); for (auto& entry : externs) { if (auto* ptr = entry.get_pointer()) diff --git a/Userland/Libraries/LibWasm/Types.h b/Userland/Libraries/LibWasm/Types.h index 891fb5925d8..415dab55226 100644 --- a/Userland/Libraries/LibWasm/Types.h +++ b/Userland/Libraries/LibWasm/Types.h @@ -258,6 +258,11 @@ public: auto min() const { return m_min; } auto& max() const { return m_max; } + bool is_subset_of(Limits other) const + { + return m_min >= other.min() + && (!other.max().has_value() || (m_max.has_value() && *m_max <= *other.max())); + } static ParseResult parse(Stream& stream);