xace: Fake return values on denials in input polling requests.

Instead of returning BadAccess when "read" permission is denied
on a device, falsify the device state (buttons down, keys pressed).
This is nicer to applications, but may still have undesired side
effects.  The long-term solution is not to use these requests in
event-driven code!

Requests affected: QueryPointer, QueryKeymap, XiQueryDevice.

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
This commit is contained in:
Eamon Walsh 2009-09-15 19:29:34 -04:00
parent 0493935691
commit 8502c06e19
5 changed files with 55 additions and 24 deletions

View File

@ -96,7 +96,7 @@ ProcXQueryDeviceState(ClientPtr client)
rep.sequenceNumber = client->sequence; rep.sequenceNumber = client->sequence;
rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess); rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess);
if (rc != Success) if (rc != Success && rc != BadAccess)
return rc; return rc;
v = dev->valuator; v = dev->valuator;
@ -130,8 +130,9 @@ ProcXQueryDeviceState(ClientPtr client)
tk->length = sizeof(xKeyState); tk->length = sizeof(xKeyState);
tk->num_keys = k->xkbInfo->desc->max_key_code - tk->num_keys = k->xkbInfo->desc->max_key_code -
k->xkbInfo->desc->min_key_code + 1; k->xkbInfo->desc->min_key_code + 1;
for (i = 0; i < 32; i++) if (rc != BadAccess)
tk->keys[i] = k->down[i]; for (i = 0; i < 32; i++)
tk->keys[i] = k->down[i];
buf += sizeof(xKeyState); buf += sizeof(xKeyState);
} }
@ -140,7 +141,8 @@ ProcXQueryDeviceState(ClientPtr client)
tb->class = ButtonClass; tb->class = ButtonClass;
tb->length = sizeof(xButtonState); tb->length = sizeof(xButtonState);
tb->num_buttons = b->numButtons; tb->num_buttons = b->numButtons;
memcpy(tb->buttons, b->down, sizeof(b->down)); if (rc != BadAccess)
memcpy(tb->buttons, b->down, sizeof(b->down));
buf += sizeof(xButtonState); buf += sizeof(xButtonState);
} }
@ -152,7 +154,9 @@ ProcXQueryDeviceState(ClientPtr client)
tv->mode = v->mode; tv->mode = v->mode;
buf += sizeof(xValuatorState); buf += sizeof(xValuatorState);
for (i = 0, values = v->axisVal; i < v->numAxes; i++) { for (i = 0, values = v->axisVal; i < v->numAxes; i++) {
*((int *)buf) = *values++; if (rc != BadAccess)
*((int *)buf) = *values;
values++;
if (client->swapped) { if (client->swapped) {
swapl((int *)buf, n); /* macro - braces needed */ swapl((int *)buf, n); /* macro - braces needed */
} }

View File

@ -45,7 +45,8 @@
#include "xiquerydevice.h" #include "xiquerydevice.h"
static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d); static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d);
static int ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); static int
ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info);
static int SizeDeviceInfo(DeviceIntPtr dev); static int SizeDeviceInfo(DeviceIntPtr dev);
static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
int int
@ -119,7 +120,7 @@ ProcXIQueryDevice(ClientPtr client)
ptr = info; ptr = info;
if (dev) if (dev)
{ {
len = ListDeviceInfo(dev, (xXIDeviceInfo*)info); len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
if (client->swapped) if (client->swapped)
SwapDeviceInfo(dev, (xXIDeviceInfo*)info); SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
info += len; info += len;
@ -131,7 +132,7 @@ ProcXIQueryDevice(ClientPtr client)
{ {
if (!skip[i]) if (!skip[i])
{ {
len = ListDeviceInfo(dev, (xXIDeviceInfo*)info); len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
if (client->swapped) if (client->swapped)
SwapDeviceInfo(dev, (xXIDeviceInfo*)info); SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
info += len; info += len;
@ -143,7 +144,7 @@ ProcXIQueryDevice(ClientPtr client)
{ {
if (!skip[i]) if (!skip[i])
{ {
len = ListDeviceInfo(dev, (xXIDeviceInfo*)info); len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
if (client->swapped) if (client->swapped)
SwapDeviceInfo(dev, (xXIDeviceInfo*)info); SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
info += len; info += len;
@ -240,7 +241,7 @@ SizeDeviceClasses(DeviceIntPtr dev)
* @return Number of bytes written into info. * @return Number of bytes written into info.
*/ */
int int
ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info) ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState)
{ {
unsigned char *bits; unsigned char *bits;
int mask_len; int mask_len;
@ -257,9 +258,11 @@ ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
bits = (unsigned char*)&info[1]; bits = (unsigned char*)&info[1];
memset(bits, 0, mask_len * 4); memset(bits, 0, mask_len * 4);
for (i = 0; dev && dev->button && i < dev->button->numButtons; i++) if (reportState)
if (BitIsOn(dev->button->down, i)) for (i = 0; dev && dev->button && i < dev->button->numButtons; i++)
SetBit(bits, i); if (BitIsOn(dev->button->down, i))
SetBit(bits, i);
bits += mask_len * 4; bits += mask_len * 4;
memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom)); memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom));
@ -327,7 +330,8 @@ SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
* @return The number of bytes written into info. * @return The number of bytes written into info.
*/ */
int int
ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber) ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber,
Bool reportState)
{ {
ValuatorClassPtr v = dev->valuator; ValuatorClassPtr v = dev->valuator;
@ -345,6 +349,9 @@ ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber)
info->mode = v->mode; /* Server doesn't have per-axis mode yet */ info->mode = v->mode; /* Server doesn't have per-axis mode yet */
info->sourceid = v->sourceid; info->sourceid = v->sourceid;
if (!reportState)
info->value = info->min;
return info->length * 4; return info->length * 4;
} }
@ -389,7 +396,7 @@ int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
* @return The number of bytes used. * @return The number of bytes used.
*/ */
static int static int
ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info) ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info)
{ {
char *any = (char*)&info[1]; char *any = (char*)&info[1];
int len = 0, total_len = 0; int len = 0, total_len = 0;
@ -407,7 +414,8 @@ ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
any += len; any += len;
total_len += len; total_len += len;
return total_len + ListDeviceClasses(dev, any, &info->num_classes); total_len += ListDeviceClasses(client, dev, any, &info->num_classes);
return total_len;
} }
/** /**
@ -416,16 +424,21 @@ ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
* written. * written.
*/ */
int int
ListDeviceClasses(DeviceIntPtr dev, char *any, uint16_t *nclasses) ListDeviceClasses(ClientPtr client, DeviceIntPtr dev,
char *any, uint16_t *nclasses)
{ {
int total_len = 0; int total_len = 0;
int len; int len;
int i; int i;
int rc;
/* Check if the current device state should be suppressed */
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess);
if (dev->button) if (dev->button)
{ {
(*nclasses)++; (*nclasses)++;
len = ListButtonInfo(dev, (xXIButtonInfo*)any); len = ListButtonInfo(dev, (xXIButtonInfo*)any, rc == Success);
any += len; any += len;
total_len += len; total_len += len;
} }
@ -441,7 +454,7 @@ ListDeviceClasses(DeviceIntPtr dev, char *any, uint16_t *nclasses)
for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++) for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++)
{ {
(*nclasses)++; (*nclasses)++;
len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i); len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i, rc == Success);
any += len; any += len;
total_len += len; total_len += len;
} }

View File

@ -37,9 +37,11 @@ int SProcXIQueryDevice(ClientPtr client);
int ProcXIQueryDevice(ClientPtr client); int ProcXIQueryDevice(ClientPtr client);
void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep); void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep);
int SizeDeviceClasses(DeviceIntPtr dev); int SizeDeviceClasses(DeviceIntPtr dev);
int ListDeviceClasses(DeviceIntPtr dev, char* any, uint16_t* nclasses); int ListDeviceClasses(ClientPtr client, DeviceIntPtr dev,
char* any, uint16_t* nclasses);
int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment); int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment);
int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info); int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState);
int ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info); int ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info);
int ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber); int ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info,
int axisnumber, Bool reportState);
#endif /* QUERYDEV_H */ #endif /* QUERYDEV_H */

View File

@ -2221,12 +2221,15 @@ ProcQueryKeymap(ClientPtr client)
rep.length = 2; rep.length = 2;
rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
if (rc != Success) if (rc != Success && rc != BadAccess)
return rc; return rc;
for (i = 0; i<32; i++) for (i = 0; i<32; i++)
rep.map[i] = down[i]; rep.map[i] = down[i];
if (rc == BadAccess)
memset(rep.map, 0, 32);
WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
return Success; return Success;

View File

@ -4974,7 +4974,7 @@ ProcQueryPointer(ClientPtr client)
if (rc != Success) if (rc != Success)
return rc; return rc;
rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
if (rc != Success) if (rc != Success && rc != BadAccess)
return rc; return rc;
keyboard = GetPairedDevice(mouse); keyboard = GetPairedDevice(mouse);
@ -5022,6 +5022,15 @@ ProcQueryPointer(ClientPtr client)
} }
#endif #endif
if (rc == BadAccess) {
rep.mask = 0;
rep.child = None;
rep.rootX = 0;
rep.rootY = 0;
rep.winX = 0;
rep.winY = 0;
}
WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep); WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
return(Success); return(Success);