xserver: Branch 'server-21.1-branch' - 3 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 1 12:20:10 UTC 2022


 Xi/exevents.c   |    2 +-
 dix/events.c    |   18 ++++++++++++++++--
 include/input.h |    1 +
 os/utils.c      |    1 -
 xkb/xkb.c       |   11 +++++------
 5 files changed, 23 insertions(+), 10 deletions(-)

New commits:
commit b713e717c34d539486f661c03a0f1b35b3208d21
Author: Povilas Kanapickas <povilas at radix.lt>
Date:   Sun Jan 23 22:18:52 2022 +0200

    dix: Correctly save replayed event into GrabInfoRec
    
    When processing events we operate on InternalEvent pointers. They may
    actually refer to a an instance of DeviceEvent, GestureEvent or any
    other event that comprises the InternalEvent union. This works well in
    practice because we always look into event type before doing anything,
    except in the case of copying the event.
    
    *dst_event = *src_event would copy whole InternalEvent event and would
    cause out of bounds read in case the pointed to event was not
    InternalEvent but e.g. DeviceEvent.
    
    This regression has been introduced in
    23a8b62d34344575f9df9d057fb74bfefa94a77b.
    
    Fixes https://gitlab.freedesktop.org/xorg/xserver/-/issues/1261
    
    Signed-off-by: Povilas Kanapickas <povilas at radix.lt>
    (cherry picked from commit 6ef5c05728f8b18170fbc8415d7502495a08670b)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 94b9983bd..217baa956 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1524,7 +1524,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
             g = AllocGrab(devgrab);
             BUG_WARN(!g);
 
-            *dev->deviceGrab.sync.event = *ev;
+            CopyPartialInternalEvent(dev->deviceGrab.sync.event, ev);
 
             /* The listener array has a sequence of grabs and then one event
              * selection. Implicit grab activation occurs through delivering an
diff --git a/dix/events.c b/dix/events.c
index 341c746d4..28d7d177c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -467,6 +467,20 @@ WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev)
     return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
 }
 
+/**
+ * When processing events we operate on InternalEvent pointers. They may actually refer to a
+ * an instance of DeviceEvent, GestureEvent or any other event that comprises the InternalEvent
+ * union. This works well in practice because we always look into event type before doing anything,
+ * except in the case of copying the event. Any copying of InternalEvent should use this function
+ * instead of doing *dst_event = *src_event whenever it's not clear whether source event actually
+ * points to full InternalEvent instance.
+ */
+void
+CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event)
+{
+    memcpy(dst_event, src_event, src_event->any.length);
+}
+
 Mask
 GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other)
 {
@@ -3873,7 +3887,7 @@ void ActivateGrabNoDelivery(DeviceIntPtr dev, GrabPtr grab,
 
     if (grabinfo->sync.state == FROZEN_NO_EVENT)
         grabinfo->sync.state = FROZEN_WITH_EVENT;
-    *grabinfo->sync.event = *real_event;
+    CopyPartialInternalEvent(grabinfo->sync.event, real_event);
 }
 
 static BOOL
@@ -4455,7 +4469,7 @@ FreezeThisEventIfNeededForSyncGrab(DeviceIntPtr thisDev, InternalEvent *event)
     case FREEZE_NEXT_EVENT:
         grabinfo->sync.state = FROZEN_WITH_EVENT;
         FreezeThaw(thisDev, TRUE);
-        *grabinfo->sync.event = *event;
+        CopyPartialInternalEvent(grabinfo->sync.event, event);
         break;
     }
 }
diff --git a/include/input.h b/include/input.h
index b1aef3663..cdb5d5a90 100644
--- a/include/input.h
+++ b/include/input.h
@@ -676,6 +676,7 @@ extern void GestureEmitGestureEndToOwner(DeviceIntPtr dev, GestureInfoPtr gi);
 extern void ProcessGestureEvent(InternalEvent *ev, DeviceIntPtr dev);
 
 /* misc event helpers */
+extern void CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event);
 extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients);
 extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
 extern Bool WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev);
commit cd3d21d8c44a35c22b7eca61a58bb5620b116102
Author: Samuel Thibault <samuel.thibault at ens-lyon.org>
Date:   Wed Jan 26 00:05:55 2022 +0100

    xkb: fix XkbSetMap when changing a keysym without changing a keytype
    
    As the comment says:
    
    "symsPerKey/mapWidths must be filled regardless of client-side flags"
    
    so we always have to call CheckKeyTypes which will notably fill mapWidths
    and nTypes. That is needed for CheckKeySyms to work since it checks the
    width. Without it, any request with XkbKeySymsMask but not
    XkbKeyTypesMask will fail because of the missing width information, for
    instance this:
    
      XkbDescPtr xkb;
      if (!(xkb = XkbGetMap (dpy, XkbKeyTypesMask|XkbKeySymsMask, XkbUseCoreKbd))) {
        fprintf (stderr, "ERROR getting map\n");
        exit(1);
      }
      XFlush (dpy);
      XSync (dpy, False);
    
      XkbMapChangesRec changes = { .changed = 0 };
      int oneGroupType[XkbNumKbdGroups] = { XkbOneLevelIndex };
    
      if (XkbChangeTypesOfKey(xkb, keycode, 1, XkbGroup1Mask, oneGroupType, &changes)) {
        fprintf(stderr, "ERROR changing type of key\n");
        exit(1);
      }
      XkbKeySymEntry(xkb,keycode,0,0) = keysym;
    
      if (!XkbChangeMap(dpy,xkb,&changes)) {
        fprintf(stderr, "ERROR changing map\n");
        exit(1);
      }
    
      XkbFreeKeyboard (xkb, 0, TRUE);
      XFlush (dpy);
      XSync (dpy, False);
    
    This had being going under the radar since about ever until commit
    de940e06f8733d87bbb857aef85d830053442cfe ("xkb: fix key type index check
    in _XkbSetMapChecks") fixed checking the values of kt_index, which was
    previously erroneously ignoring errors and ignoring all other checks, just
    because nTypes was not set, precisely because CheckKeyTypes was not called.
    
    Note: yes, CheckKeyTypes is meant to be callable without XkbKeyTypesMask, it
    does properly check for that and just fills nTypes and mapWidths in that
    case.
    
    Signed-off-by: Samuel Thibault <samuel.thibault at ens-lyon.org>
    (cherry picked from commit 0217cc6e0cf5013366105a90f5f91ccc4bab5425)

diff --git a/xkb/xkb.c b/xkb/xkb.c
index bfc21de00..820cd7166 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -2511,16 +2511,15 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
         }
     }
 
-    if (!(req->present & XkbKeyTypesMask)) {
-        nTypes = xkb->map->num_types;
-    }
-    else if (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values,
-			       &nTypes, mapWidths, doswap)) {
+    /* nTypes/mapWidths/symsPerKey must be filled for further tests below,
+     * regardless of client-side flags */
+
+    if (!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values,
+		       &nTypes, mapWidths, doswap)) {
 	    client->errorValue = nTypes;
 	    return BadValue;
     }
 
-    /* symsPerKey/mapWidths must be filled regardless of client-side flags */
     map = &xkb->map->key_sym_map[xkb->min_key_code];
     for (i = xkb->min_key_code; i < xkb->max_key_code; i++, map++) {
         register int g, ng, w;
commit f575524314e9f20a1ff639f6bd65386cdbd083f4
Author: Povilas Kanapickas <povilas at radix.lt>
Date:   Thu Feb 3 20:04:52 2022 +0200

    Revert "os: Try to discover the current seat with the XDG_SEAT var first"
    
    This reverts commit b27eaa72837eebe80adfe6c257a71a6b9eaf66ee.

diff --git a/os/utils.c b/os/utils.c
index c9a8e7367..92a66e81a 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -681,7 +681,6 @@ ProcessCommandLine(int argc, char *argv[])
                     ErrorF("Failed to disable listen for %s transport",
                            defaultNoListenList[i]);
     }
-    SeatId = getenv("XDG_SEAT");
 
     for (i = 1; i < argc; i++) {
         /* call ddx first, so it can peek/override if it wants */


More information about the xorg-commit mailing list