diff --git a/SPECS/qt5-qtsvg/CVE-2025-10729.patch b/SPECS/qt5-qtsvg/CVE-2025-10729.patch new file mode 100644 index 00000000000..bbf35c6a46b --- /dev/null +++ b/SPECS/qt5-qtsvg/CVE-2025-10729.patch @@ -0,0 +1,112 @@ +From b4112e9c8ff75ca03de65236058af41598308ca3 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Tue, 7 Oct 2025 10:08:13 +0000 +Subject: [PATCH] Don't create group nodes which will be deleted anyway; add + test for misplaced element. Task-number: QTBUG-139961 + +The old code first created the nodes, then checked whether their parent element has the right type and deleted them if not. This was wasted effort and could also lead to dangling pointers. + +Instead, first check the parent's type and only create the node if that matches. + +Reviewed-by: Hatem ElKharashy +Reviewed-by: Jani Heikkinen +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: AI Backport of https://code.qt.io/cgit/qt/qtsvg.git/patch/?id=6a6273126770006232e805cf1631f93d4919b788 +--- + src/svg/qsvghandler.cpp | 20 ++++++++------ + tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 29 ++++++++++++++++++++ + 2 files changed, 40 insertions(+), 9 deletions(-) + +diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp +index 0b3341a..ed6258d 100644 +--- a/src/svg/qsvghandler.cpp ++++ b/src/svg/qsvghandler.cpp +@@ -3730,11 +3730,12 @@ bool QSvgHandler::startElement(const QString &localName, + + if (FactoryMethod method = findGroupFactory(localName)) { + //group +- node = method(m_doc ? m_nodes.top() : 0, attributes, this); +- Q_ASSERT(node); + if (!m_doc) { +- Q_ASSERT(node->type() == QSvgNode::DOC); +- m_doc = static_cast(node); ++ node = method(nullptr, attributes, this); ++ if (node) { ++ Q_ASSERT(node->type() == QSvgNode::DOC); ++ m_doc = static_cast(node); ++ } + } else { + switch (m_nodes.top()->type()) { + case QSvgNode::DOC: +@@ -3742,16 +3743,17 @@ bool QSvgHandler::startElement(const QString &localName, + case QSvgNode::DEFS: + case QSvgNode::SWITCH: + { +- QSvgStructureNode *group = +- static_cast(m_nodes.top()); +- group->addChild(node, someId(attributes)); ++ node = method(m_nodes.top(), attributes, this); ++ if (node) { ++ QSvgStructureNode *group = ++ static_cast(m_nodes.top()); ++ group->addChild(node, someId(attributes)); ++ } + } + break; + default: + const QByteArray msg = QByteArrayLiteral("Could not add child element to parent element because the types are incorrect."); + qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData()); +- delete node; +- node = 0; + break; + } + } +diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +index 81c57f7..a0a3d6d 100644 +--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp ++++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +@@ -83,6 +83,7 @@ private slots: + void oss_fuzz_23731(); + void oss_fuzz_24131(); + void oss_fuzz_24738(); ++ void testMisplacedElement(); + + #ifndef QT_NO_COMPRESS + void testGzLoading(); +@@ -1554,5 +1555,33 @@ void tst_QSvgRenderer::oss_fuzz_24738() + QSvgRenderer().load(QByteArray("")); + } + ++ ++void tst_QSvgRenderer::testMisplacedElement() ++{ ++ // This input caused a QSvgPattern node to be created with a QSvgPatternStyle referencing to it. ++ // The code then detected that the element is misplaced in the element and ++ // deleted it. That left behind the QSvgPatternStyle pointing to the deleted QSvgPattern. That ++ // was reported when running the test with ASAN or UBSAN. ++ QByteArray svg(R"( ++ ++ ++ )"); ++ ++ QImage image(20, 20, QImage::Format_ARGB32_Premultiplied); ++ image.fill(Qt::green); ++ QImage refImage = image.copy(); ++ ++ QTest::ignoreMessage(QtWarningMsg, "