diff --git a/0001-HTTP2-Delay-any-communication-until-encrypted-can-be.patch b/0001-HTTP2-Delay-any-communication-until-encrypted-can-be.patch new file mode 100644 index 0000000..617f0f8 --- /dev/null +++ b/0001-HTTP2-Delay-any-communication-until-encrypted-can-be.patch @@ -0,0 +1,244 @@ +From 2b1e36e183ce75c224305c7a94457b92f7a5cf58 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.5 6.2 5.15 5.12 +Change-Id: Ic25a600c278203256e35f541026f34a8783235ae +Reviewed-by: Marc Mutz +Reviewed-by: Volker Hilsheimer +(cherry picked from commit b1e75376cc3adfc7da5502a277dfe9711f3e0536) +Reviewed-by: Qt Cherry-pick Bot +(cherry picked from commit 0fb43e4395da34d561814242a0186999e4956e28) +--- + src/network/access/qhttp2protocolhandler.cpp | 6 +-- + .../access/qhttpnetworkconnectionchannel.cpp | 48 ++++++++++++++++++- + .../access/qhttpnetworkconnectionchannel_p.h | 6 +++ + tests/auto/network/access/http2/tst_http2.cpp | 44 +++++++++++++++++ + 4 files changed, 99 insertions(+), 5 deletions(-) + +diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp +index 0abd99b9bc..3631b13dc8 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 6766989690..1e4161d1fd 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 c42290feca..061f20fd42 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; +diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp +index 00efbc9832..c02e7b7b5b 100644 +--- a/tests/auto/network/access/http2/tst_http2.cpp ++++ b/tests/auto/network/access/http2/tst_http2.cpp +@@ -106,6 +106,8 @@ private slots: + + void duplicateRequestsWithAborts(); + ++ void abortOnEncrypted(); ++ + protected slots: + // Slots to listen to our in-process server: + void serverStarted(quint16 port); +@@ -1479,6 +1481,48 @@ void tst_Http2::duplicateRequestsWithAborts() + QCOMPARE(finishedCount, ExpectedSuccessfulRequests); + } + ++void tst_Http2::abortOnEncrypted() ++{ ++#if !QT_CONFIG(ssl) ++ QSKIP("TLS support is needed for this test"); ++#else ++ clearHTTP2State(); ++ serverPort = 0; ++ ++ ServerPtr targetServer(newServer(defaultServerSettings, H2Type::h2Direct)); ++ ++ QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection); ++ runEventLoop(); ++ ++ nRequests = 1; ++ nSentRequests = 0; ++ ++ const auto url = requestUrl(H2Type::h2Direct); ++ QNetworkRequest request(url); ++ request.setAttribute(QNetworkRequest::Http2DirectAttribute, true); ++ ++ std::unique_ptr reply{manager->get(request)}; ++ reply->ignoreSslErrors(); ++ connect(reply.get(), &QNetworkReply::encrypted, reply.get(), [reply = reply.get()](){ ++ reply->abort(); ++ }); ++ connect(reply.get(), &QNetworkReply::errorOccurred, this, &tst_Http2::replyFinishedWithError); ++ ++ runEventLoop(); ++ STOP_ON_FAILURE ++ ++ QCOMPARE(nRequests, 0); ++ QCOMPARE(reply->error(), QNetworkReply::OperationCanceledError); ++ ++ const bool res = QTest::qWaitFor( ++ [this, server = targetServer.get()]() { ++ return serverGotSettingsACK || prefaceOK || nSentRequests > 0; ++ }, ++ 500); ++ QVERIFY(!res); ++#endif // QT_CONFIG(ssl) ++} ++ + void tst_Http2::serverStarted(quint16 port) + { + serverPort = port; +-- +2.45.2 + diff --git a/0001-Tell-the-truth-about-private-API.patch b/0001-Tell-the-truth-about-private-API.patch deleted file mode 100644 index b9c63f0..0000000 --- a/0001-Tell-the-truth-about-private-API.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 25e78cce15fdf737cc48ed5d7683ad1d01b55621 Mon Sep 17 00:00:00 2001 -From: Christophe Giboudeaux -Date: Sun, 20 Sep 2020 09:57:22 +0200 -Subject: [PATCH] Tell the truth about private API - -Mark private API with symbols only for the current patch release - -This change is a port of the libqt5-qtbase patch which was -added during the Qt 5.6 cycle. ---- - cmake/QtFlagHandlingHelpers.cmake | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake -index d8597326cc..f9da7b2171 100644 ---- a/cmake/QtFlagHandlingHelpers.cmake -+++ b/cmake/QtFlagHandlingHelpers.cmake -@@ -23,7 +23,7 @@ function(qt_internal_add_linker_version_script target) - endif() - - if(TEST_ld_version_script) -- set(contents "Qt_${PROJECT_VERSION_MAJOR}_PRIVATE_API {\n qt_private_api_tag*;\n") -+ set(contents "Qt_${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}_PRIVATE_API {\n qt_private_api_tag*;\n") - if(arg_PRIVATE_HEADERS) - foreach(ph ${arg_PRIVATE_HEADERS}) - string(APPEND contents " @FILE:${ph}@\n") --- -2.40.0 - diff --git a/gcc14.patch b/gcc14.patch new file mode 100644 index 0000000..8eb0128 --- /dev/null +++ b/gcc14.patch @@ -0,0 +1,48 @@ +From 39fa7e7bef90be2940c5f736935f963e3969e0bd Mon Sep 17 00:00:00 2001 +From: Dmitry Shachnev +Date: Sat, 27 Jul 2024 23:03:07 +0300 +Subject: [PATCH] Use _Float16 only when SSE2 is enabled + +The GCC documentation [1] says: “On x86 targets with SSE2 enabled, GCC +supports half-precision (16-bit) floating point via the _Float16 type”. + +On non-SSE2 x86 (such as Debian i386 baseline [2]), __FLT16_MAX__ is +defined starting with GCC 14 [3], however any non-trivial use of the +_Float16 type results in an error: + +error: operation not permitted on type ‘_Float16’ without option ‘-msse2’ + +which makes some packages fail to build on i386 architecture [4]. + +[1]: https://gcc.gnu.org/onlinedocs/gcc/Half-Precision.html +[2]: https://wiki.debian.org/ArchitectureSpecificsMemo#i386-1 +[3]: https://gcc.gnu.org/g:9a19fa8b616f83474c35cc5b34a3865073ced829 +[4]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1076986 + +Pick-to: 6.8 6.7 6.5 +Change-Id: I393ee83eb8e8888f5fc9e3b349dc8b063eef6f5a +Reviewed-by: Thiago Macieira +Reviewed-by: Edward Welbourne +--- + +diff --git a/src/corelib/global/qtypes.h b/src/corelib/global/qtypes.h +index db9ba38..28458f6 100644 +--- a/src/corelib/global/qtypes.h ++++ b/src/corelib/global/qtypes.h +@@ -263,13 +263,12 @@ + // disabled due to https://github.com/llvm/llvm-project/issues/56963 + # define QFLOAT16_IS_NATIVE 1 + using NativeFloat16Type = decltype(__FLT16_MAX__); +-#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) ++#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__ARM_FP16_FORMAT_IEEE) + # define QFLOAT16_IS_NATIVE 1 +-# ifdef __ARM_FP16_FORMAT_IEEE + using NativeFloat16Type = __fp16; +-# else ++#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__SSE2__) ++# define QFLOAT16_IS_NATIVE 1 + using NativeFloat16Type = _Float16; +-# endif + #else + # define QFLOAT16_IS_NATIVE 0 + using NativeFloat16Type = void; diff --git a/qt6-base.changes b/qt6-base.changes index 63f537c..7567826 100644 --- a/qt6-base.changes +++ b/qt6-base.changes @@ -1,3 +1,48 @@ +------------------------------------------------------------------- +Wed Aug 7 12:46:16 UTC 2024 - Filip Kastl + +- Add gcc14.patch so that the package builds for 32bit with GCC 14. + +------------------------------------------------------------------- +Sat Jul 6 11:22:52 UTC 2024 - Christophe Marin + +- Add upstream change (boo#1227426, CVE-2024-39936) + * 0001-HTTP2-Delay-any-communication-until-encrypted-can-be.patch + +------------------------------------------------------------------- +Wed Jun 19 07:25:37 UTC 2024 - Christophe Marin + +- Update to 6.7.2: + * https://www.qt.io/blog/qt-6.7.2-released + +------------------------------------------------------------------- +Tue May 21 08:31:24 UTC 2024 - Christophe Marin + +- Update to 6.7.1: + * https://www.qt.io/blog/qt-6.7.1-released +- Build with system md4c when possible +- Drop patches, merged upstream: + * fix_builds_with_Werror.patch + * 0001-QStringConverterICU-Pass-correct-pointer-to-callback.patch + * 0001-CMake-ELF-allow-using-Qt-s-full-version-number-in-th.patch + +------------------------------------------------------------------- +Fri May 3 07:15:23 UTC 2024 - Christophe Marin + +- Add upstream security fix (CVE-2024-33861, boo#1223917): + * 0001-QStringConverterICU-Pass-correct-pointer-to-callback.patch + +------------------------------------------------------------------- +Tue Apr 2 13:39:34 UTC 2024 - Christophe Marin + +- Update to 6.7.0: + * https://www.qt.io/blog/qt-6.7-released +- Replace 0001-Tell-the-truth-about-private-API.patch with + upstream change: + * 0001-CMake-ELF-allow-using-Qt-s-full-version-number-in-th.patch +- Add upstream fix (QTBUG-123937): + * fix_builds_with_Werror.patch + ------------------------------------------------------------------- Tue Mar 26 14:25:22 UTC 2024 - Christophe Marin diff --git a/qt6-base.spec b/qt6-base.spec index 9d1d599..17ab6e7 100644 --- a/qt6-base.spec +++ b/qt6-base.spec @@ -16,8 +16,8 @@ # -%define real_version 6.6.3 -%define short_version 6.6 +%define real_version 6.7.2 +%define short_version 6.7 %define tar_name qtbase-everywhere-src %define tar_suffix %{nil} # @@ -29,24 +29,28 @@ %ifarch %{arm} aarch64 %global with_gles 1 %endif +%if 0%{?suse_version} > 1500 +%bcond_without system_md4c +%endif Name: qt6-base%{?pkg_suffix} -Version: 6.6.3 +Version: 6.7.2 Release: 0 Summary: Qt 6 core components (Core, Gui, Widgets, Network...) # Legal: qtpaths is BSD-3-Clause License: LGPL-2.1-with-Qt-Company-Qt-exception-1.1 OR LGPL-3.0-only URL: https://www.qt.io -Source: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz +Source0: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz Source99: qt6-base-rpmlintrc # Patches 0-100 are upstream patches # +Patch0: gcc14.patch # Patches 100-200 are openSUSE and/or non-upstream(able) patches # -Patch100: 0001-Tell-the-truth-about-private-API.patch # No need to pollute the library dir with object files, install them in the qt6 subfolder -Patch101: 0001-CMake-Install-objects-files-into-ARCHDATADIR.patch +Patch100: 0001-CMake-Install-objects-files-into-ARCHDATADIR.patch %if 0%{?suse_version} == 1500 -Patch102: 0001-Use-newer-GCC-on-Leap.patch +Patch101: 0001-Use-newer-GCC-on-Leap.patch %endif -Patch103: 0001-Don-t-strip-binaries-when-building-with-qmake.patch +Patch102: 0001-Don-t-strip-binaries-when-building-with-qmake.patch +Patch103: 0001-HTTP2-Delay-any-communication-until-encrypted-can-be.patch ## BuildRequires: cmake >= 3.18.3 BuildRequires: cups-devel @@ -68,6 +72,9 @@ BuildRequires: pkgconfig BuildRequires: qt6-macros BuildRequires: xmlstarlet BuildRequires: cmake(double-conversion) +%if %{with system_md4c} +BuildRequires: cmake(md4c) +%endif BuildRequires: pkgconfig(atspi-2) BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(egl) @@ -737,6 +744,9 @@ sed -i 's#../../3rdparty/freetype/LICENSE.txt#FREETYPE_LICENSE.txt#' src/gui/pai # We don't want to use these 3rdparty libraries rm -r src/3rdparty/{blake2,double-conversion,freetype,harfbuzz-ng,libjpeg,libpng,pcre2,sqlite,xcb,zlib} +%if %{with system_md4c} +rm -r src/3rdparty/md4c +%endif # Empty file used for the meta packages cat >> meta_package << EOF @@ -771,24 +781,25 @@ sed -i '/zstd CONFIG/d' cmake/FindWrapZSTD.cmake -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ -DQT_BUILD_EXAMPLES:BOOL=TRUE \ -DQT_BUILD_TESTS:BOOL=FALSE \ - -DQT_CREATE_VERSIONED_HARD_LINK:BOOL=OFF \ - -DQT_DISABLE_RPATH:BOOL=OFF \ + -DQT_CREATE_VERSIONED_HARD_LINK:BOOL=FALSE \ + -DQT_DISABLE_RPATH:BOOL=FALSE \ %ifnarch ppc64 - -DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=ON \ + -DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=TRUE \ %endif - -DFEATURE_enable_new_dtags:BOOL=ON \ - -DFEATURE_journald:BOOL=ON \ - -DFEATURE_libproxy:BOOL=ON \ - -DFEATURE_reduce_relocations:BOOL=OFF \ - -DFEATURE_relocatable:BOOL=OFF \ - -DFEATURE_system_sqlite:BOOL=ON \ - -DFEATURE_system_xcb_xinput:BOOL=ON \ - -DFEATURE_xcb_native_painting:BOOL=ON \ + -DFEATURE_elf_private_full_version=TRUE \ + -DFEATURE_enable_new_dtags:BOOL=TRUE \ + -DFEATURE_journald:BOOL=TRUE \ + -DFEATURE_libproxy:BOOL=TRUE \ + -DFEATURE_reduce_relocations:BOOL=FALSE \ + -DFEATURE_relocatable:BOOL=FALSE \ + -DFEATURE_system_sqlite:BOOL=TRUE \ + -DFEATURE_system_xcb_xinput:BOOL=TRUE \ + -DFEATURE_xcb_native_painting:BOOL=TRUE \ -DINPUT_openssl:STRING=linked \ - -DFEATURE_forkfd_pidfd:BOOL=OFF \ + -DFEATURE_forkfd_pidfd:BOOL=FALSE \ %if 0%{?with_gles} -DINPUT_opengl:STRING=es2 \ - -DFEATURE_opengles3:BOOL=ON + -DFEATURE_opengles3:BOOL=TRUE %endif %{qt6_build} @@ -816,7 +827,6 @@ rm %{buildroot}%{_qt6_mkspecsdir}/modules/qt_lib_concurrent_private.pri rm %{buildroot}%{_qt6_mkspecsdir}/modules/qt_lib_openglwidgets_private.pri # These files are only useful for the Qt continuous integration -rm %{buildroot}%{_qt6_libexecdir}/android_*.sh rm %{buildroot}%{_qt6_libexecdir}/ensure_pro_file.cmake rm %{buildroot}%{_qt6_libexecdir}/qt-testrunner.py rm %{buildroot}%{_qt6_libexecdir}/sanitizer-testrunner.py @@ -885,6 +895,7 @@ rm -r %{buildroot}%{_qt6_mkspecsdir}/features/uikit %{_qt6_libexecdir}/qt-cmake-private %{_qt6_libexecdir}/qt-cmake-private-install.cmake %{_qt6_libexecdir}/qt-cmake-standalone-test +%{_qt6_libexecdir}/qt-internal-configure-examples %{_qt6_libexecdir}/qt-internal-configure-tests %{_qt6_libexecdir}/qvkgen %{_qt6_libexecdir}/rcc diff --git a/qtbase-everywhere-src-6.6.3.tar.xz b/qtbase-everywhere-src-6.6.3.tar.xz deleted file mode 100644 index 95efa81..0000000 --- a/qtbase-everywhere-src-6.6.3.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0493fd0b380c4edf8872f011a7f26d245aa4cdd75b349904ef340a22dedf7462 -size 48784716 diff --git a/qtbase-everywhere-src-6.7.2.tar.xz b/qtbase-everywhere-src-6.7.2.tar.xz new file mode 100644 index 0000000..b05d17f --- /dev/null +++ b/qtbase-everywhere-src-6.7.2.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5f22a5e10fb162895ded7de0963328e7307611c688487b5d152c9ee64767599 +size 49364504