LibWeb: Make exported Wasm functions keep the module instance alive

As it's not uncommon for users to drop the module instance on the floor
after having grabbed the few exports they need to hold on to.
Fixes a few UAFs that show up as "invalid" accesses to
memory/tables/etc.
This commit is contained in:
Ali Mohammad Pur 2024-05-18 20:01:29 +02:00 committed by Andrew Kaster
parent 6d0aa7e64e
commit 8b1341c77e
Notes: sideshowbarker 2024-07-16 23:57:20 +09:00
3 changed files with 5 additions and 4 deletions

View file

@ -51,7 +51,7 @@ void Instance::initialize(JS::Realm& realm)
[&](Wasm::FunctionAddress const& address) {
Optional<JS::GCPtr<JS::FunctionObject>> object = m_function_instances.get(address);
if (!object.has_value()) {
object = Detail::create_native_function(vm, address, export_.name());
object = Detail::create_native_function(vm, address, export_.name(), this);
m_function_instances.set(address, *object);
}

View file

@ -342,7 +342,7 @@ JS::ThrowCompletionOr<NonnullRefPtr<CompiledWebAssemblyModule>> parse_module(JS:
return compiled_module;
}
JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress address, ByteString const& name)
JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress address, ByteString const& name, Instance* instance)
{
auto& realm = *vm.current_realm();
Optional<Wasm::FunctionType> type;
@ -354,7 +354,8 @@ JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress add
auto function = JS::NativeFunction::create(
realm,
name,
[address, type = type.release_value()](JS::VM& vm) -> JS::ThrowCompletionOr<JS::Value> {
[address, type = type.release_value(), instance](JS::VM& vm) -> JS::ThrowCompletionOr<JS::Value> {
(void)instance;
auto& realm = *vm.current_realm();
Vector<Wasm::Value> values;
values.ensure_capacity(type.parameters().size());

View file

@ -57,7 +57,7 @@ WebAssemblyCache& get_cache(JS::Realm&);
JS::ThrowCompletionOr<NonnullOwnPtr<Wasm::ModuleInstance>> instantiate_module(JS::VM&, Wasm::Module const&);
JS::ThrowCompletionOr<NonnullRefPtr<CompiledWebAssemblyModule>> parse_module(JS::VM&, JS::Object* buffer);
JS::NativeFunction* create_native_function(JS::VM&, Wasm::FunctionAddress address, ByteString const& name);
JS::NativeFunction* create_native_function(JS::VM&, Wasm::FunctionAddress address, ByteString const& name, Instance* instance = nullptr);
JS::ThrowCompletionOr<Wasm::Value> to_webassembly_value(JS::VM&, JS::Value value, Wasm::ValueType const& type);
JS::Value to_js_value(JS::VM&, Wasm::Value& wasm_value);