fix CVE-2023-25736 CVE-2023-29543
(cherry picked from commit f18e4a7a21b3f3850b01a7cc49eee1b13e42473c)
This commit is contained in:
parent
546611a075
commit
012c4e9746
@ -0,0 +1,35 @@
|
|||||||
|
From 57d312791ac30f049de79abfb12e1b65a5c9b738 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Olli Pettay <Olli.Pettay@helsinki.fi>
|
||||||
|
Date: Fri, 20 Jan 2023 16:34:12 +0000
|
||||||
|
Subject: [PATCH] remove useless static_cast, r=mccr8
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://hg.mozilla.org/integration/autoland/rev/84398671e7e1872f3ddf17f28b3f87905c6bd3d8
|
||||||
|
---
|
||||||
|
dom/base/Selection.cpp | 5 ++---
|
||||||
|
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp
|
||||||
|
index eb70edcc31..cd3164e392 100644
|
||||||
|
--- a/dom/base/Selection.cpp
|
||||||
|
+++ b/dom/base/Selection.cpp
|
||||||
|
@@ -442,14 +442,13 @@ static nsresult GetTableSelectionMode(const nsRange& aRange,
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
- nsIContent* startContent = static_cast<nsIContent*>(startNode);
|
||||||
|
- if (!(startNode->IsElement() && startContent->IsHTMLElement())) {
|
||||||
|
+ if (!startNode->IsHTMLElement()) {
|
||||||
|
// Implies a check for being an element; if we ever make this work
|
||||||
|
// for non-HTML, need to keep checking for elements.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (startContent->IsHTMLElement(nsGkAtoms::tr)) {
|
||||||
|
+ if (startNode->IsHTMLElement(nsGkAtoms::tr)) {
|
||||||
|
*aTableSelectionType = TableSelectionMode::Cell;
|
||||||
|
} else // check to see if we are selecting a table or row (column and all
|
||||||
|
// cells not done yet)
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
From aee1effa487849cc3c48c28c60a866211b05ebae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jon Coppeard <jcoppeard@mozilla.com>
|
||||||
|
Date: Tue, 14 Feb 2023 10:32:47 +0000
|
||||||
|
Subject: [PATCH] Part 1: Disallow GC while iterating global's debugger vector
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://hg.mozilla.org/integration/autoland/rev/760275af660b20d35ace80f4d245c4ad9c4a3869
|
||||||
|
---
|
||||||
|
js/src/debugger/Debugger.cpp | 37 +++++++++++++++++++++++-------------
|
||||||
|
js/src/debugger/Debugger.h | 10 ++++++----
|
||||||
|
js/src/gc/GC.h | 2 +-
|
||||||
|
3 files changed, 31 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/js/src/debugger/Debugger.cpp b/js/src/debugger/Debugger.cpp
|
||||||
|
index be22c18354..56a172c457 100644
|
||||||
|
--- a/js/src/debugger/Debugger.cpp
|
||||||
|
+++ b/js/src/debugger/Debugger.cpp
|
||||||
|
@@ -1240,8 +1240,9 @@ bool DebugAPI::slowPathOnNewGenerator(JSContext* cx, AbstractFramePtr frame,
|
||||||
|
MakeScopeExit([&] { Debugger::terminateDebuggerFrames(cx, frame); });
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
+ gc::AutoSuppressGC nogc(cx);
|
||||||
|
Debugger::forEachOnStackDebuggerFrame(
|
||||||
|
- frame, [&](Debugger* dbg, DebuggerFrame* frameObjPtr) {
|
||||||
|
+ frame, nogc, [&](Debugger* dbg, DebuggerFrame* frameObjPtr) {
|
||||||
|
if (!ok) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -3265,7 +3266,10 @@ bool Debugger::updateExecutionObservabilityOfScripts(
|
||||||
|
|
||||||
|
template <typename FrameFn>
|
||||||
|
/* static */
|
||||||
|
-void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
|
||||||
|
+void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame,
|
||||||
|
+ const JS::AutoRequireNoGC& nogc,
|
||||||
|
+ FrameFn fn) {
|
||||||
|
+ // GC is disallowed because it may mutate the vector we are iterating.
|
||||||
|
for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
|
||||||
|
Debugger* dbg = entry.dbg;
|
||||||
|
if (FrameMap::Ptr frameEntry = dbg->frames.lookup(frame)) {
|
||||||
|
@@ -3276,9 +3280,10 @@ void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
|
||||||
|
|
||||||
|
template <typename FrameFn>
|
||||||
|
/* static */
|
||||||
|
-void Debugger::forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
|
||||||
|
- AbstractFramePtr frame,
|
||||||
|
- FrameFn fn) {
|
||||||
|
+void Debugger::forEachOnStackOrSuspendedDebuggerFrame(
|
||||||
|
+ JSContext* cx, AbstractFramePtr frame, const JS::AutoRequireNoGC& nogc,
|
||||||
|
+ FrameFn fn) {
|
||||||
|
+ // GC is disallowed because it may mutate the vector we are iterating.
|
||||||
|
Rooted<AbstractGeneratorObject*> genObj(
|
||||||
|
cx, frame.isGeneratorFrame() ? GetGeneratorObjectForFrame(cx, frame)
|
||||||
|
: nullptr);
|
||||||
|
@@ -3304,11 +3309,13 @@ void Debugger::forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
|
||||||
|
bool Debugger::getDebuggerFrames(AbstractFramePtr frame,
|
||||||
|
MutableHandle<DebuggerFrameVector> frames) {
|
||||||
|
bool hadOOM = false;
|
||||||
|
- forEachOnStackDebuggerFrame(frame, [&](Debugger*, DebuggerFrame* frameobj) {
|
||||||
|
- if (!hadOOM && !frames.append(frameobj)) {
|
||||||
|
- hadOOM = true;
|
||||||
|
- }
|
||||||
|
- });
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ forEachOnStackDebuggerFrame(frame, nogc,
|
||||||
|
+ [&](Debugger*, DebuggerFrame* frameobj) {
|
||||||
|
+ if (!hadOOM && !frames.append(frameobj)) {
|
||||||
|
+ hadOOM = true;
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
return !hadOOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6466,8 +6473,10 @@ bool Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from,
|
||||||
|
/* static */
|
||||||
|
bool DebugAPI::inFrameMaps(AbstractFramePtr frame) {
|
||||||
|
bool foundAny = false;
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
Debugger::forEachOnStackDebuggerFrame(
|
||||||
|
- frame, [&](Debugger*, DebuggerFrame* frameobj) { foundAny = true; });
|
||||||
|
+ frame, nogc,
|
||||||
|
+ [&](Debugger*, DebuggerFrame* frameobj) { foundAny = true; });
|
||||||
|
return foundAny;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6475,8 +6484,9 @@ bool DebugAPI::inFrameMaps(AbstractFramePtr frame) {
|
||||||
|
void Debugger::suspendGeneratorDebuggerFrames(JSContext* cx,
|
||||||
|
AbstractFramePtr frame) {
|
||||||
|
JSFreeOp* fop = cx->runtime()->defaultFreeOp();
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
forEachOnStackDebuggerFrame(
|
||||||
|
- frame, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
||||||
|
+ frame, nogc, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
||||||
|
dbg->frames.remove(frame);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
@@ -6495,8 +6505,9 @@ void Debugger::suspendGeneratorDebuggerFrames(JSContext* cx,
|
||||||
|
void Debugger::terminateDebuggerFrames(JSContext* cx, AbstractFramePtr frame) {
|
||||||
|
JSFreeOp* fop = cx->runtime()->defaultFreeOp();
|
||||||
|
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
forEachOnStackOrSuspendedDebuggerFrame(
|
||||||
|
- cx, frame, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
||||||
|
+ cx, frame, nogc, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
|
||||||
|
Debugger::terminateDebuggerFrame(fop, dbg, dbgFrame, frame);
|
||||||
|
});
|
||||||
|
|
||||||
|
diff --git a/js/src/debugger/Debugger.h b/js/src/debugger/Debugger.h
|
||||||
|
index bc89e4bfb1..d9da8bbe36 100644
|
||||||
|
--- a/js/src/debugger/Debugger.h
|
||||||
|
+++ b/js/src/debugger/Debugger.h
|
||||||
|
@@ -930,11 +930,13 @@ class Debugger : private mozilla::LinkedListElement<Debugger> {
|
||||||
|
IsObserving observing);
|
||||||
|
|
||||||
|
template <typename FrameFn /* void (Debugger*, DebuggerFrame*) */>
|
||||||
|
- static void forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn);
|
||||||
|
+ static void forEachOnStackDebuggerFrame(AbstractFramePtr frame,
|
||||||
|
+ const JS::AutoRequireNoGC& nogc,
|
||||||
|
+ FrameFn fn);
|
||||||
|
template <typename FrameFn /* void (Debugger*, DebuggerFrame*) */>
|
||||||
|
- static void forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
|
||||||
|
- AbstractFramePtr frame,
|
||||||
|
- FrameFn fn);
|
||||||
|
+ static void forEachOnStackOrSuspendedDebuggerFrame(
|
||||||
|
+ JSContext* cx, AbstractFramePtr frame, const JS::AutoRequireNoGC& nogc,
|
||||||
|
+ FrameFn fn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a vector containing all Debugger.Frame instances referring to
|
||||||
|
diff --git a/js/src/gc/GC.h b/js/src/gc/GC.h
|
||||||
|
index 9cee0190b6..c6fe40c263 100644
|
||||||
|
--- a/js/src/gc/GC.h
|
||||||
|
+++ b/js/src/gc/GC.h
|
||||||
|
@@ -179,7 +179,7 @@ static inline void MaybeVerifyBarriers(JSContext* cx, bool always = false) {}
|
||||||
|
* This works by updating the |JSContext::suppressGC| counter which is checked
|
||||||
|
* at the start of GC.
|
||||||
|
*/
|
||||||
|
-class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC {
|
||||||
|
+class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC : public JS::AutoRequireNoGC {
|
||||||
|
int32_t& suppressGC_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,353 @@
|
|||||||
|
From 1300cd70bd4e7f5290cf92363756ad3b37826018 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jon Coppeard <jcoppeard@mozilla.com>
|
||||||
|
Date: Tue, 14 Feb 2023 10:32:47 +0000
|
||||||
|
Subject: [PATCH] Part 2: Require no GC when giving out references to the
|
||||||
|
realm's debugger vector
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://hg.mozilla.org/integration/autoland/rev/eb7a5d363182c55a363fe46defe670f060928e76
|
||||||
|
---
|
||||||
|
js/src/debugger/DebugAPI-inl.h | 13 +++--
|
||||||
|
js/src/debugger/DebugAPI.h | 10 +++-
|
||||||
|
js/src/debugger/Debugger.cpp | 94 ++++++++++++++++++----------------
|
||||||
|
js/src/vm/GlobalObject.h | 6 ++-
|
||||||
|
js/src/vm/Realm.h | 5 +-
|
||||||
|
5 files changed, 74 insertions(+), 54 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/js/src/debugger/DebugAPI-inl.h b/js/src/debugger/DebugAPI-inl.h
|
||||||
|
index bbd6714247..5e23e34259 100644
|
||||||
|
--- a/js/src/debugger/DebugAPI-inl.h
|
||||||
|
+++ b/js/src/debugger/DebugAPI-inl.h
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
#ifndef debugger_DebugAPI_inl_h
|
||||||
|
#define debugger_DebugAPI_inl_h
|
||||||
|
|
||||||
|
+#include "gc/GC.h"
|
||||||
|
#include "debugger/DebugAPI.h"
|
||||||
|
|
||||||
|
#include "vm/GeneratorObject.h"
|
||||||
|
@@ -45,9 +46,10 @@ void DebugAPI::onNewGlobalObject(JSContext* cx, Handle<GlobalObject*> global) {
|
||||||
|
/* static */
|
||||||
|
void DebugAPI::notifyParticipatesInGC(GlobalObject* global,
|
||||||
|
uint64_t majorGCNumber) {
|
||||||
|
- Realm::DebuggerVector& dbgs = global->getDebuggers();
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ Realm::DebuggerVector& dbgs = global->getDebuggers(nogc);
|
||||||
|
if (!dbgs.empty()) {
|
||||||
|
- slowPathNotifyParticipatesInGC(majorGCNumber, dbgs);
|
||||||
|
+ slowPathNotifyParticipatesInGC(majorGCNumber, dbgs, nogc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -55,12 +57,15 @@ void DebugAPI::notifyParticipatesInGC(GlobalObject* global,
|
||||||
|
bool DebugAPI::onLogAllocationSite(JSContext* cx, JSObject* obj,
|
||||||
|
HandleSavedFrame frame,
|
||||||
|
mozilla::TimeStamp when) {
|
||||||
|
- Realm::DebuggerVector& dbgs = cx->global()->getDebuggers();
|
||||||
|
+ // slowPathOnLogAllocationSite creates GC things so we must suppress GC here.
|
||||||
|
+ gc::AutoSuppressGC nogc(cx);
|
||||||
|
+
|
||||||
|
+ Realm::DebuggerVector& dbgs = cx->global()->getDebuggers(nogc);
|
||||||
|
if (dbgs.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
RootedObject hobj(cx, obj);
|
||||||
|
- return slowPathOnLogAllocationSite(cx, hobj, frame, when, dbgs);
|
||||||
|
+ return slowPathOnLogAllocationSite(cx, hobj, frame, when, dbgs, nogc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
diff --git a/js/src/debugger/DebugAPI.h b/js/src/debugger/DebugAPI.h
|
||||||
|
index 9792a8948f..375b3a68dd 100644
|
||||||
|
--- a/js/src/debugger/DebugAPI.h
|
||||||
|
+++ b/js/src/debugger/DebugAPI.h
|
||||||
|
@@ -21,6 +21,10 @@ class AbstractGeneratorObject;
|
||||||
|
class DebugScriptMap;
|
||||||
|
class PromiseObject;
|
||||||
|
|
||||||
|
+namespace gc {
|
||||||
|
+class AutoSuppressGC;
|
||||||
|
+} // namespace gc
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* DebugAPI::onNativeCall allows the debugger to call callbacks just before
|
||||||
|
* some native functions are to be executed. It also allows the hooks
|
||||||
|
@@ -349,10 +353,12 @@ class DebugAPI {
|
||||||
|
static void slowPathOnNewGlobalObject(JSContext* cx,
|
||||||
|
Handle<GlobalObject*> global);
|
||||||
|
static void slowPathNotifyParticipatesInGC(uint64_t majorGCNumber,
|
||||||
|
- JS::Realm::DebuggerVector& dbgs);
|
||||||
|
+ JS::Realm::DebuggerVector& dbgs,
|
||||||
|
+ const JS::AutoRequireNoGC& nogc);
|
||||||
|
[[nodiscard]] static bool slowPathOnLogAllocationSite(
|
||||||
|
JSContext* cx, HandleObject obj, HandleSavedFrame frame,
|
||||||
|
- mozilla::TimeStamp when, JS::Realm::DebuggerVector& dbgs);
|
||||||
|
+ mozilla::TimeStamp when, JS::Realm::DebuggerVector& dbgs,
|
||||||
|
+ const gc::AutoSuppressGC& nogc);
|
||||||
|
[[nodiscard]] static bool slowPathOnLeaveFrame(JSContext* cx,
|
||||||
|
AbstractFramePtr frame,
|
||||||
|
jsbytecode* pc, bool ok);
|
||||||
|
diff --git a/js/src/debugger/Debugger.cpp b/js/src/debugger/Debugger.cpp
|
||||||
|
index 56a172c457..7f5756e338 100644
|
||||||
|
--- a/js/src/debugger/Debugger.cpp
|
||||||
|
+++ b/js/src/debugger/Debugger.cpp
|
||||||
|
@@ -755,7 +755,7 @@ static bool DebuggerExists(
|
||||||
|
// explicitly.
|
||||||
|
JS::AutoSuppressGCAnalysis nogc;
|
||||||
|
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : global->getDebuggers()) {
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : global->getDebuggers(nogc)) {
|
||||||
|
// Callbacks should not create new references to the debugger, so don't
|
||||||
|
// use a barrier. This allows this method to be called during GC.
|
||||||
|
if (predicate(entry.dbg.unbarrieredGet())) {
|
||||||
|
@@ -805,7 +805,8 @@ bool DebuggerList<HookIsEnabledFun>::init(JSContext* cx) {
|
||||||
|
// Make a copy of the list, since the original is mutable and we will be
|
||||||
|
// calling into arbitrary JS.
|
||||||
|
Handle<GlobalObject*> global = cx->global();
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : global->getDebuggers()) {
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : global->getDebuggers(nogc)) {
|
||||||
|
Debugger* dbg = entry.dbg;
|
||||||
|
if (dbg->isHookCallAllowed(cx) && hookIsEnabled(dbg)) {
|
||||||
|
if (!debuggers.append(ObjectValue(*dbg->toJSObject()))) {
|
||||||
|
@@ -928,20 +929,24 @@ bool DebugAPI::slowPathOnResumeFrame(JSContext* cx, AbstractFramePtr frame) {
|
||||||
|
// frame is observable.
|
||||||
|
FrameIter iter(cx);
|
||||||
|
MOZ_ASSERT(iter.abstractFramePtr() == frame);
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
|
||||||
|
- Debugger* dbg = entry.dbg;
|
||||||
|
- if (Debugger::GeneratorWeakMap::Ptr generatorEntry =
|
||||||
|
- dbg->generatorFrames.lookup(genObj)) {
|
||||||
|
- DebuggerFrame* frameObj = generatorEntry->value();
|
||||||
|
- MOZ_ASSERT(&frameObj->unwrappedGenerator() == genObj);
|
||||||
|
- if (!dbg->frames.putNew(frame, frameObj)) {
|
||||||
|
- ReportOutOfMemory(cx);
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
- if (!frameObj->resume(iter)) {
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ {
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry :
|
||||||
|
+ frame.global()->getDebuggers(nogc)) {
|
||||||
|
+ Debugger* dbg = entry.dbg;
|
||||||
|
+ if (Debugger::GeneratorWeakMap::Ptr generatorEntry =
|
||||||
|
+ dbg->generatorFrames.lookup(genObj)) {
|
||||||
|
+ DebuggerFrame* frameObj = generatorEntry->value();
|
||||||
|
+ MOZ_ASSERT(&frameObj->unwrappedGenerator() == genObj);
|
||||||
|
+ if (!dbg->frames.putNew(frame, frameObj)) {
|
||||||
|
+ ReportOutOfMemory(cx);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (!frameObj->resume(iter)) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
terminateDebuggerFramesGuard.release();
|
||||||
|
@@ -2606,7 +2611,8 @@ bool DebugAPI::onSingleStep(JSContext* cx) {
|
||||||
|
uint32_t liveStepperCount = 0;
|
||||||
|
uint32_t suspendedStepperCount = 0;
|
||||||
|
JSScript* trappingScript = iter.script();
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : cx->global()->getDebuggers()) {
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : cx->global()->getDebuggers(nogc)) {
|
||||||
|
Debugger* dbg = entry.dbg;
|
||||||
|
for (Debugger::FrameMap::Range r = dbg->frames.all(); !r.empty();
|
||||||
|
r.popFront()) {
|
||||||
|
@@ -2789,7 +2795,8 @@ void DebugAPI::slowPathOnNewGlobalObject(JSContext* cx,
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void DebugAPI::slowPathNotifyParticipatesInGC(uint64_t majorGCNumber,
|
||||||
|
- Realm::DebuggerVector& dbgs) {
|
||||||
|
+ Realm::DebuggerVector& dbgs,
|
||||||
|
+ const JS::AutoRequireNoGC& nogc) {
|
||||||
|
for (Realm::DebuggerVector::Range r = dbgs.all(); !r.empty(); r.popFront()) {
|
||||||
|
if (!r.front().dbg.unbarrieredGet()->debuggeeIsBeingCollected(
|
||||||
|
majorGCNumber)) {
|
||||||
|
@@ -2806,7 +2813,8 @@ void DebugAPI::slowPathNotifyParticipatesInGC(uint64_t majorGCNumber,
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
Maybe<double> DebugAPI::allocationSamplingProbability(GlobalObject* global) {
|
||||||
|
- Realm::DebuggerVector& dbgs = global->getDebuggers();
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ Realm::DebuggerVector& dbgs = global->getDebuggers(nogc);
|
||||||
|
if (dbgs.empty()) {
|
||||||
|
return Nothing();
|
||||||
|
}
|
||||||
|
@@ -2836,23 +2844,13 @@ Maybe<double> DebugAPI::allocationSamplingProbability(GlobalObject* global) {
|
||||||
|
bool DebugAPI::slowPathOnLogAllocationSite(JSContext* cx, HandleObject obj,
|
||||||
|
HandleSavedFrame frame,
|
||||||
|
mozilla::TimeStamp when,
|
||||||
|
- Realm::DebuggerVector& dbgs) {
|
||||||
|
+ Realm::DebuggerVector& dbgs,
|
||||||
|
+ const gc::AutoSuppressGC& nogc) {
|
||||||
|
MOZ_ASSERT(!dbgs.empty());
|
||||||
|
mozilla::DebugOnly<Realm::DebuggerVectorEntry*> begin = dbgs.begin();
|
||||||
|
|
||||||
|
- // Root all the Debuggers while we're iterating over them;
|
||||||
|
- // appendAllocationSite calls Compartment::wrap, and thus can GC.
|
||||||
|
- //
|
||||||
|
- // SpiderMonkey protocol is generally for the caller to prove that it has
|
||||||
|
- // rooted the stuff it's asking you to operate on (i.e. by passing a
|
||||||
|
- // Handle), but in this case, we're iterating over a global's list of
|
||||||
|
- // Debuggers, and globals only hold their Debuggers weakly.
|
||||||
|
- Rooted<GCVector<JSObject*>> activeDebuggers(cx, GCVector<JSObject*>(cx));
|
||||||
|
- for (auto p = dbgs.begin(); p < dbgs.end(); p++) {
|
||||||
|
- if (!activeDebuggers.append(p->dbg->object)) {
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ // GC is suppressed so we can iterate over the debuggers; appendAllocationSite
|
||||||
|
+ // calls Compartment::wrap, and thus could GC.
|
||||||
|
|
||||||
|
for (auto p = dbgs.begin(); p < dbgs.end(); p++) {
|
||||||
|
// The set of debuggers had better not change while we're iterating,
|
||||||
|
@@ -3269,8 +3267,7 @@ template <typename FrameFn>
|
||||||
|
void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame,
|
||||||
|
const JS::AutoRequireNoGC& nogc,
|
||||||
|
FrameFn fn) {
|
||||||
|
- // GC is disallowed because it may mutate the vector we are iterating.
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers(nogc)) {
|
||||||
|
Debugger* dbg = entry.dbg;
|
||||||
|
if (FrameMap::Ptr frameEntry = dbg->frames.lookup(frame)) {
|
||||||
|
fn(dbg, frameEntry->value());
|
||||||
|
@@ -3288,7 +3285,7 @@ void Debugger::forEachOnStackOrSuspendedDebuggerFrame(
|
||||||
|
cx, frame.isGeneratorFrame() ? GetGeneratorObjectForFrame(cx, frame)
|
||||||
|
: nullptr);
|
||||||
|
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers(nogc)) {
|
||||||
|
Debugger* dbg = entry.dbg;
|
||||||
|
|
||||||
|
DebuggerFrame* frameObj = nullptr;
|
||||||
|
@@ -3521,7 +3518,8 @@ bool Debugger::cannotTrackAllocations(const GlobalObject& global) {
|
||||||
|
/* static */
|
||||||
|
bool DebugAPI::isObservedByDebuggerTrackingAllocations(
|
||||||
|
const GlobalObject& debuggee) {
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : debuggee.getDebuggers()) {
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : debuggee.getDebuggers(nogc)) {
|
||||||
|
// Use unbarrieredGet() to prevent triggering read barrier while
|
||||||
|
// collecting, this is safe as long as dbg does not escape.
|
||||||
|
Debugger* dbg = entry.dbg.unbarrieredGet();
|
||||||
|
@@ -3821,7 +3819,9 @@ void DebugAPI::slowPathTraceGeneratorFrame(JSTracer* tracer,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : generator->realm()->getDebuggers()) {
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry :
|
||||||
|
+ generator->realm()->getDebuggers(nogc)) {
|
||||||
|
Debugger* dbg = entry.dbg.unbarrieredGet();
|
||||||
|
|
||||||
|
if (Debugger::GeneratorWeakMap::Ptr entry =
|
||||||
|
@@ -3891,7 +3891,8 @@ void Debugger::trace(JSTracer* trc) {
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void DebugAPI::traceFromRealm(JSTracer* trc, Realm* realm) {
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : realm->getDebuggers()) {
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : realm->getDebuggers(nogc)) {
|
||||||
|
TraceEdge(trc, &entry.debuggerLink, "realm debugger");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -4468,7 +4469,7 @@ bool Debugger::CallData::removeDebuggee() {
|
||||||
|
// Only update the realm if there are no Debuggers left, as it's
|
||||||
|
// expensive to check if no other Debugger has a live script or frame
|
||||||
|
// hook on any of the current on-stack debuggee frames.
|
||||||
|
- if (global->getDebuggers().empty() && !obs.add(global->realm())) {
|
||||||
|
+ if (!global->hasDebuggers() && !obs.add(global->realm())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!updateExecutionObservability(cx, obs, NotObserving)) {
|
||||||
|
@@ -4489,7 +4490,7 @@ bool Debugger::CallData::removeAllDebuggees() {
|
||||||
|
FromSweep::No);
|
||||||
|
|
||||||
|
// See note about adding to the observable set in removeDebuggee.
|
||||||
|
- if (global->getDebuggers().empty() && !obs.add(global->realm())) {
|
||||||
|
+ if (!global->hasDebuggers() && !obs.add(global->realm())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -4698,7 +4699,8 @@ bool Debugger::addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> global) {
|
||||||
|
// Find all realms containing debuggers debugging realm's global object.
|
||||||
|
// Add those realms to visited.
|
||||||
|
if (realm->isDebuggee()) {
|
||||||
|
- for (Realm::DebuggerVectorEntry& entry : realm->getDebuggers()) {
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ for (Realm::DebuggerVectorEntry& entry : realm->getDebuggers(nogc)) {
|
||||||
|
Realm* next = entry.dbg->object->realm();
|
||||||
|
if (std::find(visited.begin(), visited.end(), next) == visited.end()) {
|
||||||
|
if (!visited.append(next)) {
|
||||||
|
@@ -4729,7 +4731,8 @@ bool Debugger::addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> global) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// (1)
|
||||||
|
- auto& globalDebuggers = global->getDebuggers();
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ auto& globalDebuggers = global->getDebuggers(nogc);
|
||||||
|
if (!globalDebuggers.append(Realm::DebuggerVectorEntry(this, debuggeeLink))) {
|
||||||
|
ReportOutOfMemory(cx);
|
||||||
|
return false;
|
||||||
|
@@ -4847,7 +4850,8 @@ void Debugger::removeDebuggeeGlobal(JSFreeOp* fop, GlobalObject* global,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- auto& globalDebuggersVector = global->getDebuggers();
|
||||||
|
+ JS::AutoAssertNoGC nogc;
|
||||||
|
+ auto& globalDebuggersVector = global->getDebuggers(nogc);
|
||||||
|
|
||||||
|
// The relation must be removed from up to three places:
|
||||||
|
// globalDebuggersVector and debuggees for sure, and possibly the
|
||||||
|
@@ -4886,7 +4890,7 @@ void Debugger::removeDebuggeeGlobal(JSFreeOp* fop, GlobalObject* global,
|
||||||
|
Debugger::removeAllocationsTracking(*global);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (global->realm()->getDebuggers().empty()) {
|
||||||
|
+ if (!global->realm()->hasDebuggers()) {
|
||||||
|
global->realm()->unsetIsDebuggee();
|
||||||
|
} else {
|
||||||
|
global->realm()->updateDebuggerObservesAllExecution();
|
||||||
|
diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h
|
||||||
|
index dddffcf7a9..0f535eb13f 100644
|
||||||
|
--- a/js/src/vm/GlobalObject.h
|
||||||
|
+++ b/js/src/vm/GlobalObject.h
|
||||||
|
@@ -857,9 +857,11 @@ class GlobalObject : public NativeObject {
|
||||||
|
Handle<GlobalObject*> global,
|
||||||
|
const JSFunctionSpec* builtins);
|
||||||
|
|
||||||
|
- Realm::DebuggerVector& getDebuggers() const {
|
||||||
|
- return realm()->getDebuggers();
|
||||||
|
+ // Disallow GC as it may mutate the vector.
|
||||||
|
+ Realm::DebuggerVector& getDebuggers(const JS::AutoRequireNoGC& nogc) const {
|
||||||
|
+ return realm()->getDebuggers(nogc);
|
||||||
|
}
|
||||||
|
+ bool hasDebuggers() const { return realm()->hasDebuggers(); }
|
||||||
|
|
||||||
|
inline NativeObject* getForOfPICObject() {
|
||||||
|
Value forOfPIC = getReservedSlot(FOR_OF_PIC_CHAIN);
|
||||||
|
diff --git a/js/src/vm/Realm.h b/js/src/vm/Realm.h
|
||||||
|
index 1f8852befc..bfedf5d6de 100644
|
||||||
|
--- a/js/src/vm/Realm.h
|
||||||
|
+++ b/js/src/vm/Realm.h
|
||||||
|
@@ -706,7 +706,10 @@ class JS::Realm : public JS::shadow::Realm {
|
||||||
|
void setIsDebuggee();
|
||||||
|
void unsetIsDebuggee();
|
||||||
|
|
||||||
|
- DebuggerVector& getDebuggers() { return debuggers_; };
|
||||||
|
+ DebuggerVector& getDebuggers(const JS::AutoRequireNoGC& nogc) {
|
||||||
|
+ return debuggers_;
|
||||||
|
+ };
|
||||||
|
+ bool hasDebuggers() const { return !debuggers_.empty(); }
|
||||||
|
|
||||||
|
// True if this compartment's global is a debuggee of some Debugger
|
||||||
|
// object with a live hook that observes all execution; e.g.,
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
11
mozjs91.spec
11
mozjs91.spec
@ -12,7 +12,7 @@
|
|||||||
# Big endian platforms
|
# Big endian platforms
|
||||||
Name: mozjs%{major}
|
Name: mozjs%{major}
|
||||||
Version: 91.6.0
|
Version: 91.6.0
|
||||||
Release: 5
|
Release: 6
|
||||||
Summary: SpiderMonkey JavaScript library
|
Summary: SpiderMonkey JavaScript library
|
||||||
License: MPL-2.0
|
License: MPL-2.0
|
||||||
Group: System/Libraries
|
Group: System/Libraries
|
||||||
@ -42,6 +42,9 @@ Patch18: backport-CVE-2023-23601.patch
|
|||||||
Patch19: backport-CVE-2023-23602.patch
|
Patch19: backport-CVE-2023-23602.patch
|
||||||
Patch20: backport-CVE-2022-34481.patch
|
Patch20: backport-CVE-2022-34481.patch
|
||||||
Patch21: backport-CVE-2023-29532.patch
|
Patch21: backport-CVE-2023-29532.patch
|
||||||
|
Patch22: backport-CVE-2023-25736-remove-useless-static_cast-r-mccr8.patch
|
||||||
|
Patch23: backport-CVE-2023-29543-Part-1-Disallow-GC-while-iterating-global-s-debugger.patch
|
||||||
|
Patch24: backport-CVE-2023-29543-Part-2-Require-no-GC-when-giving-out-references-to-t.patch
|
||||||
|
|
||||||
BuildRequires: autoconf213 cargo ccache clang-devel gcc gcc-c++ libtool perl-devel llvm llvm-devel nasm pkgconfig python3-devel python3-setuptools
|
BuildRequires: autoconf213 cargo ccache clang-devel gcc gcc-c++ libtool perl-devel llvm llvm-devel nasm pkgconfig python3-devel python3-setuptools
|
||||||
BuildRequires: python3-six readline-devel zip rust pkgconfig(icu-i18n) >= 67.1 pkgconfig(libffi) pkgconfig(nspr) pkgconfig(zlib) icu
|
BuildRequires: python3-six readline-devel zip rust pkgconfig(icu-i18n) >= 67.1 pkgconfig(libffi) pkgconfig(nspr) pkgconfig(zlib) icu
|
||||||
@ -213,6 +216,12 @@ popd
|
|||||||
%{_includedir}/mozjs-%{major}/
|
%{_includedir}/mozjs-%{major}/
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Dec 18 2024 sunhai <sunhai10@huawei.com> - 91.6.0-6
|
||||||
|
- Type:CVE
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC: fix CVE-2023-25736 CVE-2023-29543
|
||||||
|
|
||||||
* Thu Jun 06 2024 sunhai <sunhai10@huawei.com> - 91.6.0-5
|
* Thu Jun 06 2024 sunhai <sunhai10@huawei.com> - 91.6.0-5
|
||||||
- fix CVEs
|
- fix CVEs
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user