summaryrefslogtreecommitdiff
path: root/Xi/xiquerydevice.c
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2009-06-18 23:19:21 -0400
committerEamon Walsh <ewalsh@tycho.nsa.gov>2009-06-23 21:15:27 -0400
commit84662e40c3d4141ebb298a1ad714f75056a4ab74 (patch)
tree5eeca48cb1457ef7791c1c6284a745222f31f675 /Xi/xiquerydevice.c
parent00bc8d34c68dab6c818cd1c7e03e9992d1d0cbfc (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.c55
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