Your message dated Sat, 17 May 2025 09:37:58 +0000 with message-id <E1uGDzS-005KJY-NE@coccia.debian.org> and subject line Close 1101301 has caused the Debian Bug report #1101301, regarding bookworm-pu: package qtbase-opensource-src/5.15.8+dfsg-11+deb12u3 to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact owner@bugs.debian.org immediately.) -- 1101301: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1101301 Debian Bug Tracking System Contact owner@bugs.debian.org with problems
--- Begin Message ---
- To: submit@bugs.debian.org
- Subject: bookworm-pu: package qtbase-opensource-src/5.15.8+dfsg-11+deb12u3
- From: Dmitry Shachnev <mitya57@debian.org>
- Date: Tue, 25 Mar 2025 14:33:28 +0300
- Message-id: <Z-KUiFEvDkLgph8f@mitya57.me>
Package: release.debian.org Severity: normal Tags: bookworm X-Debbugs-Cc: qtbase-opensource-src@packages.debian.org Control: affects -1 + src:qtbase-opensource-src User: release.debian.org@packages.debian.org Usertags: pu Dear Release team, I would like to request a stable update of qtbase package for Bookworm. [ Reason ] It will fix two bugs: - #1081682: Segfault in QAccessibleTableInterface::cellAt - #1076293: CVE-2024-39936 [ Impact ] The first bug is an important issue for screen reader users, which makes Qt applications with tables unusable. The second bug is minor security issue. See https://security-tracker.debian.org/tracker/CVE-2024-39936 for details. [ Tests ] The reporter of #1081682 has tested the patch and it works for them. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1081682#17. The patch for CVE-2024-39936 was not tested explicitly, but it was applied in sid since 2024-07-14 and no issues were reported. [ Risks ] The patch for #1081682 is quite trivial, it just adds NULL pointer checks. The patch for CVE-2024-39936 is a bit more complex, but it has a verbose explanation of what it does (I have included it in the Debian patch too). [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] * Backport upstream patch to add null checks in table iface methods in linuxaccessibility/atspiadaptor.cpp (closes: #1081682). * Backport upstream patch to delay any communication until encrypted() can be responded to (CVE-2024-39936, closes: #1076293). [ Other info ] Links to upstream bugs, commits, patches for the first issue: - https://bugreports.qt.io/browse/QTBUG-125954 - https://codereview.qt-project.org/c/qt/qtbase/+/518991 - https://invent.kde.org/qt/qt/qtbase/-/commit/076da096464a5d3f (KDE branch) For the second issue: - https://codereview.qt-project.org/c/qt/qtbase/+/571601 - https://download.qt.io/official_releases/qt/5.15/CVE-2024-39936-qtbase-5.15.patch - https://invent.kde.org/qt/qt/qtbase/-/commit/0581ace6d4b8c0c0 (KDE branch) -- Dmitry Shachnev--- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +qtbase-opensource-src (5.15.8+dfsg-11+deb12u3) bookworm; urgency=medium + + * Backport upstream patch to add null checks in table iface methods in + linuxaccessibility/atspiadaptor.cpp (closes: #1081682). + * Backport upstream patch to delay any communication until encrypted() can + be responded to (CVE-2024-39936, closes: #1076293). + + -- Dmitry Shachnev <mitya57@debian.org> Mon, 24 Mar 2025 11:41:15 +0300 + qtbase-opensource-src (5.15.8+dfsg-11+deb12u2) bookworm; urgency=medium * Non-maintainer upload by the LTS Team. --- /dev/null +++ b/debian/patches/CVE-2024-39936.diff @@ -0,0 +1,153 @@ +Description: HTTP2: delay any communication until encrypted() can be responded to + We have the encrypted() signal that lets users do extra checks on the + established connection. It is emitted as BlockingQueued, so the HTTP + thread stalls until it is done emitting. Users can potentially call + abort() on the QNetworkReply at that point, which is passed as a Queued + call back to the HTTP thread. That means that any currently queued + signal emission will be processed before the abort() call is processed. + . + In the case of HTTP2 it is a little special since it is multiplexed and + the code is built to start requests as they are available. This means + that, while the code worked fine for HTTP1, since one connection only + has one request, it is not working for HTTP2, since we try to send more + requests in-between the encrypted() signal and the abort() call. + . + This patch changes the code to delay any communication until the + encrypted() signal has been emitted and processed, for HTTP2 only. + It's done by adding a few booleans, both to know that we have to return + early and so we can keep track of what events arose and what we need to + resume once enough time has passed that any abort() call must have been + processed. +Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=b1e75376cc3adfc7 +Last-Update: 2025-03-25 + +--- a/src/network/access/qhttp2protocolhandler.cpp ++++ b/src/network/access/qhttp2protocolhandler.cpp +@@ -371,12 +371,12 @@ bool QHttp2ProtocolHandler::sendRequest( + } + } + +- if (!prefaceSent && !sendClientPreface()) +- return false; +- + if (!requests.size()) + return true; + ++ if (!prefaceSent && !sendClientPreface()) ++ return false; ++ + m_channel->state = QHttpNetworkConnectionChannel::WritingState; + // Check what was promised/pushed, maybe we do not have to send a request + // and have a response already? +--- a/src/network/access/qhttpnetworkconnectionchannel.cpp ++++ b/src/network/access/qhttpnetworkconnectionchannel.cpp +@@ -255,6 +255,10 @@ void QHttpNetworkConnectionChannel::abor + bool QHttpNetworkConnectionChannel::sendRequest() + { + Q_ASSERT(!protocolHandler.isNull()); ++ if (waitingForPotentialAbort) { ++ needInvokeSendRequest = true; ++ return false; // this return value is unused ++ } + return protocolHandler->sendRequest(); + } + +@@ -267,21 +271,28 @@ bool QHttpNetworkConnectionChannel::send + void QHttpNetworkConnectionChannel::sendRequestDelayed() + { + QMetaObject::invokeMethod(this, [this] { +- Q_ASSERT(!protocolHandler.isNull()); + if (reply) +- protocolHandler->sendRequest(); ++ sendRequest(); + }, Qt::ConnectionType::QueuedConnection); + } + + void QHttpNetworkConnectionChannel::_q_receiveReply() + { + Q_ASSERT(!protocolHandler.isNull()); ++ if (waitingForPotentialAbort) { ++ needInvokeReceiveReply = true; ++ return; ++ } + protocolHandler->_q_receiveReply(); + } + + void QHttpNetworkConnectionChannel::_q_readyRead() + { + Q_ASSERT(!protocolHandler.isNull()); ++ if (waitingForPotentialAbort) { ++ needInvokeReadyRead = true; ++ return; ++ } + protocolHandler->_q_readyRead(); + } + +@@ -1289,7 +1300,18 @@ void QHttpNetworkConnectionChannel::_q_e + // Similar to HTTP/1.1 counterpart below: + const auto &pairs = spdyRequestsToSend.values(); // (request, reply) + const auto &pair = pairs.first(); ++ waitingForPotentialAbort = true; + emit pair.second->encrypted(); ++ ++ // We don't send or handle any received data until any effects from ++ // emitting encrypted() have been processed. This is necessary ++ // because the user may have called abort(). We may also abort the ++ // whole connection if the request has been aborted and there is ++ // no more requests to send. ++ QMetaObject::invokeMethod(this, ++ &QHttpNetworkConnectionChannel::checkAndResumeCommunication, ++ Qt::QueuedConnection); ++ + // In case our peer has sent us its settings (window size, max concurrent streams etc.) + // let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection). + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); +@@ -1307,6 +1329,26 @@ void QHttpNetworkConnectionChannel::_q_e + } + } + ++void QHttpNetworkConnectionChannel::checkAndResumeCommunication() ++{ ++ Q_ASSERT(connection->connectionType() > QHttpNetworkConnection::ConnectionTypeHTTP); ++ ++ // Because HTTP/2 requires that we send a SETTINGS frame as the first thing we do, and respond ++ // to a SETTINGS frame with an ACK, we need to delay any handling until we can ensure that any ++ // effects from emitting encrypted() have been processed. ++ // This function is called after encrypted() was emitted, so check for changes. ++ ++ if (!reply && spdyRequestsToSend.isEmpty()) ++ abort(); ++ waitingForPotentialAbort = false; ++ if (needInvokeReadyRead) ++ _q_readyRead(); ++ if (needInvokeReceiveReply) ++ _q_receiveReply(); ++ if (needInvokeSendRequest) ++ sendRequest(); ++} ++ + void QHttpNetworkConnectionChannel::requeueSpdyRequests() + { + QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values(); +--- a/src/network/access/qhttpnetworkconnectionchannel_p.h ++++ b/src/network/access/qhttpnetworkconnectionchannel_p.h +@@ -107,6 +107,10 @@ public: + QAbstractSocket *socket; + bool ssl; + bool isInitialized; ++ bool waitingForPotentialAbort = false; ++ bool needInvokeReceiveReply = false; ++ bool needInvokeReadyRead = false; ++ bool needInvokeSendRequest = false; + ChannelState state; + QHttpNetworkRequest request; // current request, only used for HTTP + QHttpNetworkReply *reply; // current reply for this request, only used for HTTP +@@ -187,6 +191,8 @@ public: + void closeAndResendCurrentRequest(); + void resendCurrentRequest(); + ++ void checkAndResumeCommunication(); ++ + bool isSocketBusy() const; + bool isSocketWriting() const; + bool isSocketWaiting() const; --- /dev/null +++ b/debian/patches/a11y_null_checks.diff @@ -0,0 +1,76 @@ +Description: a11y atspi: add null checks in table iface methods + Add null checks to cover the cases where QAccessibleTableInterface::cellAt + returns nullptr (which happens e.g. when called with invalid indices via + AT-SPI) or where the cell object doesn't implement the + QAccessibleTableCellInterface, which would previously result in crashes. + . + Cherry-picked into 5.15 as it fixes a crash in popular accessibility client + software. Conflict resolution: remove C++17'isms (`if` with initializer). +Origin: upstream, https://invent.kde.org/qt/qt/qtbase/-/commit/076da096464a5d3f +Last-Update: 2025-03-24 +Bug: https://bugs.debian.org/1081682 + +--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp ++++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +@@ -2393,13 +2393,14 @@ bool AtSpiAdaptor::tableInterface(QAcces + if (cols > 0) { + row = index / cols; + col = index % cols; +- QAccessibleTableCellInterface *cell = interface->tableInterface()->cellAt(row, col)->tableCellInterface(); +- if (cell) { +- row = cell->rowIndex(); +- col = cell->columnIndex(); +- rowExtents = cell->rowExtent(); +- colExtents = cell->columnExtent(); +- isSelected = cell->isSelected(); ++ QAccessibleInterface *cell = interface->tableInterface()->cellAt(row, col); ++ QAccessibleTableCellInterface *cellIface = cell ? cell->tableCellInterface() : nullptr; ++ if (cellIface) { ++ row = cellIface->rowIndex(); ++ col = cellIface->columnIndex(); ++ rowExtents = cellIface->rowExtent(); ++ colExtents = cellIface->columnExtent(); ++ isSelected = cellIface->isSelected(); + success = true; + } + } +@@ -2410,12 +2411,22 @@ bool AtSpiAdaptor::tableInterface(QAcces + } else if (function == QLatin1String("GetColumnExtentAt")) { + int row = message.arguments().at(0).toInt(); + int column = message.arguments().at(1).toInt(); +- connection.send(message.createReply(interface->tableInterface()->cellAt(row, column)->tableCellInterface()->columnExtent())); ++ int columnExtent = 0; ++ QAccessibleInterface *cell = interface->tableInterface()->cellAt(row, column); ++ QAccessibleTableCellInterface *cellIface = cell ? cell->tableCellInterface() : nullptr; ++ if (cellIface) ++ columnExtent = cellIface->columnExtent(); ++ connection.send(message.createReply(columnExtent)); + + } else if (function == QLatin1String("GetRowExtentAt")) { + int row = message.arguments().at(0).toInt(); + int column = message.arguments().at(1).toInt(); +- connection.send(message.createReply(interface->tableInterface()->cellAt(row, column)->tableCellInterface()->rowExtent())); ++ int rowExtent = 0; ++ QAccessibleInterface *cell = interface->tableInterface()->cellAt(row, column); ++ QAccessibleTableCellInterface *cellIface = cell ? cell->tableCellInterface() : nullptr; ++ if (cellIface) ++ rowExtent = cellIface->rowExtent(); ++ connection.send(message.createReply(rowExtent)); + + } else if (function == QLatin1String("GetColumnHeader")) { + int column = message.arguments().at(0).toInt(); +@@ -2455,8 +2466,12 @@ bool AtSpiAdaptor::tableInterface(QAcces + } else if (function == QLatin1String("IsSelected")) { + int row = message.arguments().at(0).toInt(); + int column = message.arguments().at(1).toInt(); +- QAccessibleTableCellInterface* cell = interface->tableInterface()->cellAt(row, column)->tableCellInterface(); +- connection.send(message.createReply(cell->isSelected())); ++ bool isSelected = false; ++ QAccessibleInterface *cell = interface->tableInterface()->cellAt(row, column); ++ QAccessibleTableCellInterface *cellIface = cell ? cell->tableCellInterface() : nullptr; ++ if (cellIface) ++ isSelected = cellIface->isSelected(); ++ connection.send(message.createReply(isSelected)); + } else if (function == QLatin1String("AddColumnSelection")) { + int column = message.arguments().at(0).toInt(); + connection.send(message.createReply(interface->tableInterface()->selectColumn(column))); --- a/debian/patches/series +++ b/debian/patches/series @@ -23,9 +23,10 @@ sql_odbc_fix_unicode_check.diff CVE-2023-34410.diff CVE-2023-37369.diff CVE-2023-38197.diff - CVE-2023-51714.diff CVE-2024-25580.diff +a11y_null_checks.diff +CVE-2024-39936.diff # Debian specific. gnukfreebsd.diffAttachment: signature.asc
Description: PGP signature
--- End Message ---
--- Begin Message ---
- To: 1101301-done@bugs.debian.org
- Subject: Close 1101301
- From: jmw@debian.org
- Date: Sat, 17 May 2025 09:37:58 +0000
- Message-id: <E1uGDzS-005KJY-NE@coccia.debian.org>
Version: 12.11 This update has been released as part of 12.10. Thank you for your contribution.
--- End Message ---