Download raw body.
CVE-2025-5455 and CVE-2025-6338: qt6-qtbase-6.8.3
Simple diff to fix CVE-2025-5455 and CVE-2025-6338 in
qt6-qtbase-6.8.3. Tested on amd64. OK?
Cheers Rafael
Index: Makefile
===================================================================
RCS file: /cvs/ports/x11/qt6/qtbase/Makefile,v
diff -u -p -u -p -r1.43 Makefile
--- Makefile 6 Jun 2025 05:12:03 -0000 1.43
+++ Makefile 3 Aug 2025 07:57:55 -0000
@@ -4,7 +4,7 @@ COMMENT-main = C++ general-purpose tool
COMMENT-global = global Qt6 documentation internals
COMMENT-mysql = MySQL plugin for Qt6
COMMENT-psql = PostgresSQL plugin for Qt6
-REVISION-main = 1
+REVISION-main = 2
PKGSPEC-main = qt6-qtbase-${QT6_PKGSPEC}
Index: patches/patch-src_corelib_io_qdataurl_cpp
===================================================================
RCS file: patches/patch-src_corelib_io_qdataurl_cpp
diff -N patches/patch-src_corelib_io_qdataurl_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_corelib_io_qdataurl_cpp 3 Aug 2025 07:57:55 -0000
@@ -0,0 +1,19 @@
+https://download.qt.io/official_releases/qt/6.8/CVE-2025-5455-qtbase-6.8.patch
+Index: src/corelib/io/qdataurl.cpp
+--- src/corelib/io/qdataurl.cpp.orig
++++ src/corelib/io/qdataurl.cpp
+@@ -47,10 +47,10 @@ Q_CORE_EXPORT bool qDecodeDataUrl(const QUrl &uri, QSt
+ QLatin1StringView textPlain;
+ constexpr auto charset = "charset"_L1;
+ if (QLatin1StringView{data}.startsWith(charset, Qt::CaseInsensitive)) {
+- qsizetype i = charset.size();
+- while (data.at(i) == ' ')
+- ++i;
+- if (data.at(i) == '=')
++ QByteArrayView copy = data.sliced(charset.size());
++ while (copy.startsWith(' '))
++ copy.slice(1);
++ if (copy.startsWith('='))
+ textPlain = "text/plain;"_L1;
+ }
+
Index: patches/patch-src_plugins_tls_schannel_qtls_schannel_cpp
===================================================================
RCS file: patches/patch-src_plugins_tls_schannel_qtls_schannel_cpp
diff -N patches/patch-src_plugins_tls_schannel_qtls_schannel_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_plugins_tls_schannel_qtls_schannel_cpp 3 Aug 2025 07:57:55 -0000
@@ -0,0 +1,225 @@
+https://ftp.fau.de/qtproject/archive/qt/6.8/CVE-2025-6338-qtbase-6.8.patch
+
+Index: src/plugins/tls/schannel/qtls_schannel.cpp
+--- src/plugins/tls/schannel/qtls_schannel.cpp.orig
++++ src/plugins/tls/schannel/qtls_schannel.cpp
+@@ -7,6 +7,7 @@
+ #include "qtlskey_schannel_p.h"
+ #include "qx509_schannel_p.h"
+ #include "qtls_schannel_p.h"
++#include "../shared/qasn1element_p.h"
+
+ #include <QtNetwork/private/qsslcertificate_p.h>
+ #include <QtNetwork/private/qsslcipher_p.h>
+@@ -126,8 +127,9 @@ using namespace Qt::StringLiterals;
+ Q_LOGGING_CATEGORY(lcTlsBackendSchannel, "qt.tlsbackend.schannel");
+
+ // Defined in qsslsocket_qt.cpp.
+-QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key,
++extern QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key,
+ const QString &passPhrase);
++extern QAsn1Element _q_PKCS12_key(const QSslKey &key);
+
+ namespace {
+ bool supportsTls13();
+@@ -1003,7 +1005,6 @@ TlsCryptographSchannel::~TlsCryptographSchannel()
+ closeCertificateStores();
+ deallocateContext();
+ freeCredentialsHandle();
+- CertFreeCertificateContext(localCertContext);
+ }
+
+ void TlsCryptographSchannel::init(QSslSocket *qObj, QSslSocketPrivate *dObj)
+@@ -1098,12 +1099,6 @@ bool TlsCryptographSchannel::acquireCredentialsHandle(
+ return false;
+ }
+
+- const CERT_CHAIN_CONTEXT *chainContext = nullptr;
+- auto freeCertChain = qScopeGuard([&chainContext]() {
+- if (chainContext)
+- CertFreeCertificateChain(chainContext);
+- });
+-
+ DWORD certsCount = 0;
+ // Set up our certificate stores before trying to use one...
+ initializeCertificateStores();
+@@ -1114,36 +1109,11 @@ bool TlsCryptographSchannel::acquireCredentialsHandle(
+ if (!configuration.localCertificateChain().isEmpty() && !localCertificateStore)
+ return true; // 'true' because "tst_QSslSocket::setEmptyKey" expects us to not disconnect
+
++ PCCERT_CONTEXT localCertificate = nullptr;
+ if (localCertificateStore != nullptr) {
+- CERT_CHAIN_FIND_BY_ISSUER_PARA findParam;
+- ZeroMemory(&findParam, sizeof(findParam));
+- findParam.cbSize = sizeof(findParam);
+- findParam.pszUsageIdentifier = isClient ? szOID_PKIX_KP_CLIENT_AUTH : szOID_PKIX_KP_SERVER_AUTH;
+-
+- // There should only be one chain in our store, so.. we grab that one.
+- chainContext = CertFindChainInStore(localCertificateStore.get(),
+- X509_ASN_ENCODING,
+- 0,
+- CERT_CHAIN_FIND_BY_ISSUER,
+- &findParam,
+- nullptr);
+- if (!chainContext) {
+- const QString message = isClient
+- ? QSslSocket::tr("The certificate provided cannot be used for a client.")
+- : QSslSocket::tr("The certificate provided cannot be used for a server.");
+- setErrorAndEmit(d, QAbstractSocket::SocketError::SslInvalidUserDataError, message);
+- return false;
+- }
+- Q_ASSERT(chainContext->cChain == 1);
+- Q_ASSERT(chainContext->rgpChain[0]);
+- Q_ASSERT(chainContext->rgpChain[0]->cbSize >= 1);
+- Q_ASSERT(chainContext->rgpChain[0]->rgpElement[0]);
+- Q_ASSERT(!localCertContext);
+- localCertContext = CertDuplicateCertificateContext(chainContext->rgpChain[0]
+- ->rgpElement[0]
+- ->pCertContext);
+ certsCount = 1;
+- Q_ASSERT(localCertContext);
++ localCertificate = static_cast<PCCERT_CONTEXT>(configuration.localCertificate().handle());
++ Q_ASSERT(localCertificate);
+ }
+
+ const QList<QSslCipher> ciphers = configuration.ciphers();
+@@ -1167,7 +1137,7 @@ bool TlsCryptographSchannel::acquireCredentialsHandle(
+ SCH_CREDENTIALS_VERSION,
+ 0,
+ certsCount,
+- &localCertContext,
++ &localCertificate,
+ nullptr,
+ 0,
+ nullptr,
+@@ -1724,9 +1694,6 @@ void TlsCryptographSchannel::reset()
+ connectionInfo = {};
+ streamSizes = {};
+
+- CertFreeCertificateContext(localCertContext);
+- localCertContext = nullptr;
+-
+ contextAttributes = 0;
+ intermediateBuffer.clear();
+ schannelState = SchannelState::InitializeHandshake;
+@@ -2236,6 +2203,70 @@ bool TlsCryptographSchannel::checkSslErrors()
+ return true;
+ }
+
++static void attachPrivateKeyToCertificate(const QSslCertificate &certificate,
++ const QSslKey &privateKey)
++{
++ QAsn1Element elem = _q_PKCS12_key(privateKey);
++ QByteArray buffer;
++ QDataStream stream(&buffer, QDataStream::WriteOnly);
++ elem.write(stream);
++ NCRYPT_PROV_HANDLE provider = 0;
++ SECURITY_STATUS status = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0);
++ if (status != SEC_E_OK) {
++ qCWarning(lcTlsBackendSchannel())
++ << "Failed to open ncrypt storage provider:" << schannelErrorToString(status);
++ return;
++ }
++ const auto freeProvider = qScopeGuard([provider]() { NCryptFreeObject(provider); });
++
++ const QString certName = certificate.subjectInfo(QSslCertificate::CommonName).front();
++ QSpan<const QChar> nameSpan(certName);
++ NCryptBuffer nbuffer{ ULONG(nameSpan.size_bytes() + sizeof(char16_t)),
++ NCRYPTBUFFER_PKCS_KEY_NAME,
++ const_reinterpret_cast<void *>(nameSpan.data()) };
++ NCryptBufferDesc bufferDesc{ NCRYPTBUFFER_VERSION, 1, &nbuffer };
++ NCRYPT_KEY_HANDLE ncryptKey = 0;
++ status = NCryptImportKey(provider, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &bufferDesc, &ncryptKey,
++ PBYTE(buffer.data()), buffer.size(), 0);
++ if (status != SEC_E_OK) {
++ qCWarning(lcTlsBackendSchannel())
++ << "Failed to import private key:" << schannelErrorToString(status);
++ return;
++ }
++ const auto freeKey = qScopeGuard([ncryptKey]() { NCryptFreeObject(ncryptKey); });
++
++ CERT_CONTEXT *context = PCERT_CONTEXT(certificate.handle());
++ Q_ASSERT(context);
++
++ CRYPT_DATA_BLOB keyBlob = { sizeof(ncryptKey), PBYTE(&ncryptKey) };
++ BOOL ok =
++ CertSetCertificateContextProperty(context, CERT_NCRYPT_KEY_HANDLE_PROP_ID, 0, &keyBlob);
++ if (!ok) {
++ auto error = GetLastError();
++ if (lcTlsBackendSchannel().isWarningEnabled())
++ qErrnoWarning(int(error), "Failed to set ncrypt handle property.");
++ return;
++ }
++
++ CRYPT_KEY_PROV_INFO provInfo{
++ const_reinterpret_cast<LPWSTR>(certName.constData()),
++ const_cast<LPWSTR>(MS_KEY_STORAGE_PROVIDER),
++ 0,
++ CERT_SET_KEY_PROV_HANDLE_PROP_ID | CERT_SET_KEY_CONTEXT_PROP_ID,
++ 0,
++ nullptr,
++ 0,
++ };
++ ok = CertSetCertificateContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
++ CERT_SET_PROPERTY_INHIBIT_PERSIST_FLAG, &provInfo);
++ if (!ok) {
++ auto error = GetLastError();
++ if (lcTlsBackendSchannel().isWarningEnabled())
++ qErrnoWarning(int(error), "Failed to set key provider info property.");
++ return;
++ }
++}
++
+ void TlsCryptographSchannel::initializeCertificateStores()
+ {
+ //// helper function which turns a chain into a certificate store
+@@ -2252,7 +2283,10 @@ void TlsCryptographSchannel::initializeCertificateStor
+ CRYPT_DATA_BLOB pfxBlob;
+ pfxBlob.cbData = DWORD(pkcs12.length());
+ pfxBlob.pbData = reinterpret_cast<unsigned char *>(pkcs12.data());
+- return QHCertStorePointer(PFXImportCertStore(&pfxBlob, passphrase, 0));
++ // ALWAYS_CNG to import using "Cryptography API: Next Generation (CNG)"
++ // NO_PERSIST_KEY to request not persisting anything imported to disk
++ constexpr DWORD flags = PKCS12_ALWAYS_CNG_KSP | PKCS12_NO_PERSIST_KEY;
++ return QHCertStorePointer(PFXImportCertStore(&pfxBlob, passphrase, flags));
+ };
+
+ if (!configuration.localCertificateChain().isEmpty()) {
+@@ -2262,10 +2296,34 @@ void TlsCryptographSchannel::initializeCertificateStor
+ return;
+ }
+ if (localCertificateStore == nullptr) {
+- localCertificateStore = createStoreFromCertificateChain(configuration.localCertificateChain(),
+- configuration.privateKey());
+- if (localCertificateStore == nullptr)
++ localCertificateStore =
++ createStoreFromCertificateChain(configuration.localCertificateChain(), {});
++ if (localCertificateStore) {
++ const CERT_CONTEXT *certificateContext = CertFindCertificateInStore(
++ localCertificateStore.get(), X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
++ CERT_FIND_ANY, nullptr, nullptr);
++ if (certificateContext) {
++ auto *backend = QTlsBackend::backend<X509CertificateSchannel>(
++ configuration.localCertificate());
++ backend->certificateContext.reset(
++ CertDuplicateCertificateContext(certificateContext));
++
++ DWORD keySpec = 0;
++ BOOL mustFree = FALSE;
++ NCRYPT_KEY_HANDLE testKey = 0;
++ BOOL ok = CryptAcquireCertificatePrivateKey(
++ certificateContext, CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, nullptr,
++ &testKey, &keySpec, &mustFree);
++ if (mustFree)
++ NCryptFreeObject(testKey);
++ if (!ok) {
++ attachPrivateKeyToCertificate(configuration.localCertificate(),
++ configuration.privateKey());
++ }
++ }
++ } else {
+ qCWarning(lcTlsBackendSchannel, "Failed to load certificate chain!");
++ }
+ }
+ }
+
Index: patches/patch-src_plugins_tls_schannel_qtls_schannel_p_h
===================================================================
RCS file: patches/patch-src_plugins_tls_schannel_qtls_schannel_p_h
diff -N patches/patch-src_plugins_tls_schannel_qtls_schannel_p_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_plugins_tls_schannel_qtls_schannel_p_h 3 Aug 2025 07:57:55 -0000
@@ -0,0 +1,14 @@
+https://ftp.fau.de/qtproject/archive/qt/6.8/CVE-2025-6338-qtbase-6.8.patch
+
+Index: src/plugins/tls/schannel/qtls_schannel_p.h
+--- src/plugins/tls/schannel/qtls_schannel_p.h.orig
++++ src/plugins/tls/schannel/qtls_schannel_p.h
+@@ -106,8 +106,6 @@ class TlsCryptographSchannel final : public TlsCryptog
+ QHCertStorePointer peerCertificateStore = nullptr;
+ QHCertStorePointer caCertificateStore = nullptr;
+
+- const CERT_CONTEXT *localCertContext = nullptr;
+-
+ ULONG contextAttributes = 0;
+ qint64 missingData = 0;
+
Index: patches/patch-src_plugins_tls_shared_qsslsocket_qt_cpp
===================================================================
RCS file: patches/patch-src_plugins_tls_shared_qsslsocket_qt_cpp
diff -N patches/patch-src_plugins_tls_shared_qsslsocket_qt_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_plugins_tls_shared_qsslsocket_qt_cpp 3 Aug 2025 07:57:55 -0000
@@ -0,0 +1,14 @@
+https://ftp.fau.de/qtproject/archive/qt/6.8/CVE-2025-6338-qtbase-6.8.patch
+
+Index: src/plugins/tls/shared/qsslsocket_qt.cpp
+--- src/plugins/tls/shared/qsslsocket_qt.cpp.orig
++++ src/plugins/tls/shared/qsslsocket_qt.cpp
+@@ -134,7 +134,7 @@ static QByteArray _q_PKCS12_certBag(const QSslCertific
+ return ba;
+ }
+
+-static QAsn1Element _q_PKCS12_key(const QSslKey &key)
++QAsn1Element _q_PKCS12_key(const QSslKey &key)
+ {
+ Q_ASSERT(key.algorithm() == QSsl::Rsa || key.algorithm() == QSsl::Dsa);
+
CVE-2025-5455 and CVE-2025-6338: qt6-qtbase-6.8.3