From f3fbb3928cffd415e2b243e67683d032173eb8cc Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 27 Jun 2026 17:21:05 +0800 Subject: [PATCH] vim-patch:9.2.0738: ml_recover() may write beyond block buffer (#40446) Problem: A crafted swap file can cause an out-of-bounds write during recovery when the same block is referenced twice with different pe_page_count values (cipher-creator) Solution: Check hp->bh_page_count against page_count after mf_get() and clamp page_count to the actual block size. closes: vim/vim#20645 https://github.com/vim/vim/commit/43939cf9ebf5302bb51c85d00ac83de7e01452d5 Co-authored-by: Christian Brabandt --- src/nvim/memline.c | 12 ++++++++++++ .../testdir/samples/recover-mismatch-pc.swp | Bin 0 -> 28672 bytes test/old/testdir/test_recover.vim | 17 +++++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/old/testdir/samples/recover-mismatch-pc.swp diff --git a/src/nvim/memline.c b/src/nvim/memline.c index c1d0884c00..84d9d23323 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1111,6 +1111,18 @@ void ml_recover(bool checkext) // Append all the lines in this block. bool has_error = false; + // Verify the cached block's actual size matches the + // pointer entry's pe_page_count. mf_get() cache hits + // return the original block without resizing, so a + // crafted swap file referencing the same block twice + // with different pe_page_count values would cause an + // OOB write below. + if (hp->bh_page_count != page_count) { + error++; + ml_append(lnum++, _("??? BLOCK PAGE COUNT MISMATCH"), 0, true); + page_count = hp->bh_page_count; + } + // Check the length of the block. // If wrong, use the length given in the pointer block. if (page_count * mfp->mf_page_size != dp->db_txt_end) { diff --git a/test/old/testdir/samples/recover-mismatch-pc.swp b/test/old/testdir/samples/recover-mismatch-pc.swp new file mode 100644 index 0000000000000000000000000000000000000000..dd5a1fa083e9817bd8b926c28b65a02b120be911 GIT binary patch literal 28672 zcmYc?2=nw+u+TGLU|?Vn01=~jGz3ONV7P{Wv5_G-t1BxhDhLaO4p(oE`fD@