mirror of
https://github.com/neovim/neovim.git
synced 2026-05-28 15:55:34 +00:00
vim-patch:9.2.0486: out-of-bound read when recovering swap files (#39807)
Problem: out-of-bound read when recovering corrupted swap files
(Rahul Hoysala)
Solution: Validate the db_txt_start field when recovering a swap
file.
Supported by AI
de7a5b5425
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
@@ -182,5 +182,10 @@ recovered file. Or use |:DiffOrig|.
|
||||
Once you are sure the recovery is ok delete the swap file. Otherwise, you
|
||||
will continue to get warning messages that the ".swp" file already exists.
|
||||
|
||||
Note: Recovering swap files is best-effort. Vim attempts to validate fields
|
||||
and skip corrupted sections, but the swap file format is intended for files
|
||||
you trust. A crafted swap file may trigger parser bugs; such reports are
|
||||
treated as robustness issues rather than security vulnerabilities.
|
||||
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
||||
@@ -1123,6 +1123,12 @@ void ml_recover(bool checkext)
|
||||
dp->db_txt_end = page_count * mfp->mf_page_size;
|
||||
}
|
||||
|
||||
if (dp->db_txt_start < HEADER_SIZE || dp->db_txt_start > dp->db_txt_end) {
|
||||
ml_append(lnum++, _("??? block header corrupted"), 0, true);
|
||||
error++;
|
||||
has_error = true;
|
||||
dp->db_txt_start = dp->db_txt_end;
|
||||
}
|
||||
// Make sure there is a NUL at the end of the block so we
|
||||
// don't go over the end when copying text.
|
||||
*((char *)dp + dp->db_txt_end - 1) = NUL;
|
||||
|
||||
@@ -349,7 +349,21 @@ func Test_recover_corrupted_swap_file()
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???MANY LINES MISSING'], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" use an out-of-bounds db_txt_start in the data block (would cause OOB
|
||||
" read past dp->db_index[] in ml_recover() without the bounds check)
|
||||
let b = copy(save_b)
|
||||
let b[8200:8203] = s:little_endian ? 0zFEFFFFFF : 0zFFFFFFFE
|
||||
if s:system_64bit
|
||||
let b[8208:8215] = 0z00FFFFFF.FFFFFF00
|
||||
else
|
||||
let b[8208:8211] = 0z00FFFF00
|
||||
endif
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_match('??? block header corrupted', getline(1))
|
||||
bw!
|
||||
call delete(sn)
|
||||
endfunc
|
||||
|
||||
Reference in New Issue
Block a user