Files
RedBear-OS/local/patches/qtsvg/CVE-2026-6210.patch
T
vasilito 311a96bc94 qt/qtsvg: apply CVE-2026-6210 patch (heap-overflow in QSvgMarker::drawHelper)
Cherry-picked from Qt upstream (commit e488f852fa18c2afc2842a88eff8f66ad4105a45).
Original patch source:
https://download.qt.io/official_releases/qt/6.11/CVE-2026-6210-qtsvg-6.11.diff

Fix: Test types of nodes before downcasting them. A bad cast in
QSvgMarker::drawHelper led to endless recursion resulting in a heap
overflow. While fixing that, another similar case was also fixed.
2026-07-11 01:36:28 +03:00

75 lines
3.3 KiB
Diff

From 8368ba6ff143bd6b9a7fdf235918285d9b1f5d2a Mon Sep 17 00:00:00 2001
From: Robert Löhning <robert.loehning@qt.io>
Date: Thu, 26 Mar 2026 13:42:19 +0100
Subject: [PATCH] Test types of nodes before downcasting them
A bad cast in QSvgMarker::drawHelper lead to an endless recursion
resulting in a heap overflow. Credit to OSS-Fuzz which found this as
issue 496327371.
Amends 534d072fe9c060ca3d1b968a717513426c69c956
While fixing that, I found another, similar case and fixed it, too,
although it didn't seem to cause a crash.
Amends 29b848e9ac4e4e13c5b50116a81b1f2677196939
Pick-to: 6.8
Change-Id: Ia57491aa329fea981307a709c5a6a750125fe2c7
Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
(cherry picked from commit e488f852fa18c2afc2842a88eff8f66ad4105a45)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
diff --git a/src/svg/qsvgstructure.cpp b/src/svg/qsvgstructure.cpp
index 23606e6..5bf485e 100644
--- a/src/svg/qsvgstructure.cpp
+++ b/src/svg/qsvgstructure.cpp
@@ -426,9 +426,10 @@
const bool isPainting = (boundingRect == nullptr);
const auto markers = markersForNode(node);
for (auto &i : markers) {
- QSvgMarker *markNode = static_cast<QSvgMarker*>(node->document()->namedNode(i.markerId));
- if (!markNode)
+ QSvgNode *referencedNode = node->document()->namedNode(i.markerId);
+ if (!referencedNode || referencedNode->type() != QSvgNode::Marker)
continue;
+ QSvgMarker *markNode = static_cast<QSvgMarker *>(referencedNode);
p->save();
p->translate(i.x, i.y);
@@ -729,8 +730,9 @@
// Chrome seems to return the mask of the mask if a mask is set on the mask
if (this->hasMask()) {
- QSvgMask *maskNode = static_cast<QSvgMask*>(document()->namedNode(this->maskId()));
- if (maskNode) {
+ QSvgNode *referencedNode = document()->namedNode(this->maskId());
+ if (referencedNode && referencedNode->type() == QSvgNode::Mask) {
+ QSvgMask *maskNode = static_cast<QSvgMask *>(referencedNode);
QRectF boundsRect;
return maskNode->createMask(p, states, localRect, &boundsRect);
}
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index 118f200..7bbbedc 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -1868,6 +1868,17 @@
// runtime error: signed integer overflow: -2147483648 + -1 cannot be represented in type 'int'
QTest::newRow("excessive moveto in path") // id=406541912
<< R"(<svg><path stroke="#000" d="M- 7e8t9 ."/><marker id="c"/><use href=" c"/></svg>)"_ba;
+ // Bad-cast to QSvgMarker from QSvgLine -> Heap-buffer-overflow
+ QTest::newRow("line-as-marker") // id=496327371
+ << R"-(<svg><line x1="4" id="lledr" marker-end="url(#lledr)" stroke="#00f"/></svg>)-"_ba;
+ QTest::newRow("line-as-mask") // modeled after 496327371 to test similar problem, needs UBSAN
+ << R"-(<svg>
+ <defs>
+ <line x1="4" id="line"/>
+ <mask id="mask" width="2" height="2" mask="url(#line)"/>
+ </defs>
+ <rect width="2" height="2" mask="url(#mask)"/>
+ </svg>)-"_ba;
}
void tst_QSvgRenderer::ossFuzzRender()