diff options
author | Peter Seiderer <ps.report@gmx.net> | 2013-06-17 18:17:08 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-03 01:41:37 (GMT) |
commit | a9b48e98b8e90a0ccc729b00336e59acc86ad9ca (patch) | |
tree | b31cdf69f9001ca32965f426c1ea9f4140ee8adb /src/dbus | |
parent | 44f3fb1eec2041c6587d3347f103ca6fa0a17dad (diff) | |
download | Qt-a9b48e98b8e90a0ccc729b00336e59acc86ad9ca.zip Qt-a9b48e98b8e90a0ccc729b00336e59acc86ad9ca.tar.gz Qt-a9b48e98b8e90a0ccc729b00336e59acc86ad9ca.tar.bz2 |
Fix unprotected access to QDBusPendingCallPrivate::pending.
In QDBusConnectionPrivate::waitForFinished() pcall->pending was used
after the protection by pcall->mutex was released. A simultaneous
call to QDBusConnectionPrivate::processFinishedCall() was able
to reset pcall->pending to null before it was used for the
q_dbus_pending_call_block(pcall->pending) call.
Fixed by releasing (and setting to 0) of pcall->pending in
processFinishedCall() only in case no one is waiting yet, otherwise
release pcall->pending by the first thread waiting in waitForFinished().
There is still a race condition about deleting QDBusPendingCallPrivate
(too early) which will be fixed in the next two commits.
Task-number: QTBUG-27809
Change-Id: I040173810ad90653fe1bd1915f22d8dd70d47d8c
(cherry-picked from qtbase commit 64e3bd481e5d54d555959ceecbd5c4576c571241)
Reviewed-by: Peter Seiderer <ps.report@gmx.net>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/dbus')
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 15278b2..ae67079 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1782,6 +1782,12 @@ void QDBusConnectionPrivate::waitForFinished(QDBusPendingCallPrivate *pcall) // QDBusConnectionPrivate::processFinishedCall() is called automatically } pcall->mutex.lock(); + + if (pcall->pending) { + q_dbus_pending_call_unref(pcall->pending); + pcall->pending = 0; + } + pcall->waitForFinishedCondition.wakeAll(); } } @@ -1821,9 +1827,10 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) qDBusDebug() << "Deliver failed!"; } - if (call->pending) + if (call->pending && !call->waitingForFinished) { q_dbus_pending_call_unref(call->pending); - call->pending = 0; + call->pending = 0; + } locker.unlock(); |