Firefox · SpiderMonkey
CVE-2026-118007
Logic Error in SpiderMonkey
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifjs/src/vm/JSContext.cpp |
modified |
Files Changed
js/src/gc/AtomMarking-inl.hjs/src/gc/AtomMarking.cppjs/src/gc/AtomMarking.hjs/src/vm/JSContext.cppjs/src/vm/JSContext.h
Patch
diff --git a/js/src/gc/AtomMarking-inl.h b/js/src/gc/AtomMarking-inl.h
index 2eeb4871811..9584c0a4d9f 100644
--- a/js/src/gc/AtomMarking-inl.h
+++ b/js/src/gc/AtomMarking-inl.h
@@ -216,6 +216,17 @@ MOZ_ALWAYS_INLINE bool AtomRefRuntime::inlinedRecordRefFallible(Zone* zone,
return inlinedRecordRefInternal(zone, thing, lock);
}
+template <typename T>
+void AtomRefRuntime::recordRef(JSContext* cx, T* thing) {
+ // Trigger a read barrier on the atom, in case there is an incremental
+ // GC in progress. This is necessary if the atom is being marked
+ // because a reference to it was obtained from another zone which is
+ // not being collected by the incremental GC.
+ ReadBarrier(thing);
+
+ inlinedRecordRefInfallible(cx->zone(), thing);
+}
+
} // namespace gc
} // namespace js
diff --git a/js/src/gc/AtomMarking.cpp b/js/src/gc/AtomMarking.cpp
index 960a77b763a..8cfad994783 100644
--- a/js/src/gc/AtomMarking.cpp
+++ b/js/src/gc/AtomMarking.cpp
@@ -360,46 +360,9 @@ void AtomRefRuntime::unmarkAllGrayReferences(GCRuntime* gc) {
}
}
-template <typename T>
-void AtomRefRuntime::recordRef(JSContext* cx, T* thing) {
- // Trigger a read barrier on the atom, in case there is an incremental
- // GC in progress. This is necessary if the atom is being marked
- // because a reference to it was obtained from another zone which is
- // not being collected by the incremental GC.
- ReadBarrier(thing);
-
- inlinedRecordRefInfallible(cx->zone(), thing);
-}
-
template void AtomRefRuntime::recordRef(JSContext* cx, JSAtom* thing);
template void AtomRefRuntime::recordRef(JSContext* cx, JS::Symbol* thing);
-void AtomRefRuntime::recordRefToId(JSContext* cx, jsid id) {
- if (id.isAtom()) {
- recordRef(cx, id.toAtom());
- return;
- }
- if (id.isSymbol()) {
- recordRef(cx, id.toSymbol());
- return;
- }
- MOZ_ASSERT(!id.isGCThing());
-}
-
-void AtomRefRuntime::recordRefToValue(JSContext* cx, const Value& value) {
- if (value.isString()) {
- if (value.toString()->isAtom()) {
- recordRef(cx, &value.toString()->asAtom());
- }
- return;
- }
- if (value.isSymbol()) {
- recordRef(cx, value.toSymbol());
- return;
- }
- MOZ_ASSERT(!value.isGCThing());
-}
-
template <typename T>
CellColor AtomRefRuntime::getRefColor(Zone* zone, T* thing) {
static_assert(std::is_same_v<T, JSAtom> || std::is_same_v<T, JS::Symbol>,
diff --git a/js/src/gc/AtomMarking.h b/js/src/gc/AtomMarking.h
index 2db6b53e6a4..b258a8f92af 100644
--- a/js/src/gc/AtomMarking.h
+++ b/js/src/gc/AtomMarking.h
@@ -105,9 +105,6 @@ class AtomRefRuntime {
[[nodiscard]] MOZ_ALWAYS_INLINE bool inlinedRecordRefFallible(Zone* zone,
T* thing);
- void recordRefToId(JSContext* cx, jsid id);
- void recordRefToValue(JSContext* cx, const Value& value);
-
// Get the reference color of |thing| in the atom reference bitmap for |zone|.
template <typename T>
CellColor getRefColor(Zone* zone, T* thing);
diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp
index 7e6ccf7e955..87e676bd501 100644
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -30,6 +30,7 @@
# include "debugger/ExecutionTracer.h"
#endif
#include "frontend/FrontendContext.h"
+#include "gc/AtomMarking.h"
#include "gc/GC.h"
#include "gc/PublicIterators.h" // js::RealmsIter
#include "irregexp/RegExpAPI.h"
@@ -1562,6 +1563,47 @@ JSScript* JSContext::currentScript(jsbytecode** ppc,
return script;
}
+void JSContext::recordRef(JSAtom* atom) {
+ atomReferences().recordRef(this, atom);
+}
+
+bool JSContext::wrapOrRecordRef(JS::MutableHandle<JS::Symbol*> symbol) {
+ atomReferences().recordRef(this, symbol.get());
+ return true;
+}
+
+bool JSContext::wrapOrRecordRefToId(JS::MutableHandle<jsid> id) {
+ if (id.isAtom()) {
+ atomReferences().recordRef(this, id.toAtom());
+ return true;
+ }
+
+ if (id.isSymbol()) {
+ atomReferences().recordRef(this, id.toSymbol());
+ return true;
+ }
+
+ MOZ_ASSERT(!id.isGCThing());
+ return true;
+}
+
+bool JSContext::wrapOrRecordRefToValue(JS::MutableHandle<JS::Value> value) {
+ if (value.isString()) {
+ if (value.toString()->isAtom()) {
+ atomReferences().recordRef(this, &value.toString()->asAtom());
+ }
+ return true;
+ }
+
+ if (value.isSymbol()) {
+ atomReferences().recordRef(this, value.toSymbol());
+ return true;
+ }
+
+ MOZ_ASSERT(!value.isGCThing());
+ return true;
+}
+
#ifdef JS_CRASH_DIAGNOSTICS
void ContextChecks::check(AbstractFramePtr frame, int argIndex) {
if (frame) {
diff --git a/js/src/vm/JSContext.h b/js/src/vm/JSContext.h
index 224b80db712..0ee80aa3d15 100644
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -435,19 +435,10 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
return runtime_->gc.atomReferences;
}
- void recordRef(JSAtom* atom) { atomReferences().recordRef(this, atom); }
- bool wrapOrRecordRef(JS::MutableHandle<JS::Symbol*> symbol) {
- atomReferences().recordRef(this, symbol.get());
- return true;
- }
- bool wrapOrRecordRefToId(JS::MutableHandle<jsid> id) {
- atomReferences().recordRefToId(this, id);
- return true;
- }
- bool wrapOrRecordRefToValue(JS::MutableHandle<JS::Value> value) {
- atomReferences().recordRefToValue(this, value);
- return true;
- }
+ void recordRef(JSAtom* atom);
+ bool wrapOrRecordRef(JS::MutableHandle<JS::Symbol*> symbol);
+ bool wrapOrRecordRefToId(JS::MutableHandle<jsid> id);
+ bool wrapOrRecordRefToValue(JS::MutableHandle<JS::Value> value);
// Interface for recording telemetry metrics.
js::Metrics metrics() { return js::Metrics(runtime_); }
Loading diff…
References
On This Page