Bug 1529349 - Baldr: detect invalid section before code section during streaming compilation r=bbouvier a=lizzard
authorLuke Wagner <luke@mozilla.com>
Fri, 22 Feb 2019 09:35:19 -0600
changeset 516160 e886d8a7a57bd08d1ca8b72d67c168c858fc035b
parent 516159 2a50443802ba4760f9846ba8acc1835712c17bd6
child 516161 3b07b355d59f79c00a89accc52f029d09bdda8ba
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier, lizzard
bugs1529349
milestone66.0
Bug 1529349 - Baldr: detect invalid section before code section during streaming compilation r=bbouvier a=lizzard
js/src/jit-test/tests/wasm/streaming.js
js/src/wasm/WasmCompile.cpp
--- a/js/src/jit-test/tests/wasm/streaming.js
+++ b/js/src/jit-test/tests/wasm/streaming.js
@@ -1,10 +1,12 @@
 // |jit-test| skip-if: !wasmStreamingIsSupported()
 
+load(libdir + "wasm-binary.js");
+
 function testInstantiate(source, importObj, exportName, expectedValue) {
     var result;
     WebAssembly.instantiateStreaming(code, importObj).then(r => { result = r });
     drainJobQueue();
     assertEq(result !== undefined, true);
     assertEq(result.module instanceof WebAssembly.Module, true);
     assertEq(result.instance instanceof WebAssembly.Instance, true);
     assertEq(result.instance.exports[exportName](), expectedValue);
@@ -84,8 +86,11 @@ for (var i = 0; i < 10; i++)
     assertEq(results[i].instance.exports.run(), 5050);
 
 // No code section, but data section:
 var code = wasmTextToBinary('(module (memory (import "js" "mem") 1) (data (i32.const 0) "a"))');
 var mem = new WebAssembly.Memory({initial:1});
 WebAssembly.instantiateStreaming(code, {js:{mem}});
 drainJobQueue();
 assertEq(new Uint8Array(mem.buffer)[0], 97);
+
+// Junk section before code section.
+testFailBoth(moduleWithSections([{name: 100, body: [1, 2, 3]}, bodySection([])]), WebAssembly.CompileError);
--- a/js/src/wasm/WasmCompile.cpp
+++ b/js/src/wasm/WasmCompile.cpp
@@ -696,68 +696,73 @@ static SharedBytes CreateBytecode(const 
 
 SharedModule wasm::CompileStreaming(
     const CompileArgs& args, const Bytes& envBytes, const Bytes& codeBytes,
     const ExclusiveBytesPtr& codeBytesEnd,
     const ExclusiveStreamEndData& exclusiveStreamEnd,
     const Atomic<bool>& cancelled, UniqueChars* error,
     UniqueCharsVector* warnings) {
   CompilerEnvironment compilerEnv(args);
-  Maybe<ModuleEnvironment> env;
+  ModuleEnvironment env(
+      args.gcEnabled, &compilerEnv,
+      args.sharedMemoryEnabled ? Shareable::True : Shareable::False);
 
   {
     Decoder d(envBytes, 0, error, warnings);
 
-    env.emplace(args.gcEnabled, &compilerEnv,
-                args.sharedMemoryEnabled ? Shareable::True : Shareable::False);
-    if (!DecodeModuleEnvironment(d, env.ptr())) {
+    if (!DecodeModuleEnvironment(d, &env)) {
       return nullptr;
     }
 
-    MOZ_ASSERT(d.done());
+    if (!env.codeSection) {
+      d.fail("unknown section before code section");
+      return nullptr;
+    }
+
+    MOZ_RELEASE_ASSERT(env.codeSection->size == codeBytes.length());
+    MOZ_RELEASE_ASSERT(d.done());
   }
 
-  ModuleGenerator mg(args, env.ptr(), &cancelled, error);
+  ModuleGenerator mg(args, &env, &cancelled, error);
   if (!mg.init()) {
     return nullptr;
   }
 
   {
-    MOZ_ASSERT(env->codeSection->size == codeBytes.length());
-    StreamingDecoder d(*env, codeBytes, codeBytesEnd, cancelled, error,
+    StreamingDecoder d(env, codeBytes, codeBytesEnd, cancelled, error,
                        warnings);
 
-    if (!DecodeCodeSection(*env, d, mg)) {
+    if (!DecodeCodeSection(env, d, mg)) {
       return nullptr;
     }
 
-    MOZ_ASSERT(d.done());
+    MOZ_RELEASE_ASSERT(d.done());
   }
 
   {
     auto streamEnd = exclusiveStreamEnd.lock();
     while (!streamEnd->reached) {
       if (cancelled) {
         return nullptr;
       }
       streamEnd.wait();
     }
   }
 
   const StreamEndData& streamEnd = exclusiveStreamEnd.lock();
   const Bytes& tailBytes = *streamEnd.tailBytes;
 
   {
-    Decoder d(tailBytes, env->codeSection->end(), error, warnings);
+    Decoder d(tailBytes, env.codeSection->end(), error, warnings);
 
-    if (!DecodeModuleTail(d, env.ptr())) {
+    if (!DecodeModuleTail(d, &env)) {
       return nullptr;
     }
 
-    MOZ_ASSERT(d.done());
+    MOZ_RELEASE_ASSERT(d.done());
   }
 
   SharedBytes bytecode = CreateBytecode(envBytes, codeBytes, tailBytes, error);
   if (!bytecode) {
     return nullptr;
   }
 
   return mg.finishModule(*bytecode, streamEnd.tier2Listener);