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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
