Firefox · SpiderMonkey
CVE-2026-2786
UAF in SpiderMonkey
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifjs/public/Realm.h |
modified | |
BEGIN_TESTjs/src/jsapi-tests/testGCExactRooting.cpp |
modified | |
ifjs/src/vm/Realm.cpp |
modified |
Files Changed
js/public/Realm.hjs/src/jsapi-tests/testGCExactRooting.cppjs/src/vm/Realm.cppjs/src/vm/Realm.h
Patch
diff --git a/js/public/Realm.h b/js/public/Realm.h
index 072565e9e24..526a852ba1b 100644
--- a/js/public/Realm.h
+++ b/js/public/Realm.h
@@ -21,8 +21,8 @@
namespace js {
namespace gc {
-JS_PUBLIC_API void TraceRealm(JSTracer* trc, JS::Realm* realm,
- const char* name);
+JS_PUBLIC_API void TraceRealmRoot(JSTracer* trc, JS::Realm* realm,
+ const char* name);
} // namespace gc
} // namespace js
@@ -34,7 +34,7 @@ template <>
struct GCPolicy<Realm*> : public NonGCPointerPolicy<Realm*> {
static void trace(JSTracer* trc, Realm** vp, const char* name) {
if (*vp) {
- ::js::gc::TraceRealm(trc, *vp, name);
+ ::js::gc::TraceRealmRoot(trc, *vp, name);
}
}
};
diff --git a/js/src/jsapi-tests/testGCExactRooting.cpp b/js/src/jsapi-tests/testGCExactRooting.cpp
index 7afcc7727e1..35993639f85 100644
--- a/js/src/jsapi-tests/testGCExactRooting.cpp
+++ b/js/src/jsapi-tests/testGCExactRooting.cpp
@@ -1069,3 +1069,27 @@ BEGIN_TEST(testRootedCopying) {
return true;
}
END_TEST(testRootedCopying)
+
+BEGIN_TEST(testRootedRealm) {
+ // Create a new global and use Rooted<Realm*> to keep it alive.
+ Rooted<Realm*> realm(cx);
+ {
+ JS::RealmOptions globalOptions;
+ JSObject* otherGlobal = JS_NewGlobalObject(
+ cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, globalOptions);
+ CHECK(otherGlobal);
+ realm = JS::GetObjectRealmOrNull(otherGlobal);
+ CHECK(realm);
+ }
+
+ JS_GC(cx);
+
+ // Use the realm.
+ JSAutoRealm ar(cx, JS::GetRealmGlobalOrNull(realm));
+ JS::RootedValue v(cx);
+ EVAL("let x = -1234; Math.abs(x)", &v);
+ CHECK(v.toNumber() == 1234);
+
+ return true;
+}
+END_TEST(testRootedRealm)
diff --git a/js/src/vm/Realm.cpp b/js/src/vm/Realm.cpp
index f313294b833..6ef1690d999 100644
--- a/js/src/vm/Realm.cpp
+++ b/js/src/vm/Realm.cpp
@@ -252,6 +252,12 @@ void Realm::traceGlobalData(JSTracer* trc) {
DebugAPI::traceFromRealm(trc, this);
}
+void Realm::traceGlobalRoot(JSTracer* trc, const char* name) {
+ if (global_) {
+ TraceRoot(trc, global_.unbarrieredAddress(), name);
+ }
+}
+
void ObjectRealm::trace(JSTracer* trc) {
if (objectMetadataTable) {
objectMetadataTable->trace(trc);
@@ -274,8 +280,8 @@ void Realm::traceRoots(JSTracer* trc,
//
// If a realm is on-stack, we mark its global so that JSContext::global()
// remains valid.
- if (shouldTraceGlobal() && global_) {
- TraceRoot(trc, global_.unbarrieredAddress(), "on-stack realm global");
+ if (shouldTraceGlobal()) {
+ traceGlobalRoot(trc, "on-stack realm global");
}
// If the realm is still being initialized we set a flag so that it doesn't
@@ -690,16 +696,16 @@ void AutoSetNewObjectMetadata::setPendingMetadata() {
(void)SetNewObjectMetadata(cx_, obj);
}
-JS_PUBLIC_API void gc::TraceRealm(JSTracer* trc, JS::Realm* realm,
- const char* name) {
- // The way GC works with compartments is basically incomprehensible.
- // For Realms, what we want is very simple: each Realm has a strong
- // reference to its GlobalObject, and vice versa.
+JS_PUBLIC_API void gc::TraceRealmRoot(JSTracer* trc, JS::Realm* realm,
+ const char* name) {
+ // Trace the realm's global object to keep the realm alive.
//
- // Here we simply trace our side of that edge. During GC,
- // GCRuntime::traceRuntimeCommon() marks all other realm roots, for
- // all realms.
- realm->traceGlobalData(trc);
+ // Note: this is called for Rooted<Realm*>. If a realm has been entered with
+ // AutoRealm, the global object is traced in Realm::traceRoots.
+ MOZ_RELEASE_ASSERT(realm->hasLiveGlobal(),
+ "we need to have a global to keep the realm alive");
+ gc::AssertRootMarkingPhase(trc);
+ realm->traceGlobalRoot(trc, "rooted realm");
}
JS_PUBLIC_API JS::Realm* JS::GetCurrentRealmOrNull(JSContext* cx) {
diff --git a/js/src/vm/Realm.h b/js/src/vm/Realm.h
index aba85bc7b72..9816e52b848 100644
--- a/js/src/vm/Realm.h
+++ b/js/src/vm/Realm.h
@@ -557,6 +557,8 @@ class JS::Realm : public JS::shadow::Realm {
*/
void traceGlobalData(JSTracer* trc);
+ void traceGlobalRoot(JSTracer* trc, const char* name);
+
void traceWeakGlobalEdge(JSTracer* trc);
/*
Loading diff…
References
On This Page