diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2014-01-26 10:54:41 -0800 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2015-02-14 16:14:32 +0100 |
commit | fde1375e373137ac52d0530b819bf9df64ab14c1 (patch) | |
tree | 2a07b3ab946c2e2aa9799deea62dfefac5aea092 /nx-X11/programs/Xserver | |
parent | 985ca320f841bd9a3efc484f92436b3d65ec1b31 (diff) | |
download | nx-libs-fde1375e373137ac52d0530b819bf9df64ab14c1.tar.gz nx-libs-fde1375e373137ac52d0530b819bf9df64ab14c1.tar.bz2 nx-libs-fde1375e373137ac52d0530b819bf9df64ab14c1.zip |
Xi: unvalidated lengths in Xinput extension [CVE-2014-8095]
Multiple functions in the Xinput extension handling of requests from
clients failed to check that the length of the request sent by the
client was large enough to perform all the required operations and
thus could read or write to memory outside the bounds of the request
buffer.
This commit includes the creation of a new REQUEST_AT_LEAST_EXTRA_SIZE
macro in include/dix.h for the common case of needing to ensure a
request is large enough to include both the request itself and a
minimum amount of extra data following the request header.
v2: backport to nx-libs 3.6.x (Mike DePaulo)
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Conflicts:
Xi/chgdctl.c
Xi/chgfctl.c
Xi/xiallowev.c
Xi/xichangecursor.c
Xi/xichangehierarchy.c
Xi/xigetclientpointer.c
Xi/xigrabdev.c
Xi/xipassivegrab.c
Xi/xiproperty.c
Xi/xiquerydevice.c
Xi/xiquerypointer.c
Xi/xiselectev.c
Xi/xisetclientpointer.c
Xi/xisetdevfocus.c
Xi/xiwarppointer.c
[RHEL5: Xi/xi* files are XI2 ]
Diffstat (limited to 'nx-X11/programs/Xserver')
-rw-r--r-- | nx-X11/programs/Xserver/Xi/chgdctl.c | 4 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/Xi/chgfctl.c | 2 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/Xi/sendexev.c | 3 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/include/dix.h | 4 |
4 files changed, 11 insertions, 2 deletions
diff --git a/nx-X11/programs/Xserver/Xi/chgdctl.c b/nx-X11/programs/Xserver/Xi/chgdctl.c index 63a3c9c69..144a51ed4 100644 --- a/nx-X11/programs/Xserver/Xi/chgdctl.c +++ b/nx-X11/programs/Xserver/Xi/chgdctl.c @@ -87,7 +87,7 @@ SProcXChangeDeviceControl(client) REQUEST(xChangeDeviceControlReq); swaps(&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq); + REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl)); swaps(&stuff->control, n); return(ProcXChangeDeviceControl(client)); } @@ -111,7 +111,7 @@ ProcXChangeDeviceControl(client) CARD32 *resolution; REQUEST(xChangeDeviceControlReq); - REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq); + REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl)); len = stuff->length - (sizeof(xChangeDeviceControlReq) >>2); dev = LookupDeviceIntRec (stuff->deviceid); diff --git a/nx-X11/programs/Xserver/Xi/chgfctl.c b/nx-X11/programs/Xserver/Xi/chgfctl.c index fe8bd1fac..3ffac39b3 100644 --- a/nx-X11/programs/Xserver/Xi/chgfctl.c +++ b/nx-X11/programs/Xserver/Xi/chgfctl.c @@ -160,6 +160,8 @@ ProcXChangeFeedbackControl(client) xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]); if (client->swapped) { + if (len < (sizeof(xStringFeedbackCtl) + 3) >> 2) + return BadLength; swaps(&f->num_keysyms,n); } if (len != ((sizeof(xStringFeedbackCtl)>>2) + f->num_keysyms)) diff --git a/nx-X11/programs/Xserver/Xi/sendexev.c b/nx-X11/programs/Xserver/Xi/sendexev.c index 9b441f2d8..0b2a701bb 100644 --- a/nx-X11/programs/Xserver/Xi/sendexev.c +++ b/nx-X11/programs/Xserver/Xi/sendexev.c @@ -154,6 +154,9 @@ ProcXSendExtensionEvent (client) return Success; } + if (stuff->num_events == 0) + return ret; + /* The client's event type must be one defined by an extension. */ first = ((xEvent *) &stuff[1]); diff --git a/nx-X11/programs/Xserver/include/dix.h b/nx-X11/programs/Xserver/include/dix.h index d82979c86..9fe575e53 100644 --- a/nx-X11/programs/Xserver/include/dix.h +++ b/nx-X11/programs/Xserver/include/dix.h @@ -73,6 +73,10 @@ SOFTWARE. if ((sizeof(req) >> 2) > client->req_len )\ return(BadLength) +#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \ + if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \ + return(BadLength) + #define REQUEST_FIXED_SIZE(req, n)\ if (((sizeof(req) >> 2) > client->req_len) || \ ((n >> 2) >= client->req_len) || \ |