mirror of
https://github.com/tmux/tmux.git
synced 2026-09-22 04:47:42 +00:00
window: fix use-after-free destroying a zoomed window
window_destroy() called window_unzoom() before tearing anything down. layout_fix_panes() inside that resizes panes, which fires the pane-resized hook; the hook's event payload takes and drops its own reference on the window, and since w->references was already 0 at that point, dropping it reached 0 again and re-entered window_destroy() from inside itself - freeing w and its panes while the outer call was still using them. Pin the window's reference count across window_unzoom() so that reentrant drop can't reach zero again. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
11
window.c
11
window.c
@@ -452,7 +452,18 @@ window_destroy(struct window *w)
|
||||
{
|
||||
log_debug("window @%u destroyed (%d references)", w->id, w->references);
|
||||
|
||||
/*
|
||||
* Pin the window while unzooming: layout_fix_panes() resizes panes,
|
||||
* which fires the pane-resized hook, and its event payload takes and
|
||||
* drops its own reference on the window. references is already 0
|
||||
* here, so that reference reaching 0 again would call window_destroy()
|
||||
* a second time from inside this call, freeing w (and its panes)
|
||||
* out from under the rest of this function.
|
||||
*/
|
||||
w->references++;
|
||||
window_unzoom(w, 0);
|
||||
w->references--;
|
||||
|
||||
RB_REMOVE(windows, &windows, w);
|
||||
|
||||
layout_free_cell(w->layout_root, 0);
|
||||
|
||||
Reference in New Issue
Block a user