LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File 0003-Fix-unprotected-access-to-QDBusPendingCallPrivate-pe.patch of Package libqt4 (Project KDE:Qt)

From a9b48e98b8e90a0ccc729b00336e59acc86ad9ca Mon Sep 17 00:00:00 2001
From: Peter Seiderer <ps.report@gmx.net>
Date: Mon, 17 Jun 2013 20:17:08 +0200
Subject: [PATCH 3/6] 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>
---
 src/dbus/qdbusintegrator.cpp | 11 +++++++++--
 1 file 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();
 
-- 
1.8.3.1