xserver: Branch 'server-1.7-nominations' - 11 commits

Peter Hutterer whot at kemper.freedesktop.org
Wed Oct 21 21:05:01 PDT 2009


 Xext/xselinux.c    |   22 ++++++-------------
 Xext/xselinux.h    |   45 +++++++++++++++++++++++++++++++++------
 Xi/queryst.c       |   14 +++++++-----
 Xi/xiquerydevice.c |   41 +++++++++++++++++++++++------------
 Xi/xiquerydevice.h |    8 ++++--
 dix/devices.c      |   13 ++++++-----
 dix/events.c       |   61 ++++++++++++++++++++++++++++++-----------------------
 include/dix.h      |    4 +--
 xkb/xkb.c          |    2 -
 9 files changed, 131 insertions(+), 79 deletions(-)

New commits:
commit 23ca41f4c3a9cc54116b759615456a0496919f24
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Oct 20 12:57:05 2009 +0100

    Resolve an inconsistency between libX11 and Xserver over GetModifierMapping
    
    libX11 ModMap.c believes that GetModifierMapping can never return an error
    
    Xserver devices.c believes that GetModifierMapping can return an error if
    the ModMap couldn't be generated
    
    According to the protocol document I have, libX11 is right, so adjust the
    server to send back an empty modmap if one couldn't be made...
    
    http://bugs.freedesktop.org/show_bug.cgi?id=24621
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 909df9beb3ddd02632f36ae682537280a6a8e5b4)

diff --git a/dix/devices.c b/dix/devices.c
index 6a79073..7486827 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1520,14 +1520,12 @@ int
 ProcGetModifierMapping(ClientPtr client)
 {
     xGetModifierMappingReply rep;
-    int ret, max_keys_per_mod = 0;
+    int max_keys_per_mod = 0;
     KeyCode *modkeymap = NULL;
     REQUEST_SIZE_MATCH(xReq);
 
-    ret = generate_modkeymap(client, PickKeyboard(client), &modkeymap,
-                             &max_keys_per_mod);
-    if (ret != Success)
-        return ret;
+    generate_modkeymap(client, PickKeyboard(client), &modkeymap,
+                       &max_keys_per_mod);
 
     memset(&rep, 0, sizeof(xGetModifierMappingReply));
     rep.type = X_Reply;
commit 4b9979ae19ff9e9bcc7ede01b20c13d954272de1
Merge: d6d3620... 4549953...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Oct 22 13:31:21 2009 +1000

    Merge branch 'server-1.7-branch' of git://anongit.freedesktop.org/~ewalsh/xserver into server-1.7-nominations

commit 4549953327c31b377ad9183119b66f007fc5b698
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Wed Oct 21 21:59:01 2009 -0400

    Don't print a failure message when XACE denies an input event delivery.
    
    A denial is normal and the behavior should be to drop the event.
    Having the log message creates excessive log spam.
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>
    (cherry picked from commit d4fe55c98c28055191faeba92f43f30fb47cc43a)

diff --git a/dix/events.c b/dix/events.c
index 5250363..1b40ba5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2498,15 +2498,15 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
             if (mask & XI_MASK)
             {
                 rc = EventToXI(event, &xE, &count);
-                if (rc == Success &&
-                    XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success)
-                {
-                    filter = GetEventFilter(dev, xE);
-                    FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
-                    deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
-                                                       filter, grab);
-                    if (deliveries > 0)
-                        goto unwind;
+                if (rc == Success) {
+                    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success) {
+                        filter = GetEventFilter(dev, xE);
+                        FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
+                        deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
+                                                           filter, grab);
+                        if (deliveries > 0)
+                            goto unwind;
+                    }
                 } else if (rc != BadMatch)
                     ErrorF("[dix] %s: XI conversion failed in DDE (%d, %d). Skipping delivery.\n",
                             dev->name, event->any.type, rc);
@@ -2516,15 +2516,15 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
             if ((mask & CORE_MASK) && IsMaster(dev) && dev->coreEvents)
             {
                 rc = EventToCore(event, &core);
-                if (rc == Success &&
-                    XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success)
-                {
-                    filter = GetEventFilter(dev, &core);
-                    FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
-                    deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
-                            filter, grab);
-                    if (deliveries > 0)
-                        goto unwind;
+                if (rc == Success) {
+                    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success) {
+                        filter = GetEventFilter(dev, &core);
+                        FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
+                        deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
+                                                           filter, grab);
+                        if (deliveries > 0)
+                            goto unwind;
+                    }
                 } else if (rc != BadMatch)
                         ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n",
                                 dev->name, event->any.type, rc);
@@ -3804,13 +3804,13 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     if (sendCore)
     {
         rc = EventToCore(event, &core);
-        if (rc == Success &&
-            XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success)
-        {
-            FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
-            deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
-                                               GetEventFilter(keybd, &core),
-                                               NullGrab);
+        if (rc == Success) {
+            if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success) {
+                FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
+                deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
+                                                   GetEventFilter(keybd, &core),
+                                                   NullGrab);
+            }
         } else if (rc != BadMatch)
             ErrorF("[dix] %s: core conversion failed DFE (%d, %d). Skipping delivery.\n",
                     keybd->name, event->any.type, rc);
commit 4cf085ce926e10b7a4aa0ae672f23efc1e0525a2
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Thu Oct 15 13:51:34 2009 -0400

    xselinux: Note something in the log if disabled by boolean.
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 2b106ac..a047a00 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -1948,8 +1948,10 @@ SELinuxExtensionInit(INITARGS)
     }
 
     /* Don't init unless there's something to do */
-    if (!security_get_boolean_active("xserver_object_manager"))
+    if (!security_get_boolean_active("xserver_object_manager")) {
+	LogMessage(X_INFO, "SELinux: Disabled by boolean\n");
         return;
+    }
 
     /* Check SELinux mode in configuration file */
     switch(selinuxEnforcingState) {
commit 53c14303770ecd39534a73dbed90e4e8fd75423a
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Wed Oct 14 20:33:53 2009 -0400

    xselinux: Use the now-exported IsPointerDevice() instead of a copy.
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 3580852..2b106ac 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -400,16 +400,6 @@ SELinuxTypeToClass(RESTYPE type)
 }
 
 /*
- * Returns true if device is a pointer device.
- * Note: this duplicates dix IsPointerDevice() which is not exported.
- */
-static inline Bool
-IsPointerDev(DeviceIntPtr dev)
-{
-    return (dev->type == MASTER_POINTER) || (dev->valuator && dev->button);
-}
-
-/*
  * Performs an SELinux permission check.
  */
 static int
@@ -697,7 +687,7 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 	}
     }
 
-    cls = IsPointerDev(rec->dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
+    cls = IsPointerDevice(rec->dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
     rc = SELinuxDoCheck(subj, obj, cls, rec->access_mode, &auditdata);
     if (rc != Success)
 	rec->status = rc;
commit 951a16c51e8f62e83c84100f6e2eec09ec8b101a
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Wed Oct 14 20:32:28 2009 -0400

    dix: Export IsPointerDevice() and IsKeyboardDevice().
    
    Makes the functions available to extmod for extensions to call.
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>
    (cherry picked from commit 0ae1632be045bfbb288bb57190c830f94247460f)

diff --git a/include/dix.h b/include/dix.h
index b1edb6c..9fd2ed8 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -587,8 +587,8 @@ typedef struct {
 
 extern int XItoCoreType(int xi_type);
 extern Bool DevHasCursor(DeviceIntPtr pDev);
-extern Bool IsPointerDevice( DeviceIntPtr dev);
-extern Bool IsKeyboardDevice(DeviceIntPtr dev);
+extern Bool _X_EXPORT IsPointerDevice( DeviceIntPtr dev);
+extern Bool _X_EXPORT IsKeyboardDevice(DeviceIntPtr dev);
 extern Bool IsPointerEvent(InternalEvent *event);
 extern Bool IsMaster(DeviceIntPtr dev);
 
commit f874af7a85c4d56d4a7dbb5dc460832f294b358b
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Thu Oct 15 17:32:21 2009 -0400

    xselinux: Allow SetWindowCreateContext to be used for pixmaps as well.
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 3093bf2..3580852 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -554,7 +554,7 @@ SELinuxLabelResource(XaceResourceAccessRec *rec, SELinuxSubjectRec *subj,
     security_id_t tsid;
 
     /* Check for a create context */
-    if (rec->rtype == RT_WINDOW && subj->win_create_sid) {
+    if (rec->rtype & RC_DRAWABLE && subj->win_create_sid) {
 	sidget(obj->sid = subj->win_create_sid);
 	return Success;
     }
commit 5560f270c8c28cdae2ed84aca165724487399ece
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Tue Sep 22 13:31:49 2009 -0700

    xselinux: switch from x_device to separate x_pointer and x_keyboard classes.
    
    This will allow separate controls over pointer and keyboard without having
    to relabel the devices to separate types.
    
    [Backport to 1.7]
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>
    (cherry picked from commit 6c2ae5fec552366e11ad64a27626eb5dec4becf0)

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 7bf96fd..3093bf2 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -400,6 +400,16 @@ SELinuxTypeToClass(RESTYPE type)
 }
 
 /*
+ * Returns true if device is a pointer device.
+ * Note: this duplicates dix IsPointerDevice() which is not exported.
+ */
+static inline Bool
+IsPointerDev(DeviceIntPtr dev)
+{
+    return (dev->type == MASTER_POINTER) || (dev->valuator && dev->button);
+}
+
+/*
  * Performs an SELinux permission check.
  */
 static int
@@ -662,6 +672,7 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
     SELinuxSubjectRec *subj;
     SELinuxObjectRec *obj;
     SELinuxAuditRec auditdata = { .client = rec->client, .dev = rec->dev };
+    security_class_t cls;
     int rc;
 
     subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
@@ -686,8 +697,8 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 	}
     }
 
-    rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DEVICE, rec->access_mode,
-			&auditdata);
+    cls = IsPointerDev(rec->dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
+    rc = SELinuxDoCheck(subj, obj, cls, rec->access_mode, &auditdata);
     if (rc != Success)
 	rec->status = rc;
 }
diff --git a/Xext/xselinux.h b/Xext/xselinux.h
index e99f05b..fef207a 100644
--- a/Xext/xselinux.h
+++ b/Xext/xselinux.h
@@ -150,12 +150,13 @@ typedef struct {
 #define SECCLASS_X_SELECTION		7
 #define SECCLASS_X_CURSOR		8
 #define SECCLASS_X_CLIENT		9
-#define SECCLASS_X_DEVICE		10
-#define SECCLASS_X_SERVER		11
-#define SECCLASS_X_EXTENSION		12
-#define SECCLASS_X_EVENT		13
-#define SECCLASS_X_FAKEEVENT		14
-#define SECCLASS_X_RESOURCE		15
+#define SECCLASS_X_POINTER		10
+#define SECCLASS_X_KEYBOARD		11
+#define SECCLASS_X_SERVER		12
+#define SECCLASS_X_EXTENSION		13
+#define SECCLASS_X_EVENT		14
+#define SECCLASS_X_FAKEEVENT		15
+#define SECCLASS_X_RESOURCE		16
 
 /* Mapping from DixAccess bits to Flask permissions */
 static struct security_class_mapping map[] = {
@@ -370,7 +371,37 @@ static struct security_class_mapping map[] = {
           "",			/* DixUseAccess */
           "manage",		/* DixManageAccess */
           NULL }},
-    { "x_device",
+    { "x_pointer",
+        { "read",		/* DixReadAccess */
+          "write",		/* DixWriteAccess */
+          "destroy",		/* DixDestroyAccess */
+          "create",		/* DixCreateAccess */
+          "getattr",		/* DixGetAttrAccess */
+          "setattr",		/* DixSetAttrAccess */
+          "list_property",	/* DixListPropAccess */
+          "get_property",	/* DixGetPropAccess */
+          "set_property",	/* DixSetPropAccess */
+          "getfocus",		/* DixGetFocusAccess */
+          "setfocus",		/* DixSetFocusAccess */
+          "",			/* DixListAccess */
+          "add",		/* DixAddAccess */
+          "remove",		/* DixRemoveAccess */
+          "",			/* DixHideAccess */
+          "",			/* DixShowAccess */
+          "",			/* DixBlendAccess */
+          "grab",		/* DixGrabAccess */
+          "freeze",		/* DixFreezeAccess */
+          "force_cursor",	/* DixForceAccess */
+          "",			/* DixInstallAccess */
+          "",			/* DixUninstallAccess */
+          "",			/* DixSendAccess */
+          "",			/* DixReceiveAccess */
+          "use",		/* DixUseAccess */
+          "manage",		/* DixManageAccess */
+          "",			/* DixDebugAccess */
+          "bell",		/* DixBellAccess */
+          NULL }},
+    { "x_keyboard",
         { "read",		/* DixReadAccess */
           "write",		/* DixWriteAccess */
           "destroy",		/* DixDestroyAccess */
commit 4814532133e6c57f2656e8363ec051edd312f26c
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Tue Sep 22 13:13:03 2009 -0700

    xace: Relax permissions on XkbGetState from Read to Getattr.
    
    This request is used to get the current keyboard group and is called from
    GTK.  It does not return an actual keymap (aside from modifiers) so it
    should be safe to relax the permission on it.  However it does return
    button state information which should be controlled through a separate
    pointer Read check.
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>
    (cherry picked from commit c4ffce4dc84a0a9d134a59b7e7765c99ed767e53)

diff --git a/xkb/xkb.c b/xkb/xkb.c
index 7abbeaa..98e879d 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -554,7 +554,7 @@ ProcXkbGetState(ClientPtr client)
     if (!(client->xkbClientFlags&_XkbClientInitialized))
 	return BadAccess;
 
-    CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
+    CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
 
     xkb= &dev->key->xkbInfo->state;
     bzero(&rep,sizeof(xkbGetStateReply));
commit c1a861eedf2e3b0d11896adaab72b013a885af5a
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Tue Sep 15 19:41:04 2009 -0400

    xselinux: Stop special-casing QueryPointer access checks.
    
    XACE has been changed to not return BadAccess on device read failures.
    Thus, no need for this workaround code.
    
    [Backport to 1.7]
    
    Signed-off-by: Eamon Walsh <ewalsh at tycho.nsa.gov>
    (cherry-picked from commit 0ff28319906eeb3f236acd72201c416ce01f2c6e)

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index b9b16b6..7bf96fd 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -686,17 +686,6 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 	}
     }
 
-    /* XXX only check read permission on XQueryKeymap */
-    /* This is to allow the numerous apps that call XQueryPointer to work */
-    if (rec->access_mode & DixReadAccess) {
-	ClientPtr client = rec->client;
-	REQUEST(xReq);
-	if (stuff && stuff->reqType != X_QueryKeymap) {
-	    rec->access_mode &= ~DixReadAccess;
-	    rec->access_mode |= DixGetAttrAccess;
-	}
-    }
-
     rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DEVICE, rec->access_mode,
 			&auditdata);
     if (rc != Success)
commit 7d3f8ce505e45c888c4f309011144d212623f0f0
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Tue Sep 15 19:29:34 2009 -0400

    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 at tycho.nsa.gov>
    (cherry picked from commit 8502c06e19a4c00bf1311f54f9a365ee9e026e97)

diff --git a/Xi/queryst.c b/Xi/queryst.c
index 2ba1edb..78b97a7 100644
--- a/Xi/queryst.c
+++ b/Xi/queryst.c
@@ -96,7 +96,7 @@ ProcXQueryDeviceState(ClientPtr client)
     rep.sequenceNumber = client->sequence;
 
     rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess);
-    if (rc != Success)
+    if (rc != Success && rc != BadAccess)
 	return rc;
 
     v = dev->valuator;
@@ -130,8 +130,9 @@ ProcXQueryDeviceState(ClientPtr client)
 	tk->length = sizeof(xKeyState);
 	tk->num_keys = k->xkbInfo->desc->max_key_code -
                        k->xkbInfo->desc->min_key_code + 1;
-	for (i = 0; i < 32; i++)
-	    tk->keys[i] = k->down[i];
+	if (rc != BadAccess)
+	    for (i = 0; i < 32; i++)
+		tk->keys[i] = k->down[i];
 	buf += sizeof(xKeyState);
     }
 
@@ -140,7 +141,8 @@ ProcXQueryDeviceState(ClientPtr client)
 	tb->class = ButtonClass;
 	tb->length = sizeof(xButtonState);
 	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);
     }
 
@@ -152,7 +154,9 @@ ProcXQueryDeviceState(ClientPtr client)
 	tv->mode = v->mode;
 	buf += sizeof(xValuatorState);
 	for (i = 0, values = v->axisVal; i < v->numAxes; i++) {
-	    *((int *)buf) = *values++;
+	    if (rc != BadAccess)
+		*((int *)buf) = *values;
+	    values++;
 	    if (client->swapped) {
 		swapl((int *)buf, n);	/* macro - braces needed */
 	    }
diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index 68d91fa..435868d 100644
--- a/Xi/xiquerydevice.c
+++ b/Xi/xiquerydevice.c
@@ -45,7 +45,8 @@
 #include "xiquerydevice.h"
 
 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 void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
 int
@@ -119,7 +120,7 @@ ProcXIQueryDevice(ClientPtr client)
     ptr = info;
     if (dev)
     {
-        len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+        len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
         if (client->swapped)
             SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
         info += len;
@@ -131,7 +132,7 @@ ProcXIQueryDevice(ClientPtr client)
         {
             if (!skip[i])
             {
-                len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+                len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
                 if (client->swapped)
                     SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
                 info += len;
@@ -143,7 +144,7 @@ ProcXIQueryDevice(ClientPtr client)
         {
             if (!skip[i])
             {
-                len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+                len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
                 if (client->swapped)
                     SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
                 info += len;
@@ -240,7 +241,7 @@ SizeDeviceClasses(DeviceIntPtr dev)
  * @return Number of bytes written into info.
  */
 int
-ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
+ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState)
 {
     unsigned char *bits;
     int mask_len;
@@ -257,9 +258,11 @@ ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
     bits = (unsigned char*)&info[1];
     memset(bits, 0, mask_len * 4);
 
-    for (i = 0; dev && dev->button && i < dev->button->numButtons; i++)
-        if (BitIsOn(dev->button->down, i))
-            SetBit(bits, i);
+    if (reportState)
+	for (i = 0; dev && dev->button && i < dev->button->numButtons; i++)
+	    if (BitIsOn(dev->button->down, i))
+		SetBit(bits, i);
+
     bits += mask_len * 4;
     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.
  */
 int
-ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber)
+ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber,
+		 Bool reportState)
 {
     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->sourceid = v->sourceid;
 
+    if (!reportState)
+	info->value = info->min;
+
     return info->length * 4;
 }
 
@@ -389,7 +396,7 @@ int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
  * @return The number of bytes used.
  */
 static int
-ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
+ListDeviceInfo(ClientPtr client, DeviceIntPtr dev, xXIDeviceInfo* info)
 {
     char *any = (char*)&info[1];
     int len = 0, total_len = 0;
@@ -407,7 +414,8 @@ ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
     any += 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.
  */
 int
-ListDeviceClasses(DeviceIntPtr dev, char *any, uint16_t *nclasses)
+ListDeviceClasses(ClientPtr client, DeviceIntPtr dev,
+		  char *any, uint16_t *nclasses)
 {
     int total_len = 0;
     int len;
     int i;
+    int rc;
+
+    /* Check if the current device state should be suppressed */
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess);
 
     if (dev->button)
     {
         (*nclasses)++;
-        len = ListButtonInfo(dev, (xXIButtonInfo*)any);
+        len = ListButtonInfo(dev, (xXIButtonInfo*)any, rc == Success);
         any += 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++)
     {
         (*nclasses)++;
-        len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i);
+        len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i, rc == Success);
         any += len;
         total_len += len;
     }
diff --git a/Xi/xiquerydevice.h b/Xi/xiquerydevice.h
index 34e87bd..02f0659 100644
--- a/Xi/xiquerydevice.h
+++ b/Xi/xiquerydevice.h
@@ -37,9 +37,11 @@ int SProcXIQueryDevice(ClientPtr client);
 int ProcXIQueryDevice(ClientPtr client);
 void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep);
 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 ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info);
+int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info, Bool reportState);
 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 */
diff --git a/dix/devices.c b/dix/devices.c
index e86e606..6a79073 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2221,12 +2221,15 @@ ProcQueryKeymap(ClientPtr client)
     rep.length = 2;
 
     rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
-    if (rc != Success)
+    if (rc != Success && rc != BadAccess)
 	return rc;
 
     for (i = 0; i<32; i++)
 	rep.map[i] = down[i];
 
+    if (rc == BadAccess)
+	memset(rep.map, 0, 32);
+
     WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
 
    return Success;
diff --git a/dix/events.c b/dix/events.c
index 8f63d33..5250363 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4974,7 +4974,7 @@ ProcQueryPointer(ClientPtr client)
     if (rc != Success)
 	return rc;
     rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
-    if (rc != Success)
+    if (rc != Success && rc != BadAccess)
 	return rc;
 
     keyboard = GetPairedDevice(mouse);
@@ -5022,6 +5022,15 @@ ProcQueryPointer(ClientPtr client)
     }
 #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);
 
     return(Success);


More information about the xorg-commit mailing list