/src/qtbase/src/dbus/qdbus_symbols.cpp
Line | Count | Source |
1 | | // Copyright (C) 2016 The Qt Company Ltd. |
2 | | // Copyright (C) 2016 Intel Corporation. |
3 | | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | | // Qt-Security score:significant reason:load-external-library-via-qlibrary |
5 | | |
6 | | #include "qdbus_symbols_p.h" |
7 | | #include <QtCore/qlatin1stringview.h> |
8 | | #if QT_CONFIG(library) |
9 | | #include <QtCore/qlibrary.h> |
10 | | #include <QtCore/private/qlocking_p.h> |
11 | | #endif |
12 | | #include <QtCore/qmutex.h> |
13 | | |
14 | | #ifndef QT_NO_DBUS |
15 | | |
16 | | QT_BEGIN_NAMESPACE |
17 | | |
18 | | using namespace Qt::StringLiterals; |
19 | | |
20 | | #if !defined QT_LINKED_LIBDBUS |
21 | | |
22 | | #if QT_CONFIG(library) |
23 | | Q_CONSTINIT static QLibrary *qdbus_libdbus = nullptr; |
24 | | |
25 | | void qdbus_unloadLibDBus() |
26 | 0 | { |
27 | 0 | if (qdbus_libdbus) { |
28 | 0 | if (qEnvironmentVariableIsSet("QDBUS_FORCE_SHUTDOWN")) |
29 | 0 | qdbus_libdbus->resolve("dbus_shutdown")(); |
30 | 0 | qdbus_libdbus->unload(); |
31 | 0 | } |
32 | 0 | delete qdbus_libdbus; |
33 | 0 | qdbus_libdbus = nullptr; |
34 | 0 | } |
35 | | #endif |
36 | | |
37 | | bool qdbus_loadLibDBus() |
38 | 0 | { |
39 | 0 | #if QT_CONFIG(library) |
40 | | #ifdef QT_BUILD_INTERNAL |
41 | | // this is to simulate a library load failure for our autotest suite. |
42 | | if (!qEnvironmentVariableIsEmpty("QT_SIMULATE_DBUS_LIBFAIL")) |
43 | | return false; |
44 | | #endif |
45 | |
|
46 | 0 | Q_CONSTINIT static bool triedToLoadLibrary = false; |
47 | 0 | Q_CONSTINIT static QBasicMutex mutex; |
48 | 0 | const auto locker = qt_scoped_lock(mutex); |
49 | |
|
50 | 0 | QLibrary *&lib = qdbus_libdbus; |
51 | 0 | if (triedToLoadLibrary) |
52 | 0 | return lib && lib->isLoaded(); |
53 | | |
54 | 0 | lib = new QLibrary; |
55 | 0 | lib->setLoadHints(QLibrary::ExportExternalSymbolsHint); // make libdbus symbols available for apps that need more advanced control over the dbus |
56 | 0 | triedToLoadLibrary = true; |
57 | |
|
58 | 0 | static constexpr int majorversions[] = { 3, 2, -1 }; |
59 | 0 | const QString baseNames[] = { |
60 | | #ifdef Q_OS_WIN |
61 | | "dbus-1"_L1, |
62 | | #endif |
63 | 0 | "libdbus-1"_L1 |
64 | 0 | }; |
65 | |
|
66 | 0 | lib->unload(); |
67 | 0 | for (const int majorversion : majorversions) { |
68 | 0 | for (const QString &baseName : baseNames) { |
69 | | #ifdef Q_OS_WIN |
70 | | QString suffix; |
71 | | if (majorversion != -1) |
72 | | suffix = QString::number(- majorversion); // negative so it prepends the dash |
73 | | lib->setFileName(baseName + suffix); |
74 | | #else |
75 | 0 | lib->setFileNameAndVersion(baseName, majorversion); |
76 | 0 | #endif |
77 | 0 | if (lib->load() && lib->resolve("dbus_connection_open_private")) |
78 | 0 | return true; |
79 | | |
80 | 0 | lib->unload(); |
81 | 0 | } |
82 | 0 | } |
83 | | |
84 | 0 | delete lib; |
85 | 0 | lib = nullptr; |
86 | 0 | return false; |
87 | | #else |
88 | | return true; |
89 | | #endif |
90 | 0 | } |
91 | | |
92 | | QFunctionPointer qdbus_resolve_conditionally(const char *name) |
93 | 0 | { |
94 | 0 | #if QT_CONFIG(library) |
95 | 0 | if (qdbus_loadLibDBus()) |
96 | 0 | return qdbus_libdbus->resolve(name); |
97 | | #else |
98 | | Q_UNUSED(name); |
99 | | #endif |
100 | 0 | return nullptr; |
101 | 0 | } |
102 | | |
103 | | QFunctionPointer qdbus_resolve_me(const char *name) |
104 | 0 | { |
105 | 0 | #if QT_CONFIG(library) |
106 | 0 | if (Q_UNLIKELY(!qdbus_loadLibDBus())) |
107 | 0 | qFatal("Cannot find libdbus-1 in your system to resolve symbol '%s'.", name); |
108 | |
|
109 | 0 | QFunctionPointer ptr = qdbus_libdbus->resolve(name); |
110 | 0 | if (Q_UNLIKELY(!ptr)) |
111 | 0 | qFatal("Cannot resolve '%s' in your libdbus-1.", name); |
112 | |
|
113 | 0 | return ptr; |
114 | | #else |
115 | | Q_UNUSED(name); |
116 | | return nullptr; |
117 | | #endif |
118 | 0 | } |
119 | | |
120 | | #else |
121 | | static void qdbus_unloadLibDBus() |
122 | | { |
123 | | if (qEnvironmentVariableIsSet("QDBUS_FORCE_SHUTDOWN")) |
124 | | dbus_shutdown(); |
125 | | } |
126 | | |
127 | | #endif // !QT_LINKED_LIBDBUS |
128 | | |
129 | | #if defined(QT_LINKED_LIBDBUS) || QT_CONFIG(library) |
130 | | Q_DESTRUCTOR_FUNCTION(qdbus_unloadLibDBus) |
131 | | #endif |
132 | | |
133 | | QT_END_NAMESPACE |
134 | | |
135 | | #endif // QT_NO_DBUS |