The 'Dispatch' function accesses freed client structure if a client
happens to kill itself in a request. For example, I have a test client
that is used to check that it handles the XIO error correctly. The XIO
error is generated by requesting the client to kill itself with
XKillClient.

Signed-off-by: Rami Ylimäki <[email protected]>
Reviewed-by: Erkki Seppälä <[email protected]>
---
 dix/dispatch.c |   32 +++++++++++++++++---------------
 1 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/dix/dispatch.c b/dix/dispatch.c
index 43cb4d1..cc5ee09 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3226,6 +3226,20 @@ ProcChangeAccessControl(ClientPtr client)
     return ChangeAccessControl(client, stuff->mode == EnableAccess);
 }
 
+/**
+ * Prevents a client from killing itself immediately.
+ */
+static void CloseDownClientByClient(ClientPtr client, ClientPtr killclient)
+{
+    if (client == killclient)
+    {
+        MarkClientException(client);
+        isItTimeToYield = TRUE;
+    }
+    else
+        CloseDownClient(killclient);
+}
+
 /*********************
  * CloseDownRetainedResources
  *
@@ -3263,21 +3277,9 @@ ProcKillClient(ClientPtr client)
     }
 
     rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
-    if (rc == Success) {
-       CloseDownClient(killclient);
-       /* if an LBX proxy gets killed, isItTimeToYield will be set */
-       if (isItTimeToYield || (client == killclient))
-       {
-           /* force yield and return Success, so that Dispatch()
-            * doesn't try to touch client
-            */
-           isItTimeToYield = TRUE;
-           return Success;
-       }
-       return Success;
-    }
-    else
-       return rc;
+    if (rc == Success)
+       CloseDownClientByClient(client, killclient);
+    return rc;
 }
 
 int
-- 
1.7.1

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to