From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 8AF011581C1 for ; Tue, 16 Jul 2024 21:42:02 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 67AFC2BC02F; Tue, 16 Jul 2024 21:42:01 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 41B5F2BC02F for ; Tue, 16 Jul 2024 21:42:01 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 354D433FEF1 for ; Tue, 16 Jul 2024 21:42:00 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 70D731E35 for ; Tue, 16 Jul 2024 21:41:58 +0000 (UTC) From: "Andreas Sturmlechner" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Andreas Sturmlechner" Message-ID: <1721166022.69cfa9cc226d2c4195132da0c4a0373a080b7d9d.asturm@gentoo> Subject: [gentoo-commits] repo/gentoo:master commit in: dev-qt/qtnetwork/files/, dev-qt/qtnetwork/ X-VCS-Repository: repo/gentoo X-VCS-Files: dev-qt/qtnetwork/files/qtnetwork-5.15.14-CVE-2024-39936.patch dev-qt/qtnetwork/qtnetwork-5.15.14-r1.ebuild X-VCS-Directories: dev-qt/qtnetwork/files/ dev-qt/qtnetwork/ X-VCS-Committer: asturm X-VCS-Committer-Name: Andreas Sturmlechner X-VCS-Revision: 69cfa9cc226d2c4195132da0c4a0373a080b7d9d X-VCS-Branch: master Date: Tue, 16 Jul 2024 21:41:58 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: fa00d8f7-852b-463b-9ec9-bc0f392d4070 X-Archives-Hash: 62c10756568b8fc9cf2567f5220d53c8 commit: 69cfa9cc226d2c4195132da0c4a0373a080b7d9d Author: Andreas Sturmlechner gentoo org> AuthorDate: Tue Jul 16 21:39:56 2024 +0000 Commit: Andreas Sturmlechner gentoo org> CommitDate: Tue Jul 16 21:40:22 2024 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=69cfa9cc dev-qt/qtnetwork: Fix CVE-2024-39936 Bug: https://bugs.gentoo.org/935869 Signed-off-by: Andreas Sturmlechner gentoo.org> .../files/qtnetwork-5.15.14-CVE-2024-39936.patch | 178 +++++++++++++++++++++ dev-qt/qtnetwork/qtnetwork-5.15.14-r1.ebuild | 64 ++++++++ 2 files changed, 242 insertions(+) diff --git a/dev-qt/qtnetwork/files/qtnetwork-5.15.14-CVE-2024-39936.patch b/dev-qt/qtnetwork/files/qtnetwork-5.15.14-CVE-2024-39936.patch new file mode 100644 index 000000000000..c4445b2a72e8 --- /dev/null +++ b/dev-qt/qtnetwork/files/qtnetwork-5.15.14-CVE-2024-39936.patch @@ -0,0 +1,178 @@ +From 9f9a56d750caff8b4459e7e9bf82f1f4d725f72f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= +Date: Tue, 25 Jun 2024 17:09:35 +0200 +Subject: [PATCH] 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. + +Fixes: QTBUG-126610 +Pick-to: 6.8 6.7 6.5 6.2 5.15 5.12 +Change-Id: Ic25a600c278203256e35f541026f34a8783235ae +Reviewed-by: Marc Mutz +Reviewed-by: Volker Hilsheimer +(cherry picked from commit b1e75376cc3adfc7da5502a277dfe9711f3e0536) +(but really taken from upstream CVE-2024-39936-qtbase-5.15.patch) +--- + src/network/access/qhttp2protocolhandler.cpp | 6 +-- + .../access/qhttpnetworkconnectionchannel.cpp | 46 ++++++++++++++++++- + .../access/qhttpnetworkconnectionchannel_p.h | 6 +++ + 3 files changed, 53 insertions(+), 5 deletions(-) + +diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp +index ead88d781ae..926f3134a0e 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 7620ca16470..13f9630c658 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 spdyPairs = spdyRequestsToSend.values(); +diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h +index d8ac3979d19..eac44464926 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; +-- +2.45.2 + diff --git a/dev-qt/qtnetwork/qtnetwork-5.15.14-r1.ebuild b/dev-qt/qtnetwork/qtnetwork-5.15.14-r1.ebuild new file mode 100644 index 000000000000..b28dc1384dcf --- /dev/null +++ b/dev-qt/qtnetwork/qtnetwork-5.15.14-r1.ebuild @@ -0,0 +1,64 @@ +# Copyright 1999-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +if [[ ${PV} != *9999* ]]; then + QT5_KDEPATCHSET_REV=1 + KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~loong ~ppc ~ppc64 ~riscv ~sparc ~x86" +fi + +QT5_MODULE="qtbase" +inherit qt5-build + +DESCRIPTION="Network abstraction library for the Qt5 framework" + +IUSE="gssapi libproxy sctp +ssl" + +DEPEND=" + =dev-qt/qtcore-${QT5_PV}*:5= + sys-libs/zlib:= + gssapi? ( virtual/krb5 ) + libproxy? ( net-libs/libproxy ) + sctp? ( kernel_linux? ( net-misc/lksctp-tools ) ) + ssl? ( >=dev-libs/openssl-1.1.1:0= ) +" +RDEPEND="${DEPEND}" + +PATCHES=( "${FILESDIR}/${P}-CVE-2024-39936.patch" ) # bug 935869 + +QT5_TARGET_SUBDIRS=( + src/network + src/plugins/bearer/generic +) + +QT5_GENTOO_CONFIG=( + libproxy:libproxy: + ssl::SSL + ssl::OPENSSL + ssl:openssl-linked:LINKED_OPENSSL +) + +QT5_GENTOO_PRIVATE_CONFIG=( + :network +) + +src_configure() { + local myconf=( + $(qt_use gssapi feature-gssapi) + $(qt_use libproxy) + $(qt_use sctp) + $(usev ssl -openssl-linked) + ) + qt5-build_src_configure +} + +src_install() { + qt5-build_src_install + + # workaround for bug 652650 + if use ssl; then + sed -e "/^#define QT_LINKED_OPENSSL/s/$/ true/" \ + -i "${D}${QT5_HEADERDIR}"/Gentoo/${PN}-qconfig.h || die + fi +}