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:
parent
9e91722e02
commit
0fcbe20cad
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
10
src/window.c
10
src/window.c
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue