[packages/qt5-qtbase] upstream fix for CVE-2024-39936; rel 2

atler atler at pld-linux.org
Thu Jul 18 18:18:27 CEST 2024


commit 6c31c1ce0f0102a84962ff87572b27b7cb16f9e8
Author: Jan Palus <atler at pld-linux.org>
Date:   Thu Jul 18 17:49:39 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-5.15.patch | 136 +++++++++++++++++++++++++++++++++++++++
 qt5-qtbase.spec                  |   4 +-
 2 files changed, 139 insertions(+), 1 deletion(-)
---
diff --git a/qt5-qtbase.spec b/qt5-qtbase.spec
index 9f34fa1..90a1d37 100644
--- a/qt5-qtbase.spec
+++ b/qt5-qtbase.spec
@@ -71,7 +71,7 @@ Summary:	Qt5 - base components
 Summary(pl.UTF-8):	Biblioteka Qt5 - podstawowe komponenty
 Name:		qt5-%{orgname}
 Version:	5.15.14
-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/5.15/%{version}/submodules/%{orgname}-everywhere-opensource-src-%{version}.tar.xz
@@ -82,6 +82,7 @@ Patch0:		%{name}-system_cacerts.patch
 Patch1:		parallel-install.patch
 Patch2:		egl-x11.patch
 Patch3:		CVE-2023-32763-qtbase-5.15.diff
+Patch4:		CVE-2024-39936-qtbase-5.15.patch
 Patch6:		CVE-2023-34410-qtbase-5.15.diff
 Patch7:		CVE-2023-37369-qtbase-5.15.diff
 Patch8:		CVE-2023-38197-qtbase-5.15.diff
@@ -1183,6 +1184,7 @@ Generator plików makefile dla aplikacji Qt5.
 %patch1 -p1
 %patch2 -p1
 %patch3 -p1
+%patch4 -p1
 %patch6 -p1
 %patch7 -p1
 %patch8 -p1
diff --git a/CVE-2024-39936-qtbase-5.15.patch b/CVE-2024-39936-qtbase-5.15.patch
new file mode 100644
index 0000000..94840f6
--- /dev/null
+++ b/CVE-2024-39936-qtbase-5.15.patch
@@ -0,0 +1,136 @@
+diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
+index d1b5dfda2e2..ee04a1856c6 100644
+--- a/src/network/access/qhttp2protocolhandler.cpp
++++ b/src/network/access/qhttp2protocolhandler.cpp
+@@ -375,12 +375,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 bd2f32e3528..6f3bd807a09 100644
+--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
++++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
+@@ -255,6 +255,10 @@ void QHttpNetworkConnectionChannel::abort()
+ 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::sendRequest()
+ 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_encrypted()
+             // 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_encrypted()
+     }
+ }
+ 
++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();
+diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
+index 6be0c51f9fe..613fda7bc31 100644
+--- 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;
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/qt5-qtbase.git/commitdiff/6c31c1ce0f0102a84962ff87572b27b7cb16f9e8



More information about the pld-cvs-commit mailing list