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>
bb10
Peter Seiderer 2013-06-17 20:17:08 +02:00 committed by The Qt Project
parent 9eeb1bd4d4
commit 64e3bd481e
1 changed files with 9 additions and 2 deletions

View File

@ -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();