summaryrefslogtreecommitdiffstats
path: root/src/dbus/qdbusintegrator.cpp
diff options
context:
space:
mode:
authorPeter Seiderer <ps.report@gmx.net>2013-06-17 20:17:08 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-07-29 22:28:12 +0200
commit64e3bd481e5d54d555959ceecbd5c4576c571241 (patch)
tree9dcdf9285ed0570f21731eb229666ed45e952d52 /src/dbus/qdbusintegrator.cpp
parent9eeb1bd4d44b71c4251090e9f3b7427a493d873d (diff)
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 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/dbus/qdbusintegrator.cpp')
-rw-r--r--src/dbus/qdbusintegrator.cpp11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index d5c359aea1..ed019cb662 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1844,6 +1844,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();
}
}
@@ -1890,9 +1896,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();