xserver: Branch 'xwayland-24.1' - 21 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Feb 5 09:47:59 UTC 2025


 Xi/xichangehierarchy.c            |    2 +
 dix/enterleave.c                  |    2 -
 dix/eventconvert.c                |    4 +-
 glamor/glamor_egl.c               |   57 ++++++++++++++++-------------
 glamor/glamor_glx_provider.c      |   21 +++++++++-
 hw/xwayland/xwayland-cursor.c     |   34 +++++------------
 hw/xwayland/xwayland-glamor-gbm.c |   19 +++++++--
 hw/xwayland/xwayland-glamor.c     |    5 ++
 hw/xwayland/xwayland-input.c      |   20 ++++++++--
 hw/xwayland/xwayland-output.c     |    3 +
 hw/xwayland/xwayland-present.c    |    2 -
 hw/xwayland/xwayland-xtest.c      |    3 +
 include/inputstr.h                |    2 +
 include/meson.build               |    2 +
 os/WaitFor.c                      |    6 +--
 os/connection.c                   |    2 -
 render/picture.c                  |    3 +
 xkb/XKBMAlloc.c                   |   74 +++-----------------------------------
 xkb/xkbActions.c                  |    9 +++-
 xkb/xkbPrKeyEv.c                  |    2 -
 xkb/xkbUtils.c                    |   51 +++++++++++++++++++-------
 21 files changed, 168 insertions(+), 155 deletions(-)

New commits:
commit f18a83d6f198b027a1c1dd3d9d7ba2114896e31a
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Feb 4 11:35:36 2025 +0100

    xwayland/glamor: Disable GLAMOR after GBM cleanup
    
    The cleanup function for GBM is called on the various error paths.
    
    Once xwl_glamor_gbm_cleanup() has been called, GBM support is no longer
    usable (and the corresponding data structures are freed), so there is
    no way we can keep using GLAMOR after that point.
    
    Make sure to explicitly disable GLAMOR support in that case, so we do
    not crash later on trying to use GBM.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit e8784b7d897aa22ed93f63a57dea04bdfa784388)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index ce80284e0..05668b8e9 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -634,6 +634,10 @@ xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
     if (!xwl_gbm)
         return;
 
+    /* Cannot use GBM after clean-up, disable GLAMOR support from now on */
+    ErrorF("XWAYLAND: Disabling GLAMOR support\n");
+    xwl_screen->glamor = XWL_GLAMOR_NONE;
+
     if (xwl_gbm->device_name)
         free(xwl_gbm->device_name);
     drmFreeDevice(&xwl_gbm->device);
commit f7e3397e4db80f3e790a750d2c09b5ef5fc32fb8
Author: Michel Dänzer <michel at daenzer.net>
Date:   Tue Feb 4 11:09:29 2025 +0100

    xwayland/glamor: Clean-up GBM's screen private on failure
    
    If we bail out initializing GBM glamor backend, the screen private for
    the GBM backend may remain, pointing at freed memory.
    
    To avoid that issue, make sure to clear up the screen's private for the
    GBM backend.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1785
    Signed-off-by: Michel Dänzer <michel at daenzer.net>
    (cherry picked from commit b27b5cd5f3c2f6e17e0c68f783dca7273b7d2d84)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 21c0dd594..ce80284e0 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -631,6 +631,9 @@ xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
 {
     struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
 
+    if (!xwl_gbm)
+        return;
+
     if (xwl_gbm->device_name)
         free(xwl_gbm->device_name);
     drmFreeDevice(&xwl_gbm->device);
@@ -643,6 +646,8 @@ xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
     if (xwl_screen->explicit_sync)
         wp_linux_drm_syncobj_manager_v1_destroy(xwl_screen->explicit_sync);
 
+    dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
+                  NULL);
     free(xwl_gbm);
 }
 
commit cea92a3e0900eb611b2e683edf11272d4e306a77
Author: Julian Orth <ju.orth at gmail.com>
Date:   Sat Jan 11 17:50:12 2025 +0100

    xwayland: Don't run key behaviors and actions
    
    Consider the following keymap:
    
    ```xkb
    xkb_keymap {
        xkb_keycodes {
            <compose> = 135;
        };
        xkb_symbols {
            key <compose> {
                [ SetGroup(group = +1) ]
            };
        };
    };
    ```
    
    When the user presses the compose key, the following happens:
    
    1. The compositor forwards the key to Xwayland.
    2. Xwayland executes the SetGroup action and sets the base_group to 1
       and the effective group to 1.
    3. The compositor updates its own state and sends the effective group,
       1, to Xwayland.
    4. Xwayland sets the locked group to 1 and the effective group to
       1 + 1 = 2.
    
    This is wrong since pressing compose should set the effective group to 1
    but to X applications the effective group appears to be 2.
    
    This commit makes it so that Xwayland completely ignores the key
    behaviors and actions of the keymap and only updates the modifier and
    group components in response to the wayland modifiers events.
    
    Signed-off-by: Julian Orth <ju.orth at gmail.com>
    (cherry picked from commit 45c1d22ff6fe484b0088128a997e33b81bc8282d)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 53cc5144b..41434a89a 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1284,11 +1284,12 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
         old_state = dev->key->xkbInfo->state;
         new_state = &dev->key->xkbInfo->state;
 
+        new_state->base_group = 0;
+        new_state->latched_group = 0;
         new_state->locked_group = group & XkbAllGroupsMask;
         new_state->base_mods = mods_depressed & XkbAllModifiersMask;
+        new_state->latched_mods = mods_latched & XkbAllModifiersMask;
         new_state->locked_mods = mods_locked & XkbAllModifiersMask;
-        XkbLatchModifiers(dev, XkbAllModifiersMask,
-                          mods_latched & XkbAllModifiersMask);
 
         XkbComputeDerivedState(dev->key->xkbInfo);
 
@@ -1676,6 +1677,7 @@ add_device(struct xwl_seat *xwl_seat,
     dev->public.devicePrivate = xwl_seat;
     dev->type = SLAVE;
     dev->spriteInfo->spriteOwner = FALSE;
+    dev->ignoreXkbActionsBehaviors = TRUE;
 
     return dev;
 }
@@ -3597,6 +3599,7 @@ InitInput(int argc, char *argv[])
 
     mieqInit();
 
+    inputInfo.keyboard->ignoreXkbActionsBehaviors = TRUE;
     xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
     wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
                              xwl_screen);
diff --git a/include/inputstr.h b/include/inputstr.h
index 24dd48841..269399e1d 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -631,6 +631,8 @@ typedef struct _DeviceIntRec {
     DeviceSendEventsProc sendEventsProc;
 
     struct _SyncCounter *idle_counter;
+
+    Bool ignoreXkbActionsBehaviors; /* TRUE if keys don't trigger behaviors and actions */
 } DeviceIntRec;
 
 typedef struct {
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 5e9a6b6d6..8dd9d7da0 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1368,9 +1368,12 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
                   (event->type == ET_ButtonPress));
 
     if (pressEvent) {
-        if (keyEvent)
-            act = XkbGetKeyAction(xkbi, &xkbi->state, key);
-        else {
+        if (keyEvent) {
+            if (kbd->ignoreXkbActionsBehaviors)
+                act.type = XkbSA_NoAction;
+            else
+                act = XkbGetKeyAction(xkbi, &xkbi->state, key);
+        } else {
             act = XkbGetButtonAction(kbd, dev, key);
             key |= BTN_ACT_FLAG;
         }
diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index d2c7e33f4..53a31b727 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -68,7 +68,7 @@ XkbProcessKeyboardEvent(DeviceEvent *event, DeviceIntPtr keybd)
     /* do anything to implement the behavior, but it *does* report that */
     /* key is hardwired */
 
-    if (!(behavior.type & XkbKB_Permanent)) {
+    if (!keybd->ignoreXkbActionsBehaviors && !(behavior.type & XkbKB_Permanent)) {
         switch (behavior.type) {
         case XkbKB_Default:
             /* Neither of these should happen in practice, but ignore them
commit 1a8f0cb007dcd7b04f6687b916de9de198c7484b
Author: Julian Orth <ju.orth at gmail.com>
Date:   Sat Jan 11 20:03:27 2025 +0100

    xwayland: copy repeat settings from the compositor map
    
    Previously the repeat settings sent by the compositor were completely
    ignored.
    
    Signed-off-by: Julian Orth <ju.orth at gmail.com>
    (cherry picked from commit 8d9184db5f7b47315b6ed091e193bdf416aacf5c)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 5e4b78469..53cc5144b 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1183,9 +1183,20 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
 
     XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes);
 
-    if (xwl_seat->keyboard->key)
+    memcpy(
+        xwl_seat->keyboard->kbdfeed->ctrl.autoRepeats,
+        xkb->ctrls->per_key_repeat,
+        XkbPerKeyBitArraySize
+    );
+    if (xwl_seat->keyboard->key) {
         /* Keep the current controls */
         XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc);
+        memcpy(
+            xkb->ctrls->per_key_repeat,
+            xwl_seat->keyboard->kbdfeed->ctrl.autoRepeats,
+            XkbPerKeyBitArraySize
+        );
+    }
 
     XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb);
 
commit e6a5d545cea8950ff4f586abd2311b92016011f2
Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date:   Thu Jan 16 10:08:15 2025 +0100

    glamor: reject configs using unsupported rgbBits size
    
    The supported color depths is a hardcoded list for now, so we
    need to honor the value exposed there otherwise we'll get
    inconsistencies between what glXGetFBConfigs and XListDepths
    report to applications.
    
    Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
    (cherry picked from commit 5397854877c1b17f21c16e43365e1c2e353dc8ba)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/glamor/glamor_glx_provider.c b/glamor/glamor_glx_provider.c
index 77ccc3c8b..c27141c7c 100644
--- a/glamor/glamor_glx_provider.c
+++ b/glamor/glamor_glx_provider.c
@@ -140,12 +140,14 @@ egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
  * - drawable type masks is suspicious
  */
 static struct egl_config *
-translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
+translate_eglconfig(ScreenPtr pScreen, struct egl_screen *screen, EGLConfig hc,
                     struct egl_config *chain, Bool direct_color,
                     Bool double_buffer, Bool duplicate_for_composite,
                     Bool srgb_only)
 {
     EGLint value;
+    bool valid_depth;
+    int i;
     struct egl_config *c = calloc(1, sizeof *c);
 
     if (!c)
@@ -218,6 +220,19 @@ translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
     }
 #undef GET
 
+    /* Only expose this config if rgbBits matches a supported
+     * depth value.
+     */
+    valid_depth = false;
+    for (i = 0; i < pScreen->numDepths && !valid_depth; i++) {
+        if (pScreen->allowedDepths[i].depth == c->base.rgbBits)
+            valid_depth = true;
+    }
+    if (!valid_depth) {
+        free(c);
+        return chain;
+    }
+
     /* derived state: config caveats */
     eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value);
     if (value == EGL_NONE)
@@ -340,13 +355,13 @@ egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
         for (j = 0; j < 3; j++) /* direct_color */
             for (k = 0; k < 2; k++) /* double_buffer */ {
                 if (can_srgb)
-                    c = translate_eglconfig(screen, host_configs[i], c,
+                    c = translate_eglconfig(pScreen, screen, host_configs[i], c,
                                             /* direct_color */ j == 1,
                                             /* double_buffer */ k > 0,
                                             /* duplicate_for_composite */ j == 0,
                                             /* srgb_only */ true);
 
-                c = translate_eglconfig(screen, host_configs[i], c,
+                c = translate_eglconfig(pScreen, screen, host_configs[i], c,
                                         /* direct_color */ j == 1,
                                         /* double_buffer */ k > 0,
                                         /* duplicate_for_composite */ j == 0,
commit e1b6193a9d42b36e2a5c0197196e5b6b2ca01d7a
Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date:   Wed Jan 15 18:34:27 2025 +0100

    glamor: use gbm_format_for_depth instead of open-coding it
    
    This way glamor_back_pixmap_from_fd deals with the same depth
    values as glamor_pixmap_from_fds.
    
    Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
    (cherry picked from commit 83b13387ab8b28cbdfeb44f05e019a656214d722)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index eea55de43..136033a9a 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -561,17 +561,14 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
-    if (bpp != 32 || !(depth == 24 || depth == 32 || depth == 30) || width == 0 || height == 0)
+    if (!gbm_format_for_depth(depth, &import_data.format) ||
+        width == 0 || height == 0)
         return FALSE;
 
     import_data.fd = fd;
     import_data.width = width;
     import_data.height = height;
     import_data.stride = stride;
-    if (depth == 30)
-        import_data.format = GBM_FORMAT_ARGB2101010;
-    else
-        import_data.format = GBM_FORMAT_ARGB8888;
     bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data, 0);
     if (!bo)
         return FALSE;
commit f8e32cba6ec1eaeade05dc0f8f2a3af1e6776336
Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date:   Wed Jan 15 18:32:46 2025 +0100

    glamor: return the result of gbm_format_for_depth
    
    This way the caller knows if the conversion failed.
    While at it, check for width/height at the same time.
    
    Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
    (cherry picked from commit 87afcc7699f1d143ca91b6ed9bdbfafbbe0d77f7)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 86455c407..eea55de43 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -520,6 +520,31 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
     return fd;
 }
 
+static bool
+gbm_format_for_depth(CARD8 depth, uint32_t *format)
+{
+    switch (depth) {
+    case 15:
+        *format = GBM_FORMAT_ARGB1555;
+        return true;
+    case 16:
+        *format = GBM_FORMAT_RGB565;
+        return true;
+    case 24:
+        *format = GBM_FORMAT_XRGB8888;
+        return true;
+    case 30:
+        *format = GBM_FORMAT_ARGB2101010;
+        return true;
+    case 32:
+        *format = GBM_FORMAT_ARGB8888;
+        return true;
+    default:
+        ErrorF("unexpected depth: %d\n", depth);
+        return false;
+    }
+}
+
 Bool
 glamor_back_pixmap_from_fd(PixmapPtr pixmap,
                            int fd,
@@ -558,25 +583,6 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
     return ret;
 }
 
-static uint32_t
-gbm_format_for_depth(CARD8 depth)
-{
-    switch (depth) {
-    case 15:
-        return GBM_FORMAT_ARGB1555;
-    case 16:
-        return GBM_FORMAT_RGB565;
-    case 24:
-        return GBM_FORMAT_XRGB8888;
-    case 30:
-        return GBM_FORMAT_ARGB2101010;
-    default:
-        ErrorF("unexpected depth: %d\n", depth);
-    case 32:
-        return GBM_FORMAT_ARGB8888;
-    }
-}
-
 PixmapPtr
 glamor_pixmap_from_fds(ScreenPtr screen,
                        CARD8 num_fds, const int *fds,
@@ -599,6 +605,10 @@ glamor_pixmap_from_fds(ScreenPtr screen,
         struct gbm_import_fd_modifier_data import_data = { 0 };
         struct gbm_bo *bo;
 
+        if (!gbm_format_for_depth(depth, &import_data.format) ||
+            width == 0 || height == 0)
+            goto error;
+
         import_data.width = width;
         import_data.height = height;
         import_data.num_fds = num_fds;
@@ -608,7 +618,6 @@ glamor_pixmap_from_fds(ScreenPtr screen,
             import_data.strides[i] = strides[i];
             import_data.offsets[i] = offsets[i];
         }
-        import_data.format = gbm_format_for_depth(depth);
         bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data, 0);
         if (bo) {
             screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
@@ -624,6 +633,7 @@ glamor_pixmap_from_fds(ScreenPtr screen,
         }
     }
 
+error:
     if (ret == FALSE) {
         screen->DestroyPixmap(pixmap);
         return NULL;
commit 1ae92b8f63480c2048322d503204123a4afac725
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Jan 15 09:40:34 2025 +0100

    os/connection: Make sure partial is initialized
    
    Following the change in Xtrans 1.5 that allows for partial connections
    to succeed, we need to make sure partial is properly initialized at
    first, otherwise we rely on an uninitialized variable.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Suggested-by: Twaik Yont <twaikyont at gmail.com>
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1783
    (cherry picked from commit 080fb49eff4de7ec3a29214994d1403e4d877f6a)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/os/connection.c b/os/connection.c
index 05a5d4b79..3223eeb5d 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -242,7 +242,7 @@ void
 CreateWellKnownSockets(void)
 {
     int i;
-    int partial;
+    int partial = 0;
 
     /* display is initialized to "0" by main(). It is then set to the display
      * number if specified on the command line. */
commit ffd4d2a268913718e35d4dcbbcaaca1136ed75c2
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Jan 10 15:02:54 2025 +0100

    xkb: Always use MAP_LENGTH keymap size
    
    Generating the modifier modmap, the helper function generate_modkeymap()
    would check the entire range up to the MAP_LENGTH.
    
    However, the given keymap might have less keycodes than MAP_LENGTH, in
    which case we would go beyond the size of the modmap, as reported by
    ASAN:
    
    ==ERROR: AddressSanitizer: heap-buffer-overflow
    READ of size 1 at 0x5110001c225b thread T0
        #0 0x5e7369393873 in generate_modkeymap ../dix/inpututils.c:309
        #1 0x5e736930dcce in ProcGetModifierMapping ../dix/devices.c:1794
        #2 0x5e7369336489 in Dispatch ../dix/dispatch.c:550
        #3 0x5e736934407d in dix_main ../dix/main.c:275
        #5 0x7e46d47b2ecb in __libc_start_main
        #6 0x5e73691be324 in _start (xserver/build/hw/xwayland/Xwayland)
    
    Address is located 0 bytes after 219-byte region
    allocated by thread T0 here:
        #0 0x7e46d4cfc542 in realloc
        #1 0x5e73695aa90e in _XkbCopyClientMap ../xkb/xkbUtils.c:1142
        #2 0x5e73695aa90e in XkbCopyKeymap ../xkb/xkbUtils.c:1966
        #3 0x5e73695b1b2f in XkbDeviceApplyKeymap ../xkb/xkbUtils.c:2023
        #4 0x5e73691c6c18 in keyboard_handle_keymap ../hw/xwayland/xwayland-input.c:1194
    
    As MAP_LENGTH is used in various code paths where the max keycode might
    not be easily available, best is to always use MAP_LENGTH to allocate the
    keymaps so that the code never run past the buffer size.
    
    If the max key code is smaller than the MAP_LENGTH limit, fill-in the gap
    with zeros.
    
    That also simplifies the code slightly as we do not constantly need to
    reallocate the keymap to adjust to the max key code size.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1780
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 92bcebfd7e248f695503c0a6e7bee80be4c96834)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/xkb/XKBMAlloc.c b/xkb/XKBMAlloc.c
index fa4c86d44..4d24a01c4 100644
--- a/xkb/XKBMAlloc.c
+++ b/xkb/XKBMAlloc.c
@@ -41,7 +41,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 Status
 XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes)
 {
-    register int i;
     XkbClientMapPtr map;
 
     if ((xkb == NULL) ||
@@ -103,8 +102,7 @@ XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes)
             map->syms[0] = NoSymbol;
         }
         if (map->key_sym_map == NULL) {
-            i = xkb->max_key_code + 1;
-            map->key_sym_map = calloc(i, sizeof(XkbSymMapRec));
+            map->key_sym_map = calloc(MAP_LENGTH, sizeof(XkbSymMapRec));
             if (map->key_sym_map == NULL)
                 return BadAlloc;
         }
@@ -115,8 +113,7 @@ XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes)
             (xkb->max_key_code < xkb->min_key_code))
             return BadMatch;
         if (map->modmap == NULL) {
-            i = xkb->max_key_code + 1;
-            map->modmap = calloc(i, sizeof(unsigned char));
+            map->modmap = calloc(MAP_LENGTH, sizeof(unsigned char));
             if (map->modmap == NULL)
                 return BadAlloc;
         }
@@ -149,8 +146,7 @@ XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions)
             (xkb->max_key_code < xkb->min_key_code))
             return BadMatch;
         if (map->explicit == NULL) {
-            i = xkb->max_key_code + 1;
-            map->explicit = calloc(i, sizeof(unsigned char));
+            map->explicit = calloc(MAP_LENGTH, sizeof(unsigned char));
             if (map->explicit == NULL)
                 return BadAlloc;
         }
@@ -185,8 +181,7 @@ XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions)
                    ((map->size_acts - map->num_acts) * sizeof(XkbAction)));
         }
         if (map->key_acts == NULL) {
-            i = xkb->max_key_code + 1;
-            map->key_acts = calloc(i, sizeof(unsigned short));
+            map->key_acts = calloc(MAP_LENGTH, sizeof(unsigned short));
             if (map->key_acts == NULL)
                 return BadAlloc;
         }
@@ -197,8 +192,7 @@ XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions)
             (xkb->max_key_code < xkb->min_key_code))
             return BadMatch;
         if (map->behaviors == NULL) {
-            i = xkb->max_key_code + 1;
-            map->behaviors = calloc(i, sizeof(XkbBehavior));
+            map->behaviors = calloc(MAP_LENGTH, sizeof(XkbBehavior));
             if (map->behaviors == NULL)
                 return BadAlloc;
         }
@@ -209,8 +203,7 @@ XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions)
             (xkb->max_key_code < xkb->min_key_code))
             return BadMatch;
         if (map->vmodmap == NULL) {
-            i = xkb->max_key_code + 1;
-            map->vmodmap = calloc(i, sizeof(unsigned short));
+            map->vmodmap = calloc(MAP_LENGTH, sizeof(unsigned short));
             if (map->vmodmap == NULL)
                 return BadAlloc;
         }
@@ -651,18 +644,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
     if (maxKC > xkb->max_key_code) {
         if (changes)
             changes->map.max_key_code = maxKC;
-        tmp = maxKC - xkb->max_key_code;
+        tmp = MAP_LENGTH - xkb->max_key_code;
         if (xkb->map) {
             if (xkb->map->key_sym_map) {
-                XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
-
-                xkb->map->key_sym_map = reallocarray(xkb->map->key_sym_map,
-                                                     maxKC + 1,
-                                                     sizeof(XkbSymMapRec));
-                if (!xkb->map->key_sym_map) {
-                    free(prev_key_sym_map);
-                    return BadAlloc;
-                }
                 memset((char *) &xkb->map->key_sym_map[xkb->max_key_code], 0,
                        tmp * sizeof(XkbSymMapRec));
                 if (changes) {
@@ -675,15 +659,6 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
                 }
             }
             if (xkb->map->modmap) {
-                unsigned char *prev_modmap = xkb->map->modmap;
-
-                xkb->map->modmap = reallocarray(xkb->map->modmap,
-                                                maxKC + 1,
-                                                sizeof(unsigned char));
-                if (!xkb->map->modmap) {
-                    free(prev_modmap);
-                    return BadAlloc;
-                }
                 memset((char *) &xkb->map->modmap[xkb->max_key_code], 0, tmp);
                 if (changes) {
                     changes->map.changed = _ExtendRange(changes->map.changed,
@@ -698,15 +673,6 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
         }
         if (xkb->server) {
             if (xkb->server->behaviors) {
-                XkbBehavior *prev_behaviors = xkb->server->behaviors;
-
-                xkb->server->behaviors = reallocarray(xkb->server->behaviors,
-                                                      maxKC + 1,
-                                                      sizeof(XkbBehavior));
-                if (!xkb->server->behaviors) {
-                    free(prev_behaviors);
-                    return BadAlloc;
-                }
                 memset((char *) &xkb->server->behaviors[xkb->max_key_code], 0,
                        tmp * sizeof(XkbBehavior));
                 if (changes) {
@@ -720,15 +686,6 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
                 }
             }
             if (xkb->server->key_acts) {
-                unsigned short *prev_key_acts = xkb->server->key_acts;
-
-                xkb->server->key_acts = reallocarray(xkb->server->key_acts,
-                                                     maxKC + 1,
-                                                     sizeof(unsigned short));
-                if (!xkb->server->key_acts) {
-                    free(prev_key_acts);
-                    return BadAlloc;
-                }
                 memset((char *) &xkb->server->key_acts[xkb->max_key_code], 0,
                        tmp * sizeof(unsigned short));
                 if (changes) {
@@ -742,15 +699,6 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
                 }
             }
             if (xkb->server->vmodmap) {
-                unsigned short *prev_vmodmap = xkb->server->vmodmap;
-
-                xkb->server->vmodmap = reallocarray(xkb->server->vmodmap,
-                                                    maxKC + 1,
-                                                    sizeof(unsigned short));
-                if (!xkb->server->vmodmap) {
-                    free(prev_vmodmap);
-                    return BadAlloc;
-                }
                 memset((char *) &xkb->server->vmodmap[xkb->max_key_code], 0,
                        tmp * sizeof(unsigned short));
                 if (changes) {
@@ -765,14 +713,6 @@ XkbChangeKeycodeRange(XkbDescPtr xkb,
             }
         }
         if ((xkb->names) && (xkb->names->keys)) {
-            XkbKeyNameRec *prev_keys = xkb->names->keys;
-
-            xkb->names->keys = reallocarray(xkb->names->keys,
-                                            maxKC + 1, sizeof(XkbKeyNameRec));
-            if (!xkb->names->keys) {
-                free(prev_keys);
-                return BadAlloc;
-            }
             memset((char *) &xkb->names->keys[xkb->max_key_code], 0,
                    tmp * sizeof(XkbKeyNameRec));
             if (changes) {
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 9ad66927c..ac742b9da 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -930,6 +930,7 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
 {
     void *tmp = NULL;
     int i;
+    int gap;
     XkbKeyTypePtr stype = NULL, dtype = NULL;
 
     /* client map */
@@ -959,15 +960,20 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
         }
         dst->map->num_syms = src->map->num_syms;
         dst->map->size_syms = src->map->size_syms;
+        gap = MAP_LENGTH - (src->max_key_code + 1);
 
         if (src->map->key_sym_map) {
-            if (src->max_key_code != dst->max_key_code) {
+            if (!dst->map->key_sym_map) {
                 tmp = reallocarray(dst->map->key_sym_map,
-                                   src->max_key_code + 1, sizeof(XkbSymMapRec));
+                                   MAP_LENGTH, sizeof(XkbSymMapRec));
                 if (!tmp)
                     return FALSE;
                 dst->map->key_sym_map = tmp;
             }
+            if (gap > 0) {
+                memset((char *) &dst->map->key_sym_map[gap], 0,
+                       gap * sizeof(XkbSymMapRec));
+            }
             memcpy(dst->map->key_sym_map, src->map->key_sym_map,
                    (src->max_key_code + 1) * sizeof(XkbSymMapRec));
         }
@@ -1138,12 +1144,15 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst)
         }
 
         if (src->map->modmap) {
-            if (src->max_key_code != dst->max_key_code) {
-                tmp = realloc(dst->map->modmap, src->max_key_code + 1);
+            if (!dst->map->modmap) {
+                tmp = realloc(dst->map->modmap, MAP_LENGTH);
                 if (!tmp)
                     return FALSE;
                 dst->map->modmap = tmp;
             }
+            if (gap > 0) {
+                memset(dst->map->modmap + gap, 0, gap);
+            }
             memcpy(dst->map->modmap, src->map->modmap, src->max_key_code + 1);
         }
         else {
@@ -1163,6 +1172,7 @@ static Bool
 _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
 {
     void *tmp = NULL;
+    int gap;
 
     /* server map */
     if (src->server) {
@@ -1173,13 +1183,16 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
             dst->server = tmp;
         }
 
+        gap = MAP_LENGTH - (src->max_key_code + 1);
         if (src->server->explicit) {
-            if (src->max_key_code != dst->max_key_code) {
-                tmp = realloc(dst->server->explicit, src->max_key_code + 1);
+            if (!dst->server->explicit) {
+                tmp = realloc(dst->server->explicit, MAP_LENGTH);
                 if (!tmp)
                     return FALSE;
                 dst->server->explicit = tmp;
             }
+            if (gap > 0)
+                memset(dst->server->explicit + gap, 0, gap);
             memcpy(dst->server->explicit, src->server->explicit,
                    src->max_key_code + 1);
         }
@@ -1207,13 +1220,15 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
         dst->server->num_acts = src->server->num_acts;
 
         if (src->server->key_acts) {
-            if (src->max_key_code != dst->max_key_code) {
+            if (!dst->server->key_acts) {
                 tmp = reallocarray(dst->server->key_acts,
-                                   src->max_key_code + 1, sizeof(unsigned short));
+                                   MAP_LENGTH, sizeof(unsigned short));
                 if (!tmp)
                     return FALSE;
                 dst->server->key_acts = tmp;
             }
+            if (gap > 0)
+                memset((char *) &dst->server->key_acts[gap], 0, gap * sizeof(unsigned short));
             memcpy(dst->server->key_acts, src->server->key_acts,
                    (src->max_key_code + 1) * sizeof(unsigned short));
         }
@@ -1223,13 +1238,15 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
         }
 
         if (src->server->behaviors) {
-            if (src->max_key_code != dst->max_key_code) {
+            if (!dst->server->behaviors) {
                 tmp = reallocarray(dst->server->behaviors,
-                                   src->max_key_code + 1, sizeof(XkbBehavior));
+                                   MAP_LENGTH, sizeof(XkbBehavior));
                 if (!tmp)
                     return FALSE;
                 dst->server->behaviors = tmp;
             }
+            if (gap > 0)
+                memset((char *) &dst->server->behaviors[gap], 0, gap * sizeof(XkbBehavior));
             memcpy(dst->server->behaviors, src->server->behaviors,
                    (src->max_key_code + 1) * sizeof(XkbBehavior));
         }
@@ -1241,13 +1258,15 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst)
         memcpy(dst->server->vmods, src->server->vmods, XkbNumVirtualMods);
 
         if (src->server->vmodmap) {
-            if (src->max_key_code != dst->max_key_code) {
+            if (!dst->server->vmodmap) {
                 tmp = reallocarray(dst->server->vmodmap,
-                                   src->max_key_code + 1, sizeof(unsigned short));
+                                   MAP_LENGTH, sizeof(unsigned short));
                 if (!tmp)
                     return FALSE;
                 dst->server->vmodmap = tmp;
             }
+            if (gap > 0)
+                memset((char *) &dst->server->vmodmap[gap], 0, gap * sizeof(unsigned short));
             memcpy(dst->server->vmodmap, src->server->vmodmap,
                    (src->max_key_code + 1) * sizeof(unsigned short));
         }
@@ -1268,6 +1287,7 @@ static Bool
 _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
 {
     void *tmp = NULL;
+    int gap;
 
     /* names */
     if (src->names) {
@@ -1277,14 +1297,17 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
                 return FALSE;
         }
 
+        gap = MAP_LENGTH - (src->max_key_code + 1);
         if (src->names->keys) {
-            if (src->max_key_code != dst->max_key_code) {
-                tmp = reallocarray(dst->names->keys, src->max_key_code + 1,
+            if (!dst->names->keys) {
+                tmp = reallocarray(dst->names->keys, MAP_LENGTH,
                                    sizeof(XkbKeyNameRec));
                 if (!tmp)
                     return FALSE;
                 dst->names->keys = tmp;
             }
+            if (gap > 0)
+                memset((char *) &dst->names->keys[gap], 0, gap * sizeof(XkbKeyNameRec));
             memcpy(dst->names->keys, src->names->keys,
                    (src->max_key_code + 1) * sizeof(XkbKeyNameRec));
         }
commit efd3e1ca3d6efad4d0677bb99704a4341f3f52f5
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Dec 18 16:21:44 2024 +0100

    xwayland: Do not keep the cursor's pixmap around
    
    Currently, Xwayland creates a pixmap backed by shared memory buffer as
    soon as an X11 cursor is realized, which is destroyed when the cursor is
    eventually unrealized.
    
    If an X11 client is leaking cursors, Xwayland will be creating new
    pixmaps continuously, which will eventually cause an error once the
    limit is reached, and get Xwayland killed.
    
    However, we do not need the shared memory buffer to stay around, we
    already have the buffer retention mechanism which will take care of
    keeping the buffer around until the Wayland compositor is done with it,
    so we could just create and destroy the pixmap as needed when setting
    the cursor.
    
    That would not fix the leak in the X11 application, yet that would
    mitigate the risk of Xwayland being killed by reaching the shared memory
    limits, until the client itself reaches the limit of X11 resources.
    
    v2: Don't increase the pixmap refcnt to destroy it just after (Michel)
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Suggested-by: Michel Dänzer <michel at daenzer.net>
    See-also: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1773
    (cherry picked from commit 8707d2835c21866ca1541bed0670352604147722)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 9ee427063..fa77f6daa 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -43,8 +43,6 @@
 
 #define DELAYED_X_CURSOR_TIMEOUT 5 /* ms */
 
-static DevPrivateKeyRec xwl_cursor_private_key;
-
 static void
 expand_source_and_mask(CursorPtr cursor, CARD32 *data)
 {
@@ -80,29 +78,15 @@ expand_source_and_mask(CursorPtr cursor, CARD32 *data)
 static Bool
 xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
 {
-    PixmapPtr pixmap;
-
-    pixmap = xwl_shm_create_pixmap(screen, cursor->bits->width,
-                                   cursor->bits->height, 32,
-                                   CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
-    dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, pixmap);
-
     return TRUE;
 }
 
 static Bool
 xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
 {
-    PixmapPtr pixmap;
     struct xwl_screen *xwl_screen;
     struct xwl_seat *xwl_seat;
 
-    pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
-    if (!pixmap)
-        return TRUE;
-
-    dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, NULL);
-
     /* When called from FreeCursor(), device is always NULL */
     xwl_screen = xwl_screen_get(screen);
     xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
@@ -110,7 +94,7 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
             xwl_seat->x_cursor = NULL;
     }
 
-    return xwl_shm_destroy_pixmap(pixmap);
+    return TRUE;
 }
 
 static void
@@ -173,8 +157,9 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
     xwl_cursor->frame_cb = wl_surface_frame(xwl_cursor->surface);
     wl_callback_add_listener(xwl_cursor->frame_cb, &frame_listener, xwl_cursor);
 
-    /* Hold a reference on the pixmap until it's released by the compositor */
-    pixmap->refcnt++;
+    /* The pixmap will be destroyed in xwl_cursor_buffer_release_callback()
+     * once the compositor is done with it.
+     */
     xwl_pixmap_set_buffer_release_cb(pixmap,
                                      xwl_cursor_buffer_release_callback,
                                      pixmap);
@@ -220,7 +205,9 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
     }
 
     cursor = xwl_seat->x_cursor;
-    pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
+    pixmap = xwl_shm_create_pixmap(xwl_screen->screen, cursor->bits->width,
+                                   cursor->bits->height, 32,
+                                   CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
     if (!pixmap)
         return;
 
@@ -263,7 +250,9 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
     }
 
     cursor = xwl_seat->x_cursor;
-    pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
+    pixmap = xwl_shm_create_pixmap(xwl_screen->screen, cursor->bits->width,
+                                   cursor->bits->height, 32,
+                                   CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
     if (!pixmap)
         return;
 
@@ -443,9 +432,6 @@ static miPointerScreenFuncRec xwl_pointer_screen_funcs = {
 Bool
 xwl_screen_init_cursor(struct xwl_screen *xwl_screen)
 {
-    if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR, 0))
-        return FALSE;
-
     return miPointerInitialize(xwl_screen->screen,
                                &xwl_pointer_sprite_funcs,
                                &xwl_pointer_screen_funcs, TRUE);
commit 5294c436ac59a38964faa2cc8c4c501e7770fb08
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Oct 31 18:15:42 2024 +0100

    xwayland: Always decrement expecting_event in xwl_output_create
    
    If we bail without decrementing it, xwl_screen_init will keep waiting
    indefinitely for an event which never arrives.
    
    (cherry picked from commit 8c4b137237498f9f67e0e44e650edcb39851c870)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 794a9aa7a..80ce59ff4 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -907,6 +907,8 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id,
     struct xwl_output *xwl_output;
     char name[MAX_OUTPUT_NAME] = { 0 };
 
+    --xwl_screen->expecting_event;
+
     xwl_output = calloc(1, sizeof *xwl_output);
     if (xwl_output == NULL) {
         ErrorF("%s ENOMEM\n", __func__);
@@ -955,7 +957,6 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id,
      * use it when binding to the xdg-output protocol...
      */
     xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
-    --xwl_screen->expecting_event;
 
     if (xwl_screen->xdg_output_manager)
         xwl_output_get_xdg_output(xwl_output);
commit 15a169cd1a4f74eb690f0057856c1c762c290b12
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Oct 31 18:06:23 2024 +0100

    xwayland/glamor: Drop expecting_event bailing from xwl_drm_handle_device
    
    If we bail without decrementing xwl_screen->expecting_event,
    xwl_screen_init will keep waiting indefinitely for an event which never
    arrives.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1648
    Fixes: 2f113d68f6c1 ("xwayland: Add glamor and DRI3 support")
    (cherry picked from commit 375c35a5e4049603b3e973b2ed6a2b85317df9e7)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 45f18a47c..21c0dd594 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -1318,6 +1318,7 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
 
    if (!xwl_gbm->device_name) {
        xwl_glamor_gbm_cleanup(xwl_screen);
+       xwl_screen->expecting_event--;
        return;
    }
 
@@ -1326,12 +1327,14 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
        ErrorF("wayland-egl: could not open %s (%s)\n",
               xwl_gbm->device_name, strerror(errno));
        xwl_glamor_gbm_cleanup(xwl_screen);
+       xwl_screen->expecting_event--;
        return;
    }
 
    if (drmGetDevice2(xwl_gbm->drm_fd, 0, &xwl_gbm->device) != 0) {
        ErrorF("wayland-egl: Could not fetch DRM device %s\n",
               xwl_gbm->device_name);
+       xwl_screen->expecting_event--;
        return;
    }
 
commit f221e9f9037f89c3c0e6f8c588dbda43dc413132
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Oct 30 10:34:14 2024 -0700

    dix-config.h: add HAVE_SOCKLEN_T definition
    
    Needed to build with IPv6 disabled using gcc 14 on some platforms to avoid:
    
    In file included from /usr/X11/include/X11/Xtrans/transport.c:67,
                     from xstrans.c:17:
    /usr/X11/include/X11/Xtrans/Xtranssock.c: In function ‘_XSERVTransSocketOpen’:
    /usr/X11/include/X11/Xtrans/Xtranssock.c:467:28: error: passing argument 5
     of ‘getsockopt’ from incompatible pointer type [-Wincompatible-pointer-types]
      467 |             (char *) &val, &len) == 0 && val < 64 * 1024)
          |                            ^~~~
          |                            |
          |                            size_t * {aka long unsigned int *}
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit a1b5aa5a7f12adc43720a5ae11e6cef42b78df83)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/include/meson.build b/include/meson.build
index b83df5204..9b225163b 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -159,6 +159,8 @@ conf_data.set('HAVE_SETITIMER', cc.has_function('setitimer') ? '1' : false)
 conf_data.set('HAVE_SHMCTL64', cc.has_function('shmctl64') ? '1' : false)
 conf_data.set('HAVE_SIGACTION', cc.has_function('sigaction') ? '1' : false)
 conf_data.set('HAVE_SIGPROCMASK', cc.has_function('sigprocmask') ? '1' : false)
+# HAVE_SOCKLEN_T is used by xtrans when IPv6 is disabled
+conf_data.set('HAVE_SOCKLEN_T', cc.has_type('socklen_t', prefix: '#include <sys/socket.h>') ? '1' : false)
 conf_data.set('HAVE_STRCASECMP', cc.has_function('strcasecmp') ? '1' : false)
 conf_data.set('HAVE_STRCASESTR', cc.has_function('strcasestr') ? '1' : false)
 conf_data.set('HAVE_STRLCAT', cc.has_function('strlcat', dependencies: libbsd_dep) ? '1' : false)
commit 7c25024879824cc96dc930e1af9e4c203eea740f
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Oct 2 15:19:46 2024 +0200

    xwayland/present: Check allow_commits in xwl_present_flip
    
    We're not supposed to call wl_surface_commit while
    xwl_window->allow_commits is false. Bailing results in falling back to
    a copy.
    
    Noticed by inspection while looking into an issue which turned out to be
    due to something else.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1764
    (cherry picked from commit 56ba0b2a5f1052c5a2a0503fb2cea89b273de56f)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index d29411d2c..7b9a4ac32 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -870,7 +870,7 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
     struct xwl_present_event    *event = xwl_present_event_from_vblank(vblank);
     Bool                        implicit_sync = TRUE;
 
-    if (!xwl_window)
+    if (!xwl_window || !xwl_window->allow_commits)
         return FALSE;
 
     buffer = xwl_pixmap_get_wl_buffer(pixmap);
commit f340f082b8e77135323f2e8030b629be6bffcd9b
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Oct 12 17:33:24 2024 -0700

    dix: limit checks to MAX_VALUATORS when generating Xi events
    
    Previously, it was looping through sizeof(ev->valuators.mask) * 8
    valuators, where valuators.mask is defined as an array of
    (MAX_VALUATORS + 7) / 8 entries.  Since MAX_VALUATORS is defined as 36,
    this made it actually loop through 40 entries.  The last 4 bits in this
    array should never be set, so we should never access memory outside the
    bounds of the arrays defined to be exactly MAX_VALUATORS in length, but
    we can make the static analyzer happier and not waste time checking bits
    that should never be set.
    
    Found by Oracle Parfait 13.3 static analyzer:
    
       Read outside array bounds [read-outside-array-bounds]:
          In array dereference of ev->valuators.data[i] with index i
          Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
            at line 741 of dix/eventconvert.c in function 'eventToDeviceEvent'.
    
       Read outside array bounds [read-outside-array-bounds]:
          In array dereference of ev->valuators.data[i] with index i
          Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
            at line 808 of dix/eventconvert.c in function 'eventToRawEvent'.
    
       Read outside array bounds [read-outside-array-bounds]:
          In array dereference of ev->valuators.data_raw[i] with index i
          Array size is 36 elements (of 8 bytes each), index >= 0 and index <= 39
            at line 809 of dix/eventconvert.c in function 'eventToRawEvent'.
    
    Fixes: b2ba77bac ("dix: add EventToXI2 and GetXI2Type.")
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit b65eea43dd18cdf6d389b7f82ee55ae764c3bf31)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index ac1472290..8dd7bfc64 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -736,7 +736,7 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
 
     ptr += xde->buttons_len * 4;
     axisval = (FP3232 *) (ptr + xde->valuators_len * 4);
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
+    for (i = 0; i < MAX_VALUATORS; i++) {
         if (BitIsOn(ev->valuators.mask, i)) {
             SetBit(ptr, i);
             *axisval = double_to_fp3232(ev->valuators.data[i]);
@@ -803,7 +803,7 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
     ptr = (char *) &raw[1];
     axisval = (FP3232 *) (ptr + raw->valuators_len * 4);
     axisval_raw = axisval + nvals;
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) {
+    for (i = 0; i < MAX_VALUATORS; i++) {
         if (BitIsOn(ev->valuators.mask, i)) {
             SetBit(ptr, i);
             *axisval = double_to_fp3232(ev->valuators.data[i]);
commit 30427d3ddc84fb38cacaa900eb74f6be23a28586
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Oct 12 17:01:03 2024 -0700

    dix: fix button offset when generating DeviceButtonStateNotify events
    
    Found by Oracle Parfait 13.3 static analyzer:
       Buffer Overflow in STD C function [buffer-overflow-call-stdc]:
          Buffer overflow in call to memcpy. Buffer &bev->buttons[4] of
           size 24 is written at an offset of 28
          Array size is 28 bytes, index is 32
            at line 743 of dix/enterleave.c in function
             'DeliverStateNotifyEvent'.
    
    Fixes: a85f0d6b9 ("Xi: fix use of button->down - bitflags instead of int arrays.")
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 4b073d65bb5e1f4accb7ed280c8926134582b7ab)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/dix/enterleave.c b/dix/enterleave.c
index 236a9e218..2b488b7ce 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -740,7 +740,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
         (ev - 1)->deviceid |= MORE_EVENTS;
         bev->type = DeviceButtonStateNotify;
         bev->deviceid = dev->id;
-        memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
+        memcpy((char *) &bev->buttons[0], (char *) &b->down[4],
                DOWN_LENGTH - 4);
     }
 
commit 5e320e1193c51a2482d5ae943282244343bf6ddc
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Oct 12 16:38:55 2024 -0700

    render: avoid NULL pointer dereference if PictureFindVisual returns NULL
    
    Found by Oracle Parfait 13.3:
       Null pointer dereference [null-pointer-deref]:
          Read from null pointer pVisual
            at line 257 of dix/colormap.c in function 'CreateColormap'.
              Null pointer introduced at line 412 of render/picture.c in
               function 'PictureFindVisual'.
              Constant 'NULL' passed into function CreateColormap, argument
               pVisual, from call at line 431 in function
               'PictureInitIndexedFormat'.
              Function PictureFindVisual may return constant 'NULL' at
               line 412, called at line 429.
    
    Fixes: d4a101d4e ("Integration of DAMAGE-XFIXES branch to trunk")
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit 7af077dd2f939b76e7d6ba84250368b6649fb777)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/render/picture.c b/render/picture.c
index 495cc2955..6cc3e7e4c 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -428,6 +428,9 @@ PictureInitIndexedFormat(ScreenPtr pScreen, PictFormatPtr format)
     else {
         VisualPtr pVisual = PictureFindVisual(pScreen, format->index.vid);
 
+        if (pVisual == NULL)
+            return FALSE;
+
         if (CreateColormap(FakeClientID(0), pScreen, pVisual,
                            &format->index.pColormap, AllocNone, 0)
             != Success)
commit cec5c7c3b2e39ac63447dee5bc0a6f7109827a71
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Oct 12 16:12:13 2024 -0700

    Xi: avoid NULL pointer dereference if GetXTestDevice returns NULL
    
    The comments in that function say "This only happens if master is a
    slave device. don't do that" but static analysis doesn't respect that.
    
    Found by Oracle Parfait 13.3:
       Null pointer dereference [null-pointer-deref]:
          Read from null pointer XTestptr
            at line 274 of Xi/xichangehierarchy.c in function 'remove_master'.
              Null pointer introduced at line 691 of Xext/xtest.c in function
               'GetXTestDevice'.
              Function GetXTestDevice may return constant 'NULL' at line 691,
               called at line 273 of Xi/xichangehierarchy.c in function
               'remove_master'.
       Null pointer dereference [null-pointer-deref]:
          Read from null pointer XTestkeybd
            at line 279 of Xi/xichangehierarchy.c in function 'remove_master'.
              Null pointer introduced at line 691 of Xext/xtest.c in function
               'GetXTestDevice'.
              Function GetXTestDevice may return constant 'NULL' at line 691,
               called at line 278 of Xi/xichangehierarchy.c in function
               'remove_master'.
    
    Fixes: 0814f511d ("input: store the master device's ID in the devPrivate for XTest devices.")
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit d10589cc09c68ad09bebd3a4155c44d1b8f2614b)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index d8aaf95cb..57339781f 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -271,11 +271,13 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
         goto unwind;
 
     XTestptr = GetXTestDevice(ptr);
+    BUG_RETURN_VAL(XTestptr == NULL, BadDevice);
     rc = dixLookupDevice(&XTestptr, XTestptr->id, client, DixDestroyAccess);
     if (rc != Success)
         goto unwind;
 
     XTestkeybd = GetXTestDevice(keybd);
+    BUG_RETURN_VAL(XTestkeybd == NULL, BadDevice);
     rc = dixLookupDevice(&XTestkeybd, XTestkeybd->id, client, DixDestroyAccess);
     if (rc != Success)
         goto unwind;
commit a939e47c131d4cdde248781933764ba403ea546d
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Oct 3 12:33:56 2024 +0200

    xwayland/glamor/gbm: Don't close fence_fd after xwl_glamor_wait_fence
    
    eglCreateSyncKHR takes ownership of the file descriptor. Noticed by
    inspection.
    
    While we're at it, move the fence_fd declaration to the scope where
    it's used.
    
    Last but not least, close the fd in xwl_glamor_wait_fence when bailing
    before calling eglCreateSyncKHR, and document that it takes ownership.
    
    (cherry picked from commit 91b5a003a5f48df2920e628c1f0a0bd02f476280)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 92241bd1e..45f18a47c 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -1516,16 +1516,15 @@ xwl_glamor_gbm_wait_syncpts(PixmapPtr pixmap)
 #ifdef DRI3
     struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
     struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
-    int fence_fd;
 
     if (!xwl_screen->glamor || !xwl_pixmap)
         return;
 
     if (xwl_pixmap->syncobj) {
-        fence_fd = xwl_pixmap->syncobj->export_fence(xwl_pixmap->syncobj,
-                                                     xwl_pixmap->timeline_point);
+        int fence_fd = xwl_pixmap->syncobj->export_fence(xwl_pixmap->syncobj,
+                                                         xwl_pixmap->timeline_point);
+
         xwl_glamor_wait_fence(xwl_screen, fence_fd);
-        close(fence_fd);
     }
 #endif /* DRI3 */
 }
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 604658284..88ced5da0 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -191,14 +191,17 @@ xwl_glamor_get_fence(struct xwl_screen *xwl_screen)
     return fence_fd;
 }
 
+/* Takes ownership of fence_fd, specifically eglCreateSyncKHR does */
 void
 xwl_glamor_wait_fence(struct xwl_screen *xwl_screen, int fence_fd)
 {
     EGLint attribs[3];
     EGLSyncKHR sync;
 
-    if (!xwl_screen->glamor)
+    if (!xwl_screen->glamor) {
+        close(fence_fd);
         return;
+    }
 
     xwl_glamor_egl_make_current(xwl_screen);
 
commit ce9d18710171fba3a670c7928b4b274e48610dcb
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Sep 9 16:21:46 2024 -0700

    os: NextDPMSTimeout: mark intentional fallthroughs in switch
    
    The comment at the top of the function tells humans the fallthroughs
    are intentional, but gcc doesn't parse that.
    
    Clears 3 -Wimplicit-fallthrough warnings from gcc 14.1
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    (cherry picked from commit b306df5a6060beea82b5157c3603593527b220b0)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/os/WaitFor.c b/os/WaitFor.c
index a388cd573..a421e5b2a 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -416,13 +416,13 @@ NextDPMSTimeout(INT32 timeout)
     switch (DPMSPowerLevel) {
     case DPMSModeOn:
         DPMS_CHECK_TIMEOUT(DPMSStandbyTime)
-
+        /* fallthrough */
     case DPMSModeStandby:
         DPMS_CHECK_TIMEOUT(DPMSSuspendTime)
-
+        /* fallthrough */
     case DPMSModeSuspend:
         DPMS_CHECK_TIMEOUT(DPMSOffTime)
-
+        /* fallthrough */
     default:                   /* DPMSModeOff */
         return 0;
     }
commit ca0799e7f26c58f6066cec799ddf36d729b8866b
Author: YaoBing Xiao <xiaoyaobing at uniontech.com>
Date:   Fri Oct 11 09:35:18 2024 +0800

    xwayland: prevent potential null pointer dereference
    
    Signed-off-by: YaoBing Xiao <xiaoyaobing at uniontech.com>
    (cherry picked from commit e12d9863fd46698f8904976db7364b62c99daf36)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1766>

diff --git a/hw/xwayland/xwayland-xtest.c b/hw/xwayland/xwayland-xtest.c
index e947a35e7..c2aacca66 100644
--- a/hw/xwayland/xwayland-xtest.c
+++ b/hw/xwayland/xwayland-xtest.c
@@ -358,11 +358,12 @@ setup_ei(ClientPtr client)
     }
 
     xwl_ei_client = calloc(1, sizeof *xwl_ei_client);
-    xwl_ei_client->cmdline = xstrdup(cmdname);
     if (!xwl_ei_client) {
         error_ei("OOM, cannot setup EI\n");
         goto out;
     }
+
+    xwl_ei_client->cmdline = xstrdup(cmdname);
     xorg_list_init(&xwl_ei_client->link);
 
     ei = ei_new(NULL);


More information about the xorg-commit mailing list