Skip to content

Commit

Permalink
qt5-base: Update to latest KDE stable
Browse files Browse the repository at this point in the history
Fixes CVE-2023-43114

Signed-off-by: Reilly Brogan <[email protected]>
  • Loading branch information
ReillyBrogan committed Oct 3, 2023
1 parent 703071b commit 7e6ad39
Show file tree
Hide file tree
Showing 4 changed files with 322 additions and 6 deletions.
218 changes: 218 additions & 0 deletions packages/q/qt5-base/files/qlibraryprivate-actually-merge.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
From 1b83b8a61f1d099a54beace7ba7c172cc4e4c65e Mon Sep 17 00:00:00 2001
From: Ievgenii Meshcheriakov <[email protected]>
Date: Tue, 13 Jun 2023 12:52:28 +0200
Subject: [PATCH] QLibraryPrivate: Actually merge load hints

Or old and new load hints in mergeLoadHints() instead of just storing
new ones. Andjust QLibraryPrivate::setLoadHints() to handle objects
with no file name differently and just set load hints directly.

Mention that load hints are merged once the file name is set
in the documentation for QLibrary::setLoadHints().

Add a regression test into tst_qfactoryloader.

Update and extend tst_QPluginLoader::loadHints() to take into account
load hints merging.

Fixes: QTBUG-114480
Change-Id: I3b9afaec7acde1f5ff992d913f8d7217392c7e00
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Thiago Macieira <[email protected]>
(cherry picked from commit 666ce51d4eb6b5dd312f98e2d7a18c54b59945e4)
---
src/corelib/plugin/qlibrary.cpp | 13 ++++++++-
src/corelib/plugin/qpluginloader.cpp | 5 ++--
.../plugin/qfactoryloader/plugin1/plugin1.h | 2 +-
.../qfactoryloader/plugin1/plugin1.json | 5 ++++
.../qfactoryloader/tst_qfactoryloader.cpp | 27 +++++++++++++++++++
.../qpluginloader/tst_qpluginloader.cpp | 26 +++++++++++++++---
6 files changed, 71 insertions(+), 7 deletions(-)
create mode 100644 tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json

diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 5d2f0242674..45b5a3fe27f 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -526,7 +526,7 @@ void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
if (pHnd.loadRelaxed())
return;

- loadHintsInt.storeRelaxed(lh);
+ loadHintsInt.fetchAndOrRelaxed(lh);
}

QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
@@ -538,6 +538,13 @@ QFunctionPointer QLibraryPrivate::resolve(const char *symbol)

void QLibraryPrivate::setLoadHints(QLibrary::LoadHints lh)
{
+ // Set the load hints directly for a dummy if this object is not associated
+ // with a file. Such object is not shared between multiple instances.
+ if (fileName.isEmpty()) {
+ loadHintsInt.storeRelaxed(lh);
+ return;
+ }
+
// this locks a global mutex
QMutexLocker lock(&qt_library_mutex);
mergeLoadHints(lh);
@@ -1166,6 +1173,10 @@ QString QLibrary::errorString() const
lazy symbol resolution, and will not export external symbols for resolution
in other dynamically-loaded libraries.

+ \note Hints can only be cleared when this object is not associated with a
+ file. Hints can only be added once the file name is set (\a hints will
+ be or'ed with the old hints).
+
\note Setting this property after the library has been loaded has no effect
and loadHints() will not reflect those changes.

diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index de429d5b476..02b8c588be7 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -416,10 +416,11 @@ QString QPluginLoader::errorString() const
void QPluginLoader::setLoadHints(QLibrary::LoadHints loadHints)
{
if (!d) {
- d = QLibraryPrivate::findOrCreate(QString()); // ugly, but we need a d-ptr
+ d = QLibraryPrivate::findOrCreate({}, {}, loadHints); // ugly, but we need a d-ptr
d->errorString.clear();
+ } else {
+ d->setLoadHints(loadHints);
}
- d->setLoadHints(loadHints);
}

QLibrary::LoadHints QPluginLoader::loadHints() const
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h
index ca2ceed7a91..624316dfdbf 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h
@@ -35,7 +35,7 @@
class Plugin1 : public QObject, public PluginInterface1
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface1")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface1" FILE "plugin1.json")
Q_INTERFACES(PluginInterface1)

public:
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json
new file mode 100644
index 00000000000..ce67846d485
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json
@@ -0,0 +1,5 @@
+{
+ "Keys": [
+ "plugin1"
+ ]
+}
diff --git a/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp
index 9fa61804b38..88ada1b806d 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp
+++ b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp
@@ -31,6 +31,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qplugin.h>
#include <private/qfactoryloader_p.h>
+#include <private/qlibrary_p.h>
#include "plugin1/plugininterface1.h"
#include "plugin2/plugininterface2.h"

@@ -52,6 +53,7 @@ public slots:

private slots:
void usingTwoFactoriesFromSameDir();
+ void multiplePaths();
};

static const char binFolderC[] = "bin";
@@ -92,5 +94,30 @@ void tst_QFactoryLoader::usingTwoFactoriesFromSameDir()
QCOMPARE(plugin2->pluginName(), QLatin1String("Plugin2 ok"));
}

+void tst_QFactoryLoader::multiplePaths()
+{
+#if !QT_CONFIG(library) || !(defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)) || defined(Q_OS_ANDROID)
+ QSKIP("Test not applicable in this configuration.");
+#else
+ const QString binFolder = QFINDTESTDATA(binFolderC);
+
+ QTemporaryDir dir;
+ QVERIFY(dir.isValid());
+
+ QString pluginsPath = QFileInfo(binFolder, binFolderC).absolutePath();
+ QString linkPath = dir.filePath(binFolderC);
+ QVERIFY(QFile::link(pluginsPath, linkPath));
+
+ QCoreApplication::setLibraryPaths({ QFileInfo(binFolder).absolutePath(), dir.path() });
+
+ const QString suffix = QLatin1Char('/') + QLatin1String(binFolderC);
+ QFactoryLoader loader1(PluginInterface1_iid, suffix);
+
+ QLibraryPrivate *library1 = loader1.library("plugin1");
+ QVERIFY(library1);
+ QCOMPARE(library1->loadHints(), QLibrary::PreventUnloadHint);
+#endif
+}
+
QTEST_MAIN(tst_QFactoryLoader)
#include "tst_qfactoryloader.moc"
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index 3b91fc7d0d8..833f68b1def 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -193,7 +193,9 @@ void tst_QPluginLoader::errorString()
QVERIFY(!unloaded);
}

-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_HPUX)
+// A bug in QNX causes the test to crash on exit after attempting to load
+// a shared library with undefined symbols (tracked as QTBUG-114682).
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_HPUX) && !defined(Q_OS_QNX)
{
QPluginLoader loader( sys_qualifiedLibraryName("almostplugin")); //a plugin with unresolved symbols
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
@@ -246,16 +248,34 @@ void tst_QPluginLoader::loadHints()
QCOMPARE(loader.loadHints(), QLibrary::PreventUnloadHint); //Do not crash
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
+ // We can clear load hints when file name is not set.
+ loader.setLoadHints(QLibrary::LoadHints{});
+ QCOMPARE(loader.loadHints(), QLibrary::LoadHints{});
+ // Set the hints again
+ loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
+ QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
loader.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin
QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);

+ QPluginLoader loader4;
+ QCOMPARE(loader4.loadHints(), QLibrary::PreventUnloadHint);
+ loader4.setLoadHints(QLibrary::LoadHints{});
+ QCOMPARE(loader4.loadHints(), QLibrary::LoadHints{});
+ loader4.setFileName(sys_qualifiedLibraryName("theplugin"));
+ // Hints are merged with hints from the previous loader.
+ QCOMPARE(loader4.loadHints(), QLibrary::ResolveAllSymbolsHint);
+ // We cannot clear load hints after associating the loader with a file.
+ loader.setLoadHints(QLibrary::LoadHints{});
+ QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
+
QPluginLoader loader2;
QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint);
loader2.setFileName(sys_qualifiedLibraryName("theplugin"));
- QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint);
+ // Hints are merged with hints from previous loaders.
+ QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint | QLibrary::ResolveAllSymbolsHint);

QPluginLoader loader3(sys_qualifiedLibraryName("theplugin"));
- QCOMPARE(loader3.loadHints(), QLibrary::PreventUnloadHint);
+ QCOMPARE(loader3.loadHints(), QLibrary::PreventUnloadHint | QLibrary::ResolveAllSymbolsHint);
}

void tst_QPluginLoader::deleteinstanceOnUnload()
--
GitLab

96 changes: 96 additions & 0 deletions packages/q/qt5-base/files/qpluginloader-report-the-right.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
From 29380235b7281986f924bca9cab2275b999eff02 Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo <[email protected]>
Date: Wed, 2 Feb 2022 16:10:18 +0100
Subject: [PATCH] QPluginLoader: report the right load hints

A default-constructed QPluginLoader erroneously reports that the
load hints are empty. However, setting a filename would then
automatically set the PreventUnload hint, surprising the user.

Return the correct flags instead.

Amends 494376f980e96339b6f1eff7c41336ca4d853065

Change-Id: I7a95964cb680afd3adf2f71ed73d2f93023238f2
Fixes: QTBUG-100416
Pick-to: 5.15 6.2 6.3
Reviewed-by: Thiago Macieira <[email protected]>
(cherry picked from commit e7d627339cc35907c0d5bb263ede10a017e0b988)
---
src/corelib/plugin/qpluginloader.cpp | 13 ++++++++++---
.../plugin/qpluginloader/tst_qpluginloader.cpp | 11 ++++++++++-
2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 0a63b93762c..de429d5b476 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -105,6 +105,8 @@ QT_BEGIN_NAMESPACE
\sa QLibrary, {Plug & Paint Example}
*/

+static constexpr QLibrary::LoadHints defaultLoadHints = QLibrary::PreventUnloadHint;
+
/*!
\class QStaticPlugin
\inmodule QtCore
@@ -155,7 +157,7 @@ QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent)
: QObject(parent), d(nullptr), did_load(false)
{
setFileName(fileName);
- setLoadHints(QLibrary::PreventUnloadHint);
+ setLoadHints(defaultLoadHints);
}

/*!
@@ -357,7 +359,7 @@ static QString locatePlugin(const QString& fileName)
void QPluginLoader::setFileName(const QString &fileName)
{
#if defined(QT_SHARED)
- QLibrary::LoadHints lh = QLibrary::PreventUnloadHint;
+ QLibrary::LoadHints lh = defaultLoadHints;
if (d) {
lh = d->loadHints();
d->release();
@@ -422,7 +424,12 @@ void QPluginLoader::setLoadHints(QLibrary::LoadHints loadHints)

QLibrary::LoadHints QPluginLoader::loadHints() const
{
- return d ? d->loadHints() : QLibrary::LoadHints();
+ // Not having a d-pointer means that the user hasn't called
+ // setLoadHints() / setFileName() yet. In setFileName() we will
+ // then force defaultLoadHints on loading, so we must return them
+ // from here as well.
+
+ return d ? d->loadHints() : defaultLoadHints;
}

#endif // QT_CONFIG(library)
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index ce8057372cf..3b91fc7d0d8 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -243,10 +243,19 @@ void tst_QPluginLoader::loadHints()
QSKIP("This test requires Qt to create shared libraries.");
#endif
QPluginLoader loader;
- QCOMPARE(loader.loadHints(), QLibrary::LoadHints{}); //Do not crash
+ QCOMPARE(loader.loadHints(), QLibrary::PreventUnloadHint); //Do not crash
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
+ QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
loader.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin
QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
+
+ QPluginLoader loader2;
+ QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint);
+ loader2.setFileName(sys_qualifiedLibraryName("theplugin"));
+ QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint);
+
+ QPluginLoader loader3(sys_qualifiedLibraryName("theplugin"));
+ QCOMPARE(loader3.loadHints(), QLibrary::PreventUnloadHint);
}

void tst_QPluginLoader::deleteinstanceOnUnload()
--
GitLab

6 changes: 4 additions & 2 deletions packages/q/qt5-base/package.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name : qt5-base
version : 5.15.10
release : 84
release : 85
source :
- git|https://invent.kde.org/qt/qt/qtbase.git : 74917690e8cded41b087acfe6c58fcd3674864a4
- git|https://invent.kde.org/qt/qt/qtbase.git : 9b7fd27c2b4a363ba4434353be2932483be99234
homepage : https://www.qt.io
license :
- GPL-2.0
Expand Down Expand Up @@ -66,6 +66,8 @@ environment: |
unset LD_AS_NEEDED
setup : |
%patch -p1 -i $pkgfiles/0001-Support-stateless-config-directories.patch
%patch -p1 -i $pkgfiles/qpluginloader-report-the-right.patch
%patch -p1 -i $pkgfiles/qlibraryprivate-actually-merge.patch
sed -i -e 's|^\(QMAKE_STRIP.*=\).*$|\1|g' mkspecs/common/linux.conf
./configure -prefix /usr \
-libdir %libdir% \
Expand Down
8 changes: 4 additions & 4 deletions packages/q/qt5-base/pspec_x86_64.xml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
</Description>
<PartOf>programming.library</PartOf>
<RuntimeDependencies>
<Dependency release="84">qt5-base</Dependency>
<Dependency release="85">qt5-base</Dependency>
</RuntimeDependencies>
<Files>
<Path fileType="library">/usr/lib64/qt5/examples/README</Path>
Expand Down Expand Up @@ -2394,7 +2394,7 @@
</Description>
<PartOf>programming.devel</PartOf>
<RuntimeDependencies>
<Dependency release="84">qt5-base</Dependency>
<Dependency release="85">qt5-base</Dependency>
</RuntimeDependencies>
<Files>
<Path fileType="executable">/usr/bin/fixqt4headers.pl</Path>
Expand Down Expand Up @@ -5645,8 +5645,8 @@
</Replaces>
</Package>
<History>
<Update release="84">
<Date>2023-09-21</Date>
<Update release="85">
<Date>2023-10-03</Date>
<Version>5.15.10</Version>
<Comment>Packaging update</Comment>
<Name>Reilly Brogan</Name>
Expand Down

0 comments on commit 7e6ad39

Please sign in to comment.