High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionOn arm64, a WASM <code>br_table</code> instruction with a lot of entries could lead to the label being too far from the instruction causing truncation and incorrect computation of the branch address.
ComponentSpiderMonkey
Bug ClassLogic Error
Tracker1971581
Fix commite2a15b231f19 (firefox) +4/-4
CISA KEVNot listed
CreditedGary Kwong
Disclosed2025-07-22

Files Changed

  • js/src/jit-test/tests/asm.js/testControlFlow.js
  • js/src/wasm/WasmConstants.h
diff --git a/js/src/jit-test/tests/asm.js/testControlFlow.js b/js/src/jit-test/tests/asm.js/testControlFlow.js
index 40711cd6cef..bef7f12e840 100644
--- a/js/src/jit-test/tests/asm.js/testControlFlow.js
+++ b/js/src/jit-test/tests/asm.js/testControlFlow.js
@@ -148,11 +148,11 @@ var exp = asmLink(asmCompile(USE_ASM + "var x=0; function a() { return x|0 } fun
 assertEq(exp.c(10), undefined);
 assertEq(exp.a(), 10);
 
-var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=-1; break; case 133742: i=2; break; default: i=42; break } return i|0 } return f"));
+var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=-1; break; case 65520: i=2; break; default: i=42; break } return i|0 } return f"));
 assertEq(f(1), -1);
 assertEq(f(2), 42);
-assertEq(f(133742), 2);
-assertEq(f(133743), 42);
+assertEq(f(65520), 2);
+assertEq(f(65521), 42);
 
 var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=42; break; default: i=13 } return i|0 } return f"));
 assertEq(f(-1), 13);
diff --git a/js/src/wasm/WasmConstants.h b/js/src/wasm/WasmConstants.h
index 6aff7c3a6f5..eea1c6cfa92 100644
--- a/js/src/wasm/WasmConstants.h
+++ b/js/src/wasm/WasmConstants.h
@@ -1181,7 +1181,7 @@ static_assert(uint64_t(MaxArrayPayloadBytes) <
 // These limits pertain to our WebAssembly implementation only.
 
 static const unsigned MaxTryTableCatches = 10000;
-static const unsigned MaxBrTableElems = 1000000;
+static const unsigned MaxBrTableElems = 65520;
 static const unsigned MaxCodeSectionBytes = MaxModuleBytes;
 static const unsigned MaxBranchHintValue = 2;
 
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/js/src/jit-test/tests/asm.js/testControlFlow.js b/js/src/jit-test/tests/asm.js/testControlFlow.js
index 40711cd6cef..bef7f12e840 100644
--- a/js/src/jit-test/tests/asm.js/testControlFlow.js
+++ b/js/src/jit-test/tests/asm.js/testControlFlow.js
@@ -148,11 +148,11 @@ var exp = asmLink(asmCompile(USE_ASM + "var x=0; function a() { return x|0 } fun
 assertEq(exp.c(10), undefined);
 assertEq(exp.a(), 10);
 
-var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=-1; break; case 133742: i=2; break; default: i=42; break } return i|0 } return f"));
+var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=-1; break; case 65520: i=2; break; default: i=42; break } return i|0 } return f"));
 assertEq(f(1), -1);
 assertEq(f(2), 42);
-assertEq(f(133742), 2);
-assertEq(f(133743), 42);
+assertEq(f(65520), 2);
+assertEq(f(65521), 42);
 
 var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=42; break; default: i=13 } return i|0 } return f"));
 assertEq(f(-1), 13);
Loading diff…