diff options
author | Olivier Fourdan <ofourdan@redhat.com> | 2016-09-22 09:38:50 +0200 |
---|---|---|
committer | Olivier Fourdan <ofourdan@redhat.com> | 2016-09-23 09:19:05 +0200 |
commit | 6a929fafbdaa83d1d496011b0cd0d7477cc8153e (patch) | |
tree | 2060067e4e426b885dcce6cfa2b04c1f76aa6ad6 | |
parent | 2b54aedfd15a0e1c6fafabbc27446b6cf2ff12ef (diff) |
xwayland: Clear up x_cursor on UnrealizeCursor()server-1.18-backports
In Xwayland's xwl_unrealize_cursor(), the x_cursor is cleared up only
when a device value is provided to the UnrealizeCursor() routine, but
if the device is NULL as called from FreeCursor(), the corresponding
x_cursor for the xwl_seat is left untouched.
This might cause a segfault when trying to access the unrealized
cursor's devPrivates in xwl_seat_set_cursor().
A possible occurrence of this is the client changing the cursor, the
Xserver calling FreeCursor() which does UnrealizeCursor() and then
the Wayland server sending a pointer enter event, which invokes
xwl_seat_set_cursor() while the seat's x_cursor has just been
unrealized.
To avoid this, walk through all the xwl_seats and clear up all x_cursor
matching the cursor being unrealized.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Jonas Ã…dahl <jadahl@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 0a20d5f8cb3f3f9a81b2795ae1865e72541022d4)
-rw-r--r-- | hw/xwayland/xwayland-cursor.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c index 7d14a3d52..b2ae93ff9 100644 --- a/hw/xwayland/xwayland-cursor.c +++ b/hw/xwayland/xwayland-cursor.c @@ -76,6 +76,7 @@ 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); @@ -85,9 +86,9 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, NULL); /* When called from FreeCursor(), device is always NULL */ - if (device) { - xwl_seat = device->public.devicePrivate; - if (xwl_seat && cursor == xwl_seat->x_cursor) + xwl_screen = xwl_screen_get(screen); + xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) { + if (cursor == xwl_seat->x_cursor) xwl_seat->x_cursor = NULL; } |