diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-09-01 15:16:17 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-09-03 08:39:26 +1000 |
commit | 58c298acc1045927e0d90be73b8dbc8837252589 (patch) | |
tree | 32ee2b8db1c18696bba79a8d4b4a72052fe18929 /Xi | |
parent | 0e4dd3b2d28d3dbbfc152d6f5030901ec063a7ae (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>
Diffstat (limited to 'Xi')
-rw-r--r-- | Xi/xiselectev.c | 11 |
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; |