Details
-
Bug
-
Resolution: Incomplete
-
Not Evaluated
-
None
-
5.9, 5.12, 5.15, 6.0
-
None
Description
The QDBusConnectionPrivate::registerServiceNoLock() and unregisterServiceNoLock() slots modify the serviceNames list while holding a read lock when called for NameAcquired or NameLost.
That list is used (also under a read lock) by QDBusConnectionPrivate::isServiceRegisteredByThread(), which is reachable on any thread making a method call. Because those slots don't have the write lock, it can race and crash in QStringList or QString.
This is reproducible with QDBusConnection::call() soon after QDBusConnection::registerService(). The race is more likely if both threads were waiting on the read lock, which can easily happen if a third thread had the write lock.
Those slots are called directly on the QDBusConnection thread. The read lock comes from QDBusConnectionPrivate::handleSignal(QDBusMessage), so we can't change it easily.
It looks like serviceOwnerChangedNoLock() has a similar problem where it assigns a QString in the watchedServices map. That's theoretically reachable in a race between the NameOwnerChanged signal and getNameOwner() called by the QDBusAbstractInterface constructor.