[packages/qt6] upstream fix for CVE-2024-39936; rel 2
atler
atler at pld-linux.org
Thu Jul 18 18:19:08 CEST 2024
commit 7b2c77b94f1ef10eed05f65f353fd6b1bc1a63cf
Author: Jan Palus <atler at pld-linux.org>
Date: Thu Jul 18 17:51:14 2024 +0200
upstream fix for CVE-2024-39936; rel 2
as advised in:
https://lists.qt-project.org/pipermail/announce/2024-July/000507.html
CVE-2024-39936-qtbase-6.7.patch | 138 ++++++++++++++++++++++++++++++++++++++++
qt6.spec | 4 +-
2 files changed, 141 insertions(+), 1 deletion(-)
---
diff --git a/qt6.spec b/qt6.spec
index 563b568..54dc011 100644
--- a/qt6.spec
+++ b/qt6.spec
@@ -113,7 +113,7 @@ Summary: Qt6 Library
Summary(pl.UTF-8): Biblioteka Qt6
Name: qt6
Version: 6.7.2
-Release: 1
+Release: 2
License: LGPL v3 or GPL v2 or GPL v3 or commercial
Group: X11/Libraries
Source0: https://download.qt.io/official_releases/qt/6.7/%{version}/single/qt-everywhere-src-%{version}.tar.xz
@@ -124,6 +124,7 @@ Patch2: %{name}-gn.patch
Patch3: no-implicit-sse2.patch
Patch4: x32.patch
Patch5: qtwebengine-cmake-build-type.patch
+Patch6: CVE-2024-39936-qtbase-6.7.patch
URL: https://www.qt.io/
%{?with_directfb:BuildRequires: DirectFB-devel}
BuildRequires: EGL-devel
@@ -3693,6 +3694,7 @@ narzędzia.
%patch3 -p1
%patch4 -p1
%patch5 -p1
+%patch6 -p1 -d qtbase
%{__sed} -i -e 's,usr/X11R6/,usr/,g' qtbase/mkspecs/linux-g++-64/qmake.conf
diff --git a/CVE-2024-39936-qtbase-6.7.patch b/CVE-2024-39936-qtbase-6.7.patch
new file mode 100644
index 0000000..bef53fb
--- /dev/null
+++ b/CVE-2024-39936-qtbase-6.7.patch
@@ -0,0 +1,138 @@
+diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
+index 0abd99b9bc2..3631b13dc85 100644
+--- a/src/network/access/qhttp2protocolhandler.cpp
++++ b/src/network/access/qhttp2protocolhandler.cpp
+@@ -303,12 +303,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?
+diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
+index 6766989690c..1e4161d1fdf 100644
+--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
++++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
+@@ -209,6 +209,10 @@ void QHttpNetworkConnectionChannel::abort()
+ bool QHttpNetworkConnectionChannel::sendRequest()
+ {
+ Q_ASSERT(protocolHandler);
++ if (waitingForPotentialAbort) {
++ needInvokeSendRequest = true;
++ return false; // this return value is unused
++ }
+ return protocolHandler->sendRequest();
+ }
+
+@@ -221,21 +225,28 @@ bool QHttpNetworkConnectionChannel::sendRequest()
+ void QHttpNetworkConnectionChannel::sendRequestDelayed()
+ {
+ QMetaObject::invokeMethod(this, [this] {
+- Q_ASSERT(protocolHandler);
+ if (reply)
+- protocolHandler->sendRequest();
++ sendRequest();
+ }, Qt::ConnectionType::QueuedConnection);
+ }
+
+ void QHttpNetworkConnectionChannel::_q_receiveReply()
+ {
+ Q_ASSERT(protocolHandler);
++ if (waitingForPotentialAbort) {
++ needInvokeReceiveReply = true;
++ return;
++ }
+ protocolHandler->_q_receiveReply();
+ }
+
+ void QHttpNetworkConnectionChannel::_q_readyRead()
+ {
+ Q_ASSERT(protocolHandler);
++ if (waitingForPotentialAbort) {
++ needInvokeReadyRead = true;
++ return;
++ }
+ protocolHandler->_q_readyRead();
+ }
+
+@@ -1239,7 +1250,18 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
+ if (!h2RequestsToSend.isEmpty()) {
+ // Similar to HTTP/1.1 counterpart below:
+ const auto &pair = std::as_const(h2RequestsToSend).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).
+ }
+@@ -1257,6 +1279,28 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
+ QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
+ }
+
++
++void QHttpNetworkConnectionChannel::checkAndResumeCommunication()
++{
++ Q_ASSERT(connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
++ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct);
++
++ // 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 && h2RequestsToSend.isEmpty())
++ abort();
++ waitingForPotentialAbort = false;
++ if (needInvokeReadyRead)
++ _q_readyRead();
++ if (needInvokeReceiveReply)
++ _q_receiveReply();
++ if (needInvokeSendRequest)
++ sendRequest();
++}
++
+ void QHttpNetworkConnectionChannel::requeueHttp2Requests()
+ {
+ const auto h2RequestsToSendCopy = std::exchange(h2RequestsToSend, {});
+diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
+index c42290feca4..061f20fd426 100644
+--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
++++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
+@@ -74,6 +74,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
+@@ -146,6 +150,8 @@ public:
+ void closeAndResendCurrentRequest();
+ void resendCurrentRequest();
+
++ void checkAndResumeCommunication();
++
+ bool isSocketBusy() const;
+ bool isSocketWriting() const;
+ bool isSocketWaiting() const;
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/qt6.git/commitdiff/7b2c77b94f1ef10eed05f65f353fd6b1bc1a63cf
More information about the pld-cvs-commit
mailing list