diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2013-05-28 15:52:32 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2013-06-27 05:37:18 +1000 |
commit | 4c8e9bcab459ea5f870d3e56eff15f931807f9b7 (patch) | |
tree | 8eca648742d6d46ad9e28967020fa04e29b37666 /src/XIGrabDevice.c | |
parent | 661c45ca17c434dbd342a46fd3fb813852ae0ca9 (diff) |
Fix potential corruption in mask_len handling
First: check for allocation failure on the mask.
XI2 requires that the mask is zeroed, so we can't just Data() the mask
provided by the client (it will pad) - we need a tmp buffer. Make sure that
doesn't fail.
Second:
req->mask_len is a uint16_t, so check against malicious mask_lens that would
cause us to corrupt memory on copy, as the code always allocates
req->mask_len * 4, but copies mask->mask_len bytes.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src/XIGrabDevice.c')
-rw-r--r-- | src/XIGrabDevice.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/XIGrabDevice.c b/src/XIGrabDevice.c index dd1bd10..2bff3d8 100644 --- a/src/XIGrabDevice.c +++ b/src/XIGrabDevice.c @@ -50,6 +50,17 @@ XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time, if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) return (NoSuchExtension); + if (mask->mask_len > INT_MAX - 3 || + (mask->mask_len + 3)/4 >= 0xffff) + return BadValue; + + /* mask->mask_len is in bytes, but we need 4-byte units on the wire, + * and they need to be padded with 0 */ + len = (mask->mask_len + 3)/4; + buff = calloc(4, len); + if (!buff) + return BadAlloc; + GetReq(XIGrabDevice, req); req->reqType = extinfo->codes->major_opcode; req->ReqType = X_XIGrabDevice; @@ -59,14 +70,9 @@ XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time, req->grab_mode = grab_mode; req->paired_device_mode = paired_device_mode; req->owner_events = owner_events; - req->mask_len = (mask->mask_len + 3)/4; + req->mask_len = len; req->cursor = cursor; - - /* mask->mask_len is in bytes, but we need 4-byte units on the wire, - * and they need to be padded with 0 */ - len = req->mask_len; - buff = calloc(1, len * 4); memcpy(buff, mask->mask, mask->mask_len); SetReqLen(req, len, len); |