xserver: Branch 'server-1.20-branch' - 4 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 21 08:06:43 UTC 2020


 hw/xwayland/xwayland-input.c   |   73 ++++++++++++++++++++++++++++++-----------
 hw/xwayland/xwayland-vidmode.c |    1 
 2 files changed, 56 insertions(+), 18 deletions(-)

New commits:
commit ccbcf083d5c676311aab77cc837a2539a7278a62
Author: Lyude Paul <lyude at redhat.com>
Date:   Tue Jul 14 18:32:39 2020 -0400

    xwayland: Store xwl_tablet_pad in its own private key
    
    When a slave device causes the master virtual pointer device to change
    device types, the device's private data pointer
    (device->public.devicePrivate) is also changed to match the type of the
    slave device. This can be a problem though, as tablet pad devices will
    set the device's private data pointer to their own xwl_tablet_pad
    struct. This can cause us to dereference the pointer as the wrong type,
    and result in a segfault:
    
    Thread 1 "Xwayland" received signal SIGSEGV, Segmentation fault.
    wl_proxy_marshal (proxy=0x51, opcode=opcode at entry=0) at src/wayland-client.c:792
    792             va_start(ap, opcode);
    (gdb) bt
    0  wl_proxy_marshal (proxy=0x51, opcode=opcode at entry=0) at
      src/wayland-client.c:792
    1  0x00005610b27b6c55 in wl_pointer_set_cursor (hotspot_y=0,
      hotspot_x=0, surface=0x0, serial=<optimized out>, wl_pointer=<optimized
      out>) at /usr/include/wayland-client-protocol.h:4610
    2  xwl_seat_set_cursor (xwl_seat=xwl_seat at entry=0x5610b46d5d10) at
      xwayland-cursor.c:137
    3  0x00005610b27b6ecd in xwl_set_cursor (device=<optimized out>,
      screen=<optimized out>, cursor=<optimized out>, x=<optimized out>,
      y=<optimized out>) at xwayland-cursor.c:249
    4  0x00005610b2800b46 in miPointerUpdateSprite (pDev=0x5610b4501a30) at
      mipointer.c:468
    5  miPointerUpdateSprite (pDev=0x5610b4501a30) at mipointer.c:410
    6  0x00005610b2800e56 in miPointerDisplayCursor (pCursor=0x5610b4b35740,
      pScreen=0x5610b3d54410, pDev=0x5610b4501a30) at mipointer.c:206
    7  miPointerDisplayCursor (pDev=0x5610b4501a30, pScreen=0x5610b3d54410,
      pCursor=0x5610b4b35740) at mipointer.c:194
    8  0x00005610b27ed62b in CursorDisplayCursor (pDev=<optimized out>,
      pScreen=0x5610b3d54410, pCursor=0x5610b4b35740) at cursor.c:168
    9  0x00005610b28773ee in AnimCurDisplayCursor (pDev=0x5610b4501a30,
      pScreen=0x5610b3d54410, pCursor=0x5610b4b35740) at animcur.c:197
    10 0x00005610b28eb4ca in ChangeToCursor (pDev=0x5610b4501a30,
      cursor=0x5610b4b35740) at events.c:938
    11 0x00005610b28ec99f in WindowHasNewCursor
      (pWin=pWin at entry=0x5610b4b2e0c0) at events.c:3362
    12 0x00005610b291102d in ChangeWindowAttributes (pWin=0x5610b4b2e0c0,
      vmask=<optimized out>, vlist=vlist at entry=0x5610b4c41dcc,
      client=client at entry=0x5610b4b2c900) at window.c:1561
    13 0x00005610b28db8e3 in ProcChangeWindowAttributes (client=0x5610b4b2c900)
      at dispatch.c:746
    14 0x00005610b28e1e5b in Dispatch () at dispatch.c:497
    15 0x00005610b28e5f34 in dix_main (argc=16, argv=0x7ffc7a601b68,
      envp=<optimized out>) at main.c:276
    16 0x00007f8828cde042 in __libc_start_main (main=0x5610b27ae930 <main>,
      argc=16, argv=0x7ffc7a601b68, init=<optimized out>, fini=<optimized
      out>, rtld_fini=<optimized out>, stack_end=0x7ffc7a601b58) at
      ../csu/libc-start.c:308
    17 0x00005610b27ae96e in _start () at cursor.c:1064
    
    Simple reproducer in gnome-shell: open up an Xwayland window, press some
    tablet buttons, lock and unlock the screen. Repeat if it doesn't crash
    the first time.
    
    So, let's fix this by registering our own device-specific private key
    for storing a backpointer to xwl_tablet_pad, so that all input devices
    have their private data pointers set to their respective xwl_seat.
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Lyude Paul <lyude at redhat.com>
    (cherry picked from commit ba0e789b912671c724a21b3a30291247718bcf7d)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index c0916f87d..9b3b46ba7 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -48,6 +48,8 @@ struct sync_pending {
     DeviceIntPtr pending_dev;
 };
 
+static DevPrivateKeyRec xwl_tablet_private_key;
+
 static void
 xwl_pointer_warp_emulator_handle_motion(struct xwl_pointer_warp_emulator *warp_emulator,
                                         double dx,
@@ -2085,7 +2087,8 @@ static struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener = {
 static int
 xwl_tablet_pad_proc(DeviceIntPtr device, int what)
 {
-    struct xwl_tablet_pad *pad = device->public.devicePrivate;
+    struct xwl_tablet_pad *pad = dixGetPrivate(&device->devPrivates,
+                                               &xwl_tablet_private_key);
     /* Axis layout mirrors that of xf86-input-wacom to have better
        compatibility with existing clients */
 #define NAXES 7
@@ -2209,7 +2212,7 @@ tablet_pad_done(void *data,
 
     pad->xdevice = add_device(pad->seat, "xwayland-pad",
                               xwl_tablet_pad_proc);
-    pad->xdevice->public.devicePrivate = pad;
+    dixSetPrivate(&pad->xdevice->devPrivates, &xwl_tablet_private_key, pad);
     ActivateDevice(pad->xdevice, TRUE);
     EnableDevice(pad->xdevice, TRUE);
 }
@@ -2924,6 +2927,11 @@ InitInput(int argc, char *argv[])
     ScreenPtr pScreen = screenInfo.screens[0];
     struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
 
+    if (!dixRegisterPrivateKey(&xwl_tablet_private_key, PRIVATE_DEVICE, 0)) {
+        ErrorF("Failed to register private key\n");
+        return;
+    }
+
     mieqInit();
 
     xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
commit cc36135595fad70ce81697d7c98eb8a26cec9a72
Author: SimonP <simonp.git at gmail.com>
Date:   Tue Jun 9 13:26:48 2020 +0200

    xwayland: Initialise values in xwlVidModeGetGamma()
    
    ProcVidModeGetGamma() relies on GetGamma() to initialise values if it
    returns TRUE. Without this, we're sending uninitialised values to
    clients.
    
    Fixes: xorg/xserver#1040
    (cherry picked from commit 6748a4094158d2bde1630b915a5318f9f22c8e0a)

diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
index 0bcd11401..d25d1aca1 100644
--- a/hw/xwayland/xwayland-vidmode.c
+++ b/hw/xwayland/xwayland-vidmode.c
@@ -332,6 +332,7 @@ static Bool
 xwlVidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
 {
     /* Unsupported for now, but pretend it works */
+    *red = *green = *blue = 1.0f;
     return TRUE;
 }
 
commit 533cc6ca046a9e59503bd0763ab28f66284f7dc7
Author: Sjoerd Simons <sjoerd at collabora.com>
Date:   Fri Apr 10 16:34:06 2020 +0200

    xwayland: Fix crashes when there is no pointer
    
    When running with a weston session without a pointer device (thus with
    the wl_seat not having a pointer) xwayland pointer warping and pointer
    confining should simply be ignored to avoid crashes.
    
    Signed-off-by: Sjoerd Simons <sjoerd at collabora.com>
    (cherry picked from commit d35f68336b0a462dc660797d1779581f348af04e)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index d069f72f6..c0916f87d 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -2782,6 +2782,9 @@ xwl_seat_can_emulate_pointer_warp(struct xwl_seat *xwl_seat)
 {
     struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
 
+    if (!xwl_seat->pointer)
+        return FALSE;
+
     if (!xwl_screen->relative_pointer_manager)
         return FALSE;
 
@@ -2874,6 +2877,9 @@ xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
     if (!pointer_constraints)
         return;
 
+    if (!xwl_seat->wl_pointer)
+        return;
+
     if (xwl_seat->cursor_confinement_window == xwl_window &&
         xwl_seat->confined_pointer)
         return;
commit 3aa31823dbc3dd026ce08958ca5324d7af94a86a
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue May 5 15:40:43 2020 +0200

    xwayland: Clear private on device removal
    
    Xwayland uses the device private to point to the `xwl_seat`.
    
    Device may be removed at any time, including on suspend.
    
    On resume, if the DIX code ends up calling a function that requires the
    `xwl_seat` such as `xwl_set_cursor()` we may end up pointing at random
    data.
    
    Make sure the clear the device private data on removal so that we don't
    try to use it and crash later.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    https://gitlab.freedesktop.org/xorg/xserver/issues/709
    (cherry picked from commit 4195e8035645007be313ade79032b8d561ceec6c)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index ba2febc1d..d069f72f6 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -831,6 +831,9 @@ remove_sync_pending(DeviceIntPtr dev)
     struct xwl_seat *xwl_seat = dev->public.devicePrivate;
     struct sync_pending *p, *npd;
 
+    if (!xwl_seat)
+        return;
+
     xorg_list_for_each_entry_safe(p, npd, &xwl_seat->sync_pending, l) {
         if (p->pending_dev == dev) {
             xorg_list_del(&xwl_seat->sync_pending);
@@ -857,11 +860,15 @@ static Bool
 keyboard_check_repeat (DeviceIntPtr dev, XkbSrvInfoPtr xkbi, unsigned key)
 {
     struct xwl_seat *xwl_seat = dev->public.devicePrivate;
-    struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
+    struct xwl_screen *xwl_screen;
     struct wl_callback *callback;
     struct sync_pending *p;
 
+    if (!xwl_seat)
+        return FALSE;
+
     /* Make sure we didn't miss a possible reply from the compositor */
+    xwl_screen = xwl_seat->xwl_screen;
     xwl_sync_events (xwl_screen);
 
     xorg_list_for_each_entry(p, &xwl_seat->sync_pending, l) {
@@ -1149,6 +1156,21 @@ add_device(struct xwl_seat *xwl_seat,
     return dev;
 }
 
+static void
+disable_device(DeviceIntPtr dev)
+{
+    DisableDevice(dev, TRUE);
+    dev->public.devicePrivate = NULL;
+}
+
+static void
+enable_device(struct xwl_seat *xwl_seat, DeviceIntPtr dev)
+{
+    dev->public.devicePrivate = xwl_seat;
+    EnableDevice(dev, TRUE);
+}
+
+
 static void
 init_pointer(struct xwl_seat *xwl_seat)
 {
@@ -1162,7 +1184,7 @@ init_pointer(struct xwl_seat *xwl_seat)
             add_device(xwl_seat, "xwayland-pointer", xwl_pointer_proc);
         ActivateDevice(xwl_seat->pointer, TRUE);
     }
-    EnableDevice(xwl_seat->pointer, TRUE);
+    enable_device(xwl_seat, xwl_seat->pointer);
 }
 
 static void
@@ -1172,7 +1194,7 @@ release_pointer(struct xwl_seat *xwl_seat)
     xwl_seat->wl_pointer = NULL;
 
     if (xwl_seat->pointer)
-        DisableDevice(xwl_seat->pointer, TRUE);
+        disable_device(xwl_seat->pointer);
 }
 
 static void
@@ -1196,7 +1218,7 @@ init_relative_pointer(struct xwl_seat *xwl_seat)
                        xwl_pointer_proc_relative);
         ActivateDevice(xwl_seat->relative_pointer, TRUE);
     }
-    EnableDevice(xwl_seat->relative_pointer, TRUE);
+    enable_device(xwl_seat, xwl_seat->relative_pointer);
 }
 
 static void
@@ -1208,7 +1230,7 @@ release_relative_pointer(struct xwl_seat *xwl_seat)
     }
 
     if (xwl_seat->relative_pointer)
-        DisableDevice(xwl_seat->relative_pointer, TRUE);
+        disable_device(xwl_seat->relative_pointer);
 }
 
 static void
@@ -1225,7 +1247,7 @@ init_keyboard(struct xwl_seat *xwl_seat)
             add_device(xwl_seat, "xwayland-keyboard", xwl_keyboard_proc);
         ActivateDevice(xwl_seat->keyboard, TRUE);
     }
-    EnableDevice(xwl_seat->keyboard, TRUE);
+    enable_device(xwl_seat, xwl_seat->keyboard);
     xwl_seat->keyboard->key->xkbInfo->checkRepeat = keyboard_check_repeat;
 
     if (xwl_seat->xwl_screen->wp_grab) {
@@ -1245,7 +1267,7 @@ release_keyboard(struct xwl_seat *xwl_seat)
 
     if (xwl_seat->keyboard) {
         remove_sync_pending(xwl_seat->keyboard);
-        DisableDevice(xwl_seat->keyboard, TRUE);
+        disable_device(xwl_seat->keyboard);
     }
 }
 
@@ -1261,8 +1283,7 @@ init_touch(struct xwl_seat *xwl_seat)
             add_device(xwl_seat, "xwayland-touch", xwl_touch_proc);
         ActivateDevice(xwl_seat->touch, TRUE);
     }
-    EnableDevice(xwl_seat->touch, TRUE);
-
+    enable_device(xwl_seat, xwl_seat->touch);
 }
 
 static void
@@ -1272,7 +1293,7 @@ release_touch(struct xwl_seat *xwl_seat)
     xwl_seat->wl_touch = NULL;
 
     if (xwl_seat->touch)
-        DisableDevice(xwl_seat->touch, TRUE);
+        disable_device(xwl_seat->touch);
 }
 
 static void
@@ -1431,19 +1452,19 @@ tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet)
         xwl_seat->stylus = add_device(xwl_seat, "xwayland-stylus", xwl_tablet_proc);
         ActivateDevice(xwl_seat->stylus, TRUE);
     }
-    EnableDevice(xwl_seat->stylus, TRUE);
+    enable_device(xwl_seat, xwl_seat->stylus);
 
     if (xwl_seat->eraser == NULL) {
         xwl_seat->eraser = add_device(xwl_seat, "xwayland-eraser", xwl_tablet_proc);
         ActivateDevice(xwl_seat->eraser, TRUE);
     }
-    EnableDevice(xwl_seat->eraser, TRUE);
+    enable_device(xwl_seat, xwl_seat->eraser);
 
     if (xwl_seat->puck == NULL) {
         xwl_seat->puck = add_device(xwl_seat, "xwayland-cursor", xwl_tablet_proc);
         ActivateDevice(xwl_seat->puck, TRUE);
     }
-    EnableDevice(xwl_seat->puck, TRUE);
+    enable_device(xwl_seat, xwl_seat->puck);
 }
 
 static void
@@ -1458,11 +1479,11 @@ tablet_handle_removed(void *data, struct zwp_tablet_v2 *tablet)
        will re-use the same X devices */
     if (xorg_list_is_empty(&xwl_seat->tablets)) {
         if (xwl_seat->stylus)
-            DisableDevice(xwl_seat->stylus, TRUE);
+            disable_device(xwl_seat->stylus);
         if (xwl_seat->eraser)
-            DisableDevice(xwl_seat->eraser, TRUE);
+            disable_device(xwl_seat->eraser);
         if (xwl_seat->puck)
-            DisableDevice(xwl_seat->puck, TRUE);
+            disable_device(xwl_seat->puck);
         /* pads are removed separately */
     }
 
@@ -2524,6 +2545,8 @@ sprite_check_lost_focus(SpritePtr sprite, WindowPtr window)
         return FALSE;
 
     xwl_seat = device->public.devicePrivate;
+    if (!xwl_seat)
+        return FALSE;
 
     master = GetMaster(device, POINTER_OR_FLOAT);
     if (!master || !master->lastSlave)


More information about the xorg-commit mailing list