Bug 1464477 - Crash [@ JSObject::getClass] with wasm. r=lth.
authorJulian Seward <jseward@acm.org>
Wed, 30 May 2018 10:15:29 +0200
changeset 474686 9fc0e4096849fcee3a72b41bbf9a40ab509f06be
parent 474685 a2fd9b7493a1d028685856220f246242a1a1b316
child 474687 efd5c0553e738b8268ccd7e15447c521c80630f9
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1464477
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1464477 - Crash [@ JSObject::getClass] with wasm. r=lth. OpIter<Policy>::readMem{Copy,Fill} have to do with memory operations. But they don't verify that the current module actually has a valid memory. If indeed there is no memory, the generated code segfaults. This patch causes verification to fail for modules without memories that use BulkMem.{Copy,Fill}. It also fixes a testcase whose lack of memory is exposed by the C++ fix.
js/src/jit-test/tests/wasm/memory-bulk.js
js/src/wasm/WasmOpIter.h
--- a/js/src/jit-test/tests/wasm/memory-bulk.js
+++ b/js/src/jit-test/tests/wasm/memory-bulk.js
@@ -78,24 +78,32 @@ function funcBody(func) {
     return body;
 }
 
 function bodySection(bodies) {
     var body = varU32(bodies.length).concat(...bodies);
     return { name: codeId, body };
 }
 
+function memorySection(initialSize) {
+    var body = [];
+    body.push(...varU32(1));           // number of memories
+    body.push(...varU32(0x0));         // for now, no maximum
+    body.push(...varU32(initialSize));
+    return { name: memoryId, body };
+}
+
 const v2vSig = {args:[], ret:VoidCode};
 const v2vSigSection = sigSection([v2vSig]);
 
 // Prefixed opcodes
 
 function checkMiscPrefixed(opcode, expect_failure) {
     let binary = moduleWithSections(
-           [v2vSigSection, declSection([0]),
+           [v2vSigSection, declSection([0]), memorySection(1),
             bodySection(
                 [funcBody(
                     {locals:[],
                      body:[0x41, 0x0, 0x41, 0x0, 0x41, 0x0, // 3 x const.i32 0
                            MiscPrefix, opcode]})])]);
     if (expect_failure) {
         assertErrorMessage(() => new WebAssembly.Module(binary),
                            WebAssembly.CompileError, /unrecognized opcode/);
--- a/js/src/wasm/WasmOpIter.h
+++ b/js/src/wasm/WasmOpIter.h
@@ -2238,16 +2238,19 @@ OpIter<Policy>::readSimdCtor(ValType ele
 }
 
 template <typename Policy>
 inline bool
 OpIter<Policy>::readMemCopy(Value* dest, Value* src, Value* len)
 {
     MOZ_ASSERT(Classify(op_) == OpKind::MemCopy);
 
+    if (!env_.usesMemory())
+        return fail("can't touch memory without memory");
+
     if (!popWithType(ValType::I32, len))
         return false;
 
     if (!popWithType(ValType::I32, src))
         return false;
 
     if (!popWithType(ValType::I32, dest))
         return false;
@@ -2256,16 +2259,19 @@ OpIter<Policy>::readMemCopy(Value* dest,
 }
 
 template <typename Policy>
 inline bool
 OpIter<Policy>::readMemFill(Value* start, Value* val, Value* len)
 {
     MOZ_ASSERT(Classify(op_) == OpKind::MemFill);
 
+    if (!env_.usesMemory())
+        return fail("can't touch memory without memory");
+
     if (!popWithType(ValType::I32, len))
         return false;
 
     if (!popWithType(ValType::I32, val))
         return false;
 
     if (!popWithType(ValType::I32, start))
         return false;