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:
parent
0493935691
commit
8502c06e19
14
Xi/queryst.c
14
Xi/queryst.c
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
11
dix/events.c
11
dix/events.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue