xwayland/selection: destroy all selections on Xwayland restart
Previously, Xwayland could restart, and we'd get events for transfers pointing to the previous (now freed) xwm instance. This led to use-after-free segfaults. Closes #2565.
This commit is contained in:
parent
3417fc0cca
commit
b6ba595862
|
@ -51,6 +51,9 @@ void xwm_selection_transfer_finish(struct wlr_xwm_selection_transfer *transfer);
|
||||||
bool xwm_selection_transfer_get_selection_property(
|
bool xwm_selection_transfer_get_selection_property(
|
||||||
struct wlr_xwm_selection_transfer *transfer, bool delete);
|
struct wlr_xwm_selection_transfer *transfer, bool delete);
|
||||||
|
|
||||||
|
void xwm_selection_transfer_destroy_outgoing(
|
||||||
|
struct wlr_xwm_selection_transfer *transfer);
|
||||||
|
|
||||||
xcb_atom_t xwm_mime_type_to_atom(struct wlr_xwm *xwm, char *mime_type);
|
xcb_atom_t xwm_mime_type_to_atom(struct wlr_xwm *xwm, char *mime_type);
|
||||||
char *xwm_mime_type_from_atom(struct wlr_xwm *xwm, xcb_atom_t atom);
|
char *xwm_mime_type_from_atom(struct wlr_xwm *xwm, xcb_atom_t atom);
|
||||||
struct wlr_xwm_selection *xwm_get_selection(struct wlr_xwm *xwm,
|
struct wlr_xwm_selection *xwm_get_selection(struct wlr_xwm *xwm,
|
||||||
|
|
|
@ -66,7 +66,7 @@ static struct wlr_xwm_selection_transfer *xwm_selection_transfer_get_first(
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xwm_selection_transfer_destroy_outgoing(
|
void xwm_selection_transfer_destroy_outgoing(
|
||||||
struct wlr_xwm_selection_transfer *transfer) {
|
struct wlr_xwm_selection_transfer *transfer) {
|
||||||
struct wlr_xwm_selection *selection = transfer->selection;
|
struct wlr_xwm_selection *selection = transfer->selection;
|
||||||
bool was_first = transfer == xwm_selection_transfer_get_first(selection);
|
bool was_first = transfer == xwm_selection_transfer_get_first(selection);
|
||||||
|
|
|
@ -249,25 +249,47 @@ void xwm_selection_finish(struct wlr_xwm *xwm) {
|
||||||
if (!xwm) {
|
if (!xwm) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_xwm_selection *selections[] = {
|
||||||
|
&xwm->clipboard_selection,
|
||||||
|
&xwm->primary_selection,
|
||||||
|
&xwm->dnd_selection,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(selections)/sizeof(selections[0]); i++) {
|
||||||
|
struct wlr_xwm_selection *selection = selections[i];
|
||||||
|
|
||||||
|
struct wlr_xwm_selection_transfer *outgoing, *tmp;
|
||||||
|
wl_list_for_each_safe(outgoing, tmp, &selection->outgoing, outgoing_link) {
|
||||||
|
wlr_log(WLR_INFO, "destroyed pending transfer %ld/%p", i, outgoing);
|
||||||
|
xwm_selection_transfer_destroy_outgoing(outgoing);
|
||||||
|
}
|
||||||
|
|
||||||
|
xwm_selection_transfer_finish(&selection->incoming);
|
||||||
|
}
|
||||||
|
|
||||||
if (xwm->selection_window) {
|
if (xwm->selection_window) {
|
||||||
xcb_destroy_window(xwm->xcb_conn, xwm->selection_window);
|
xcb_destroy_window(xwm->xcb_conn, xwm->selection_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xwm->dnd_window) {
|
if (xwm->dnd_window) {
|
||||||
xcb_destroy_window(xwm->xcb_conn, xwm->dnd_window);
|
xcb_destroy_window(xwm->xcb_conn, xwm->dnd_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xwm->seat) {
|
if (xwm->seat) {
|
||||||
if (xwm->seat->selection_source &&
|
if (xwm->seat->selection_source &&
|
||||||
data_source_is_xwayland(
|
data_source_is_xwayland(xwm->seat->selection_source)) {
|
||||||
xwm->seat->selection_source)) {
|
|
||||||
wlr_seat_set_selection(xwm->seat, NULL,
|
wlr_seat_set_selection(xwm->seat, NULL,
|
||||||
wl_display_next_serial(xwm->xwayland->wl_display));
|
wl_display_next_serial(xwm->xwayland->wl_display));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xwm->seat->primary_selection_source &&
|
if (xwm->seat->primary_selection_source &&
|
||||||
primary_selection_source_is_xwayland(
|
primary_selection_source_is_xwayland(
|
||||||
xwm->seat->primary_selection_source)) {
|
xwm->seat->primary_selection_source)) {
|
||||||
wlr_seat_set_primary_selection(xwm->seat, NULL,
|
wlr_seat_set_primary_selection(xwm->seat, NULL,
|
||||||
wl_display_next_serial(xwm->xwayland->wl_display));
|
wl_display_next_serial(xwm->xwayland->wl_display));
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_xwayland_set_seat(xwm->xwayland, NULL);
|
wlr_xwayland_set_seat(xwm->xwayland, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue