From 2547f96984b79bbb1c732a0afa4d0d62be7c18f0 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 4 Aug 2025 20:55:16 -0400 Subject: [PATCH] view: assert internal signals are disconnected before destroy If they are not empty, then we are headed for use-after-free shortly. An assert() failure is easier to debug than UAF, so let's fail early. Inspired by: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/8f56f7ca43257cc05c7c4eb57a0f541e05cf9a79 --- src/view.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/view.c b/src/view.c index 95cafc80..33b92444 100644 --- a/src/view.c +++ b/src/view.c @@ -2684,6 +2684,16 @@ view_destroy(struct view *view) view->scene_tree = NULL; } + assert(wl_list_empty(&view->events.new_app_id.listener_list)); + assert(wl_list_empty(&view->events.new_title.listener_list)); + assert(wl_list_empty(&view->events.new_outputs.listener_list)); + assert(wl_list_empty(&view->events.maximized.listener_list)); + assert(wl_list_empty(&view->events.minimized.listener_list)); + assert(wl_list_empty(&view->events.fullscreened.listener_list)); + assert(wl_list_empty(&view->events.activated.listener_list)); + assert(wl_list_empty(&view->events.set_icon.listener_list)); + assert(wl_list_empty(&view->events.destroy.listener_list)); + /* Remove view from server->views */ wl_list_remove(&view->link); free(view);