[JSC] JSWebAssemblyGlobal creation should have exception check
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Dec 2019 21:50:59 +0000 (21:50 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Dec 2019 21:50:59 +0000 (21:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204857
<rdar://problem/57618579>

Reviewed by Mark Lam.

JSTests:

* wasm/regress/wasm-global-creation-can-throw-an-exception.js: Added.

Source/JavaScriptCore:

Each WebAssembly cells have a path throwing an exception if WebAssembly is disabled. We lack exception checking after calling JSWebAssemblyGlobal::create
in WebAssemblyModuleRecord linking phase. While exception is never thrown in this place since this happens only when WebAssembly is enabled, we should put
`scope.assertNoException()` to satisfy exception verifier requirement. We also rename factory function of Wasm cells from "create" to "tryCreate" since it
can fail potentially.

* wasm/js/JSWebAssembly.cpp:
(JSC::instantiate):
* wasm/js/JSWebAssemblyGlobal.cpp:
(JSC::JSWebAssemblyGlobal::tryCreate):
(JSC::JSWebAssemblyGlobal::create): Deleted.
* wasm/js/JSWebAssemblyGlobal.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::tryCreate):
(JSC::JSWebAssemblyInstance::create): Deleted.
* wasm/js/JSWebAssemblyInstance.h:
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::tryCreate):
(JSC::JSWebAssemblyMemory::create): Deleted.
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::tryCreate):
(JSC::JSWebAssemblyTable::create): Deleted.
* wasm/js/JSWebAssemblyTable.h:
* wasm/js/WebAssemblyGlobalConstructor.cpp:
(JSC::constructJSWebAssemblyGlobal):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253121 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
JSTests/ChangeLog
JSTests/wasm/regress/wasm-global-creation-can-throw-an-exception.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyGlobal.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyGlobal.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h
Source/JavaScriptCore/wasm/js/WebAssemblyGlobalConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp

index f677b1a..5c9de8c 100644 (file)
@@ -1,5 +1,15 @@
 2019-12-04  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        [JSC] JSWebAssemblyGlobal creation should have exception check
+        https://bugs.webkit.org/show_bug.cgi?id=204857
+        <rdar://problem/57618579>
+
+        Reviewed by Mark Lam.
+
+        * wasm/regress/wasm-global-creation-can-throw-an-exception.js: Added.
+
+2019-12-04  Yusuke Suzuki  <ysuzuki@apple.com>
+
         [JSC] Update Wasm spec-tests
         https://bugs.webkit.org/show_bug.cgi?id=204844
 
diff --git a/JSTests/wasm/regress/wasm-global-creation-can-throw-an-exception.js b/JSTests/wasm/regress/wasm-global-creation-can-throw-an-exception.js
new file mode 100644 (file)
index 0000000..80ed400
--- /dev/null
@@ -0,0 +1,3 @@
+let wasmCode = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 7, 1, 96, 2, 126, 127, 1, 127, 3, 2, 1, 0, 4, 4, 1, 112, 0, 4, 6, 46, 5, 127, 0, 65, 42, 11, 125, 0, 67, 116, 0, 0, 77, 11, 124, 0, 68, 131, 136, 136, 0, 0, 0, 255, 255, 11, 125, 0, 67, 0, 0, 9, 127, 11, 124, 0, 68, 0, 60, 0, 0, 0, 0, 248, 127, 11, 7, 64, 7, 5, 116, 97, 98, 63, 69, 1, 0, 3, 125, 117, 109, 0, 0, 6, 97, 61, 34, 0, 13, 114, 3, 0, 7, 79, 124, 82, 37, 101, 32, 49, 3, 1, 7, 65, 65, 65, 65, 65, 65, 65, 3, 2, 7, 97, 110, 115, 119, 101, 114, 60, 3, 3, 7, 97, 110, 115, 119, 101, 114, 52, 3, 4, 9, 7, 1, 0, 65, 0, 11, 1, 0, 10, 9, 1, 7, 0, 32, 1, 0, 1, 0, 11]);
+let wasmModule = new WebAssembly.Module(wasmCode);
+new WebAssembly.Instance(wasmModule, {});
index 4bbffc4..eba3bfd 100644 (file)
@@ -1,5 +1,47 @@
 2019-12-04  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        [JSC] JSWebAssemblyGlobal creation should have exception check
+        https://bugs.webkit.org/show_bug.cgi?id=204857
+        <rdar://problem/57618579>
+
+        Reviewed by Mark Lam.
+
+        Each WebAssembly cells have a path throwing an exception if WebAssembly is disabled. We lack exception checking after calling JSWebAssemblyGlobal::create
+        in WebAssemblyModuleRecord linking phase. While exception is never thrown in this place since this happens only when WebAssembly is enabled, we should put
+        `scope.assertNoException()` to satisfy exception verifier requirement. We also rename factory function of Wasm cells from "create" to "tryCreate" since it
+        can fail potentially.
+
+        * wasm/js/JSWebAssembly.cpp:
+        (JSC::instantiate):
+        * wasm/js/JSWebAssemblyGlobal.cpp:
+        (JSC::JSWebAssemblyGlobal::tryCreate):
+        (JSC::JSWebAssemblyGlobal::create): Deleted.
+        * wasm/js/JSWebAssemblyGlobal.h:
+        * wasm/js/JSWebAssemblyInstance.cpp:
+        (JSC::JSWebAssemblyInstance::tryCreate):
+        (JSC::JSWebAssemblyInstance::create): Deleted.
+        * wasm/js/JSWebAssemblyInstance.h:
+        * wasm/js/JSWebAssemblyMemory.cpp:
+        (JSC::JSWebAssemblyMemory::tryCreate):
+        (JSC::JSWebAssemblyMemory::create): Deleted.
+        * wasm/js/JSWebAssemblyMemory.h:
+        * wasm/js/JSWebAssemblyTable.cpp:
+        (JSC::JSWebAssemblyTable::tryCreate):
+        (JSC::JSWebAssemblyTable::create): Deleted.
+        * wasm/js/JSWebAssemblyTable.h:
+        * wasm/js/WebAssemblyGlobalConstructor.cpp:
+        (JSC::constructJSWebAssemblyGlobal):
+        * wasm/js/WebAssemblyInstanceConstructor.cpp:
+        (JSC::constructJSWebAssemblyInstance):
+        * wasm/js/WebAssemblyMemoryConstructor.cpp:
+        (JSC::constructJSWebAssemblyMemory):
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+        * wasm/js/WebAssemblyTableConstructor.cpp:
+        (JSC::constructJSWebAssemblyTable):
+
+2019-12-04  Yusuke Suzuki  <ysuzuki@apple.com>
+
         [JSC] Put more cells into IsoSubspace
         https://bugs.webkit.org/show_bug.cgi?id=204845
 
index 44b734e..fc4158f 100644 (file)
@@ -214,7 +214,7 @@ static void instantiate(VM& vm, JSGlobalObject* globalObject, JSPromise* promise
 {
     auto scope = DECLARE_CATCH_SCOPE(vm);
     // In order to avoid potentially recompiling a module. We first gather all the import/memory information prior to compiling code.
-    JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, globalObject, moduleKey, module, importObject, globalObject->webAssemblyInstanceStructure(), Ref<Wasm::Module>(module->module()), creationMode);
+    JSWebAssemblyInstance* instance = JSWebAssemblyInstance::tryCreate(vm, globalObject, moduleKey, module, importObject, globalObject->webAssemblyInstanceStructure(), Ref<Wasm::Module>(module->module()), creationMode);
     RETURN_IF_EXCEPTION(scope, reject(globalObject, scope, promise));
 
     Vector<Strong<JSCell>> dependencies;
index 1a5d964..20eaed0 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
 
 const ClassInfo JSWebAssemblyGlobal::s_info = { "WebAssembly.Global", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyGlobal) };
 
-JSWebAssemblyGlobal* JSWebAssemblyGlobal::create(JSGlobalObject* globalObject, VM& vm, Structure* structure, Ref<Wasm::Global>&& global)
+JSWebAssemblyGlobal* JSWebAssemblyGlobal::tryCreate(JSGlobalObject* globalObject, VM& vm, Structure* structure, Ref<Wasm::Global>&& global)
 {
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
index 435ad85..e6d0f09 100644 (file)
@@ -49,7 +49,7 @@ public:
         return vm.webAssemblyGlobalSpace<mode>();
     }
 
-    static JSWebAssemblyGlobal* create(JSGlobalObject*, VM&, Structure*, Ref<Wasm::Global>&&);
+    static JSWebAssemblyGlobal* tryCreate(JSGlobalObject*, VM&, Structure*, Ref<Wasm::Global>&&);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
     DECLARE_INFO;
index 919cbe8..fadf515 100644 (file)
@@ -157,7 +157,7 @@ Identifier JSWebAssemblyInstance::createPrivateModuleKey()
     return Identifier::fromUid(PrivateName(PrivateName::Description, "WebAssemblyInstance"));
 }
 
-JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, JSGlobalObject* globalObject, const Identifier& moduleKey, JSWebAssemblyModule* jsModule, JSObject* importObject, Structure* instanceStructure, Ref<Wasm::Module>&& module, Wasm::CreationMode creationMode)
+JSWebAssemblyInstance* JSWebAssemblyInstance::tryCreate(VM& vm, JSGlobalObject* globalObject, const Identifier& moduleKey, JSWebAssemblyModule* jsModule, JSObject* importObject, Structure* instanceStructure, Ref<Wasm::Module>&& module, Wasm::CreationMode creationMode)
 {
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
@@ -290,7 +290,7 @@ JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, JSGlobalObject* glo
             // We create a memory when it's a memory definition.
             RELEASE_ASSERT(!moduleInformation.memory.isImport());
 
-            auto* jsMemory = JSWebAssemblyMemory::create(globalObject, vm, globalObject->webAssemblyMemoryStructure());
+            auto* jsMemory = JSWebAssemblyMemory::tryCreate(globalObject, vm, globalObject->webAssemblyMemoryStructure());
             RETURN_IF_EXCEPTION(throwScope, nullptr);
 
             RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(moduleInformation.memory.initial(), moduleInformation.memory.maximum(),
@@ -308,7 +308,8 @@ JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, JSGlobalObject* glo
     
     if (!jsInstance->memory()) {
         // Make sure we have a dummy memory, so that wasm -> wasm thunks avoid checking for a nullptr Memory when trying to set pinned registers.
-        auto* jsMemory = JSWebAssemblyMemory::create(globalObject, vm, globalObject->webAssemblyMemoryStructure());
+        auto* jsMemory = JSWebAssemblyMemory::tryCreate(globalObject, vm, globalObject->webAssemblyMemoryStructure());
+        RETURN_IF_EXCEPTION(throwScope, nullptr);
         jsMemory->adopt(Wasm::Memory::create());
         jsInstance->setMemory(vm, jsMemory);
         RETURN_IF_EXCEPTION(throwScope, nullptr);
index f78a621..b2cc2af 100644 (file)
@@ -59,7 +59,7 @@ public:
 
     static Identifier createPrivateModuleKey();
 
-    static JSWebAssemblyInstance* create(VM&, JSGlobalObject*, const Identifier& moduleKey, JSWebAssemblyModule*, JSObject* importObject, Structure*, Ref<Wasm::Module>&&, Wasm::CreationMode);
+    static JSWebAssemblyInstance* tryCreate(VM&, JSGlobalObject*, const Identifier& moduleKey, JSWebAssemblyModule*, JSObject* importObject, Structure*, Ref<Wasm::Module>&&, Wasm::CreationMode);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
     DECLARE_EXPORT_INFO;
index 64f420b..3f8be36 100644 (file)
@@ -37,7 +37,7 @@ namespace JSC {
 
 const ClassInfo JSWebAssemblyMemory::s_info = { "WebAssembly.Memory", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyMemory) };
 
-JSWebAssemblyMemory* JSWebAssemblyMemory::create(JSGlobalObject* globalObject, VM& vm, Structure* structure)
+JSWebAssemblyMemory* JSWebAssemblyMemory::tryCreate(JSGlobalObject* globalObject, VM& vm, Structure* structure)
 {
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
index e5ba711..ab9c474 100644 (file)
@@ -49,7 +49,7 @@ public:
         return vm.webAssemblyMemorySpace<mode>();
     }
 
-    static JSWebAssemblyMemory* create(JSGlobalObject*, VM&, Structure*);
+    static JSWebAssemblyMemory* tryCreate(JSGlobalObject*, VM&, Structure*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
     DECLARE_EXPORT_INFO;
index 10bb229..a9f84d6 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
 
 const ClassInfo JSWebAssemblyTable::s_info = { "WebAssembly.Table", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyTable) };
 
-JSWebAssemblyTable* JSWebAssemblyTable::create(JSGlobalObject* globalObject, VM& vm, Structure* structure, Ref<Wasm::Table>&& table)
+JSWebAssemblyTable* JSWebAssemblyTable::tryCreate(JSGlobalObject* globalObject, VM& vm, Structure* structure, Ref<Wasm::Table>&& table)
 {
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
index 01ae100..c7cc2eb 100644 (file)
@@ -49,7 +49,7 @@ public:
         return vm.webAssemblyTableSpace<mode>();
     }
 
-    static JSWebAssemblyTable* create(JSGlobalObject*, VM&, Structure*, Ref<Wasm::Table>&&);
+    static JSWebAssemblyTable* tryCreate(JSGlobalObject*, VM&, Structure*, Ref<Wasm::Table>&&);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
     DECLARE_INFO;
index 4dca2e0..4bdd006 100644 (file)
@@ -121,7 +121,7 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyGlobal(JSGlobalObject*
     }
 
     Ref<Wasm::Global> wasmGlobal = Wasm::Global::create(type, mutability, initialValue);
-    RELEASE_AND_RETURN(throwScope, JSValue::encode(JSWebAssemblyGlobal::create(globalObject, vm, globalObject->webAssemblyGlobalStructure(), WTFMove(wasmGlobal))));
+    RELEASE_AND_RETURN(throwScope, JSValue::encode(JSWebAssemblyGlobal::tryCreate(globalObject, vm, globalObject->webAssemblyGlobalStructure(), WTFMove(wasmGlobal))));
 }
 
 static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyGlobal(JSGlobalObject* globalObject, CallFrame*)
index 60029ef..3ba6243 100644 (file)
@@ -78,7 +78,7 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyInstance(JSGlobalObjec
     Structure* instanceStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), callFrame->newTarget(), globalObject->webAssemblyInstanceStructure());
     RETURN_IF_EXCEPTION(scope, { });
 
-    JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, globalObject, JSWebAssemblyInstance::createPrivateModuleKey(), module, importObject, instanceStructure, Ref<Wasm::Module>(module->module()), Wasm::CreationMode::FromJS);
+    JSWebAssemblyInstance* instance = JSWebAssemblyInstance::tryCreate(vm, globalObject, JSWebAssemblyInstance::createPrivateModuleKey(), module, importObject, instanceStructure, Ref<Wasm::Module>(module->module()), Wasm::CreationMode::FromJS);
     RETURN_IF_EXCEPTION(scope, { });
 
     instance->finalizeCreation(vm, globalObject, module->module().compileSync(&vm.wasmContext, instance->memoryMode(), &Wasm::createJSToWasmWrapper, &Wasm::operationWasmToJSException), importObject, Wasm::CreationMode::FromJS);
index 530a879..62ceed8 100644 (file)
@@ -98,7 +98,7 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyMemory(JSGlobalObject*
         }
     }
 
-    auto* jsMemory = JSWebAssemblyMemory::create(globalObject, vm, globalObject->webAssemblyMemoryStructure());
+    auto* jsMemory = JSWebAssemblyMemory::tryCreate(globalObject, vm, globalObject->webAssemblyMemoryStructure());
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
 
     RefPtr<Wasm::Memory> memory = Wasm::Memory::tryCreate(initialPageCount, maximumPageCount,
index a752cf7..133358b 100644 (file)
@@ -350,7 +350,7 @@ void WebAssemblyModuleRecord::link(JSGlobalObject* globalObject, JSValue, JSObje
             RefPtr<Wasm::Table> wasmTable = Wasm::Table::tryCreate(moduleInformation.tables[i].initial(), moduleInformation.tables[i].maximum(), moduleInformation.tables[i].type());
             if (!wasmTable)
                 return exception(createJSWebAssemblyLinkError(globalObject, vm, "couldn't create Table"));
-            JSWebAssemblyTable* table = JSWebAssemblyTable::create(globalObject, vm, globalObject->webAssemblyTableStructure(), wasmTable.releaseNonNull());
+            JSWebAssemblyTable* table = JSWebAssemblyTable::tryCreate(globalObject, vm, globalObject->webAssemblyTableStructure(), wasmTable.releaseNonNull());
             // We should always be able to allocate a JSWebAssemblyTable we've defined.
             // If it's defined to be too large, we should have thrown a validation error.
             scope.assertNoException();
@@ -425,7 +425,8 @@ void WebAssemblyModuleRecord::link(JSGlobalObject* globalObject, JSValue, JSObje
             case Wasm::GlobalInformation::BindingMode::Portable: {
                 ASSERT(global.mutability == Wasm::GlobalInformation::Mutability::Mutable);
                 Ref<Wasm::Global> globalRef = Wasm::Global::create(global.type, Wasm::GlobalInformation::Mutability::Mutable, initialBits);
-                JSWebAssemblyGlobal* globalValue = JSWebAssemblyGlobal::create(globalObject, vm, globalObject->webAssemblyGlobalStructure(), WTFMove(globalRef));
+                JSWebAssemblyGlobal* globalValue = JSWebAssemblyGlobal::tryCreate(globalObject, vm, globalObject->webAssemblyGlobalStructure(), WTFMove(globalRef));
+                scope.assertNoException();
                 m_instance->linkGlobal(vm, globalIndex, globalValue);
                 keepAlive(bitwise_cast<void*>(initialBits)); // Ensure this is kept alive while creating JSWebAssemblyGlobal.
                 break;
@@ -473,7 +474,8 @@ void WebAssemblyModuleRecord::link(JSGlobalObject* globalObject, JSValue, JSObje
                 if (global.bindingMode == Wasm::GlobalInformation::BindingMode::EmbeddedInInstance) {
                     uint64_t initialValue = m_instance->instance().loadI64Global(exp.kindIndex);
                     Ref<Wasm::Global> globalRef = Wasm::Global::create(global.type, global.mutability, initialValue);
-                    exportedValue = JSWebAssemblyGlobal::create(globalObject, vm, globalObject->webAssemblyGlobalStructure(), WTFMove(globalRef));
+                    exportedValue = JSWebAssemblyGlobal::tryCreate(globalObject, vm, globalObject->webAssemblyGlobalStructure(), WTFMove(globalRef));
+                    scope.assertNoException();
                 } else {
                     ASSERT(global.mutability == Wasm::GlobalInformation::Mutability::Mutable);
                     RefPtr<Wasm::Global> globalRef = m_instance->instance().getGlobalBinding(exp.kindIndex);
index 36d14ed..d2c2089 100644 (file)
@@ -101,7 +101,7 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyTable(JSGlobalObject*
             createRangeError(globalObject, "couldn't create Table"_s)));
     }
 
-    RELEASE_AND_RETURN(throwScope, JSValue::encode(JSWebAssemblyTable::create(globalObject, vm, globalObject->webAssemblyTableStructure(), wasmTable.releaseNonNull())));
+    RELEASE_AND_RETURN(throwScope, JSValue::encode(JSWebAssemblyTable::tryCreate(globalObject, vm, globalObject->webAssemblyTableStructure(), wasmTable.releaseNonNull())));
 }
 
 static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyTable(JSGlobalObject* globalObject, CallFrame*)