diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2014-01-26 10:54:41 -0800 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2014-12-08 18:09:48 -0800 |
commit | 73c63afb93c0af1bfd1969bf6e71c9edca586c77 (patch) | |
tree | e368f1f7c6b6bc8ecdcb28323f337092cbd0d4a4 /Xi/xigrabdev.c | |
parent | 2ef42519c41e793579c9cea699c866fee3d9321f (diff) |
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.
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'Xi/xigrabdev.c')
-rw-r--r-- | Xi/xigrabdev.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c index 63d95bc1c..e2a2ae333 100644 --- a/Xi/xigrabdev.c +++ b/Xi/xigrabdev.c @@ -47,6 +47,11 @@ int SProcXIGrabDevice(ClientPtr client) { REQUEST(xXIGrabDeviceReq); + /* + * Check here for at least the length of the struct we swap, then + * let ProcXIGrabDevice check the full size after we swap mask_len. + */ + REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); swaps(&stuff->length); swaps(&stuff->deviceid); @@ -71,7 +76,7 @@ ProcXIGrabDevice(ClientPtr client) unsigned int pointer_mode; REQUEST(xXIGrabDeviceReq); - REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); + REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4); ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); if (ret != Success) @@ -131,6 +136,7 @@ int SProcXIUngrabDevice(ClientPtr client) { REQUEST(xXIUngrabDeviceReq); + REQUEST_SIZE_MATCH(xXIUngrabDeviceReq); swaps(&stuff->length); swaps(&stuff->deviceid); @@ -148,6 +154,7 @@ ProcXIUngrabDevice(ClientPtr client) TimeStamp time; REQUEST(xXIUngrabDeviceReq); + REQUEST_SIZE_MATCH(xXIUngrabDeviceReq); ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); if (ret != Success) |