From c8a4e1e75c745c5c3ad947ba61c52cc5963d31dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erkki=20Sepp=C3=A4l=C3=A4?= Date: Thu, 6 Apr 2017 14:09:19 +0200 Subject: record: avoid crash when calling RecordFlushReplyBuffer recursively MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backported from X.Org: commit 0801afbd7c2c644c672b37f8463f1a0cbadebd2e Author: Erkki Seppälä Date: Thu Feb 10 15:35:14 2011 +0200 record: avoid crash when calling RecordFlushReplyBuffer recursively RecordFlushReplyBuffer can call itself recursively through WriteClient->CallCallbacks->_CallCallbacks->RecordFlushAllContexts when the recording client's buffer cannot be completely emptied in one WriteClient. When a such a recursion occurs, it will not be broken out of which results in segmentation fault when the stack is exhausted. This patch adds a counter (a flag, really) that guards against this situation, to break out of the recursion. One alternative to this change would be to change _CallCallbacks to check the corresponding counter before the callback loop, but that might affect existing behavior, which may be relied upon. Reviewed-by: Rami Ylimäki Signed-off-by: Erkki Seppälä Signed-off-by: Keith Packard Backported-to-NX-by: Mihai Moldovan Fixes: ArcticaProject/nx-libs#417. --- nx-X11/programs/Xserver/record/record.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nx-X11/programs/Xserver/record/record.c b/nx-X11/programs/Xserver/record/record.c index df9419f22..48b1964e6 100644 --- a/nx-X11/programs/Xserver/record/record.c +++ b/nx-X11/programs/Xserver/record/record.c @@ -74,6 +74,7 @@ typedef struct { char bufCategory; /* category of protocol in replyBuffer */ int numBufBytes; /* number of bytes in replyBuffer */ char replyBuffer[REPLY_BUF_SIZE]; /* buffered recorded protocol */ + int inFlush; /* are we inside RecordFlushReplyBuffer */ } RecordContextRec, *RecordContextPtr; /* RecordMinorOpRec - to hold minor opcode selections for extension requests @@ -242,8 +243,9 @@ RecordFlushReplyBuffer( int len2 ) { - if (!pContext->pRecordingClient || pContext->pRecordingClient->clientGone) + if (!pContext->pRecordingClient || pContext->pRecordingClient->clientGone || pContext->inFlush) return; + ++pContext->inFlush; if (pContext->numBufBytes) WriteToClient(pContext->pRecordingClient, pContext->numBufBytes, (char *)pContext->replyBuffer); @@ -252,6 +254,7 @@ RecordFlushReplyBuffer( WriteToClient(pContext->pRecordingClient, len1, data1); if (len2) WriteToClient(pContext->pRecordingClient, len2, data2); + --pContext->inFlush; } /* RecordFlushReplyBuffer */ @@ -2039,6 +2042,7 @@ ProcRecordCreateContext(client) pContext->numBufBytes = 0; pContext->pBufClient = NULL; pContext->continuedReply = 0; + pContext->inFlush = 0; err = RecordRegisterClients(pContext, client, (xRecordRegisterClientsReq *)stuff); -- cgit v1.2.3