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
This commit is contained in:
		
							parent
							
								
									6ef1b0108e
								
							
						
					
					
						commit
						4195e80356
					
				| 
						 | 
				
			
			@ -854,6 +854,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);
 | 
			
		||||
| 
						 | 
				
			
			@ -880,11 +883,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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1172,6 +1179,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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1185,7 +1207,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1195,7 +1217,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1219,7 +1241,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1231,7 +1253,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1248,7 +1270,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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1268,7 +1290,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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1284,8 +1306,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1295,7 +1316,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
 | 
			
		||||
| 
						 | 
				
			
			@ -1454,19 +1475,19 @@ tablet_handle_done(void *data, struct zwp_tablet_v2 *tablet)
 | 
			
		|||
        xwl_seat->stylus = add_device(xwl_seat, "xwayland-tablet 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-tablet 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-tablet cursor", xwl_tablet_proc);
 | 
			
		||||
        ActivateDevice(xwl_seat->puck, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
    EnableDevice(xwl_seat->puck, TRUE);
 | 
			
		||||
    enable_device(xwl_seat, xwl_seat->puck);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -1481,11 +1502,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 */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2541,6 +2562,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