Title: [288945] trunk
Revision
288945
Author
[email protected]
Date
2022-02-02 00:22:40 -0800 (Wed, 02 Feb 2022)

Log Message

[JSC] wasm atomic opcodes should be rejected if alignment is not equal to natural width
https://bugs.webkit.org/show_bug.cgi?id=235990

Reviewed by Saam Barati.

JSTests:

* wasm/stress/invalid-atomic-alignment.js: Added.
(async buildAndThrow):

Source/_javascript_Core:

While normal load and store can accept larger alignment than an access width,
wasm module validator rejects if atomic ops' alignment is not equal to an access width.
This patch applies this restriction.
No runtime semantics change since atomic ops are always checked against an access width alignment.

* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::atomicLoad):
(JSC::Wasm::FunctionParser<Context>::atomicStore):
(JSC::Wasm::FunctionParser<Context>::atomicBinaryRMW):
(JSC::Wasm::FunctionParser<Context>::atomicCompareExchange):
(JSC::Wasm::FunctionParser<Context>::atomicWait):
(JSC::Wasm::FunctionParser<Context>::atomicNotify):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (288944 => 288945)


--- trunk/JSTests/ChangeLog	2022-02-02 05:50:59 UTC (rev 288944)
+++ trunk/JSTests/ChangeLog	2022-02-02 08:22:40 UTC (rev 288945)
@@ -1,3 +1,13 @@
+2022-02-02  Yusuke Suzuki  <[email protected]>
+
+        [JSC] wasm atomic opcodes should be rejected if alignment is not equal to natural width
+        https://bugs.webkit.org/show_bug.cgi?id=235990
+
+        Reviewed by Saam Barati.
+
+        * wasm/stress/invalid-atomic-alignment.js: Added.
+        (async buildAndThrow):
+
 2022-02-01  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r288538.

Added: trunk/JSTests/wasm/stress/invalid-atomic-alignment.js (0 => 288945)


--- trunk/JSTests/wasm/stress/invalid-atomic-alignment.js	                        (rev 0)
+++ trunk/JSTests/wasm/stress/invalid-atomic-alignment.js	2022-02-02 08:22:40 UTC (rev 288945)
@@ -0,0 +1,89 @@
+import * as assert from '../assert.js';
+import { instantiate } from "../wabt-wrapper.js";
+
+async function buildAndThrow(text)
+{
+    let error = null;
+    try {
+        await instantiate(text, { }, { threads: true });
+    } catch (e) {
+        error = e;
+    }
+    return error;
+}
+
+async function testLoad()
+{
+    let text = `
+    (module
+      (memory 1 1 shared)
+      (func (export "i32.atomic.load") (param $addr i32) (result i32) (i32.atomic.load align=8 (local.get $addr)))
+    )`;
+    let error = await buildAndThrow(text);
+    assert.eq(String(error), `CompileError: WebAssembly.Module doesn't parse at byte 6: byte alignment 8 does not match against atomic op's natural alignment 4, in function at index 0 (evaluating 'new WebAssembly.Module(binaryResult.buffer)')`);
+}
+
+async function testStore()
+{
+    let text = `
+    (module
+      (memory 1 1 shared)
+      (func (export "i32.atomic.store") (param $addr i32) (param $value i32) (i32.atomic.store align=8 (local.get $addr) (local.get $value)))
+    )`;
+    let error = await buildAndThrow(text);
+    assert.eq(String(error), `CompileError: WebAssembly.Module doesn't parse at byte 8: byte alignment 8 does not match against atomic op's natural alignment 4, in function at index 0 (evaluating 'new WebAssembly.Module(binaryResult.buffer)')`);
+}
+
+async function testRMW()
+{
+    let text = `
+    (module
+      (memory 1 1 shared)
+      (func (export "i32.atomic.rmw.add") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.add align=8 (local.get $addr) (local.get $value)))
+    )`;
+    let error = await buildAndThrow(text);
+    assert.eq(String(error), `CompileError: WebAssembly.Module doesn't parse at byte 8: byte alignment 8 does not match against atomic op's natural alignment 4, in function at index 0 (evaluating 'new WebAssembly.Module(binaryResult.buffer)')`);
+}
+
+async function testCmpXchg()
+{
+    let text = `
+    (module
+      (memory 1 1 shared)
+      (func (export "i32.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw.cmpxchg align=8 (local.get $addr) (local.get $expected) (local.get $value)))
+    )`;
+    let error = await buildAndThrow(text);
+    assert.eq(String(error), `CompileError: WebAssembly.Module doesn't parse at byte 10: byte alignment 8 does not match against atomic op's natural alignment 4, in function at index 0 (evaluating 'new WebAssembly.Module(binaryResult.buffer)')`);
+}
+
+async function testAtomicNotify()
+{
+    let text = `
+    (module
+      (memory 1 1 shared)
+      (func (export "init") (param $value i64) (i64.store (i32.const 0) (local.get $value)))
+      (func (export "memory.atomic.notify") (param $addr i32) (param $expected i32) (result i32)
+          (memory.atomic.notify align=8 (local.get 0) (local.get 1)))
+    )`;
+    let error = await buildAndThrow(text);
+    assert.eq(String(error), `CompileError: WebAssembly.Module doesn't parse at byte 8: byte alignment 8 does not match against atomic op's natural alignment 4, in function at index 1 (evaluating 'new WebAssembly.Module(binaryResult.buffer)')`);
+}
+
+async function testAtomicWait()
+{
+    let text = `
+    (module
+      (memory 1 1 shared)
+      (func (export "memory.atomic.wait32") (param $addr i32) (param $expected i32) (param $timeout i64) (result i32)
+          (memory.atomic.wait32 align=8 (local.get 0) (local.get 1) (local.get 2)))
+    )`;
+    let error = await buildAndThrow(text);
+    assert.eq(String(error), `CompileError: WebAssembly.Module doesn't parse at byte 10: byte alignment 8 does not match against atomic op's natural alignment 4, in function at index 0 (evaluating 'new WebAssembly.Module(binaryResult.buffer)')`);
+}
+
+await testLoad();
+await testStore();
+await testRMW();
+await testCmpXchg();
+await testAtomicNotify();
+await testAtomicWait();

Modified: trunk/Source/_javascript_Core/ChangeLog (288944 => 288945)


--- trunk/Source/_javascript_Core/ChangeLog	2022-02-02 05:50:59 UTC (rev 288944)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-02-02 08:22:40 UTC (rev 288945)
@@ -1,3 +1,24 @@
+2022-02-02  Yusuke Suzuki  <[email protected]>
+
+        [JSC] wasm atomic opcodes should be rejected if alignment is not equal to natural width
+        https://bugs.webkit.org/show_bug.cgi?id=235990
+
+        Reviewed by Saam Barati.
+
+        While normal load and store can accept larger alignment than an access width,
+        wasm module validator rejects if atomic ops' alignment is not equal to an access width.
+        This patch applies this restriction.
+        No runtime semantics change since atomic ops are always checked against an access width alignment.
+
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser<Context>::atomicLoad):
+        (JSC::Wasm::FunctionParser<Context>::atomicStore):
+        (JSC::Wasm::FunctionParser<Context>::atomicBinaryRMW):
+        (JSC::Wasm::FunctionParser<Context>::atomicCompareExchange):
+        (JSC::Wasm::FunctionParser<Context>::atomicWait):
+        (JSC::Wasm::FunctionParser<Context>::atomicNotify):
+        (JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
+
 2022-02-01  Pablo Saavedra  <[email protected]>
 
         [GTK][WPE] Fixes for non-unified builds after r288807 and r288820

Modified: trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h (288944 => 288945)


--- trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2022-02-02 05:50:59 UTC (rev 288944)
+++ trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2022-02-02 08:22:40 UTC (rev 288945)
@@ -403,7 +403,7 @@
     uint32_t offset;
     TypedExpression pointer;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(alignment), "can't get load alignment");
-    WASM_PARSER_FAIL_IF(alignment > memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " exceeds load's natural alignment ", 1ull << memoryLog2Alignment(op));
+    WASM_PARSER_FAIL_IF(alignment != memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " does not match against atomic op's natural alignment ", 1ull << memoryLog2Alignment(op));
     WASM_PARSER_FAIL_IF(!parseVarUInt32(offset), "can't get load offset");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(pointer, "load pointer");
 
@@ -425,7 +425,7 @@
     TypedExpression value;
     TypedExpression pointer;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(alignment), "can't get store alignment");
-    WASM_PARSER_FAIL_IF(alignment > memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " exceeds store's natural alignment ", 1ull << memoryLog2Alignment(op));
+    WASM_PARSER_FAIL_IF(alignment != memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " does not match against atomic op's natural alignment ", 1ull << memoryLog2Alignment(op));
     WASM_PARSER_FAIL_IF(!parseVarUInt32(offset), "can't get store offset");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(value, "store value");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(pointer, "store pointer");
@@ -447,7 +447,7 @@
     TypedExpression pointer;
     TypedExpression value;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(alignment), "can't get load alignment");
-    WASM_PARSER_FAIL_IF(alignment > memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " exceeds load's natural alignment ", 1ull << memoryLog2Alignment(op));
+    WASM_PARSER_FAIL_IF(alignment != memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " does not match against atomic op's natural alignment ", 1ull << memoryLog2Alignment(op));
     WASM_PARSER_FAIL_IF(!parseVarUInt32(offset), "can't get load offset");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(value, "value");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(pointer, "pointer");
@@ -472,7 +472,7 @@
     TypedExpression expected;
     TypedExpression value;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(alignment), "can't get load alignment");
-    WASM_PARSER_FAIL_IF(alignment > memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " exceeds load's natural alignment ", 1ull << memoryLog2Alignment(op));
+    WASM_PARSER_FAIL_IF(alignment !=  memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " does not match against atomic op's natural alignment ", 1ull << memoryLog2Alignment(op));
     WASM_PARSER_FAIL_IF(!parseVarUInt32(offset), "can't get load offset");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(value, "value");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(expected, "expected");
@@ -499,7 +499,7 @@
     TypedExpression value;
     TypedExpression timeout;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(alignment), "can't get load alignment");
-    WASM_PARSER_FAIL_IF(alignment > memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " exceeds load's natural alignment ", 1ull << memoryLog2Alignment(op));
+    WASM_PARSER_FAIL_IF(alignment != memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " does not match against atomic op's natural alignment ", 1ull << memoryLog2Alignment(op));
     WASM_PARSER_FAIL_IF(!parseVarUInt32(offset), "can't get load offset");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(timeout, "timeout");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(value, "value");
@@ -525,7 +525,7 @@
     TypedExpression pointer;
     TypedExpression count;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(alignment), "can't get load alignment");
-    WASM_PARSER_FAIL_IF(alignment > memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " exceeds load's natural alignment ", 1ull << memoryLog2Alignment(op));
+    WASM_PARSER_FAIL_IF(alignment != memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " does not match against atomic op's natural alignment ", 1ull << memoryLog2Alignment(op));
     WASM_PARSER_FAIL_IF(!parseVarUInt32(offset), "can't get load offset");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(count, "count");
     WASM_TRY_POP_EXPRESSION_STACK_INTO(pointer, "pointer");
@@ -1951,7 +1951,7 @@
             uint32_t alignment;
             uint32_t unused;
             WASM_PARSER_FAIL_IF(!parseVarUInt32(alignment), "can't get load alignment");
-            WASM_PARSER_FAIL_IF(alignment > memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " exceeds load's natural alignment ", 1ull << memoryLog2Alignment(op));
+            WASM_PARSER_FAIL_IF(alignment != memoryLog2Alignment(op), "byte alignment ", 1ull << alignment, " does not match against atomic op's natural alignment ", 1ull << memoryLog2Alignment(op));
             WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), "can't get first immediate for atomic ", static_cast<unsigned>(op), " in unreachable context");
             break;
         }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to