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

392b428d12

Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
This commit is contained in:
Sean Dewar
2026-02-03 15:16:39 +00:00
parent f5931102f8
commit fede568692
2 changed files with 24 additions and 1 deletions

View File

@@ -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.

View File

@@ -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