Moderate firefox Logic Error 🔧 Commit mapped

Overview

Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionUse-after-free in the JavaScript: WebAssembly component
ComponentSpiderMonkey
Bug ClassLogic Error
Tracker2067174
Fix commit020950975934 (firefox) +1630/-1308
CISA KEVNot listed
CreditedMozilla
Disclosed2026-10-13

Files Changed

  • js/src/jit/MacroAssembler.cpp
  • js/src/jit/MacroAssembler.h
  • js/src/jit/arm/CodeGenerator-arm.cpp
  • js/src/jit/arm/MacroAssembler-arm.cpp
  • js/src/jit/arm/MacroAssembler-arm.h
  • js/src/jit/arm64/MacroAssembler-arm64.cpp
  • js/src/jit/arm64/MacroAssembler-arm64.h
  • js/src/jit/loong64/MacroAssembler-loong64.cpp
  • js/src/jit/loong64/MacroAssembler-loong64.h
  • js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp
  • js/src/jit/mips64/MacroAssembler-mips64.cpp
  • js/src/jit/riscv64/MacroAssembler-riscv64.cpp
  • js/src/jit/riscv64/MacroAssembler-riscv64.h
  • js/src/jit/wasm32/MacroAssembler-wasm32.cpp
  • js/src/jit/x64/MacroAssembler-x64.cpp
  • js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
  • js/src/jit/x86-shared/MacroAssembler-x86-shared.h
  • js/src/jit/x86/CodeGenerator-x86.cpp
  • js/src/jit/x86/MacroAssembler-x86.cpp
  • js/src/wasm/WasmBCMemory.cpp
  • js/src/wasm/WasmBaselineCompile.cpp
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
index 109cd6d1bbf..44f057cd3b8 100644
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -7278,7 +7278,7 @@ void MacroAssembler::wasmReturnCallRef(
   append(wasm::CodeRangeUnwindInfo::Normal, currentOffset());
 }
 
-void MacroAssembler::wasmBoundsCheckRange32(
+FaultingCodeRange MacroAssembler::wasmBoundsCheckRange32(
     Register index, Register length, Register limit, Register tmp,
     const wasm::TrapSiteDesc& trapSiteDesc) {
   Label ok;
@@ -7290,9 +7290,10 @@ void MacroAssembler::wasmBoundsCheckRange32(
   jump(&ok);
 
   bind(&fail);
-  wasmTrap(wasm::Trap::OutOfBounds, trapSiteDesc);
+  FaultingCodeRange fcr = wasmTrap(wasm::Trap::OutOfBounds, trapSiteDesc);
 
   bind(&ok);
+  return fcr;
 }
 
 void MacroAssembler::wasmClampTable64Address(Register64 address, Register out) {
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
index cdb9fcadf58..73096c29751 100644
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -3845,14 +3845,24 @@ class MacroAssembler : public MacroAssemblerSpecific {
                          Address boundsCheckLimit, Label* label) PER_ARCH;
 
   // Each wasm load/store instruction appends its own wasm::Trap::OutOfBounds.
-  void wasmLoad(const wasm::MemoryAccessDesc& access, Operand srcAddr,
-                AnyRegister out) DEFINED_ON(x86, x64);
-  void wasmLoadI64(const wasm::MemoryAccessDesc& access, Operand srcAddr,
-                   Register64 out) DEFINED_ON(x86, x64);
-  void wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value,
-                 Operand dstAddr) DEFINED_ON(x86, x64);
-  void wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value,
-                    Operand dstAddr) DEFINED_ON(x86);
+  FaultingCodeRange wasmLoad(const wasm::MemoryAccessDesc& access,
+                             Operand srcAddr, AnyRegister out)
+      DEFINED_ON(x86, x64);
+
+  FaultingCodeRange wasmLoadI64(const wasm::MemoryAccessDesc& access,
+                                Operand srcAddr, Register64 out)
+      DEFINED_ON(x64);
+  FaultingCodeRangePair wasmLoadI32x2(const wasm::MemoryAccessDesc& access,
+                                      Operand srcAddr, Register64 out)
+      DEFINED_ON(x86);
+
+  FaultingCodeRange wasmStore(const wasm::MemoryAccessDesc& access,
+                              AnyRegister value, Operand dstAddr)
+      DEFINED_ON(x86, x64);
+
+  FaultingCodeRangePair wasmStoreI32x2(const wasm::MemoryAccessDesc& access,
+                                       Register64 value, Operand dstAddr)
+      DEFINED_ON(x86);
 
   // For all the ARM/MIPS/LOONG64 wasmLoad and wasmStore functions below, `ptr`
   // MUST equal `ptrScratch`, and that register will be updated based on
@@ -3860,47 +3870,72 @@ class MacroAssembler : public MacroAssemblerSpecific {
 
   // `ptr` will be updated if access.offset32() != 0 or access.type() ==
   // Scalar::Int64.
-  void wasmLoad(const wasm::MemoryAccessDesc& access, Register memoryBase,
-                Register ptr, Register ptrScratch, AnyRegister output)
+  FaultingCodeRange wasmLoad(const wasm::MemoryAccessDesc& access,
+                             Register memoryBase, Register ptr,
+                             Register ptrScratch, AnyRegister output)
       DEFINED_ON(arm, loong64, mips64);
-  void wasmLoadI64(const wasm::MemoryAccessDesc& access, Register memoryBase,
-                   Register ptr, Register ptrScratch, Register64 output)
-      DEFINED_ON(arm, mips64, loong64);
-  void wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value,
-                 Register memoryBase, Register ptr, Register ptrScratch)
+
+  FaultingCodeRangePair wasmLoadI32x2(const wasm::MemoryAccessDesc& access,
+                                      Register memoryBase, Register ptr,
+                                      Register ptrScratch, Register64 output)
+      DEFINED_ON(arm);
+  FaultingCodeRange wasmLoadI64(const wasm::MemoryAccessDesc& access,
+                                Register memoryBase, Register ptr,
+                                Register ptrScratch, Register64 output)
+      DEFINED_ON(mips64, loong64);
+
+  FaultingCodeRange wasmStore(const wasm::MemoryAccessDesc& access,
+                              AnyRegister value, Register memoryBase,
+                              Register ptr, Register ptrScratch)
       DEFINED_ON(arm, loong64, mips64);
-  void wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value,
-                    Register memoryBase, Register ptr, Register ptrScratch)
-      DEFINED_ON(arm, mips64, loong64);
+
+  FaultingCodeRangePair wasmStoreI32x2(const wasm::MemoryAccessDesc& access,
+                                       Register64 value, Register memoryBase,
+                                       Register ptr, Register ptrScratch)
+      DEFINED_ON(arm);
+  FaultingCodeRange wasmStoreI64(const wasm::MemoryAccessDesc& access,
+                                 Register64 value, Register memoryBase,
+                                 Register ptr, Register ptrScratch)
+      DEFINED_ON(mips64, loong64);
 
   // These accept general memoryBase + ptr + offset (in `access`); the offset is
   // always smaller than the guard region.  They will insert an additional add
   // if the offset is nonzero, and of course that add may require a temporary
   // register for the offset if the offset is large, and instructions to set it
   // up.
-  void wasmLoad(const wasm::MemoryAccessDesc& access, Register memoryBase,
-                Register ptr, AnyRegister output) DEFINED_ON(arm64);
-  void wasmLoadI64(const wasm::MemoryAccessDesc& access, Register memoryBase,
-                   Register ptr, Register64 output) DEFINED_ON(arm64);
-  void wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value,
-                 Register memoryBase, Register ptr) DEFINED_ON(arm64);
-  void wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value,
-                    Register memoryBase, Register ptr) DEFINED_ON(arm64);
+  FaultingCodeRange wasmLoad(const wasm::MemoryAccessDesc& access,
+                             Register memoryBase, Register ptr,
+                             AnyRegister output) DEFINED_ON(arm64);
+  FaultingCodeRange wasmLoadI64(const wasm::MemoryAccessDesc& access,
+                                Register memoryBase, Register ptr,
+                                Register64 output) DEFINED_ON(arm64);
+  FaultingCodeRange wasmStore(const wasm::MemoryAccessDesc& access,
+                              AnyRegister value, Register memoryBase,
+                              Register ptr) DEFINED_ON(arm64);
+  FaultingCodeRange wasmStoreI64(const wasm::MemoryAccessDesc& access,
+                                 Register64 value, Register memoryBase,
+                                 Register ptr) DEFINED_ON(arm64);
 
   // RISCV64 additionally supports ZeroExtendIndex. The other parameters are the
   // same as for ARM64.
-  void wasmLoad(const wasm::MemoryAccessDesc& access, Register memoryBase,
-                Register ptr, AnyRegister output,
-                wasm::ZeroExtendIndex zeroExtend) DEFINED_ON(riscv64);
-  void wasmLoadI64(const wasm::MemoryAccessDesc& access, Register memoryBase,
-                   Register ptr, Register64 output,
-                   wasm::ZeroExtendIndex zeroExtend) DEFINED_ON(riscv64);
-  void wasmStore(const wasm::MemoryAccessDesc& access, AnyRegister value,
-                 Register memoryBase, Register ptr,
-                 wasm::ZeroExtendIndex zeroExtend) DEFINED_ON(riscv64);
-  void wasmStoreI64(const wasm::MemoryAccessDesc& access, Register64 value,
-                    Register memoryBase, Register ptr,
-                    wasm::ZeroExtendIndex zeroExtend) DEFINED_ON(riscv64);
+  FaultingCodeRange wasmLoad(const wasm::MemoryAccessDesc& access,
+                             Register memoryBase, Register ptr,
+                             AnyRegister output,
+                             wasm::ZeroExtendIndex zeroExtend)
+      DEFINED_ON(riscv64);
+  FaultingCodeRange wasmLoadI64(const wasm::MemoryAccessDesc& access,
+                                Register memoryBase, Register ptr,
+                                Register64 output,
+                                wasm::ZeroExtendIndex zeroExtend)
+      DEFINED_ON(riscv64);
+  FaultingCodeRange wasmStore(const wasm::MemoryAccessDesc& access,
+                              AnyRegister value, Register memoryBase,
+                              Register ptr, wasm::ZeroExtendIndex zeroExtend)
+      DEFINED_ON(riscv64);
+  FaultingCodeRange wasmStoreI64(const wasm::MemoryAccessDesc& access,
+                                 Register64 value, Register memoryBase,
+                                 Register ptr, wasm::ZeroExtendIndex zeroExtend)
+      DEFINED_ON(riscv64);
 
   // `ptr` will always be updated.
   void wasmUnalignedLoad(const wasm::MemoryAccessDesc& access,
@@ -4094,9 +4129,9 @@ class MacroAssembler : public MacroAssemblerSpecific {
   // itself being out of bounds.
   //
   // `length` and `limit` will be unchanged.
-  void wasmBoundsCheckRange32(Register index, Register length, Register limit,
-                              Register tmp,
-                              const wasm::TrapSiteDesc& trapSiteDesc);
+  FaultingCodeRange wasmBoundsCheckRange32(
+      Register index, Register length, Register limit, Register tmp,
+      const wasm::TrapSiteDesc& trapSiteDesc);
 
   // Returns information about which registers are necessary for a
   // branchWasmRefIsSubtype call.
@@ -4574,84 +4609,95 @@ class MacroAssembler : public MacroAssemblerSpecific {
   // Constraints, when omitted, are exactly as for the primitive operations
   // above.
 
-  void wasmCompareExchange(const wasm::MemoryAccessDesc& access,
-                           const Address& mem, Register expected,
-                           Register replacement, Register output)
+  FaultingCodeRange wasmCompareExchange(const wasm::MemoryAccessDesc& access,
+                                        const Address& mem, Register expected,
+                                        Register replacement, Register output)
       DEFINED_ON(arm, arm64, x86_shared);
 
-  void wasmCompareExchange(const wasm::MemoryAccessDesc& access,
-                           const BaseIndex& mem, Register expected,
-                           Register replacement, Register output)
+  FaultingCodeRange wasmCompareExchange(const wasm::MemoryAccessDesc& access,
+                                        const BaseIndex& mem, Register expected,
+                                        Register replacement, Register output)
       DEFINED_ON(arm, arm64, x86_shared);
 
-  void wasmCompareExchange(const wasm::MemoryAccessDesc& access,
-                           const Address& mem, Register expected,
-                           Register replacement, Register valueTemp,
-                           Register offsetTemp, Register maskTemp,
-                           Register output)
+  FaultingCodeRange wasmCompareExchange(const wasm::MemoryAccessDesc& access,
+                                        const Address& mem, Register expected,
+                                        Register replacement,
+                                        Register valueTemp, Register offsetTemp,
+                                        Register maskTemp, Register output)
       DEFINED_ON(mips64, loong64, riscv64);
 
-  void wasmCompareExchange(const wasm::MemoryAccessDesc& access,
-                           const BaseIndex& mem, Register expected,
-                           Register replacement, Register valueTemp,
-                           Register offsetTemp, Register maskTemp,
-                           Register output)
+  FaultingCodeRange wasmCompareExchange(const wasm::MemoryAccessDesc& access,
+                                        const BaseIndex& mem, Register expected,
+                                        Register replacement,
+                                        Register valueTemp, Register offsetTemp,
+                                        Register maskTemp, Register output)
       DEFINED_ON(mips64, loong64, riscv64);
 
-  void wasmCompareExchange(const wasm::MemoryAccessDesc& access,
-                           const BaseIndex& mem, Register expected,
-                           Register replacement, Register valueTemp,
-                           Register offsetTemp, Register maskTemp,
-                           Register output, wasm::ZeroExtendIndex zeroExtend)
+  FaultingCodeRange wasmCompareExchange(const wasm::MemoryAccessDesc& access,
+                                        const BaseIndex& mem, Register expected,
+                                        Register replacement,
+                                        Register valueTemp, Register offsetTemp,
+                                        Register maskTemp, Register output,
+                                        wasm::ZeroExtendIndex zeroExtend)
       DEFINED_ON(loong64, riscv64);
 
-  void wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
-                          const Address& mem, Register value, Register output)
+  FaultingCodeRange wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
+                                       const Address& mem, Register value,
+                                       Register output)
       DEFINED_ON(arm, arm64, x86_shared);
 
-  void wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
-                          const BaseIndex& mem, Register value, Register output)
+  FaultingCodeRange wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
+                                       const BaseIndex& mem, Register value,
+                                       Register output)
       DEFINED_ON(arm, arm64, x86_shared);
 
-  void wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
-                          const Address& mem, Register value,
-                          Register valueTemp, Register offsetTemp,
-                          Register maskTemp, Register output)
+  FaultingCodeRange wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
+                                       const Address& mem, Register value,
+                                       Register valueTemp, Register offsetTemp,
+                                       Register maskTemp, Register output)
       DEFINED_ON(mips64, loong64, riscv64);
 
-  void wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
-                          const BaseIndex& mem, Register value,
-                          Register valueTemp, Register offsetTemp,
-                          Register maskTemp, Register output)
+  FaultingCodeRange wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
+                                       const BaseIndex& mem, Register value,
+                                       Register valueTemp, Register offsetTemp,
+                                       Register maskTemp, Register output)
       DEFINED_ON(mips64, loong64, riscv64);
 
-  void wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
-                          const BaseIndex& mem, Register value,
-                          Register valueTemp, Register offsetTemp,
-                          Register maskTemp, Register output,
-                          wasm::ZeroExtendIndex zeroExtend)
+  FaultingCodeRange wasmAtomicExchange(const wasm::MemoryAccessDesc& access,
+                                       const BaseIndex& mem, Register value,
+                                       Register valueTemp, Register offsetTemp,
+                                       Register maskTemp, Register output,
+                                       wasm::ZeroExtendIndex zeroExtend)
       DEFINED_ON(loong64, riscv64);
 
-  void wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access, AtomicOp op,
-                         Register value, const Address& mem, Register temp,
-                         Register output) DEFINED_ON(arm, arm64, x86_shared);
+  FaultingCodeRange wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access,
+                                      AtomicOp op, Register value,
+                                      const Address& mem, Register temp,
+                                      Register output)
+      DEFINED_ON(arm, arm64, x86_shared);
 
-  void wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access, AtomicOp op,
-                         Imm32 value, const Address& mem, Register temp,
-                         Register output) DEFINED_ON(x86_shared);
+  FaultingCodeRange wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access,
+                                      AtomicOp op, Imm32 value,
+                                      const Address& mem, Register temp,
+                                      Register output) DEFINED_ON(x86_shared);
 
-  void wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access, AtomicOp op,
-                         Register value, const BaseIndex& mem, Register temp,
-                         Register output) DEFINED_ON(arm, arm64, x86_shared);
+  FaultingCodeRange wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access,
+                                      AtomicOp op, Register value,
+                                      const BaseIndex& mem, Register temp,
+                                      Register output)
+      DEFINED_ON(arm, arm64, x86_shared);
 
-  void wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access, AtomicOp op,
-                         Imm32 value, const BaseIndex& mem, Register temp,
-                         Register output) DEFINED_ON(x86_shared);
+  FaultingCodeRange wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access,
+                                      AtomicOp op, Imm32 value,
+                                      const BaseIndex& mem, Register temp,
+                                      Register output) DEFINED_ON(x86_shared);
 
-  void wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access, AtomicOp op,
-                         Register value, const Address& mem, Register valueTemp,
-                         Register offsetTemp, Register maskTemp,
-                         Register output) DEFINED_ON(mips64, loong64, riscv64);
+  FaultingCodeRange wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access,
+                                      AtomicOp op, Register value,
+                                      const Address& mem, Register valueTemp,
+                                      Register offsetTemp, Register maskTemp,
+                                      Register output)
+      DEFINED_ON(mips64, loong64, riscv64);
 
   void wasmAtomicFetchOp(const wasm::MemoryAccessDesc& access, AtomicOp op,
                          Register value, const BaseIndex& mem,
@@ -4713,13 +4759,15 @@ class MacroAssembler : public MacroAssemblerSpecific {
   // x86: `temp` must be ecx:ebx; `output` must be edx:eax.
   // ARM: `temp` should be invalid; `output` must be (even,odd) pair.
 
-  void wasmAtomicLoad64(const wasm::MemoryAccessDesc& access,
-                        const Address& mem, Register64 temp, Register64 output)
+  FaultingCodeRange wasmAtomicLoad64(const wasm::MemoryAccessDesc& access,
+                                     const Address& mem, Register64 temp,
+                                     Register64 output)
       DEFINED_ON(arm, x86, wasm32);
 
-  void wasmAtomicLoad64(const wasm::MemoryAccessDesc& access,
-                        const BaseIndex& mem, Register64 temp,
-                        Register64 output) DEFINED_ON(arm, x86, wasm32);
+  FaultingCodeRange wasmAtomicLoad64(const wasm::MemoryAccessDesc& access,
+                                     const BaseIndex& mem, Register64 temp,
+                                     Register64 output)
+      DEFINED_ON(arm, x86, wasm32);
 
   // x86: `expected` must be the same as `output`, and must be edx:eax.
   // x86: `replacement` must be ecx:ebx.
@@ -4729,15 +4777,17 @@ class MacroAssembler : public MacroAssemblerSpecific {
   // ARM64: The base register in `mem` must not overlap `output`.
   // MIPS: Registers must be distinct.
 
-  void wasmCompareExchange64(const wasm::MemoryAccessDesc& access,
-                             const Address& mem, Register64 expected,
-                             Register64 replacement,
-                             Register64 output) PER_ARCH;
+  FaultingCodeRange wasmCompareExchange64(const wasm::MemoryAccessDesc& access,
+                                          const Address& mem,
+                                          Register64 expected,
+                                          Register64 replacement,
+                                          Register64 output) PER_ARCH;
 
-  void wasmCompareExchange64(const wasm::MemoryAccessDesc& access,
-                             const BaseIndex& mem, Register64 expected,
-                             Register64 replacement,
-                             Register64 output) PER_ARCH;
+  FaultingCodeRange wasmCompareExchange64(const wasm::MemoryAccessDesc& access,
+                                          const BaseIndex& mem,
+                                          Register64 expected,
+                                          Register64 replacement,
+                                          Register64 output) PER_ARCH;
 
   void wasmCompareExchange64(const wasm::MemoryAccessDesc& access,
                              const BaseIndex& mem, Register64 expected,
@@ -4750,13 +4800,13 @@ class MacroAssembler : public MacroAssemblerSpecific {
   // pairs.
   // MIPS: Registers must be distinct.
 
-  void wasmAtomicExchange64(const wasm::MemoryAccessDesc& access,
-                            const Address& mem, Register64 value,
-                            Register64 output) PER_ARCH;
+  FaultingCodeRange wasmAtomicExchange64(const wasm::MemoryAccessDesc& access,
+                                         const Address& mem, Register64 value,
+                                         Register64 output) PER_ARCH;
 
-  void wasmAtomicExchange64(const wasm::MemoryAccessDesc& access,
-                            const BaseIndex& mem, Register64 value,
-                            Register64 output) PER_ARCH;
+  FaultingCodeRange wasmAtomicExchange64(const wasm::MemoryAccessDesc& access,
+                                         const BaseIndex& mem, Register64 value,
+                                         Register64 output) PER_ARCH;
 
   void wasmAtomicExchange64(const wasm::MemoryAccessDesc& access,
                             const BaseIndex& mem, Register64 value,
@@ -4769,14 +4819,16 @@ class MacroAssembler : public MacroAssemblerSpecific {
   // pairs.
   // MIPS: Registers must be distinct.
 
-  void wasmAtomicFetchOp64(const wasm::MemoryAccessDesc& access, AtomicOp op,
... (file diff truncated)
Loading diff…