Firefox · Graphics
CVE-2026-109743
Logic Error in Graphics
Overview
Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifgfx/layers/wr/WebRenderBridgeParent.cpp |
modified | |
mPaintSequenceNumbergfx/layers/wr/WebRenderScrollData.cpp |
modified |
Files Changed
gfx/layers/wr/WebRenderBridgeParent.cppgfx/layers/wr/WebRenderScrollData.cppgfx/layers/wr/WebRenderScrollData.h
Patch
diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp
index 58842a96f2d..7ed9c9014b1 100644
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -1352,6 +1352,33 @@ bool WebRenderBridgeParent::SetDisplayList(
return success;
}
+// True if every referent id in aScrollData is actually embedded by
+// aOwnLayersId, per the parent process's own record of the frame tree.
+static bool ReferentsAreOwnedBy(const WebRenderScrollData& aScrollData,
+ LayersId aOwnLayersId) {
+ for (size_t i = 0; i < aScrollData.GetLayerCount(); i++) {
+ Maybe<LayersId> referent = aScrollData.GetLayerData(i)->GetReferentId();
+ if (!referent) {
+ continue;
+ }
+ LayersId embedder;
+ bool found = CompositorBridgeParent::CallWithLayerTreeState(
+ *referent, [&](CompositorBridgeParent::LayerTreeState& aState) {
+ embedder = aState.mEmbedderLayersId;
+ });
+ if (!found || embedder != aOwnLayersId) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool ValidateScrollData(const WebRenderScrollData& aScrollData,
+ LayersId aOwnLayersId) {
+ return aScrollData.ValidateShape() &&
+ ReferentsAreOwnedBy(aScrollData, aOwnLayersId);
+}
+
bool WebRenderBridgeParent::ProcessDisplayListData(
DisplayListData& aDisplayList, wr::Epoch aWrEpoch,
const TimeStamp& aTxnStartTime, bool aValidTransaction,
@@ -1360,13 +1387,16 @@ bool WebRenderBridgeParent::ProcessDisplayListData(
mRemoteTextureTxnScheduler, mFwdTransactionId);
Maybe<wr::AutoTransactionSender> sender;
- if (aDisplayList.mScrollData && !aDisplayList.mScrollData->Validate()) {
- // If the scroll data is invalid, the entire transaction needs to be dropped
- // because the scroll data and the display list cross-reference each other.
- MOZ_ASSERT(
- false,
- "Content sent malformed scroll data (or validation check has a bug)");
- aValidTransaction = false;
+ if (aDisplayList.mScrollData) {
+ // If the scroll data is invalid, the entire transaction needs to be
+ // dropped because the scroll data and the display list cross-reference
+ // each other.
+ if (!ValidateScrollData(*aDisplayList.mScrollData, GetLayersId())) {
+ MOZ_ASSERT(false,
+ "Content sent malformed scroll data (or validation check "
+ "has a bug)");
+ aValidTransaction = false;
+ }
}
if (!aValidTransaction) {
diff --git a/gfx/layers/wr/WebRenderScrollData.cpp b/gfx/layers/wr/WebRenderScrollData.cpp
index d8f2e99d0b6..ec4494fddf7 100644
--- a/gfx/layers/wr/WebRenderScrollData.cpp
+++ b/gfx/layers/wr/WebRenderScrollData.cpp
@@ -222,7 +222,7 @@ WebRenderScrollData::WebRenderScrollData(WebRenderLayerManager* aManager,
mIsFirstPaint(false),
mPaintSequenceNumber(0) {}
-bool WebRenderScrollData::Validate() const {
+bool WebRenderScrollData::ValidateShape() const {
// Attempt to traverse the tree structure encoded by the descendant counts,
// validating as we go that everything is within bounds and properly nested.
// In addition, check that the traversal visits every node exactly once.
diff --git a/gfx/layers/wr/WebRenderScrollData.h b/gfx/layers/wr/WebRenderScrollData.h
index 7bec2045315..b1f08180826 100644
--- a/gfx/layers/wr/WebRenderScrollData.h
+++ b/gfx/layers/wr/WebRenderScrollData.h
@@ -45,7 +45,7 @@ class WebRenderLayerScrollData final {
using ViewID = ScrollableLayerGuid::ViewID;
- // Helper function for WebRenderScrollData::Validate().
+ // Helper function for WebRenderScrollData::ValidateShape().
bool ValidateSubtree(const WebRenderScrollData& aParent,
std::vector<size_t>& aVisitCounts,
size_t aCurrentIndex) const;
@@ -241,7 +241,7 @@ class WebRenderScrollData {
// Validate that the scroll data is well-formed, and particularly that
// |mLayerScrollData| encodes a valid tree. This is necessary because
// the data can be sent over IPC from a less-trusted content process.
- bool Validate() const;
+ bool ValidateShape() const;
WebRenderLayerManager* GetManager() const;
Loading diff…
References
On This Page