patch 9.2.0486: out-of-bound read when recovering swap files
Commit:
https://github.com/vim/vim/commit/de7a5b5425811169f589a7a3492696e8dedf8d68
Author: Christian Brabandt <[email protected]>
Date: Fri May 15 16:31:14 2026 +0000
patch 9.2.0486: out-of-bound read when recovering swap files
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
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/runtime/doc/recover.txt b/runtime/doc/recover.txt
index c52910c1f..d52aacd88 100644
--- a/runtime/doc/recover.txt
+++ b/runtime/doc/recover.txt
@@ -195,6 +195,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.
ENCRYPTION AND THE SWAP FILE *:recover-crypt*
diff --git a/src/memline.c b/src/memline.c
index 2887ebbf9..ffd3fbd72 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -1690,6 +1690,15 @@ ml_recover(int 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++, (char_u *)_("??? block header
corrupted"),
+ (colnr_T)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_u *)dp + dp->db_txt_end - 1) = NUL;
diff --git a/src/po/vim.pot b/src/po/vim.pot
index 5db285038..3c0746495 100644
--- a/src/po/vim.pot
+++ b/src/po/vim.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim
"
"Report-Msgid-Bugs-To: [email protected]
"
-"POT-Creation-Date: 2026-05-07 19:25+0000
"
+"POT-Creation-Date: 2026-05-15 16:34+0000
"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>
"
"Language-Team: LANGUAGE <[email protected]>
"
@@ -1969,6 +1969,9 @@ msgstr ""
msgid "??? from here until ???END lines may be messed up"
msgstr ""
+msgid "??? block header corrupted"
+msgstr ""
+
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr ""
diff --git a/src/testdir/test_recover.vim b/src/testdir/test_recover.vim
index b36d23e18..69caa8913 100644
--- a/src/testdir/test_recover.vim
+++ b/src/testdir/test_recover.vim
@@ -344,7 +344,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
diff --git a/src/version.c b/src/version.c
index fa746a9ae..046cc8342 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 486,
/**/
485,
/**/
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1wNveq-006W5N-0j%40256bit.org.