QDBusServer: Fix potential crash when private pointer is null
Check that the private pointer is not null before attempting to dereference it. This can happen, for example, when a QDBusServer instance was constructed with an empty string as address. Attempting to destroy an object constructed this way was causing a segmentation fault on Linux. Add a test case that attempts to construct a QDBusServer object with an empty string as address to check that this does not cause a segmentation fault anymore. Change-Id: I5fe63134026e2a9f509b61d452285891b1ec624d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 90d3c5b95145c1fa326d1d6d9fa5bcd7b3dedc4c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
8a35934362
commit
a558ecb235
@ -39,6 +39,8 @@ QDBusServer::QDBusServer(const QString &address, QObject *parent)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
emit instance->serverRequested(address, this);
|
emit instance->serverRequested(address, this);
|
||||||
|
Q_ASSERT(d != nullptr);
|
||||||
|
|
||||||
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
|
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
|
||||||
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
|
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
@ -66,6 +68,8 @@ QDBusServer::QDBusServer(QObject *parent)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
emit instance->serverRequested(address, this);
|
emit instance->serverRequested(address, this);
|
||||||
|
Q_ASSERT(d != nullptr);
|
||||||
|
|
||||||
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
|
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
|
||||||
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
|
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
@ -75,17 +79,20 @@ QDBusServer::QDBusServer(QObject *parent)
|
|||||||
*/
|
*/
|
||||||
QDBusServer::~QDBusServer()
|
QDBusServer::~QDBusServer()
|
||||||
{
|
{
|
||||||
QMutex *managerMutex = nullptr;
|
if (!d)
|
||||||
if (QDBusConnectionManager::instance())
|
return;
|
||||||
managerMutex = &QDBusConnectionManager::instance()->mutex;
|
|
||||||
QMutexLocker locker(managerMutex);
|
auto manager = QDBusConnectionManager::instance();
|
||||||
|
if (!manager)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMutexLocker locker(&manager->mutex);
|
||||||
QWriteLocker writeLocker(&d->lock);
|
QWriteLocker writeLocker(&d->lock);
|
||||||
if (QDBusConnectionManager::instance()) {
|
for (const QString &name : std::as_const(d->serverConnectionNames))
|
||||||
for (const QString &name : std::as_const(d->serverConnectionNames))
|
manager->removeConnection(name);
|
||||||
QDBusConnectionManager::instance()->removeConnection(name);
|
d->serverConnectionNames.clear();
|
||||||
d->serverConnectionNames.clear();
|
locker.unlock();
|
||||||
locker.unlock();
|
|
||||||
}
|
|
||||||
d->serverObject = nullptr;
|
d->serverObject = nullptr;
|
||||||
d->ref.storeRelaxed(0);
|
d->ref.storeRelaxed(0);
|
||||||
d->deleteLater();
|
d->deleteLater();
|
||||||
@ -138,6 +145,9 @@ QString QDBusServer::address() const
|
|||||||
*/
|
*/
|
||||||
void QDBusServer::setAnonymousAuthenticationAllowed(bool value)
|
void QDBusServer::setAnonymousAuthenticationAllowed(bool value)
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
d->anonymousAuthenticationAllowed = value;
|
d->anonymousAuthenticationAllowed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +160,9 @@ void QDBusServer::setAnonymousAuthenticationAllowed(bool value)
|
|||||||
*/
|
*/
|
||||||
bool QDBusServer::isAnonymousAuthenticationAllowed() const
|
bool QDBusServer::isAnonymousAuthenticationAllowed() const
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
return false;
|
||||||
|
|
||||||
return d->anonymousAuthenticationAllowed;
|
return d->anonymousAuthenticationAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1412,6 +1412,11 @@ void tst_QDBusConnection::pendingCallWhenDisconnected()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QDBusConnection::emptyServerAddress()
|
||||||
|
{
|
||||||
|
QDBusServer server({}, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
QString MyObject::path;
|
QString MyObject::path;
|
||||||
QString MyObjectWithoutInterface::path;
|
QString MyObjectWithoutInterface::path;
|
||||||
QString MyObjectWithoutInterface::interface;
|
QString MyObjectWithoutInterface::interface;
|
||||||
|
@ -115,6 +115,8 @@ private slots:
|
|||||||
void callVirtualObjectLocal();
|
void callVirtualObjectLocal();
|
||||||
void pendingCallWhenDisconnected();
|
void pendingCallWhenDisconnected();
|
||||||
|
|
||||||
|
void emptyServerAddress();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
|
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
|
||||||
bool callMethod(const QDBusConnection &conn, const QString &path);
|
bool callMethod(const QDBusConnection &conn, const QString &path);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user