From 2fbca399b56ccffd2ef4aa9d3c7868f671240872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cwh02252983=E2=80=9D?= <“wh02252983@alibaba-inc.com”> Date: Tue, 20 May 2025 13:38:01 +0800 Subject: [PATCH] [CVE] FIX CVE-2024-43374 and FIX CVE-2024-43802 To # N/A FIX CVE-2024-43374 FIX CVE-2024-43802 Project: TC2024080204 Signed-off-by: wh02252983 --- 0009-fix-CVE-2024-43374.patch | 262 ++++ 0010-fix-CVE-2024-43802.patch | 2161 +++++++++++++++++++++++++++++++++ vim.spec | 8 +- 3 files changed, 2430 insertions(+), 1 deletion(-) create mode 100644 0009-fix-CVE-2024-43374.patch create mode 100644 0010-fix-CVE-2024-43802.patch diff --git a/0009-fix-CVE-2024-43374.patch b/0009-fix-CVE-2024-43374.patch new file mode 100644 index 0000000..fdf430d --- /dev/null +++ b/0009-fix-CVE-2024-43374.patch @@ -0,0 +1,262 @@ +diff --git a/src/arglist.c b/src/arglist.c +index a63f6c7..050f96f 100644 +--- a/src/arglist.c ++++ b/src/arglist.c +@@ -184,6 +184,8 @@ alist_set( + /* + * Add file "fname" to argument list "al". + * "fname" must have been allocated and "al" must have been checked for room. ++ * ++ * May trigger Buf* autocommands + */ + void + alist_add( +@@ -196,6 +198,7 @@ alist_add( + if (check_arglist_locked() == FAIL) + return; + arglist_locked = TRUE; ++ curwin->w_locked = TRUE; + + #ifdef BACKSLASH_IN_FILENAME + slash_adjust(fname); +@@ -207,6 +210,7 @@ alist_add( + ++al->al_ga.ga_len; + + arglist_locked = FALSE; ++ curwin->w_locked = FALSE; + } + + #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) +@@ -365,6 +369,7 @@ alist_add_list( + mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]), + (ARGCOUNT - after) * sizeof(aentry_T)); + arglist_locked = TRUE; ++ curwin->w_locked = TRUE; + for (i = 0; i < count; ++i) + { + int flags = BLN_LISTED | (will_edit ? BLN_CURBUF : 0); +@@ -373,6 +378,7 @@ alist_add_list( + ARGLIST[after + i].ae_fnum = buflist_add(files[i], flags); + } + arglist_locked = FALSE; ++ curwin->w_locked = FALSE; + ALIST(curwin)->al_ga.ga_len += count; + if (old_argcount > 0 && curwin->w_arg_idx >= after) + curwin->w_arg_idx += count; +diff --git a/src/buffer.c b/src/buffer.c +index 9ee74f5..95193a0 100644 +--- a/src/buffer.c ++++ b/src/buffer.c +@@ -1451,7 +1451,7 @@ do_buffer_ext( + // (unless it's the only window). Repeat this so long as we end up in + // a window with this buffer. + while (buf == curbuf +- && !(curwin->w_closing || curwin->w_buffer->b_locked > 0) ++ && !(win_locked(curwin) || curwin->w_buffer->b_locked > 0) + && (!ONE_WINDOW || first_tabpage->tp_next != NULL)) + { + if (win_close(curwin, FALSE) == FAIL) +@@ -5438,7 +5438,7 @@ ex_buffer_all(exarg_T *eap) + : wp->w_width != Columns) + || (had_tab > 0 && wp != firstwin)) + && !ONE_WINDOW +- && !(wp->w_closing || wp->w_buffer->b_locked > 0) ++ && !(win_locked(wp) || wp->w_buffer->b_locked > 0) + && !win_unlisted(wp)) + { + if (win_close(wp, FALSE) == FAIL) +diff --git a/src/ex_cmds.c b/src/ex_cmds.c +index a08682b..46c4503 100644 +--- a/src/ex_cmds.c ++++ b/src/ex_cmds.c +@@ -2827,7 +2827,7 @@ do_ecmd( + + // Set the w_closing flag to avoid that autocommands close the + // window. And set b_locked for the same reason. +- the_curwin->w_closing = TRUE; ++ the_curwin->w_locked = TRUE; + ++buf->b_locked; + + if (curbuf == old_curbuf.br_buf) +@@ -2841,7 +2841,7 @@ do_ecmd( + + // Autocommands may have closed the window. + if (win_valid(the_curwin)) +- the_curwin->w_closing = FALSE; ++ the_curwin->w_locked = FALSE; + --buf->b_locked; + + #ifdef FEAT_EVAL +diff --git a/src/proto/window.pro b/src/proto/window.pro +index cfb771d..12edf0b 100644 +--- a/src/proto/window.pro ++++ b/src/proto/window.pro +@@ -93,4 +93,5 @@ int win_hasvertsplit(void); + int get_win_number(win_T *wp, win_T *first_win); + int get_tab_number(tabpage_T *tp); + char *check_colorcolumn(win_T *wp); ++int win_locked(win_T *wp); + /* vim: set ft=c : */ +diff --git a/src/structs.h b/src/structs.h +index 6d9dcbb..1f4742b 100644 +--- a/src/structs.h ++++ b/src/structs.h +@@ -3740,7 +3740,7 @@ struct window_S + synblock_T *w_s; // for :ownsyntax + #endif + +- int w_closing; // window is being closed, don't let ++ int w_locked; // window is being closed, don't let + // autocommands close it too. + + frame_T *w_frame; // frame containing this window +diff --git a/src/terminal.c b/src/terminal.c +index f79d102..37cd0f2 100644 +--- a/src/terminal.c ++++ b/src/terminal.c +@@ -3669,10 +3669,10 @@ term_after_channel_closed(term_T *term) + if (is_aucmd_win(curwin)) + do_set_w_closing = TRUE; + if (do_set_w_closing) +- curwin->w_closing = TRUE; ++ curwin->w_locked = TRUE; + do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE); + if (do_set_w_closing) +- curwin->w_closing = FALSE; ++ curwin->w_locked = FALSE; + aucmd_restbuf(&aco); + } + #ifdef FEAT_PROP_POPUP +diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim +index edc8b77..8d81a82 100644 +--- a/src/testdir/test_arglist.vim ++++ b/src/testdir/test_arglist.vim +@@ -359,6 +359,7 @@ func Test_argv() + call assert_equal('', argv(1, 100)) + call assert_equal([], argv(-1, 100)) + call assert_equal('', argv(10, -1)) ++ %argdelete + endfunc + + " Test for the :argedit command +@@ -744,4 +745,26 @@ func Test_all_command() + %bw! + endfunc + ++" Test for deleting buffer when creating an arglist. This was accessing freed ++" memory ++func Test_crash_arglist_uaf() ++ "%argdelete ++ new one ++ au BufAdd XUAFlocal :bw ++ "call assert_fails(':arglocal XUAFlocal', 'E163:') ++ arglocal XUAFlocal ++ au! BufAdd ++ bw! XUAFlocal ++ ++ au BufAdd XUAFlocal2 :bw ++ new two ++ new three ++ arglocal ++ argadd XUAFlocal2 Xfoobar ++ bw! XUAFlocal2 ++ bw! two ++ ++ au! BufAdd ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +diff --git a/src/window.c b/src/window.c +index 55ce31c..1a8463a 100644 +--- a/src/window.c ++++ b/src/window.c +@@ -2441,7 +2441,7 @@ close_windows( + for (wp = firstwin; wp != NULL && !ONE_WINDOW; ) + { + if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) +- && !(wp->w_closing || wp->w_buffer->b_locked > 0)) ++ && !(win_locked(wp) || wp->w_buffer->b_locked > 0)) + { + if (win_close(wp, FALSE) == FAIL) + // If closing the window fails give up, to avoid looping +@@ -2462,7 +2462,7 @@ close_windows( + if (tp != curtab) + FOR_ALL_WINDOWS_IN_TAB(tp, wp) + if (wp->w_buffer == buf +- && !(wp->w_closing || wp->w_buffer->b_locked > 0)) ++ && !(win_locked(wp) || wp->w_buffer->b_locked > 0)) + { + win_close_othertab(wp, FALSE, tp); + +@@ -2584,10 +2584,10 @@ win_close_buffer(win_T *win, int action, int abort_if_last) + bufref_T bufref; + + set_bufref(&bufref, curbuf); +- win->w_closing = TRUE; ++ win->w_locked = TRUE; + close_buffer(win, win->w_buffer, action, abort_if_last, TRUE); + if (win_valid_any_tab(win)) +- win->w_closing = FALSE; ++ win->w_locked = FALSE; + // Make sure curbuf is valid. It can become invalid if 'bufhidden' is + // "wipe". + if (!bufref_valid(&bufref)) +@@ -2635,7 +2635,7 @@ win_close(win_T *win, int free_buf) + if (window_layout_locked(CMD_close)) + return FAIL; + +- if (win->w_closing || (win->w_buffer != NULL ++ if (win_locked(win) || (win->w_buffer != NULL + && win->w_buffer->b_locked > 0)) + return FAIL; // window is already being closed + if (win_unlisted(win)) +@@ -2684,19 +2684,19 @@ win_close(win_T *win, int free_buf) + other_buffer = TRUE; + if (!win_valid(win)) + return FAIL; +- win->w_closing = TRUE; ++ win->w_locked = TRUE; + apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); + if (!win_valid(win)) + return FAIL; +- win->w_closing = FALSE; ++ win->w_locked = FALSE; + if (last_window()) + return FAIL; + } +- win->w_closing = TRUE; ++ win->w_locked = TRUE; + apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); + if (!win_valid(win)) + return FAIL; +- win->w_closing = FALSE; ++ win->w_locked = FALSE; + if (last_window()) + return FAIL; + #ifdef FEAT_EVAL +@@ -3269,7 +3269,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) + + // Get here with win->w_buffer == NULL when win_close() detects the tab + // page changed. +- if (win->w_closing || (win->w_buffer != NULL ++ if (win_locked(win) || (win->w_buffer != NULL + && win->w_buffer->b_locked > 0)) + return; // window is already being closed + +@@ -7794,4 +7794,13 @@ skip: + + return NULL; // no error + } ++ + #endif ++/* ++ * Don't let autocommands close the given window ++ */ ++ int ++win_locked(win_T *wp) ++{ ++ return wp->w_locked; ++} +-- +2.41.0 + diff --git a/0010-fix-CVE-2024-43802.patch b/0010-fix-CVE-2024-43802.patch new file mode 100644 index 0000000..568412b --- /dev/null +++ b/0010-fix-CVE-2024-43802.patch @@ -0,0 +1,2161 @@ +diff --git a/src/getchar.c b/src/getchar.c +index da05033..3411cc5 100644 +--- a/src/getchar.c ++++ b/src/getchar.c +@@ -439,8 +439,17 @@ flush_buffers(flush_buffers_T flush_typeahead) + if (flush_typeahead == FLUSH_MINIMAL) + { + // remove mapped characters at the start only +- typebuf.tb_off += typebuf.tb_maplen; +- typebuf.tb_len -= typebuf.tb_maplen; ++ // but only when enough space left in typebuf ++ if (typebuf.tb_off + typebuf.tb_maplen >= typebuf.tb_buflen) ++ { ++ typebuf.tb_off = MAXMAPLEN; ++ typebuf.tb_len = 0; ++ } ++ else ++ { ++ typebuf.tb_off += typebuf.tb_maplen; ++ typebuf.tb_len -= typebuf.tb_maplen; ++ } + #if defined(FEAT_CLIENTSERVER) || defined(FEAT_EVAL) + if (typebuf.tb_len == 0) + typebuf_was_filled = FALSE; +diff --git a/src/testdir/crash/heap_overflow3 b/src/testdir/crash/heap_overflow3 +new file mode 100644 +index 0000000..35eff93 +--- /dev/null ++++ b/src/testdir/crash/heap_overflow3 +@@ -0,0 +1,2112 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ vim/src/testdir/crash/heap_overflow3 at master · vim/vim · GitHub ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++
++ Skip to content ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++
++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++ ++
++ ++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++
++
++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++ ++
++ ++
++ ++
++ ++ ++ ++ / ++ ++ vim ++ ++ ++ Public ++
++ ++ ++
++ ++
++ ++ ++
++
++ ++
++
++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++
++ ++ ++ ++ ++
++ ++
++ ++
++
++ ++
++ ++
++

Footer

++ ++ ++ ++ ++
++
++ ++ ++ ++ ++ © 2025 GitHub, Inc. ++ ++
++ ++ ++
++
++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++ ++
++
++ ++ ++ +diff --git a/src/testdir/test_crash.vim b/src/testdir/test_crash.vim +index 233b84d..9f2bbc9 100644 +--- a/src/testdir/test_crash.vim ++++ b/src/testdir/test_crash.vim +@@ -136,6 +136,11 @@ func Test_crash1_2() + \ ' && echo "crash 1: [OK]" > '.. result .. "\") + call TermWait(buf, 150) + ++ let file = 'crash/heap_overflow3' ++ let cmn_args = "%s -u NONE -i NONE -n -X -m -n -e -s -S %s -c ':qa!'" ++ let args = printf(cmn_args, vim, file) ++ call s:RunCommandAndWait(buf, args) ++ + " clean up + exe buf .. "bw!" + +-- +2.41.0 + diff --git a/vim.spec b/vim.spec index 5fa603f..2d00395 100644 --- a/vim.spec +++ b/vim.spec @@ -1,4 +1,4 @@ -%define anolis_release 5 +%define anolis_release 6 %bcond_without gui %bcond_with default_editor @@ -64,6 +64,8 @@ Patch0005: 0005-fix-CVE-2023-48235.patch Patch0006: 0006-fix-CVE-2023-48236.patch Patch0007: 0007-fix-CVE-2023-48237.patch Patch0008: 0008-fix-CVE-2023-48706.patch +Patch0009: 0009-fix-CVE-2024-43374.patch +Patch0010: 0010-fix-CVE-2024-43802.patch Patch1001: 1001-vim-8.0-copy-paste.patch #CVE-2024-22667 @@ -815,6 +817,10 @@ touch %{buildroot}/%{data_dir}/vimfiles/doc/tags %endif %changelog +* Tue May 20 2025 wh02252983 - 3:9.0.2092-6 +- Fix cve regression: +- CVE-2024-43374 and CVE-2024-43802 + * Mon Mar 3 2025 Chang Gao - 3:9.0.2092-5 - Fix cve regression: - CVE-2023-48231~CVE-2023-48237 and CVE-2023-48706 -- Gitee