summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-09-01 15:16:17 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-09-03 08:39:26 +1000
commit58c298acc1045927e0d90be73b8dbc8837252589 (patch)
tree32ee2b8db1c18696bba79a8d4b4a72052fe18929
parent0e4dd3b2d28d3dbbfc152d6f5030901ec063a7ae (diff)
Xi: extra length checking for requests providing masks.
masks can be of arbitrary length. If the client did not initialize mask_len, some sort of boundary check is needed to avoid running over memory. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--Xi/xiselectev.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index d7b16446f..eac12c50f 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -69,6 +69,7 @@ ProcXISelectEvents(ClientPtr client)
DeviceIntRec dummy;
xXIEventMask *evmask;
int *types = NULL;
+ int len;
REQUEST(xXISelectEventsReq);
REQUEST_AT_LEAST_SIZE(xXISelectEventsReq);
@@ -80,11 +81,18 @@ ProcXISelectEvents(ClientPtr client)
if (rc != Success)
return rc;
+ len = sz_xXISelectEventsReq;
+
/* check request validity */
evmask = (xXIEventMask*)&stuff[1];
num_masks = stuff->num_masks;
while(num_masks--)
{
+ len += sizeof(xXIEventMask) + evmask->mask_len * 4;
+
+ if (bytes_to_int32(len) > stuff->length)
+ return BadLength;
+
if (evmask->deviceid != XIAllDevices &&
evmask->deviceid != XIAllMasterDevices)
rc = dixLookupDevice(&dev, evmask->deviceid, client, DixUseAccess);
@@ -128,6 +136,9 @@ ProcXISelectEvents(ClientPtr client)
evmask++;
}
+ if (bytes_to_int32(len) != stuff->length)
+ return BadLength;
+
/* Set masks on window */
evmask = (xXIEventMask*)&stuff[1];
num_masks = stuff->num_masks;