[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1006182: buster-pu: package qtbase-opensource-src/5.11.3+dfsg1-1+deb10u5



Hi all, and sorry for delay.

On Fri, Mar 18, 2022 at 12:34:33PM +0100, Emilio Pozuelo Monfort wrote:
> On 18/03/2022 12:28, Adam D. Barratt wrote:
> > On Fri, 2022-03-18 at 12:24 +0100, Emilio Pozuelo Monfort wrote:
> > > There are a couple of CVEs open (one of them a no-dsa, DOS one).
> > > Perhaps they
> > > can be addressed in this update as well, provided the patches (which
> > > seem rather
> > > small) are fine for the buster version?
> > >
> > > I know the deadline for the point release is just around the corner,
> > > so if
> > > there's not enough time to address those then that'd be alright.
> >
> > Well, we'd need to see a diff. :-)
>
> Heh sure. This was more meant for Dmitry...
>
> > (Was Dmitry intentionally not CCed on your mail?)
>
> My bad, I hit reply rather than reply to all... Dmitry, see my comments
> above regarding the couple CVEs open in buster, in case they can be included
> in this update.

I looked at these two CVEs.

- Patch for CVE-2022-25255 is a behavior change and it may break someone's
  workflow. For example, it broke the way qt_test_helper works, and that's why
  upstream abandoned the attempt to backport it to 5.12 LTS branch:
  https://codereview.qt-project.org/c/qt/qtbase/+/396020

- Patch for CVE-2015-9541 is pretty straightforward, I applied it.

New debdiff is attached.

--
Dmitry Shachnev
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+qtbase-opensource-src (5.11.3+dfsg1-1+deb10u5) buster; urgency=medium
+
+  * Backport two upstream commits to fix setTabOrder for compound widgets
+    (closes: #1001082).
+  * Backport upstream patch to add an expansion limit for XML entities
+    (CVE-2015-9541, closes: #951066).
+
+ -- Dmitry Shachnev <mitya57@debian.org>  Sat, 26 Mar 2022 10:12:03 +0300
+
 qtbase-opensource-src (5.11.3+dfsg1-1+deb10u4) buster; urgency=medium
 
   [ Dmitry Shachnev ]
--- /dev/null
+++ b/debian/patches/CVE-2015-9541.diff
@@ -0,0 +1,71 @@
+Description: add an expansion limit for entities
+ Recursively defined entities can easily exhaust all available
+ memory. Limit entity expansion to a default of 4096 characters to
+ avoid DoS attacks when a user loads untrusted content.
+Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=f432c08882ffebe5
+Last-Update: 2022-03-25
+
+--- a/src/corelib/serialization/qxmlstream.g
++++ b/src/corelib/serialization/qxmlstream.g
+@@ -277,9 +277,19 @@ public:
+     QHash<QStringView, Entity> entityHash;
+     QHash<QStringView, Entity> parameterEntityHash;
+     QXmlStreamSimpleStack<Entity *>entityReferenceStack;
++    int entityExpansionLimit = 4096;
++    int entityLength = 0;
+     inline bool referenceEntity(Entity &entity) {
+         if (entity.isCurrentlyReferenced) {
+-            raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
++            raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected."));
++            return false;
++        }
++        // entityLength represents the amount of additional characters the
++        // entity expands into (can be negative for e.g. &amp;). It's used to
++        // avoid DoS attacks through recursive entity expansions
++        entityLength += entity.value.size() - entity.name.size() - 2;
++        if (entityLength > entityExpansionLimit) {
++            raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit."));
+             return false;
+         }
+         entity.isCurrentlyReferenced = true;
+@@ -830,6 +840,8 @@ entity_done ::= ENTITY_DONE;
+ /.
+         case $rule_number:
+             entityReferenceStack.pop()->isCurrentlyReferenced = false;
++            if (entityReferenceStack.isEmpty())
++                entityLength = 0;
+             clearSym();
+         break;
+ ./
+--- a/src/corelib/serialization/qxmlstream_p.h
++++ b/src/corelib/serialization/qxmlstream_p.h
+@@ -774,9 +774,19 @@ public:
+     QHash<QStringView, Entity> entityHash;
+     QHash<QStringView, Entity> parameterEntityHash;
+     QXmlStreamSimpleStack<Entity *>entityReferenceStack;
++    int entityExpansionLimit = 4096;
++    int entityLength = 0;
+     inline bool referenceEntity(Entity &entity) {
+         if (entity.isCurrentlyReferenced) {
+-            raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
++            raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected."));
++            return false;
++        }
++        // entityLength represents the amount of additional characters the
++        // entity expands into (can be negative for e.g. &amp;). It's used to
++        // avoid DoS attacks through recursive entity expansions
++        entityLength += entity.value.size() - entity.name.size() - 2;
++        if (entityLength > entityExpansionLimit) {
++            raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit."));
+             return false;
+         }
+         entity.isCurrentlyReferenced = true;
+@@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse()
+ 
+         case 10:
+             entityReferenceStack.pop()->isCurrentlyReferenced = false;
++            if (entityReferenceStack.isEmpty())
++                entityLength = 0;
+             clearSym();
+         break;
+ 
--- /dev/null
+++ b/debian/patches/fix_settaborder.diff
@@ -0,0 +1,76 @@
+Description: QWidget: fix setTabOrder for compound widgets
+Origin: upstream, commits:
+ https://code.qt.io/cgit/qt/qtbase.git/commit/?id=81e298a51d08c510
+ https://code.qt.io/cgit/qt/qtbase.git/commit/?id=a7cbb8c639487edb
+Last-Update: 2022-02-13
+
+--- a/src/widgets/kernel/qwidget.cpp
++++ b/src/widgets/kernel/qwidget.cpp
+@@ -6975,35 +6975,41 @@ void QWidget::setTabOrder(QWidget* first
+                 lastFocusChild = focusNext;
+         }
+     };
++    auto setPrev = [](QWidget *w, QWidget *prev)
++    {
++        w->d_func()->focus_prev = prev;
++    };
++    auto setNext = [](QWidget *w, QWidget *next)
++    {
++        w->d_func()->focus_next = next;
++    };
+ 
+-    QWidget *lastFocusChildOfFirst, *lastFocusChildOfSecond;
+-    determineLastFocusChild(first, lastFocusChildOfFirst);
++    // remove the second widget from the chain
++    QWidget *lastFocusChildOfSecond;
+     determineLastFocusChild(second, lastFocusChildOfSecond);
++    {
++        QWidget *oldPrev = second->d_func()->focus_prev;
++        QWidget *prevWithFocus = oldPrev;
++        while (prevWithFocus->focusPolicy() == Qt::NoFocus)
++            prevWithFocus = prevWithFocus->d_func()->focus_prev;
++        // only widgets between first and second -> all is fine
++        if (prevWithFocus == first)
++            return;
++        QWidget *oldNext = lastFocusChildOfSecond->d_func()->focus_next;
++        setPrev(oldNext, oldPrev);
++        setNext(oldPrev, oldNext);
++    }
+ 
+-    // If the tab order is already correct, exit early
+-    if (lastFocusChildOfFirst->d_func()->focus_next == second)
+-        return;
+-
+-    // Note that we need to handle two different sections in the tab chain; The section
+-    // that 'first' belongs to (firstSection), where we are about to insert 'second', and
+-    // the section that 'second' used be a part of (secondSection). When we pull 'second'
+-    // out of the second section and insert it into the first, we also need to ensure
+-    // that we leave the second section in a connected state.
+-    QWidget *firstChainOldSecond = lastFocusChildOfFirst->d_func()->focus_next;
+-    QWidget *secondChainNewFirst = second->d_func()->focus_prev;
+-    QWidget *secondChainNewSecond = lastFocusChildOfSecond->d_func()->focus_next;
+-
+-    // Insert 'second' after 'first'
+-    lastFocusChildOfFirst->d_func()->focus_next = second;
+-    second->d_func()->focus_prev = lastFocusChildOfFirst;
+-
+-    // The widget that used to be 'second' in the first section, should now become 'third'
+-    lastFocusChildOfSecond->d_func()->focus_next = firstChainOldSecond;
+-    firstChainOldSecond->d_func()->focus_prev = lastFocusChildOfSecond;
+-
+-    // Repair the second section after we pulled 'second' out of it
+-    secondChainNewFirst->d_func()->focus_next = secondChainNewSecond;
+-    secondChainNewSecond->d_func()->focus_prev = secondChainNewFirst;
++    // insert the second widget into the chain
++    QWidget *lastFocusChildOfFirst;
++    determineLastFocusChild(first, lastFocusChildOfFirst);
++    {
++        QWidget *oldNext = lastFocusChildOfFirst->d_func()->focus_next;
++        setPrev(second, lastFocusChildOfFirst);
++        setNext(lastFocusChildOfFirst, second);
++        setPrev(oldNext, lastFocusChildOfSecond);
++        setNext(lastFocusChildOfSecond, oldNext);
++    }
+ }
+ 
+ /*!\internal
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -12,6 +12,8 @@ CVE-2020-0569.diff
 CVE-2020-0570.diff
 XCB_Fix_clipboard_breaking_when_timer_wraps_after_50_days.patch
 CVE-2020-17507.diff
+fix_settaborder.diff
+CVE-2015-9541.diff
 
 # Debian specific.
 gnukfreebsd.diff

Attachment: signature.asc
Description: PGP signature


Reply to: