commit fede5686929139ff6cf72e171718326d72c57857
parent f5931102f8c8d859930eb205088d83cab3efee01
Author: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Date: Tue, 3 Feb 2026 15:16:39 +0000
vim-patch:9.1.2128: Heap use after free in buf_check_timestamp()
Problem: heap UAF if autocommands from reloading a file changed outside
of Vim wipe its buffer.
Solution: Validate the bufref after buf_reload (Sean Dewar)
closes: vim/vim#19317
https://github.com/vim/vim/commit/392b428d1239e963020b73682cd03f17ffb538b3
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Diffstat:
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
@@ -3049,7 +3049,7 @@ int buf_check_timestamp(buf_T *buf)
if (reload != RELOAD_NONE) {
// Reload the buffer.
buf_reload(buf, orig_mode, reload == RELOAD_DETECT);
- if (buf->b_p_udf && buf->b_ffname != NULL) {
+ if (bufref_valid(&bufref) && buf->b_p_udf && buf->b_ffname != NULL) {
uint8_t hash[UNDO_HASH_SIZE];
// Any existing undo file is unusable, write it now.
diff --git a/test/old/testdir/test_filechanged.vim b/test/old/testdir/test_filechanged.vim
@@ -289,4 +289,27 @@ func Test_FileChangedShell_newbuf()
call delete('Xfile')
endfunc
+func Test_file_changed_wipeout()
+ call writefile(['foo'], 'Xchanged_bw', 'D')
+ edit Xchanged_bw
+ augroup FileChangedWipeout
+ autocmd FileChangedShell * ++once let v:fcs_choice = 'reload'
+ autocmd BufReadPost * ++once %bw!
+ augroup END
+
+ " Need to wait until the timestamp would change.
+ if has('nanotime')
+ sleep 10m
+ else
+ sleep 2
+ endif
+ call writefile(['bar'], 'Xchanged_bw')
+ call assert_equal(1, bufexists('Xchanged_bw'))
+ checktime " used to be a heap UAF
+ call assert_equal(0, bufexists('Xchanged_bw'))
+
+ au! FileChangedWipeout
+ %bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab