aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTudor Brindus <me@tbrindus.ca>2021-02-10 20:42:18 -0500
committerSimon Ser <contact@emersion.fr>2021-02-15 13:50:14 +0100
commit7d52b4d0b5592a3bc87e097c44b8629695bc9cad (patch)
tree9aa2baf74b4e1e5e502103a23c5a9e965af13d74
parent4a9e70ccde1263d628be2d960dab511377cfbc6c (diff)
xwayland/selection: ignore requests for anything but the newest data
Our internal state machine gets screwed up if selection events are not monotonically increasing in time, and we can enter a self-copy loop from the proxy window that exhausts all pipes. Snippet of logs when this occurs: 00:00:46.238 [wlr] [xwayland/selection/incoming.c:487] XCB_XFIXES_SELECTION_NOTIFY (selection=277, owner=4194626) 00:00:46.238 [wlr] [xwayland/selection/incoming.c:487] XCB_XFIXES_SELECTION_NOTIFY (selection=277, owner=2097153) 00:00:46.238 [wlr] [xwayland/selection/outgoing.c:378] XCB_SELECTION_REQUEST (time=58979563 owner=2097153, requestor=2097153 selection=277, target=279, property=278) 00:00:46.238 [wlr] [xwayland/selection/outgoing.c:397] ignoring old request from timestamp 58979563; expecting > 58979563 00:00:46.238 [wlr] [xwayland/selection/outgoing.c:29] SendEvent destination=2097153 SelectionNotify(31) time=58979563 requestor=2097153 selection=277 target=279 property=0 00:00:46.238 [wlr] [xwayland/selection/incoming.c:453] XCB_SELECTION_NOTIFY (selection=277, property=0, target=279) Note that 2097153 is `selection->window`, and 4194626 is Emacs. The race occurs if the selection owner changes back to our proxy window between when we get `XCB_XFIXES_SELECTION_NOTIFY` for Emacs and when we call `xcb_convert_selection` in `incoming.c:source_send` -- the ConvertSelection request can end up hitting our proxy window, but the timestamp will be rejected. Fixes #2192.
-rw-r--r--xwayland/selection/outgoing.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/xwayland/selection/outgoing.c b/xwayland/selection/outgoing.c
index 7c5c5f40..87c0fb06 100644
--- a/xwayland/selection/outgoing.c
+++ b/xwayland/selection/outgoing.c
@@ -392,9 +392,22 @@ void xwm_handle_selection_request(struct wlr_xwm *xwm,
goto fail_notify_requestor;
}
+ if (req->requestor == selection->window) {
+ wlr_log(WLR_ERROR, "selection request should have been caught before");
+ goto fail_notify_requestor;
+ }
+
if (selection->window != req->owner) {
+ if (req->time != XCB_CURRENT_TIME && req->time < selection->timestamp) {
+ wlr_log(WLR_DEBUG, "ignored old request from timestamp %d; expected > %d",
+ req->time, selection->timestamp);
+ goto fail_notify_requestor;
+ }
+
wlr_log(WLR_DEBUG, "received selection request with invalid owner");
- goto fail_notify_requestor;
+ // Don't fail (`goto fail_notify_requestor`) the selection request if we're
+ // no longer the selection owner.
+ return;
}
// No xwayland surface focused, deny access to clipboard