[xorg-x11-server/f16] xserver-1.11.2-record-crasher.patch: Fix a crash in DRI2. (#714746)

Adam Jackson ajax at fedoraproject.org
Thu Nov 10 19:33:53 UTC 2011


commit 0bad2c2fc1d95761635ebbbf278d39142f8dbb37
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Nov 10 14:33:49 2011 -0500

    xserver-1.11.2-record-crasher.patch: Fix a crash in DRI2. (#714746)

 xorg-x11-server.spec                |    7 +-
 xserver-1.11.2-record-crasher.patch |  241 +++++++++++++++++++++++++++++++++++
 2 files changed, 247 insertions(+), 1 deletions(-)
---
diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec
index b8123a7..e6783c0 100644
--- a/xorg-x11-server.spec
+++ b/xorg-x11-server.spec
@@ -30,7 +30,7 @@
 Summary:   X.Org X11 X server
 Name:      xorg-x11-server
 Version:   1.11.2
-Release:   2%{?gitdate:.%{gitdate}}%{dist}
+Release:   3%{?gitdate:.%{gitdate}}%{dist}
 URL:       http://www.x.org
 License:   MIT
 Group:     User Interface/X
@@ -93,6 +93,8 @@ Patch7010: 0001-Xi-allow-passive-keygrabs-on-the-XIAll-Master-Device.patch
 # Bug 737031 - [Crestline] Coredump when doing exit
 Patch7011: 0001-dix-block-signals-when-closing-all-devices.patch
 
+# BUg #714746: Xorg crash in record when ProcDRI2WaitMSCReply called
+Patch7012: xserver-1.11.2-record-crasher.patch
 
 %define moduledir	%{_libdir}/xorg/modules
 %define drimoduledir	%{_libdir}/dri
@@ -558,6 +560,9 @@ rm -rf $RPM_BUILD_ROOT
 %{xserver_source_dir}
 
 %changelog
+* Thu Nov 10 2011 Adam Jackson <ajax at redhat.com> 1.11.2-3
+- xserver-1.11.2-record-crasher.patch: Fix a crash in DRI2. (#714746)
+
 * Wed Nov 09 2011 Peter Hutterer <peter.hutterer at redhat.com> 1.11.2-2
 - Block signals when removing all input devices #737031
 
diff --git a/xserver-1.11.2-record-crasher.patch b/xserver-1.11.2-record-crasher.patch
new file mode 100644
index 0000000..3af207b
--- /dev/null
+++ b/xserver-1.11.2-record-crasher.patch
@@ -0,0 +1,241 @@
+From patchwork Tue Nov  8 18:22:13 2011
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+Subject: Save major/minor opcodes in ClientRec for RecordAReply
+Date: Tue, 08 Nov 2011 18:22:13 -0000
+From: Keith Packard <keithp at keithp.com>
+X-Patchwork-Id: 7866
+Message-Id: <1320776533-3120-1-git-send-email-keithp at keithp.com>
+To: xorg-devel at lists.freedesktop.org
+
+The record extension needs the major and minor opcodes in the reply
+hook, but the request buffer may have been freed by the time the hook
+is invoked. Saving the request major and minor codes as the request is
+executed avoids fetching from the defunct request buffer.
+
+This patch also eliminates the public MinorOpcodeOfRequest function,
+making it static to dispatch. Usages of that function have been
+replaced with direct access to the new ClientRec field.
+
+Signed-off-by: Keith Packard <keithp at keithp.com>
+Reviewed-by: Rami Ylimäki <rami.ylimaki at vincit.fi>
+
+---
+Here's what I was thinking of to fix this -- just record the major and
+minor opcodes of the request in the ClientRec during Dispatch and then
+using those fields in RecordAReply instead of fetching the discarded
+request buffer.
+
+This is entirely untested; I don't know how to make the old code break.
+
+ Xext/security.c       |    4 +---
+ Xext/xselinux_hooks.c |    4 ++--
+ dix/dispatch.c        |   31 ++++++++++++++++++++++---------
+ dix/extension.c       |   14 --------------
+ include/dixstruct.h   |    1 +
+ include/extension.h   |    2 --
+ record/record.c       |    8 +++-----
+ 7 files changed, 29 insertions(+), 35 deletions(-)
+
+[ fedora: technically this is an ABI breaker since it's changing ClientRec,
+  but hopefully not in a way that matters.  If it does matter, easiest thing
+  to do is have Record add a hook for XaceHookDispatch. - ajax ]
+
+diff --git a/Xext/security.c b/Xext/security.c
+index 08d8158..b0d82ab 100644
+--- a/Xext/security.c
++++ b/Xext/security.c
+@@ -148,9 +148,7 @@ SecurityLabelInitial(void)
+ static _X_INLINE const char *
+ SecurityLookupRequestName(ClientPtr client)
+ {
+-    int major = ((xReq *)client->requestBuffer)->reqType;
+-    int minor = MinorOpcodeOfRequest(client);
+-    return LookupRequestName(major, minor);
++    return LookupRequestName(client->majorOp, client->minorOp);
+ }
+ 
+ 
+diff --git a/Xext/xselinux_hooks.c b/Xext/xselinux_hooks.c
+index f1d8e5d..0d4c9ab 100644
+--- a/Xext/xselinux_hooks.c
++++ b/Xext/xselinux_hooks.c
+@@ -263,8 +263,8 @@ SELinuxAudit(void *auditdata,
+     if (client) {
+ 	REQUEST(xReq);
+ 	if (stuff) {
+-	    major = stuff->reqType;
+-	    minor = MinorOpcodeOfRequest(client);
++	    major = client->majorOp;
++	    minor = client->minorOp;
+ 	}
+     }
+     if (audit->id)
+diff --git a/dix/dispatch.c b/dix/dispatch.c
+index 6e33615..3600acd 100644
+--- a/dix/dispatch.c
++++ b/dix/dispatch.c
+@@ -337,7 +337,20 @@ DisableLimitedSchedulingLatency(void)
+ 	SmartScheduleLatencyLimited = 0;
+ }
+ 
+-#define MAJOROP ((xReq *)client->requestBuffer)->reqType
++static inline unsigned short
++MinorOpcodeOfRequest(ClientPtr client)
++{
++    unsigned char major;
++    ExtensionEntry *ext;
++
++    major = ((xReq *)client->requestBuffer)->reqType;
++    if (major < EXTENSION_BASE)
++	return 0;
++    ext = GetExtensionEntry(major);
++    if (!ext)
++	return 0;
++    return ext->MinorOpcode (client);
++}
+ 
+ void
+ Dispatch(void)
+@@ -419,21 +432,23 @@ Dispatch(void)
+ 	        }
+ 
+ 		client->sequence++;
++		client->majorOp = ((xReq *)client->requestBuffer)->reqType;
++		client->minorOp = MinorOpcodeOfRequest(client);
+ #ifdef XSERVER_DTRACE
+-		XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP,
++		XSERVER_REQUEST_START(LookupMajorName(client->majorOp), client->majorOp,
+ 			      ((xReq *)client->requestBuffer)->length,
+ 			      client->index, client->requestBuffer);
+ #endif
+ 		if (result > (maxBigRequestSize << 2))
+ 		    result = BadLength;
+ 		else {
+-		    result = XaceHookDispatch(client, MAJOROP);
++		    result = XaceHookDispatch(client, client->majorOp);
+ 		    if (result == Success)
+-			result = (* client->requestVector[MAJOROP])(client);
++			result = (* client->requestVector[client->majorOp])(client);
+ 		    XaceHookAuditEnd(client, result);
+ 		}
+ #ifdef XSERVER_DTRACE
+-		XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
++		XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp), client->majorOp,
+ 			      client->sequence, client->index, result);
+ #endif
+ 
+@@ -444,8 +459,8 @@ Dispatch(void)
+ 		}
+ 		else if (result != Success)
+ 		{
+-		    SendErrorToClient(client, MAJOROP,
+-				      MinorOpcodeOfRequest(client),
++		    SendErrorToClient(client, client->majorOp,
++				      client->minorOp,
+ 				      client->errorValue, result);
+ 		    break;
+ 		}
+@@ -466,8 +481,6 @@ Dispatch(void)
+     SmartScheduleLatencyLimited = 0;
+ }
+ 
+-#undef MAJOROP
+-
+ static int  VendorRelease = VENDOR_RELEASE;
+ static char *VendorString = VENDOR_NAME;
+ 
+diff --git a/dix/extension.c b/dix/extension.c
+index c7bbac5..b677cdb 100644
+--- a/dix/extension.c
++++ b/dix/extension.c
+@@ -228,20 +228,6 @@ StandardMinorOpcode(ClientPtr client)
+     return ((xReq *)client->requestBuffer)->data;
+ }
+ 
+-unsigned short
+-MinorOpcodeOfRequest(ClientPtr client)
+-{
+-    unsigned char major;
+-
+-    major = ((xReq *)client->requestBuffer)->reqType;
+-    if (major < EXTENSION_BASE)
+-	return 0;
+-    major -= EXTENSION_BASE;
+-    if (major >= NumExtensions)
+-	return 0;
+-    return (*extensions[major]->MinorOpcode)(client);
+-}
+-
+ void
+ CloseDownExtensions(void)
+ {
+diff --git a/include/dixstruct.h b/include/dixstruct.h
+index 6cc9614..0a85f40 100644
+--- a/include/dixstruct.h
++++ b/include/dixstruct.h
+@@ -122,6 +122,7 @@ typedef struct _Client {
+     
+     DeviceIntPtr clientPtr;
+     ClientIdPtr  clientIds;
++    unsigned short majorOp, minorOp;
+ }           ClientRec;
+ 
+ /*
+diff --git a/include/extension.h b/include/extension.h
+index 29a11c3..9249951 100644
+--- a/include/extension.h
++++ b/include/extension.h
+@@ -52,8 +52,6 @@ _XFUNCPROTOBEGIN
+ 
+ extern _X_EXPORT unsigned short StandardMinorOpcode(ClientPtr /*client*/);
+ 
+-extern _X_EXPORT unsigned short MinorOpcodeOfRequest(ClientPtr /*client*/);
+-
+ extern _X_EXPORT Bool EnableDisableExtension(char *name, Bool enable);
+ 
+ extern _X_EXPORT void EnableDisableExtensionError(char *name, Bool enable);
+diff --git a/record/record.c b/record/record.c
+index 68311ac..4a0fe23 100644
+--- a/record/record.c
++++ b/record/record.c
+@@ -546,7 +546,7 @@ RecordARequest(ClientPtr client)
+ 	    }
+ 	    else /* extension, check minor opcode */
+ 	    {
+-		int minorop = MinorOpcodeOfRequest(client);
++		int minorop = client->minorOp;
+ 		int numMinOpInfo;
+ 		RecordMinorOpPtr pMinorOpInfo = pRCAP->pRequestMinOpInfo;
+ 
+@@ -603,12 +603,9 @@ RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+     RecordContextPtr pContext;
+     RecordClientsAndProtocolPtr pRCAP;
+     int eci;
+-    int majorop;
+     ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
+     ClientPtr client = pri->client;
+-    REQUEST(xReq);
+ 
+-    majorop = stuff->reqType;
+     for (eci = 0; eci < numEnabledContexts; eci++)
+     {
+ 	pContext = ppAllContexts[eci];
+@@ -616,6 +613,7 @@ RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+ 					  NULL);
+ 	if (pRCAP)
+ 	{
++	    int majorop = client->majorOp;
+ 	    if (pContext->continuedReply)
+ 	    {
+ 		RecordAProtocolElement(pContext, client, XRecordFromServer,
+@@ -635,7 +633,7 @@ RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+ 		}
+ 		else /* extension, check minor opcode */
+ 		{
+-		    int minorop = MinorOpcodeOfRequest(client);
++		    int minorop = client->minorOp;
+ 		    int numMinOpInfo;
+ 		    RecordMinorOpPtr pMinorOpInfo = pRCAP->pReplyMinOpInfo;
+ 		    		    assert (pMinorOpInfo);


More information about the scm-commits mailing list