Pārlūkot izejas kodu

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.
Ali Mohammad Pur 1 gadu atpakaļ
vecāks
revīzija
8b1341c77e

+ 1 - 1
Userland/Libraries/LibWeb/WebAssembly/Instance.cpp

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

+ 3 - 2
Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp

@@ -342,7 +342,7 @@ JS::ThrowCompletionOr<NonnullRefPtr<CompiledWebAssemblyModule>> parse_module(JS:
     return compiled_module;
     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();
     auto& realm = *vm.current_realm();
     Optional<Wasm::FunctionType> type;
     Optional<Wasm::FunctionType> type;
@@ -354,7 +354,8 @@ JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress add
     auto function = JS::NativeFunction::create(
     auto function = JS::NativeFunction::create(
         realm,
         realm,
         name,
         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();
             auto& realm = *vm.current_realm();
             Vector<Wasm::Value> values;
             Vector<Wasm::Value> values;
             values.ensure_capacity(type.parameters().size());
             values.ensure_capacity(type.parameters().size());

+ 1 - 1
Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h

@@ -57,7 +57,7 @@ WebAssemblyCache& get_cache(JS::Realm&);
 
 
 JS::ThrowCompletionOr<NonnullOwnPtr<Wasm::ModuleInstance>> instantiate_module(JS::VM&, Wasm::Module const&);
 JS::ThrowCompletionOr<NonnullOwnPtr<Wasm::ModuleInstance>> instantiate_module(JS::VM&, Wasm::Module const&);
 JS::ThrowCompletionOr<NonnullRefPtr<CompiledWebAssemblyModule>> parse_module(JS::VM&, JS::Object* buffer);
 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::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);
 JS::Value to_js_value(JS::VM&, Wasm::Value& wasm_value);