[PATCH] dix: fake up a client resource for implicit passive grabs

Peter Hutterer peter.hutterer at who-t.net
Sun Nov 18 21:45:52 PST 2012


Using client->clientAsMask as resource for implicit passive grabs causes
resource conflict with client-allocated resources. Freeing the passive grab
frees all resources with that ID, so arbitrary resources can get freed while
still in use. This causes random crashes.

Use a fake ID, but since fake IDs are limited, use the same ID every time -
we can only have one implicit grab at a time anyway. Reserve that ID by
bumping the fake ID start up by one and use that first one.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
This patch goes on top of a currently unmerged set
http://lists.x.org/archives/xorg-devel/2012-November/034274.html


 dix/events.c       |  2 +-
 dix/resource.c     | 13 +++++++++++++
 include/resource.h |  1 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/dix/events.c b/dix/events.c
index 7c8207e..2bddab0 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1971,7 +1971,7 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
         return FALSE;
     tempGrab->next = NULL;
     tempGrab->device = dev;
-    tempGrab->resource = client->clientAsMask;
+    tempGrab->resource = PassiveGrabResourceID(client);
     tempGrab->window = win;
     tempGrab->ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
     tempGrab->eventMask = deliveryMask;
diff --git a/dix/resource.c b/dix/resource.c
index 2aafa34..71b1197 100644
--- a/dix/resource.c
+++ b/dix/resource.c
@@ -636,6 +636,8 @@ InitClientResources(ClientPtr client)
      */
     clientTable[i].fakeID = client->clientAsMask |
         (client->index ? SERVER_BIT : SERVER_MINID);
+    /* We skip the first fake ID, it is used for implicit passive grabs */
+    clientTable[i].fakeID++;
     clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
     for (j = 0; j < INITBUCKETS; j++) {
         clientTable[i].resources[j] = NULL;
@@ -757,6 +759,17 @@ GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
     return found;
 }
 
+/**
+ * Return the fake client ID used by this client for implicit passive
+ * grabs. Since there can only ever be implicit passive grab at a time, we
+ * just return the same number every time.
+ */
+XID
+PassiveGrabResourceID(ClientPtr client)
+{
+    return client->clientAsMask | SERVER_BIT;
+}
+
 /*
  * Return the next usable fake client ID.
  *
diff --git a/include/resource.h b/include/resource.h
index 4a8dc31..20bf783 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -194,6 +194,7 @@ extern _X_EXPORT RESTYPE CreateNewResourceClass(void);
 extern _X_EXPORT Bool InitClientResources(ClientPtr /*client */ );
 
 extern _X_EXPORT XID FakeClientID(int /*client */ );
+extern _X_EXPORT XID PassiveGrabResourceID(ClientPtr client);
 
 /* Quartz support on Mac OS X uses the CarbonCore
    framework whose AddResource function conflicts here. */
-- 
1.7.11.7



More information about the xorg-devel mailing list