diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2014-06-08 14:49:36 -0400 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2014-06-15 23:04:28 +0200 |
commit | acd0dae3f49662047d76f5e7d6ab1f333c38549e (patch) | |
tree | 4db99968e1ac9a0cb92ecf9e6ec11d6dd2915a52 | |
parent | 66bd87e5c6f2b374e01c28fd2884a839edfcc06f (diff) |
Fix data race in accessing QDBusConnectionPrivate::serviceNames
The trick of creating a copy is not thread-safe. I'd known this since
the moment I wrote that code, but thought "what could go wrong?".
Task-number: QTBUG-39285
Change-Id: If521d4a649c06e6a34926687e85623aa25cb4c35
Reviewed-by: David Faure <david.faure@kdab.com>
-rw-r--r-- | src/dbus/qdbusconnection_p.h | 2 | ||||
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 9 |
2 files changed, 7 insertions, 4 deletions
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index f2590f9c54..fd4ced078d 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -256,7 +256,7 @@ private: void deliverCall(QObject *object, int flags, const QDBusMessage &msg, const QVector<int> &metaTypes, int slotIdx); - bool isServiceRegisteredByThread(const QString &serviceName) const; + bool isServiceRegisteredByThread(const QString &serviceName); QString getNameOwnerNoCache(const QString &service); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 1fef6d4d49..6b6ac6bc62 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -2488,12 +2488,15 @@ void QDBusConnectionPrivate::unregisterServiceNoLock(const QString &serviceName) serviceNames.removeAll(serviceName); } -bool QDBusConnectionPrivate::isServiceRegisteredByThread(const QString &serviceName) const +bool QDBusConnectionPrivate::isServiceRegisteredByThread(const QString &serviceName) { if (!serviceName.isEmpty() && serviceName == baseService) return true; - QStringList copy = serviceNames; - return copy.contains(serviceName); + if (serviceName == dbusServiceString()) + return false; + + QDBusReadLocker locker(UnregisterServiceAction, this); + return serviceNames.contains(serviceName); } void QDBusConnectionPrivate::postEventToThread(int action, QObject *object, QEvent *ev) |