Commit 4308f5d3 authored by Aaron Plattner's avatar Aaron Plattner
Browse files

os: Don't crash in AttendClient if the client is gone

If a client is in the process of being closed down, then its client->osPrivate
pointer will be set to NULL by CloseDownConnection. This can cause a crash if
freeing the client's resources results in a call to AttendClient. For example,
if the client has a pending sync fence:

 Thread 1 "X" received signal SIGSEGV, Segmentation fault.
 AttendClient (client=0x5571c4aed9a0) at ../os/connection.c:942
 (gdb) bt
 #0  AttendClient (client=0x5571c4aed9a0) at ../os/connection.c:942
 #1  0x00005571c3dbb865 in SyncAwaitTriggerFired (pTrigger=<optimized out>) at ../Xext/sync.c:694
 #2  0x00005571c3dd5749 in miSyncDestroyFence (pFence=0x5571c5063980) at ../miext/sync/misync.c:120
 #3  0x00005571c3dbbc69 in FreeFence (obj=<optimized out>, id=<optimized out>) at ../Xext/sync.c:1909
 #4  0x00005571c3d7a01d in doFreeResource (res=0x5571c506e3d0, skip=skip@entry=0) at ../dix/resource.c:880
 #5  0x00005571c3d7b1dc in FreeClientResources (client=0x5571c4aed9a0) at ../dix/...
parent 66da95a1
Pipeline #80625 passed with stages
in 8 minutes and 37 seconds
......@@ -125,8 +125,7 @@ ClientSleepUntil(ClientPtr client,
static void
ClientAwaken(ClientPtr client, void *closure)
{
if (!client->clientGone)
AttendClient(client);
AttendClient(client);
}
static int
......
......@@ -662,14 +662,7 @@ ClientWakeup(ClientPtr client)
if (q->client == client) {
*prev = q->next;
free(q);
if (client->clientGone)
/* Oops -- new zombie cleanup code ensures this only
* happens from inside CloseDownClient; don't want to
* recurse here...
*/
/* CloseDownClient(client) */ ;
else
AttendClient(client);
AttendClient(client);
break;
}
prev = &q->next;
......
......@@ -924,6 +924,14 @@ AttendClient(ClientPtr client)
{
OsCommPtr oc = (OsCommPtr) client->osPrivate;
if (client->clientGone) {
/*
* client is gone, so any pending requests will be dropped and its
* ignore count doesn't matter.
*/
return;
}
client->ignoreCount--;
if (client->ignoreCount)
return;
......
......@@ -2362,9 +2362,9 @@ RecordDisableContext(RecordContextPtr pContext)
if (!pContext->pRecordingClient->clientGone) {
RecordAProtocolElement(pContext, NULL, XRecordEndOfData, NULL, 0, 0, 0);
RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
/* Re-enable request processing on this connection. */
AttendClient(pContext->pRecordingClient);
}
/* Re-enable request processing on this connection. */
AttendClient(pContext->pRecordingClient);
for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP) {
RecordUninstallHooks(pRCAP, 0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment