diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2024-02-11 20:15:47 +0000 |
---|---|---|
committer | Sean Dewar <6256228+seandewar@users.noreply.github.com> | 2024-03-08 23:24:03 +0000 |
commit | b1e24f240baeea80dcf4a3d8453fed0230fb88fd (patch) | |
tree | a41992d36bc950c8f8f2478f7b477622d2d16e18 /src/nvim/api/win_config.c | |
parent | e55a502ed413d2bc8954b5227acfb34c8689f979 (diff) | |
download | rneovim-b1e24f240baeea80dcf4a3d8453fed0230fb88fd.tar.gz rneovim-b1e24f240baeea80dcf4a3d8453fed0230fb88fd.tar.bz2 rneovim-b1e24f240baeea80dcf4a3d8453fed0230fb88fd.zip |
fix(api): avoid open_win UAF if target buf deleted by autocmds
Problem: WinNew and win_enter autocommands can delete the target buffer to
switch to, causing a heap-use-after-free.
Solution: store a bufref to the buffer, check it before attempting to switch.
Diffstat (limited to 'src/nvim/api/win_config.c')
-rw-r--r-- | src/nvim/api/win_config.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 238ec5df1e..3959e74af9 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -12,6 +12,7 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/autocmd_defs.h" +#include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/decoration.h" #include "nvim/decoration_defs.h" @@ -279,6 +280,9 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err // Autocommands may close `wp` or move it to another tabpage, so update and check `tp` after each // event. In each case, `wp` should already be valid in `tp`, so switch_win should not fail. + // Also, autocommands may free the `buf` to switch to, so store a bufref to check. + bufref_T bufref; + set_bufref(&bufref, buf); switchwin_T switchwin; { const int result = switch_win_noblock(&switchwin, wp, tp, true); @@ -293,7 +297,7 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err goto_tabpage_win(tp, wp); tp = win_find_tabpage(wp); } - if (tp && buf != wp->w_buffer) { + if (tp && bufref_valid(&bufref) && buf != wp->w_buffer) { const bool noautocmd = curwin != wp || fconfig.noautocmd; win_set_buf(wp, buf, noautocmd, err); if (!noautocmd) { |