From c9a1e257f1630a0866447e53a564f7ff96a80ead Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Sat, 11 Jan 2025 15:25:00 +0100 Subject: [PATCH] patch 9.1.1003: [security]: heap-buffer-overflow with visual mode Problem: [security]: heap-buffer-overflow with visual mode when using :all, causing Vim trying to access beyond end-of-line (gandalf) Solution: Reset visual mode on :all, validate position in gchar_pos() and charwise_block_prep() This fixes CVE-2025-22134 Github Advisory: https://github.com/vim/vim/security/advisories/GHSA-5rgf-26wj-48v8 Co-authored-by: zeertzjq Signed-off-by: Christian Brabandt --- src/arglist.c | 4 ++++ src/misc1.c | 4 ++++ src/testdir/test_visual.vim | 26 ++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/arglist.c b/src/arglist.c index 8825c8e252ccc5..4eec079df438a3 100644 --- a/src/arglist.c +++ b/src/arglist.c @@ -1248,6 +1248,10 @@ do_arg_all( tabpage_T *new_lu_tp = curtab; + // Stop Visual mode, the cursor and "VIsual" may very well be invalid after + // switching to another buffer. + reset_VIsual_and_resel(); + // Try closing all windows that are not in the argument list. // Also close windows that are not full width; // When 'hidden' or "forceit" set the buffer becomes hidden. diff --git a/src/misc1.c b/src/misc1.c index 90cf914742b115..142a6161ea6c8a 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -535,11 +535,15 @@ plines_m_win(win_T *wp, linenr_T first, linenr_T last, int limit_winheight) gchar_pos(pos_T *pos) { char_u *ptr; + int ptrlen; // When searching columns is sometimes put at the end of a line. if (pos->col == MAXCOL) return NUL; + ptrlen = STRLEN(ml_get(pos->lnum)); ptr = ml_get_pos(pos); + if (pos->col > ptrlen) + return NUL; if (has_mbyte) return (*mb_ptr2char)(ptr); return (int)*ptr; diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim index 0be73ecc1342b9..03335a464d62f3 100644 --- a/src/testdir/test_visual.vim +++ b/src/testdir/test_visual.vim @@ -469,7 +469,7 @@ func Test_Visual_Block() \ "\t{", \ "\t}"], getline(1, '$')) - close! + bw! endfunc " Test for 'p'ut in visual block mode @@ -1079,7 +1079,7 @@ func Test_star_register() delmarks < > call assert_fails('*yank', 'E20:') - close! + bw! endfunc " Test for changing text in visual mode with 'exclusive' selection @@ -1095,7 +1095,7 @@ func Test_exclusive_selection() call assert_equal('l one', getline(1)) set virtualedit& set selection& - close! + bw! endfunc " Test for starting linewise visual with a count. @@ -1152,7 +1152,7 @@ func Test_visual_inner_block() 8,9d call cursor(5, 1) call assert_beeps('normal ViBiB') - close! + bw! endfunc func Test_visual_put_in_block() @@ -1587,4 +1587,22 @@ func Test_Visual_r_CTRL_C() bw! endfu +" the following caused a Heap-Overflow, because Vim was accessing outside of a +" line end +func Test_visual_pos_buffer_heap_overflow() + set virtualedit=all + args Xa Xb + all + call setline(1, ['', '', '']) + call cursor(3, 1) + wincmd w + call setline(1, 'foobar') + normal! $lv0 + all + call setreg('"', 'baz') + normal! [P + set virtualedit= + bw! Xa Xb +endfunc + " vim: shiftwidth=2 sts=2 expandtab -- 2.43.0