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@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
https://gitlab.freedesktop.org/xorg/xserver/issues/709
(cherry picked from commit 4195e80356
)
This commit is contained in:
parent
22c0808ac8
commit
3aa31823db
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue