Firefox · SpiderMonkey
CVE-2026-6758
UAF in SpiderMonkey
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
OutOfLineCodejs/src/wasm/WasmBCClass.h |
modified | |
OutOfLineAbortingTrapjs/src/wasm/WasmBaselineCompile.cpp |
modified | |
OutOfLineResumableTrapjs/src/wasm/WasmBaselineCompile.cpp |
modified | |
OutOfLineTrapjs/src/wasm/WasmBaselineCompile.cpp |
modified | |
ifjs/src/wasm/WasmBaselineCompile.cpp |
modified | |
lastOpcodeOffset_js/src/wasm/WasmBaselineCompile.cpp |
modified |
Files Changed
js/src/wasm/WasmBCClass.hjs/src/wasm/WasmBCCodegen-inl.hjs/src/wasm/WasmBCFrame.cppjs/src/wasm/WasmBaselineCompile.cpp
Patch
diff --git a/js/src/wasm/WasmBCClass.h b/js/src/wasm/WasmBCClass.h
index 99bf2ba09a7..976e3c3ac9e 100644
--- a/js/src/wasm/WasmBCClass.h
+++ b/js/src/wasm/WasmBCClass.h
@@ -32,6 +32,8 @@
namespace js {
namespace wasm {
+struct StackMap;
+
// Container for a piece of out-of-line code, the slow path that supports an
// operation.
class OutOfLineCode;
@@ -957,6 +959,10 @@ struct BaseCompiler final {
[[nodiscard]] bool createStackMap(
const char* who, HasDebugFrameWithLiveRefs debugFrameWithLiveRefs);
+ // Creates a stack map for an aborting trap instruction that will be emitted
+ // OOL.
+ [[nodiscard]] bool createAbortingOutOfLineTrapStackMap(StackMap** result);
+
////////////////////////////////////////////////////////////
//
// Control stack
@@ -1362,7 +1368,10 @@ struct BaseCompiler final {
inline TrapSiteDesc trapSiteDesc() const;
// Generate a trap instruction for the current bytecodeOffset.
- inline void trap(Trap t) const;
+ inline void trap(Trap t);
+
+ // Generate a trap instruction for given location and stack map.
+ inline void trap(Trap t, const TrapSiteDesc& trapSite, StackMap* stackMap);
// Abstracted helper for throwing, used for throw, rethrow, and rethrowing
// at the end of a series of catch blocks (if none matched the exception).
diff --git a/js/src/wasm/WasmBCCodegen-inl.h b/js/src/wasm/WasmBCCodegen-inl.h
index ca5a29b9fd7..896bc5165ab 100644
--- a/js/src/wasm/WasmBCCodegen-inl.h
+++ b/js/src/wasm/WasmBCCodegen-inl.h
@@ -211,7 +211,25 @@ RegRef BaseCompiler::captureReturnedRef() {
//
// Miscellaneous.
-void BaseCompiler::trap(Trap t) const { masm.wasmTrap(t, trapSiteDesc()); }
+void BaseCompiler::trap(Trap t) {
+ masm.wasmTrap(t, trapSiteDesc());
+
+ if (MOZ_LIKELY(!compilerEnv_.debugEnabled())) {
+ return;
+ }
+
+ masm.propagateOOM(
+ createStackMap("BaseCompiler::trap", HasDebugFrameWithLiveRefs::Maybe));
+}
+
+void BaseCompiler::trap(Trap t, const TrapSiteDesc& trapSite,
+ StackMap* stackMap) {
+ masm.wasmTrap(t, trapSite);
+
+ if (stackMap && !stackMaps_->add(masm.currentOffset(), stackMap)) {
+ masm.setOOM();
+ }
+}
void BaseCompiler::cmp64Set(Assembler::Condition cond, RegI64 lhs, RegI64 rhs,
RegI32 dest) {
diff --git a/js/src/wasm/WasmBCFrame.cpp b/js/src/wasm/WasmBCFrame.cpp
index cc2b1793420..45f3eeeed85 100644
--- a/js/src/wasm/WasmBCFrame.cpp
+++ b/js/src/wasm/WasmBCFrame.cpp
@@ -18,6 +18,7 @@
#include "wasm/WasmBCFrame.h"
+#include "mozilla/Likely.h"
#include "wasm/WasmBaselineCompile.h" // For BaseLocalIter
#include "wasm/WasmBCClass.h"
@@ -164,6 +165,18 @@ bool BaseCompiler::createStackMap(
(!stackMap || stackMaps_->add(masm.currentOffset(), stackMap));
}
+[[nodiscard]] bool BaseCompiler::createAbortingOutOfLineTrapStackMap(
+ StackMap** result) {
+ if (MOZ_LIKELY(!compilerEnv_.debugEnabled())) {
+ *result = nullptr;
+ return true;
+ }
+
+ ExitStubMapVector extras;
+ return stackMapGenerator_.createStackMap(
+ "OutOfLineTrap", extras, HasDebugFrameWithLiveRefs::Maybe, stk_, result);
+}
+
bool MachineStackTracker::cloneTo(MachineStackTracker* dst) {
MOZ_ASSERT(dst->vec_.empty());
if (!dst->vec_.appendAll(vec_)) {
diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp
index a231fed675b..2659565ce13 100644
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -213,40 +213,23 @@ class OutOfLineCode : public TempObject {
// All other registers must be explicitly saved and restored by the OOL code
// before being used.
- virtual void generate(MacroAssembler* masm) = 0;
+ virtual void generate(MacroAssembler* masm, BaseCompiler* bc) = 0;
};
-class OutOfLineAbortingTrap : public OutOfLineCode {
- Trap trap_;
- TrapSiteDesc desc_;
-
- public:
- OutOfLineAbortingTrap(Trap trap, const TrapSiteDesc& desc)
- : trap_(trap), desc_(desc) {}
-
- virtual void generate(MacroAssembler* masm) override {
- masm->wasmTrap(trap_, desc_);
- MOZ_ASSERT(!rejoin()->bound());
- }
-};
-
-class OutOfLineResumableTrap : public OutOfLineCode {
+class OutOfLineTrap : public OutOfLineCode {
Trap trap_;
TrapSiteDesc desc_;
wasm::StackMap* stackMap_;
- wasm::StackMaps* stackMaps_;
public:
- OutOfLineResumableTrap(Trap trap, const TrapSiteDesc& desc,
- wasm::StackMap* stackMap, wasm::StackMaps* stackMaps)
- : trap_(trap), desc_(desc), stackMap_(stackMap), stackMaps_(stackMaps) {}
+ OutOfLineTrap(Trap trap, const TrapSiteDesc& desc, wasm::StackMap* stackMap)
+ : trap_(trap), desc_(desc), stackMap_(stackMap) {}
- virtual void generate(MacroAssembler* masm) override {
- masm->wasmTrap(trap_, desc_);
- if (stackMap_ && !stackMaps_->add(masm->currentOffset(), stackMap_)) {
- masm->setOOM();
+ virtual void generate(MacroAssembler* masm, BaseCompiler* bc) override {
+ bc->trap(trap_, desc_, stackMap_);
+ if (rejoin()) {
+ masm->jump(rejoin());
}
- masm->jump(rejoin());
}
};
@@ -264,7 +247,7 @@ bool BaseCompiler::generateOutOfLineCode() {
continue;
}
ool->bind(&fr, &masm);
- ool->generate(&masm);
+ ool->generate(&masm, this);
}
return !masm.oom();
@@ -583,17 +566,16 @@ bool BaseCompiler::beginFunction() {
}
OutOfLineCode* oolStackOverflowTrap =
- addOutOfLineCode(new (alloc_) OutOfLineAbortingTrap(
+ addOutOfLineCode(new (alloc_) OutOfLineTrap(
Trap::StackOverflow,
- TrapSiteDesc(BytecodeOffset(func_.lineOrBytecode))));
+ TrapSiteDesc(BytecodeOffset(func_.lineOrBytecode)), nullptr));
if (!oolStackOverflowTrap) {
return false;
}
fr.checkStack(ABINonArgReg0, ABINonArgReg1, oolStackOverflowTrap->entry());
- OutOfLineCode* oolInterruptTrap = addOutOfLineCode(
- new (alloc_) OutOfLineResumableTrap(Trap::CheckInterrupt, trapSiteDesc(),
- functionEntryStackMap, stackMaps_));
+ OutOfLineCode* oolInterruptTrap = addOutOfLineCode(new (alloc_) OutOfLineTrap(
+ Trap::CheckInterrupt, trapSiteDesc(), functionEntryStackMap));
if (!oolInterruptTrap) {
return false;
}
@@ -1128,7 +1110,7 @@ class OutOfLineRequestTierUp : public OutOfLineCode {
: instance_(instance),
scratch_(scratch),
lastOpcodeOffset_(lastOpcodeOffset) {}
- virtual void generate(MacroAssembler* masm) override {
+ virtual void generate(MacroAssembler* masm, BaseCompiler* bc) override {
// Generate:
//
// [optionally, if `instance_` != InstanceReg: swap(instance_, InstanceReg)]
@@ -2071,8 +2053,12 @@ bool BaseCompiler::callIndirect(uint32_t funcTypeIndex, uint32_t tableIndex,
CallSiteDesc desc(bytecodeOffset(), CallSiteKind::Indirect);
CalleeDesc callee =
CalleeDesc::wasmTable(codeMeta_, table, tableIndex, callIndirectId);
- OutOfLineCode* oob = addOutOfLineCode(
- new (alloc_) OutOfLineAbortingTrap(Trap::OutOfBounds, trapSiteDesc()));
+ StackMap* oobTrapStackMap;
+ if (!createAbortingOutOfLineTrapStackMap(&oobTrapStackMap)) {
+ return false;
Loading diff…
References
On This Page