Xi: Unify checking for invalid bits in grab masks.

Bits above XI2LASTEVENT are invalid and cause in BadValues. These checks
must be performed anywhere where a mask_len parameter is given.

This patch also adds the missing checks to grab masks.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-09-01 16:33:56 +10:00
parent 59a6d7d478
commit 727de7c90d
4 changed files with 34 additions and 19 deletions

View File

@ -39,6 +39,7 @@
#include <X11/extensions/XI2proto.h>
#include "exglobals.h" /* BadDevice */
#include "exevents.h"
#include "xigrabdev.h"
int
@ -78,6 +79,10 @@ ProcXIGrabDevice(ClientPtr client)
if (!IsMaster(dev))
stuff->paired_device_mode = GrabModeAsync;
if (XICheckInvalidMaskBits((unsigned char*)&stuff[1],
stuff->mask_len * 4) != Success)
return BadValue;
mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
memcpy(mask.xi2mask, (char*)&stuff[1], mask_len);

View File

@ -118,15 +118,9 @@ ProcXIPassiveGrabDevice(ClientPtr client)
return BadValue;
}
if ((stuff->mask_len * 4) > XI2LASTEVENT)
{
unsigned char *bits = (unsigned char*)&stuff[1];
for (i = XI2LASTEVENT; i < stuff->mask_len * 4; i++)
{
if (BitIsOn(bits, i))
return BadValue;
}
}
if (XICheckInvalidMaskBits((unsigned char*)&stuff[1],
stuff->mask_len * 4) != Success)
return BadValue;
mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
memset(mask.xi2mask, 0, sizeof(mask.xi2mask));

View File

@ -36,6 +36,25 @@
#include "xiselectev.h"
/**
* Check the given mask (in len bytes) for invalid mask bits.
* Invalid mask bits are any bits above XI2LastEvent.
*
* @return BadValue if at least one invalid bit is set or Success otherwise.
*/
int XICheckInvalidMaskBits(unsigned char *mask, int len)
{
if (len >= XIMaskLen(XI2LASTEVENT))
{
int i;
for (i = XI2LASTEVENT + 1; i < len * 8; i++)
if (BitIsOn(mask, i))
return BadValue;
}
return Success;
}
int
SProcXISelectEvents(ClientPtr client)
{
@ -63,7 +82,7 @@ SProcXISelectEvents(ClientPtr client)
int
ProcXISelectEvents(ClientPtr client)
{
int rc, num_masks, i;
int rc, num_masks;
WindowPtr win;
DeviceIntPtr dev;
DeviceIntRec dummy;
@ -122,15 +141,9 @@ ProcXISelectEvents(ClientPtr client)
return BadValue;
}
if ((evmask->mask_len * 4) >= (XI2LASTEVENT + 8)/8)
{
unsigned char *bits = (unsigned char*)&evmask[1];
for (i = XI2LASTEVENT + 1; i < evmask->mask_len * 4; i++)
{
if (BitIsOn(bits, i))
return BadValue;
}
}
if (XICheckInvalidMaskBits((unsigned char*)&evmask[1],
evmask->mask_len * 4) != Success)
return BadValue;
evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
evmask++;

View File

@ -309,4 +309,7 @@ extern void
XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
unsigned int len, unsigned char* mask);
extern int
XICheckInvalidMaskBits(unsigned char *mask, int len);
#endif /* EXEVENTS_H */