xserver: Branch 'xwayland-24.1' - 12 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Apr 14 06:29:02 UTC 2025


 Xi/xigrabdev.c          |    3 +
 dix/enterleave.c        |    2 
 dix/events.c            |   36 +++++++++++++++-
 hw/xwayland/meson.build |    1 
 include/meson.build     |    2 
 mi/mipointer.c          |   27 +++++++++++-
 xkb/XKBAlloc.c          |    4 +
 xkb/XKBMAlloc.c         |    2 
 xkb/xkbtext.c           |  104 ++++++++++++++++++++++++++++--------------------
 9 files changed, 131 insertions(+), 50 deletions(-)

New commits:
commit 34ef671aa5ae0df3a499ae0852e1ffbfe7086888
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 20 10:37:53 2025 +1000

    dix: pick the right keyboard for focus FollowKeyboard
    
    This fixes a crash when we try to send focus events and dereference
    FollowKeyboardWin (0x3) as WindowPtr.
    
    A device set to XSetDeviceFocus(FollowKeyboard) is supposed to follow
    the focus of the corresponding master device. During ActivateKeyboard
    a slave device is detached from the master for the duration for the grab
    so we don't actually have a master to follow - leaving our oldWin set to
    the FollowKeyboardWin constant. This later crashes when we try to
    dereference it.
    
    Fix this by getting the current master (if any), or the saved master (if
    temporarily detached due to a grab). And if failing that, use the VCK
    as fallback device - that is technically wrong but it's such a niche use
    case that it shouldn't matter.
    
    Reproducer:
         window = XCreateSimpleWindow(...)
         deviceid = any device that is IsXExtensionKeyboard device
         XSetDeviceFocus(deviceid, FollowKeyboard, ...)
         XGrabDevice(deviceid, window, ...)
    
    Fixes: f01ee198ff0c ("dix: don't use inputInfo.keyboard to get the focus window in ActivateKbdGrab")
    
    Found-by: Olivier Fourdan <ofourdan at redhat.com>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    Tested-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit cab9017485566da656b12b686e571d42b0f28afb)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/dix/events.c b/dix/events.c
index b28da9489..d21e1894c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1486,6 +1486,30 @@ ReattachToOldMaster(DeviceIntPtr dev)
     }
 }
 
+/**
+ * Return the current master keyboard or, if we're temporarily detached, the one
+ * we've been attached to previously.
+ */
+static DeviceIntPtr
+CurrentOrOldMasterKeyboard(DeviceIntPtr dev)
+{
+    DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD);
+
+    if (kbd)
+        return kbd;
+
+    if (dev->saved_master_id) {
+        dixLookupDevice(&kbd, dev->saved_master_id, serverClient, DixUseAccess);
+        if (!kbd)
+            return NULL;
+        /* if dev is a pointer the saved master is a master pointer,
+         * we want the keybard */
+        return GetMaster(kbd, MASTER_KEYBOARD);
+    }
+
+    return NULL;
+}
+
 /**
  * Update touch records when an explicit grab is activated. Any touches owned by
  * the grabbing client are updated so the listener state reflects the new grab.
@@ -1713,6 +1737,10 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
     GrabInfoPtr grabinfo = &keybd->deviceGrab;
     GrabPtr oldgrab = grabinfo->grab;
     WindowPtr oldWin;
+    DeviceIntPtr master_keyboard = CurrentOrOldMasterKeyboard(keybd);
+
+    if (!master_keyboard)
+        master_keyboard = inputInfo.keyboard;
 
     /* slave devices need to float for the duration of the grab. */
     if (grab->grabtype == XI2 && keybd->enabled &&
@@ -1728,7 +1756,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
     else
         oldWin = keybd->spriteInfo->sprite->win;
     if (oldWin == FollowKeyboardWin)
-        oldWin = keybd->focus->win;
+        oldWin = master_keyboard->focus->win;
     if (keybd->valuator)
         keybd->valuator->motionHintWindow = NullWindow;
     if (oldWin &&
@@ -1759,6 +1787,10 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
     WindowPtr focusWin;
     Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab &&
                         keybd->deviceGrab.implicitGrab);
+    DeviceIntPtr master_keyboard = CurrentOrOldMasterKeyboard(keybd);
+
+    if (!master_keyboard)
+        master_keyboard = inputInfo.keyboard;
 
     if (keybd->valuator)
         keybd->valuator->motionHintWindow = NullWindow;
@@ -1779,7 +1811,7 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
         focusWin = NullWindow;
 
     if (focusWin == FollowKeyboardWin)
-        focusWin = inputInfo.keyboard->focus->win;
+        focusWin = master_keyboard->focus->win;
 
     DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
 
commit a50e6a2e33a5c2c710ad5a0c8e873a4d615f25a1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 20 11:24:32 2025 +1000

    dix: fix erroneous BUG_RETURN check
    
    Check was inverted, we want to complain if evcount exceeds our target
    array.
    
    Fixes: 219c54b8a333 ("dix: fix DeviceStateNotify event calculation")
    (cherry picked from commit 2bca68f41b222ca7bf881f0e2d7011e9fea43c60)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/dix/enterleave.c b/dix/enterleave.c
index 2b488b7ce..b083d894a 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -731,7 +731,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
         evcount += ((nval - 3) + 6)/6;
     }
 
-    BUG_RETURN(evcount <= ARRAY_SIZE(sev));
+    BUG_RETURN(evcount > ARRAY_SIZE(sev));
 
     FixDeviceStateNotify(dev, ev, k, b, v, first);
 
commit 1119ea220a005949d039f06db17010312330a279
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 8 16:29:53 2025 -0800

    dix-config.h: define HAVE_STRUCT_SOCKADDR_STORAGE for xtrans 1.6
    
    xtrans 1.6 will use struct sockaddr_storage if HAVE_STRUCT_SOCKADDR_STORAGE
    is defined, even if IPv6 is disabled, unlike previous versions which tied
    it to the IPv6 #define.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 4b5d410591ed29afba010cd30594d8ed7c195c2e)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/include/meson.build b/include/meson.build
index 9b225163b..72e1e5d5b 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -167,6 +167,8 @@ conf_data.set('HAVE_STRLCAT', cc.has_function('strlcat', dependencies: libbsd_de
 conf_data.set('HAVE_STRLCPY', cc.has_function('strlcpy', dependencies: libbsd_dep) ? '1' : false)
 conf_data.set('HAVE_STRNCASECMP', cc.has_function('strncasecmp') ? '1' : false)
 conf_data.set('HAVE_STRNDUP', cc.has_function('strndup') and cc.has_header_symbol('string.h', 'strndup') ? '1' : false)
+# HAVE_STRUCT_SOCKADDR_STORAGE is used by xtrans >= 1.6
+conf_data.set('HAVE_STRUCT_SOCKADDR_STORAGE', cc.has_type('struct sockaddr_storage', prefix: '#include <sys/socket.h>') ? '1' : false)
 conf_data.set('HAVE_TIMINGSAFE_MEMCMP', cc.has_function('timingsafe_memcmp') ? '1' : false)
 conf_data.set('HAVE_VASPRINTF', cc.has_function('vasprintf') ? '1' : false)
 conf_data.set('HAVE_VSNPRINTF', cc.has_function('vsnprintf') ? '1' : false)
commit 6f1acb0dff2f3a5023b90db00cc814d1381e052c
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Mar 8 14:49:16 2025 -0800

    pkgconfig files: Add URL
    
    https://github.com/pkgconf/pkgconf/blob/master/man/pc.5 says it's
    a mandatory field in *.pc files.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit b73cd6066af1dde94e66c5593290b78a96d10dc0)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
index a89753d44..9fff6445d 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -196,6 +196,7 @@ pkgconfig.generate(
         'exec_prefix=${prefix}',
         'xwayland=' + xwayland_path + '/Xwayland',
     ] + xwayland_vars,
+    url: 'https://gitlab.freedesktop.org/xorg/xserver/',
 )
 
 xwayland_manpage = configure_file(
commit 3a6d035aecb53ba5187f969883107f78cd4ccc32
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 6 09:40:22 2025 +1000

    Xi: disallow grabbing disabled devices
    
    Grabbing a disabled (pointer) device will lead to a segfault later
    in the myriad of places where we look at the device's spriteInfo - which
    will be NULL.
    
    As a workaround, disallow grabbing a disabled device by pretending it's
    already grabbed. Since the point of a grab is to receive all events by
    that device and disabled devices cannot send events, this should be Good
    Enough.
    
    Tested-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 797f63b8be1693a7c0ae5df8b76911d804959ce5)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index cf3ee7b95..40e2e5817 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -82,6 +82,9 @@ ProcXIGrabDevice(ClientPtr client)
     if (ret != Success)
         return ret;
 
+    if (!dev->enabled)
+        return AlreadyGrabbed;
+
     if (!IsMaster(dev))
         stuff->paired_device_mode = GrabModeAsync;
 
commit 91e42e523cb37da26b2b2d4b55b186a25ec6285f
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sun Oct 8 13:22:13 2023 -0700

    xkb: Add tbGetBufferString helper function
    
    Handles common case of allocating & copying string to temporary buffer
    
    (cherry picked from xorg/lib/libxkbfile at 8a91517ca6ea77633476595b0eb5b213357c60e5)
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 42a1f25faff612641dffb95a77f9ec3661111875)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c
index c6cc21ce3..d6f688f5c 100644
--- a/xkb/xkbtext.c
+++ b/xkb/xkbtext.c
@@ -71,6 +71,20 @@ tbGetBuffer(unsigned size)
 
 /***====================================================================***/
 
+static inline char *
+tbGetBufferString(const char *str)
+{
+    size_t size = strlen(str) + 1;
+    char *rtrn = tbGetBuffer((unsigned) size);
+
+    if (rtrn != NULL)
+        memcpy(rtrn, str, size);
+
+    return rtrn;
+}
+
+/***====================================================================***/
+
 char *
 XkbAtomText(Atom atm, unsigned format)
 {
@@ -79,11 +93,7 @@ XkbAtomText(Atom atm, unsigned format)
 
     atmstr = NameForAtom(atm);
     if (atmstr != NULL) {
-        int len;
-
-        len = strlen(atmstr) + 1;
-        rtrn = tbGetBuffer(len);
-        strlcpy(rtrn, atmstr, len);
+        rtrn = tbGetBufferString(atmstr);
     }
     else {
         rtrn = tbGetBuffer(1);
@@ -233,7 +243,6 @@ static const char *modNames[XkbNumModifiers] = {
 char *
 XkbModIndexText(unsigned ndx, unsigned format)
 {
-    char *rtrn;
     char buf[100];
 
     if (format == XkbCFile) {
@@ -252,9 +261,7 @@ XkbModIndexText(unsigned ndx, unsigned format)
         else
             snprintf(buf, sizeof(buf), "ILLEGAL_%02x", ndx);
     }
-    rtrn = tbGetBuffer(strlen(buf) + 1);
-    strcpy(rtrn, buf);
-    return rtrn;
+    return tbGetBufferString(buf);
 }
 
 char *
@@ -296,8 +303,7 @@ XkbModMaskText(unsigned mask, unsigned format)
             }
         }
     }
-    rtrn = tbGetBuffer(strlen(buf) + 1);
-    strcpy(rtrn, buf);
+    rtrn = tbGetBufferString(buf);
     return rtrn;
 }
 
@@ -1229,7 +1235,7 @@ static actionCopy copyActionArgs[XkbSA_NumActions] = {
 char *
 XkbActionText(XkbDescPtr xkb, XkbAction *action, unsigned format)
 {
-    char buf[ACTION_SZ], *tmp;
+    char buf[ACTION_SZ];
     int sz;
 
     if (format == XkbCFile) {
@@ -1250,16 +1256,13 @@ XkbActionText(XkbDescPtr xkb, XkbAction *action, unsigned format)
             CopyOtherArgs(xkb, action, buf, &sz);
         TryCopyStr(buf, ")", &sz);
     }
-    tmp = tbGetBuffer(strlen(buf) + 1);
-    if (tmp != NULL)
-        strcpy(tmp, buf);
-    return tmp;
+    return tbGetBufferString(buf);
 }
 
 char *
 XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
 {
-    char buf[256], *tmp;
+    char buf[256];
 
     if (format == XkbCFile) {
         if (behavior->type == XkbKB_Default)
@@ -1280,6 +1283,7 @@ XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
         }
         else if (type == XkbKB_RadioGroup) {
             int g;
+            char *tmp;
             size_t tmpsize;
 
             g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1;
@@ -1315,10 +1319,7 @@ XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
                 snprintf(buf, sizeof(buf), "overlay%d= %s", ndx, kn);
         }
     }
-    tmp = tbGetBuffer(strlen(buf) + 1);
-    if (tmp != NULL)
-        strcpy(tmp, buf);
-    return tmp;
+    return tbGetBufferString(buf);
 }
 
 /***====================================================================***/
commit bd43d90cd1d107e36081a6080d46a29b1719e979
Author: Martin Burggraf <TSO at gmx.net>
Date:   Thu Aug 13 21:16:40 2015 +0200

    xkb: correcting mathematical nonsense in XkbGeomFPText
    
    Fixes formatting of negative numbers, so they don't show minus sign
    after the decimal point.
    
    (cherry picked from xorg/lib/libxkbfile at d2ec504fec2550f4fd046e801b34317ef4a4bab9)
    
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 7a23010232312c24cde6070a50dbb5433ce52a59)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c
index 45237ac42..c6cc21ce3 100644
--- a/xkb/xkbtext.c
+++ b/xkb/xkbtext.c
@@ -623,7 +623,7 @@ XkbGeomFPText(int val, unsigned format)
 {
     int whole, frac;
     char *buf;
-    const int bufsize = 12;
+    const int bufsize = 13;
 
     buf = tbGetBuffer(bufsize);
     if (format == XkbCFile) {
@@ -631,9 +631,17 @@ XkbGeomFPText(int val, unsigned format)
     }
     else {
         whole = val / XkbGeomPtsPerMM;
-        frac = val % XkbGeomPtsPerMM;
-        if (frac != 0)
-            snprintf(buf, bufsize, "%d.%d", whole, frac);
+        frac = abs(val % XkbGeomPtsPerMM);
+        if (frac != 0) {
+            if (val < 0)
+            {
+                int wholeabs;
+                wholeabs = abs(whole);
+                snprintf(buf, bufsize, "-%d.%d", wholeabs, frac);
+            }
+            else
+                snprintf(buf, bufsize, "%d.%d", whole, frac);
+        }
         else
             snprintf(buf, bufsize, "%d", whole);
     }
commit ed54cc2a034eeb60df32a7210803f3e28d3d147e
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Feb 22 16:15:01 2025 -0800

    xkb: Convert more sprintf calls to snprintf in xkbtext.c
    
    Based on xorg/lib/libxkbfile at 390acfe5bb88cdab509b5eaae4041f265e969d2b
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 60419d8e4a02dc2599351b65b3503f0bb0932eaa)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c
index 96d2a683e..45237ac42 100644
--- a/xkb/xkbtext.c
+++ b/xkb/xkbtext.c
@@ -151,11 +151,12 @@ XkbVModMaskText(XkbDescPtr xkb,
     char *str, buf[VMOD_BUFFER_SIZE];
 
     if ((modMask == 0) && (mask == 0)) {
-        rtrn = tbGetBuffer(5);
+        const int rtrnsize = 5;
+        rtrn = tbGetBuffer(rtrnsize);
         if (format == XkbCFile)
-            sprintf(rtrn, "0");
+            snprintf(rtrn, rtrnsize, "0");
         else
-            sprintf(rtrn, "none");
+            snprintf(rtrn, rtrnsize, "none");
         return rtrn;
     }
     if (modMask != 0)
@@ -306,8 +307,9 @@ XkbModMaskText(unsigned mask, unsigned format)
 XkbConfigText(unsigned config, unsigned format)
 {
     static char *buf;
+    const int bufsize = 32;
 
-    buf = tbGetBuffer(32);
+    buf = tbGetBuffer(bufsize);
     switch (config) {
     case XkmSemanticsFile:
         strcpy(buf, "Semantics");
@@ -341,7 +343,7 @@ XkbConfigText(unsigned config, unsigned format)
         strcpy(buf, "VirtualMods");
         break;
     default:
-        sprintf(buf, "unknown(%d)", config);
+        snprintf(buf, bufsize, "unknown(%d)", config);
         break;
     }
     return buf;
@@ -440,7 +442,7 @@ static const char *imWhichNames[] = {
 char *
 XkbIMWhichStateMaskText(unsigned use_which, unsigned format)
 {
-    int len;
+    int len, bufsize;
     unsigned i, bit, tmp;
     char *buf;
 
@@ -458,7 +460,8 @@ XkbIMWhichStateMaskText(unsigned use_which, unsigned format)
                 len += 9;
         }
     }
-    buf = tbGetBuffer(len + 1);
+    bufsize = len + 1;
+    buf = tbGetBuffer(bufsize);
     tmp = use_which & XkbIM_UseAnyMods;
     for (len = i = 0, bit = 1; tmp != 0; i++, bit <<= 1) {
         if (tmp & bit) {
@@ -466,13 +469,14 @@ XkbIMWhichStateMaskText(unsigned use_which, unsigned format)
             if (format == XkbCFile) {
                 if (len != 0)
                     buf[len++] = '|';
-                sprintf(&buf[len], "XkbIM_Use%s", imWhichNames[i]);
-                buf[len + 9] = toupper(buf[len + 9]);
+                snprintf(&buf[len], bufsize - len,
+                         "XkbIM_Use%s", imWhichNames[i]);
+                buf[len + 9] = toupper((unsigned char)buf[len + 9]);
             }
             else {
                 if (len != 0)
                     buf[len++] = '+';
-                sprintf(&buf[len], "%s", imWhichNames[i]);
+                snprintf(&buf[len], bufsize - len, "%s", imWhichNames[i]);
             }
             len += strlen(&buf[len]);
         }
@@ -619,18 +623,19 @@ XkbGeomFPText(int val, unsigned format)
 {
     int whole, frac;
     char *buf;
+    const int bufsize = 12;
 
-    buf = tbGetBuffer(12);
+    buf = tbGetBuffer(bufsize);
     if (format == XkbCFile) {
-        sprintf(buf, "%d", val);
+        snprintf(buf, bufsize, "%d", val);
     }
     else {
         whole = val / XkbGeomPtsPerMM;
         frac = val % XkbGeomPtsPerMM;
         if (frac != 0)
-            sprintf(buf, "%d.%d", whole, frac);
+            snprintf(buf, bufsize, "%d.%d", whole, frac);
         else
-            sprintf(buf, "%d", whole);
+            snprintf(buf, bufsize, "%d", whole);
     }
     return buf;
 }
@@ -641,7 +646,8 @@ XkbDoodadTypeText(unsigned type, unsigned format)
     char *buf;
 
     if (format == XkbCFile) {
-        buf = tbGetBuffer(24);
+        const int bufsize = 24;
+        buf = tbGetBuffer(bufsize);
         if (type == XkbOutlineDoodad)
             strcpy(buf, "XkbOutlineDoodad");
         else if (type == XkbSolidDoodad)
@@ -653,10 +659,11 @@ XkbDoodadTypeText(unsigned type, unsigned format)
         else if (type == XkbLogoDoodad)
             strcpy(buf, "XkbLogoDoodad");
         else
-            sprintf(buf, "UnknownDoodad%d", type);
+            snprintf(buf, bufsize, "UnknownDoodad%d", type);
     }
     else {
-        buf = tbGetBuffer(12);
+        const int bufsize = 12;
+        buf = tbGetBuffer(bufsize);
         if (type == XkbOutlineDoodad)
             strcpy(buf, "outline");
         else if (type == XkbSolidDoodad)
@@ -668,7 +675,7 @@ XkbDoodadTypeText(unsigned type, unsigned format)
         else if (type == XkbLogoDoodad)
             strcpy(buf, "logo");
         else
-            sprintf(buf, "unknown%d", type);
+            snprintf(buf, bufsize, "unknown%d", type);
     }
     return buf;
 }
@@ -1265,6 +1272,7 @@ XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
         }
         else if (type == XkbKB_RadioGroup) {
             int g;
+            size_t tmpsize;
 
             g = ((behavior->data) & (~XkbKB_RGAllowNone)) + 1;
             if (XkbKB_RGAllowNone & behavior->data) {
@@ -1273,10 +1281,11 @@ XkbBehaviorText(XkbDescPtr xkb, XkbBehavior * behavior, unsigned format)
             }
             else
                 tmp = buf;
+            tmpsize = sizeof(buf) - (tmp - buf);
             if (permanent)
-                sprintf(tmp, "permanentRadioGroup= %d", g);
+                snprintf(tmp, tmpsize, "permanentRadioGroup= %d", g);
             else
-                sprintf(tmp, "radioGroup= %d", g);
+                snprintf(tmp, tmpsize, "radioGroup= %d", g);
         }
         else if ((type == XkbKB_Overlay1) || (type == XkbKB_Overlay2)) {
             int ndx, kc;
commit b32d637f5154854624e3630e8068d17a756f1d09
Author: José Expósito <jexposit at redhat.com>
Date:   Tue Apr 30 17:37:39 2024 +0200

    xkb: Check that needed is > 0 in XkbResizeKeyActions
    
    Passing a negative value in `needed` to the `XkbResizeKeyActions()`
    function can create a `newActs` array of an unespected size.
    Check the value and return if it is invalid.
    
    This error has been found by a static analysis tool. This is the report:
    
        Error: OVERRUN (CWE-119):
        libX11-1.8.7/src/xkb/XKBMAlloc.c:811: cond_const:
          Checking "xkb->server->size_acts == 0" implies that
          "xkb->server->size_acts" is 0 on the true branch.
        libX11-1.8.7/src/xkb/XKBMAlloc.c:811: buffer_alloc:
          "calloc" allocates 8 bytes dictated by parameters
          "(size_t)((xkb->server->size_acts == 0) ? 1 : xkb->server->size_acts)"
          and "8UL".
        libX11-1.8.7/src/xkb/XKBMAlloc.c:811: var_assign:
          Assigning: "newActs" = "calloc((size_t)((xkb->server->size_acts == 0) ? 1 : xkb->server->size_acts), 8UL)".
        libX11-1.8.7/src/xkb/XKBMAlloc.c:815: assignment:
          Assigning: "nActs" = "1".
        libX11-1.8.7/src/xkb/XKBMAlloc.c:829: cond_at_least:
          Checking "nCopy > 0" implies that "nCopy" is at least 1 on the
          true branch.
        libX11-1.8.7/src/xkb/XKBMAlloc.c:830: overrun-buffer-arg:
          Overrunning buffer pointed to by "&newActs[nActs]" of 8 bytes by
          passing it to a function which accesses it at byte offset 15
          using argument "nCopy * 8UL" (which evaluates to 8).
        #  828|
        #  829|           if (nCopy > 0)
        #  830|->             memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i),
        #  831|                      nCopy * sizeof(XkbAction));
        #  832|           if (nCopy < nKeyActs)
    
    (cherry picked from xorg/lib/libx11 at af1312d2873d2ce49b18708a5029895aed477392)
    
    Signed-off-by: José Expósito <jexposit at redhat.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 6d3383418672dd87e6cd73931268fcbacdaae9c8)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/xkb/XKBMAlloc.c b/xkb/XKBMAlloc.c
index 4d24a01c4..78e597f3d 100644
--- a/xkb/XKBMAlloc.c
+++ b/xkb/XKBMAlloc.c
@@ -733,7 +733,7 @@ XkbResizeKeyActions(XkbDescPtr xkb, int key, int needed)
     register int i, nActs;
     XkbAction *newActs;
 
-    if (needed == 0) {
+    if (needed <= 0) {
         xkb->server->key_acts[key] = 0;
         return NULL;
     }
commit 852595a51d63bfeb9a4457761f45bde3316d382a
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Feb 22 10:02:20 2025 -0800

    xkb: ensure XkbAllocNames sets num_rg to 0 on allocation failure
    
    If there was a previous radio_groups array which we failed to realloc
    and freed instead, clear the array size in the XkbNamesRec.
    
    Taken from xorg/lib/libx11 at 258a8ced681dc1bc50396be7439fce23f9807e2a
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 09c6f09eb77a306f44490a9af0751e77cc9d1530)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/xkb/XKBAlloc.c b/xkb/XKBAlloc.c
index 18557b804..dced42eeb 100644
--- a/xkb/XKBAlloc.c
+++ b/xkb/XKBAlloc.c
@@ -194,8 +194,10 @@ XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases)
                 free(prev_radio_groups);
             }
         }
-        if (names->radio_groups == NULL)
+        if (names->radio_groups == NULL) {
+            names->num_rg = 0;
             return BadAlloc;
+        }
         names->num_rg = nTotalRG;
     }
     return Success;
commit 15075baac20de55422bd188b32dd73f086a5d0e6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 10 10:49:24 2025 +1000

    mi: guard miPointer functions against NULL dereferences
    
    Already in place for some functions, let's add it to most others.
    The only function missing is miPointerSetPosition() which needs to
    return the ScreenPtr and that one is unclear if we don't have a screen -
    returning NULL will crash the caller(s) so let's wait for something to
    trigger this bug before we try to fix it wrongly.
    
    Related to #1782
    
    (cherry picked from commit 68c17477d29937e081c482a343a942d5bd41c4ee)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index a90bc94a6..b08de625d 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -200,6 +200,8 @@ miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
         return FALSE;
 
     pPointer = MIPOINTER(pDev);
+    if (!pPointer)
+        return FALSE;
 
     pPointer->pCursor = pCursor;
     pPointer->pScreen = pScreen;
@@ -222,6 +224,8 @@ miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox)
     miPointerPtr pPointer;
 
     pPointer = MIPOINTER(pDev);
+    if (!pPointer)
+        return;
 
     pPointer->limits = *pBox;
     pPointer->confined = PointerConfinedToScreen(pDev);
@@ -273,6 +277,9 @@ miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
     SetupScreen(pScreen);
     miPointerPtr pPointer = MIPOINTER(pDev);
 
+    if (!pPointer)
+        return TRUE;
+
     pPointer->generateEvent = generateEvent;
 
     if (pScreen->ConstrainCursorHarder)
@@ -379,6 +386,8 @@ miPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     BOOL changedScreen = FALSE;
 
     pPointer = MIPOINTER(pDev);
+    if (!pPointer)
+        return;
 
     if (pPointer->pScreen != pScreen) {
         mieqSwitchScreen(pDev, pScreen, TRUE);
@@ -504,6 +513,9 @@ miPointerInvalidateSprite(DeviceIntPtr pDev)
     miPointerPtr pPointer;
 
     pPointer = MIPOINTER(pDev);
+    if (!pPointer)
+        return;
+
     pPointer->pSpriteCursor = (CursorPtr) 1;
 }
 
@@ -522,6 +534,8 @@ miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
     miPointerPtr pPointer;
 
     pPointer = MIPOINTER(pDev);
+    if (!pPointer)
+        return;
 
     pScreen = screenInfo.screens[screen_no];
     mieqSwitchScreen(pDev, pScreen, FALSE);
@@ -566,6 +580,8 @@ miPointerMoveNoEvent(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     SetupScreen(pScreen);
 
     pPointer = MIPOINTER(pDev);
+    if (!pPointer)
+        return;
 
     /* Hack: We mustn't call into ->MoveCursor for anything but the
      * VCP, as this may cause a non-HW rendered cursor to be rendered while
commit 6d33c347ea21c5bae36ceda87a5662925edda1ed
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 7 18:14:55 2025 +1000

    mi: don't crash on miPointerGetPosition for disabled devices
    
    If a device is disabled, its master device is forcibly reset to NULL but
    unlike a floating device it doesn't have a sprite allocated. Calling
    miPointerGetPosition for a disabled device thus crashes.
    
    Avoid this by returning 0/0 for any device without a miPointer.
    This is a quick fix only, a proper fix for this issue is rather more
    involved.
    
    Closes #1782
    
    (cherry picked from commit acbdd0ecddc18d9fa7fc1634d4daf868ee0cd755)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1895>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index 652726f3b..a90bc94a6 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -718,8 +718,15 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
 void
 miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
 {
-    *x = MIPOINTER(pDev)->x;
-    *y = MIPOINTER(pDev)->y;
+    miPointerPtr pPointer = MIPOINTER(pDev);
+    if (pPointer) {
+        *x = pPointer->x;
+        *y = pPointer->y;
+    }
+    else {
+        *x = 0;
+        *y = 0;
+    }
 }
 
 /**


More information about the xorg-commit mailing list