diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2009-06-18 23:19:21 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2009-06-23 21:15:27 -0400 |
commit | 84662e40c3d4141ebb298a1ad714f75056a4ab74 (patch) | |
tree | 5eeca48cb1457ef7791c1c6284a745222f31f675 /Xi/xiquerydevice.c | |
parent | 00bc8d34c68dab6c818cd1c7e03e9992d1d0cbfc (diff) |
Xi: check for GetAttr permission when listing or querying devices.
If the check fails, leave the device off the returned list of info
structures. Under XI2, this may cause inconsistent views of the device
topology after a change (for example, devices disappearing from view,
or showing as attached to a master that cannot be seen). More work is
needed to deal with topology changes and device relabeling.
Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
Diffstat (limited to 'Xi/xiquerydevice.c')
-rw-r--r-- | Xi/xiquerydevice.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c index 6aa168521..33628a6ef 100644 --- a/Xi/xiquerydevice.c +++ b/Xi/xiquerydevice.c @@ -40,9 +40,11 @@ #include "xkbsrv.h" #include "xserver-properties.h" #include "exevents.h" +#include "xace.h" #include "xiquerydevice.h" +static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d); static int ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); static int SizeDeviceInfo(DeviceIntPtr dev); static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); @@ -65,8 +67,9 @@ ProcXIQueryDevice(ClientPtr client) xXIQueryDeviceReply rep; DeviceIntPtr dev = NULL; int rc = Success; - int len = 0; + int i = 0, len = 0; char *info, *ptr; + Bool *skip = NULL; REQUEST(xXIQueryDeviceReq); REQUEST_SIZE_MATCH(xXIQueryDeviceReq); @@ -79,28 +82,27 @@ ProcXIQueryDevice(ClientPtr client) client->errorValue = stuff->deviceid; return rc; } - } - - if (dev) len += SizeDeviceInfo(dev); + } else { - len = 0; - for (dev = inputInfo.devices; dev; dev = dev->next) + skip = xcalloc(sizeof(Bool), inputInfo.numDevices); + if (!skip) + return BadAlloc; + + for (dev = inputInfo.devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) len += SizeDeviceInfo(dev); } - for (dev = inputInfo.off_devices; dev; dev = dev->next) + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) len += SizeDeviceInfo(dev); } - - dev = NULL; } info = xcalloc(1, len); @@ -124,10 +126,10 @@ ProcXIQueryDevice(ClientPtr client) rep.num_devices = 1; } else { - for (dev = inputInfo.devices; dev; dev = dev->next) + i = 0; + for (dev = inputInfo.devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + if (!skip[i]) { len = ListDeviceInfo(dev, (xXIDeviceInfo*)info); if (client->swapped) @@ -137,10 +139,9 @@ ProcXIQueryDevice(ClientPtr client) } } - for (dev = inputInfo.off_devices; dev; dev = dev->next) + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + if (!skip[i]) { len = ListDeviceInfo(dev, (xXIDeviceInfo*)info); if (client->swapped) @@ -154,6 +155,7 @@ ProcXIQueryDevice(ClientPtr client) WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep); WriteToClient(client, rep.length * 4, ptr); xfree(ptr); + xfree(skip); return rc; } @@ -172,6 +174,21 @@ SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep) } +/** + * @return Whether the device should be included in the returned list. + */ +static Bool +ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev) +{ + /* if all devices are not being queried, only master devices are */ + if (deviceid == XIAllDevices || IsMaster(dev)) + { + int rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); + if (rc == Success) + return FALSE; + } + return TRUE; +} /** * @return The number of bytes needed to store this device's xXIDeviceInfo |