aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-07-04 06:41:10 -0700
committerGitHub <noreply@github.com>2018-07-04 06:41:10 -0700
commitb0f7072737ecc14d70597ba9002be0be71c3b359 (patch)
tree6561511a395375505411fc5824f2f5af11a2ef01
parent12dd9544f9756f7f172259d7ad75a60e2eb86a41 (diff)
parent48e8da851d3ddfd7147353f1d06993c95c5f27d2 (diff)
Merge pull request #1111 from martinetd/wlr-seat-destroy
wlr_seat destroy: fix use-after-free when destroying clients
-rw-r--r--types/seat/wlr_seat.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/types/seat/wlr_seat.c b/types/seat/wlr_seat.c
index c9eecef6..3c415483 100644
--- a/types/seat/wlr_seat.c
+++ b/types/seat/wlr_seat.c
@@ -175,10 +175,18 @@ void wlr_seat_destroy(struct wlr_seat *seat) {
struct wlr_seat_client *client, *tmp;
wl_list_for_each_safe(client, tmp, &seat->clients, link) {
- struct wl_resource *resource, *next_resource;
- wl_resource_for_each_safe(resource, next_resource, &client->wl_resources) {
+ struct wl_resource *resource, *next;
+ /* wl_resource_for_each_safe isn't safe to use here, because the last
+ * wl_resource_destroy will also destroy the head we cannot do the last
+ * 'next' update that usually is harmless here.
+ * Work around this by breaking one step ahead
+ */
+ wl_resource_for_each_safe(resource, next, &client->wl_resources) {
// will destroy other resources as well
wl_resource_destroy(resource);
+ if (wl_resource_get_link(next) == &client->wl_resources) {
+ break;
+ }
}
}