wlr_seat: clear `drag->seat_client` when destroyed

This was previously a use-after-free in `wlr_drag.c`.
This commit is contained in:
bi4k8 2022-11-15 01:00:27 +00:00
parent 77d9fc0848
commit 8b12037cad
2 changed files with 7 additions and 3 deletions

View File

@ -55,14 +55,14 @@ static void drag_set_focus(struct wlr_drag *drag,
goto out; goto out;
} }
if (!drag->source && if (!drag->source && drag->seat_client &&
wl_resource_get_client(surface->resource) != wl_resource_get_client(surface->resource) !=
drag->seat_client->client) { drag->seat_client->client) {
goto out; goto out;
} }
struct wlr_seat_client *focus_client = wlr_seat_client_for_wl_client( struct wlr_seat_client *focus_client = wlr_seat_client_for_wl_client(
drag->seat_client->seat, wl_resource_get_client(surface->resource)); drag->seat, wl_resource_get_client(surface->resource));
if (!focus_client) { if (!focus_client) {
goto out; goto out;
} }
@ -71,7 +71,7 @@ static void drag_set_focus(struct wlr_drag *drag,
drag->source->accepted = false; drag->source->accepted = false;
uint32_t serial = uint32_t serial =
wl_display_next_serial(drag->seat_client->seat->display); wl_display_next_serial(drag->seat->display);
struct wl_resource *device_resource; struct wl_resource *device_resource;
wl_resource_for_each(device_resource, &focus_client->data_devices) { wl_resource_for_each(device_resource, &focus_client->data_devices) {

View File

@ -75,6 +75,10 @@ static void seat_client_handle_resource_destroy(
client->seat->keyboard_state.focused_client = NULL; client->seat->keyboard_state.focused_client = NULL;
} }
if (client->seat->drag && client == client->seat->drag->seat_client) {
client->seat->drag->seat_client = NULL;
}
struct wl_resource *resource, *tmp; struct wl_resource *resource, *tmp;
wl_resource_for_each_safe(resource, tmp, &client->pointers) { wl_resource_for_each_safe(resource, tmp, &client->pointers) {
wl_resource_destroy(resource); wl_resource_destroy(resource);