fix UAF: get WApplication before wUnmanageWindow frees wwin

wApplicationOf must be called before wUnmanageWindow because the
latter frees the WWindow struct. Accessing app->main_window_desc
afterward is a use-after-free.
This commit is contained in:
lkn 2026-06-23 22:50:27 +02:00
parent 9e91722e02
commit 0fcbe20cad
3 changed files with 12 additions and 11 deletions

View File

@ -402,16 +402,8 @@ handle_toplevel_unmap(struct wl_listener *listener, void *data)
WObjDescriptor *desc = wm_backend->context_find(view->id, WM_CTX_CLIENT_WIN);
if (desc && desc->parent_type == WCLASS_WINDOW) {
WWindow *wwin = (WWindow *)desc->parent;
WNativeWindow main_win = wwin->main_window;
wwin->flags.destroyed = 1;
wUnmanageWindow(wwin, False, True);
/* Destroy the WApplication (and its appicon) if this was the
* main window. Mirrors handleDestroyNotify in event.c. */
WApplication *app = wApplicationOf(main_win);
if (app) {
if (main_win == app->main_window)
app->refcount = 0;
wApplicationDestroy(app);
}
}
}
}

View File

@ -3534,8 +3534,7 @@ static void iconDblClick(WObjDescriptor *desc, WMEvent *event)
if (btn->icon->owner && !(event->u.button.state & WM_MOD_CONTROL)) {
wapp = wApplicationOf(btn->icon->owner->main_window);
assert(wapp != NULL);
if (!wapp) return;
unhideHere = (event->u.button.state & WM_MOD_SHIFT);

View File

@ -1655,6 +1655,16 @@ void wUnmanageWindow(WWindow *wwin, Bool restore, Bool destroyed)
wm_backend->netwm_cleanup_frame_extents(wwin);
/* NULL out appicon owner before freeing so dock icon handlers
* (iconDblClick) don't access freed memory on Wayland where
* toplevel unmap fires synchronously during event dispatch. */
if (wwin->main_window) {
WApplication *oapp = wApplicationOf(wwin->main_window);
if (oapp && oapp->app_icon && oapp->app_icon->icon
&& oapp->app_icon->icon->owner == wwin)
oapp->app_icon->icon->owner = NULL;
}
wWindowDestroy(wwin);
wm_backend->event_flush();
}