Firefox · SpiderMonkey
CVE-2026-100796
Logic Error in SpiderMonkey
Overview
Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifjs/src/jit/arm/MacroAssembler-arm.cpp |
modified | |
ifjs/src/jit/arm64/CodeGenerator-arm64.cpp |
modified | |
ifjs/src/jit/arm64/MacroAssembler-arm64.cpp |
modified |
Files Changed
js/src/jit/MacroAssembler.cppjs/src/jit/MacroAssembler.hjs/src/jit/arm/CodeGenerator-arm.cppjs/src/jit/arm/MacroAssembler-arm.cppjs/src/jit/arm/MacroAssembler-arm.hjs/src/jit/arm64/CodeGenerator-arm64.cppjs/src/jit/arm64/MacroAssembler-arm64.cppjs/src/jit/loong64/MacroAssembler-loong64.cppjs/src/jit/mips-shared/MacroAssembler-mips-shared.cppjs/src/jit/riscv64/CodeGenerator-riscv64.cppjs/src/jit/riscv64/MacroAssembler-riscv64.cppjs/src/jit/wasm32/MacroAssembler-wasm32.cppjs/src/jit/x86-shared/CodeGenerator-x86-shared.cppjs/src/jit/x86-shared/MacroAssembler-x86-shared.cppjs/src/wasm/WasmBaselineCompile.cppjs/src/wasm/WasmCodegenTypes.h
Patch
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
index 8eefa58edff..03f5c97aabf 100644
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -6206,13 +6206,14 @@ void MacroAssembler::appendAndVerify(const wasm::MemoryAccessDesc& access,
appendAndVerify(wasm::Trap::OutOfBounds, insn, fcr, access.trapDesc());
}
-void MacroAssembler::wasmTrap(wasm::Trap trap,
- const wasm::TrapSiteDesc& trapSiteDesc) {
+FaultingCodeRange MacroAssembler::wasmTrap(
+ wasm::Trap trap, const wasm::TrapSiteDesc& trapSiteDesc) {
FaultingCodeRange fcr = wasmTrapInstruction();
MOZ_ASSERT_IF(!oom(),
currentOffset() - fcr.get() == WasmTrapInstructionLength);
appendAndVerify(trap, wasm::TrapMachineInsn::OfficialUD, fcr, trapSiteDesc);
+ return fcr;
}
uint32_t MacroAssembler::wasmReserveStackChecked(uint32_t amount, Label* fail) {
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
index 5e0a21a7feb..2b5c16817af 100644
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -3790,7 +3790,8 @@ class MacroAssembler : public MacroAssemblerSpecific {
void appendAndVerify(const wasm::MemoryAccessDesc& access,
wasm::TrapMachineInsn insn, FaultingCodeRange fcr);
- void wasmTrap(wasm::Trap trap, const wasm::TrapSiteDesc& trapSiteDesc);
+ FaultingCodeRange wasmTrap(wasm::Trap trap,
+ const wasm::TrapSiteDesc& trapSiteDesc);
// Load all pinned regs via InstanceReg. If the trapOffset is something,
// give the first load a trap descriptor with type IndirectCallToNull, so that
@@ -3935,20 +3936,22 @@ class MacroAssembler : public MacroAssemblerSpecific {
void wasmTruncateDoubleToInt32(FloatRegister input, Register output,
bool isSaturating,
Label* oolEntry) PER_SHARED_ARCH;
- void oolWasmTruncateCheckF64ToI32(FloatRegister input, Register output,
- TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc,
- Label* rejoin) PER_SHARED_ARCH;
+ void oolWasmTruncateCheckF64ToI32(
+ FloatRegister input, Register output, TruncFlags flags,
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) PER_SHARED_ARCH;
void wasmTruncateFloat32ToUInt32(FloatRegister input, Register output,
bool isSaturating, Label* oolEntry) PER_ARCH;
void wasmTruncateFloat32ToInt32(FloatRegister input, Register output,
bool isSaturating,
Label* oolEntry) PER_SHARED_ARCH;
- void oolWasmTruncateCheckF32ToI32(FloatRegister input, Register output,
- TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc,
- Label* rejoin) PER_SHARED_ARCH;
+ void oolWasmTruncateCheckF32ToI32(
+ FloatRegister input, Register output, TruncFlags flags,
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) PER_SHARED_ARCH;
// The truncate-to-int64 methods will always bind the `oolRejoin` label
// after the last emitted instruction.
@@ -3960,10 +3963,11 @@ class MacroAssembler : public MacroAssemblerSpecific {
bool isSaturating, Label* oolEntry,
Label* oolRejoin, FloatRegister tempDouble)
DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64, wasm32);
- void oolWasmTruncateCheckF64ToI64(FloatRegister input, Register64 output,
- TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc,
- Label* rejoin) PER_SHARED_ARCH;
+ void oolWasmTruncateCheckF64ToI64(
+ FloatRegister input, Register64 output, TruncFlags flags,
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) PER_SHARED_ARCH;
void wasmTruncateFloat32ToInt64(FloatRegister input, Register64 output,
bool isSaturating, Label* oolEntry,
@@ -3973,10 +3977,11 @@ class MacroAssembler : public MacroAssemblerSpecific {
bool isSaturating, Label* oolEntry,
Label* oolRejoin, FloatRegister tempDouble)
DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64, wasm32);
- void oolWasmTruncateCheckF32ToI64(FloatRegister input, Register64 output,
- TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc,
- Label* rejoin) PER_SHARED_ARCH;
+ void oolWasmTruncateCheckF32ToI64(
+ FloatRegister input, Register64 output, TruncFlags flags,
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) PER_SHARED_ARCH;
// This function takes care of loading the callee's instance and pinned regs
// but it is the caller's responsibility to save/restore instance or pinned
diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp
index e80799d2b5e..cb95d2e8d7d 100644
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -2168,9 +2168,9 @@ void CodeGeneratorARM::visitOutOfLineWasmTruncateCheck(
return;
}
- masm.outOfLineWasmTruncateToIntCheck(ool->input(), ool->fromType(),
- ool->toType(), ool->isUnsigned(),
- ool->rejoin(), ool->trapSiteDesc());
+ masm.outOfLineWasmTruncateToIntCheck(
+ ool->input(), ool->fromType(), ool->toType(), ool->isUnsigned(),
+ ool->rejoin(), ool->trapSiteDesc(), nullptr, nullptr);
}
void CodeGenerator::visitInt64ToFloatingPointCall(
diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp
index 20938b833e9..626714d88cd 100644
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -5013,30 +5013,42 @@ void MacroAssembler::wasmTruncateFloat32ToInt32(FloatRegister input,
void MacroAssembler::oolWasmTruncateCheckF32ToI32(
FloatRegister input, Register output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
outOfLineWasmTruncateToIntCheck(input, MIRType::Float32, MIRType::Int32,
- flags, rejoin, trapSiteDesc);
+ flags, rejoin, trapSiteDesc, stackMapForTraps,
+ stackMapRegistry);
}
void MacroAssembler::oolWasmTruncateCheckF64ToI32(
FloatRegister input, Register output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
outOfLineWasmTruncateToIntCheck(input, MIRType::Double, MIRType::Int32, flags,
- rejoin, trapSiteDesc);
+ rejoin, trapSiteDesc, stackMapForTraps,
+ stackMapRegistry);
}
void MacroAssembler::oolWasmTruncateCheckF32ToI64(
FloatRegister input, Register64 output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
outOfLineWasmTruncateToIntCheck(input, MIRType::Float32, MIRType::Int64,
- flags, rejoin, trapSiteDesc);
+ flags, rejoin, trapSiteDesc, stackMapForTraps,
+ stackMapRegistry);
}
void MacroAssembler::oolWasmTruncateCheckF64ToI64(
FloatRegister input, Register64 output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
outOfLineWasmTruncateToIntCheck(input, MIRType::Double, MIRType::Int64, flags,
- rejoin, trapSiteDesc);
+ rejoin, trapSiteDesc, stackMapForTraps,
+ stackMapRegistry);
}
void MacroAssembler::wasmLoad(const wasm::MemoryAccessDesc& access,
@@ -6257,7 +6269,9 @@ void MacroAssemblerARM::wasmTruncateToInt32(FloatRegister input,
void MacroAssemblerARM::outOfLineWasmTruncateToIntCheck(
FloatRegister input, MIRType fromType, MIRType toType, TruncFlags flags,
- Label* rejoin, const wasm::TrapSiteDesc& trapSiteDesc) {
+ Label* rejoin, const wasm::TrapSiteDesc& trapSiteDesc,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
// On ARM, saturating truncation codegen handles saturating itself rather
// than relying on out-of-line fixup code.
if (flags & TRUNC_SATURATING) {
@@ -6340,10 +6354,18 @@ void MacroAssemblerARM::outOfLineWasmTruncateToIntCheck(
// Handle errors.
bind(&fail);
- asMasm().wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ FaultingCodeRange fcr1 =
+ asMasm().wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr1));
+ }
bind(&inputIsNaN);
- asMasm().wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ FaultingCodeRange fcr2 =
+ asMasm().wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr2));
+ }
}
void MacroAssemblerARM::wasmLoadImpl(const wasm::MemoryAccessDesc& access,
diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h
index 75d0b6cf2a0..4ad066e85ea 100644
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -131,10 +131,11 @@ class MacroAssemblerARM : public Assembler {
void wasmTruncateToInt32(FloatRegister input, Register output,
MIRType fromType, bool isUnsigned, bool isSaturating,
Label* oolEntry);
- void outOfLineWasmTruncateToIntCheck(FloatRegister input, MIRType fromType,
- MIRType toType, TruncFlags flags,
- Label* rejoin,
- const wasm::TrapSiteDesc& trapSiteDesc);
+ void outOfLineWasmTruncateToIntCheck(
+ FloatRegister input, MIRType fromType, MIRType toType, TruncFlags flags,
+ Label* rejoin, const wasm::TrapSiteDesc& trapSiteDesc,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry);
// Somewhat direct wrappers for the low-level assembler funcitons
// bitops. Attempt to encode a virtual alu instruction using two real
diff --git a/js/src/jit/arm64/CodeGenerator-arm64.cpp b/js/src/jit/arm64/CodeGenerator-arm64.cpp
index 6eac79f7c72..7e6ff1c86e5 100644
--- a/js/src/jit/arm64/CodeGenerator-arm64.cpp
+++ b/js/src/jit/arm64/CodeGenerator-arm64.cpp
@@ -2747,20 +2747,20 @@ void CodeGeneratorARM64::visitOutOfLineWasmTruncateCheck(
if (fromType == MIRType::Float32) {
if (toType == MIRType::Int32) {
masm.oolWasmTruncateCheckF32ToI32(input, output, flags, trapSiteDesc,
- oolRejoin);
+ oolRejoin, nullptr, nullptr);
} else if (toType == MIRType::Int64) {
masm.oolWasmTruncateCheckF32ToI64(input, output64, flags, trapSiteDesc,
- oolRejoin);
+ oolRejoin, nullptr, nullptr);
} else {
MOZ_CRASH("unexpected type");
}
} else if (fromType == MIRType::Double) {
if (toType == MIRType::Int32) {
masm.oolWasmTruncateCheckF64ToI32(input, output, flags, trapSiteDesc,
- oolRejoin);
+ oolRejoin, nullptr, nullptr);
} else if (toType == MIRType::Int64) {
masm.oolWasmTruncateCheckF64ToI64(input, output64, flags, trapSiteDesc,
- oolRejoin);
+ oolRejoin, nullptr, nullptr);
} else {
MOZ_CRASH("unexpected type");
}
diff --git a/js/src/jit/arm64/MacroAssembler-arm64.cpp b/js/src/jit/arm64/MacroAssembler-arm64.cpp
index b6e6cddac8f..f60c1d002d0 100644
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -2295,10 +2295,17 @@ void MacroAssembler::wasmTruncateFloat32ToInt64(
void MacroAssembler::oolWasmTruncateCheckF32ToI32(
FloatRegister input, Register output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
+ MOZ_ASSERT_IF(stackMapForTraps, stackMapRegistry);
Label notNaN;
branchFloat(Assembler::DoubleOrdered, input, input, ¬NaN);
- wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ FaultingCodeRange fcr1 =
+ wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr1));
+ }
bind(¬NaN);
Label isOverflow;
@@ -2318,15 +2325,25 @@ void MacroAssembler::oolWasmTruncateCheckF32ToI32(
branchFloat(Assembler::DoubleGreaterThanOrEqual, input, fpscratch, rejoin);
}
bind(&isOverflow);
- wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ FaultingCodeRange fcr2 = wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr2));
+ }
}
void MacroAssembler::oolWasmTruncateCheckF64ToI32(
FloatRegister input, Register output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
+ MOZ_ASSERT_IF(stackMapForTraps, stackMapRegistry);
Label notNaN;
branchDouble(Assembler::DoubleOrdered, input, input, ¬NaN);
- wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ FaultingCodeRange fcr1 =
+ wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr1));
+ }
bind(¬NaN);
Label isOverflow;
@@ -2346,15 +2363,25 @@ void MacroAssembler::oolWasmTruncateCheckF64ToI32(
branchDouble(Assembler::DoubleGreaterThan, input, fpscratch, rejoin);
}
bind(&isOverflow);
- wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ FaultingCodeRange fcr2 = wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr2));
+ }
}
void MacroAssembler::oolWasmTruncateCheckF32ToI64(
FloatRegister input, Register64 output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
+ MOZ_ASSERT_IF(stackMapForTraps, stackMapRegistry);
Label notNaN;
branchFloat(Assembler::DoubleOrdered, input, input, ¬NaN);
- wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ FaultingCodeRange fcr1 =
+ wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr1));
+ }
bind(¬NaN);
Label isOverflow;
@@ -2374,15 +2401,25 @@ void MacroAssembler::oolWasmTruncateCheckF32ToI64(
branchFloat(Assembler::DoubleGreaterThanOrEqual, input, fpscratch, rejoin);
}
bind(&isOverflow);
- wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ FaultingCodeRange fcr2 = wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr2));
+ }
}
void MacroAssembler::oolWasmTruncateCheckF64ToI64(
FloatRegister input, Register64 output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
+ MOZ_ASSERT_IF(stackMapForTraps, stackMapRegistry);
Label notNaN;
branchDouble(Assembler::DoubleOrdered, input, input, ¬NaN);
- wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ FaultingCodeRange fcr1 =
+ wasmTrap(wasm::Trap::InvalidConversionToInteger, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr1));
+ }
bind(¬NaN);
Label isOverflow;
@@ -2402,7 +2439,10 @@ void MacroAssembler::oolWasmTruncateCheckF64ToI64(
branchDouble(Assembler::DoubleGreaterThanOrEqual, input, fpscratch, rejoin);
}
bind(&isOverflow);
- wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ FaultingCodeRange fcr2 = wasmTrap(wasm::Trap::IntegerOverflow, trapSiteDesc);
+ if (stackMapRegistry) {
+ propagateOOM(stackMapRegistry->addMap(stackMapForTraps, fcr2));
+ }
}
void MacroAssembler::wasmLoad(const wasm::MemoryAccessDesc& access,
diff --git a/js/src/jit/loong64/MacroAssembler-loong64.cpp b/js/src/jit/loong64/MacroAssembler-loong64.cpp
index d41dc9a34a2..75ea202bdb0 100644
--- a/js/src/jit/loong64/MacroAssembler-loong64.cpp
+++ b/js/src/jit/loong64/MacroAssembler-loong64.cpp
@@ -3537,28 +3537,40 @@ void MacroAssembler::wasmTruncateFloat32ToInt64(
void MacroAssembler::oolWasmTruncateCheckF32ToI32(
FloatRegister input, Register output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
+ // FIXME
outOfLineWasmTruncateToInt32Check(input, output, MIRType::Float32, flags,
rejoin, trapSiteDesc);
}
void MacroAssembler::oolWasmTruncateCheckF64ToI32(
FloatRegister input, Register output, TruncFlags flags,
- const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin) {
+ const wasm::TrapSiteDesc& trapSiteDesc, Label* rejoin,
+ wasm::StackMap* stackMapForTraps,
+ wasm::StackMapRegistry* stackMapRegistry) {
+ // FIXME
outOfLineWasmTruncateToInt32Check(input, output, MIRType::Double, flags,
rejoin, trapSiteDesc);
... (file diff truncated)
Loading diff…
References
On This Page