fix CVE-2023-4736 CVE-2023-4733 CVE-2023-4734 CVE-2023-4735

(cherry picked from commit 1f97a3d5951002935a4abf4dbefb1b843d6b099f)
This commit is contained in:
wangjiang 2023-09-07 06:54:45 +00:00 committed by openeuler-sync-bot
parent 3d28f9eecb
commit 49a60b4e33
7 changed files with 477 additions and 1 deletions

View File

@ -0,0 +1,43 @@
From e1dc9a627536304bc4f738c21e909ad9fcf3974c Mon Sep 17 00:00:00 2001
From: Christian Brabandt <cb@256bit.org>
Date: Sat, 2 Sep 2023 14:40:13 +0200
Subject: [PATCH 13/52] patch 9.0.1840: [security] use-after-free in do_ecmd
Problem: use-after-free in do_ecmd
Solution: Verify oldwin pointer after reset_VIsual()
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
src/ex_cmds.c | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 20d4d9a2e..9348b4edd 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2603,12 +2603,18 @@ do_ecmd(
goto theend;
}
- /*
- * End Visual mode before switching to another buffer, so the text can be
- * copied into the GUI selection buffer.
- */
+
+ // End Visual mode before switching to another buffer, so the text can be
+ // copied into the GUI selection buffer.
+ // Careful: may trigger ModeChanged() autocommand
+
+ // Should we block autocommands here?
reset_VIsual();
+ // autocommands freed window :(
+ if (oldwin != NULL && !win_valid(oldwin))
+ oldwin = NULL;
+
#if defined(FEAT_EVAL)
if ((command != NULL || newlnum > (linenr_T)0)
&& *get_vim_var_str(VV_SWAPCOMMAND) == NUL)
--
2.33.0

View File

@ -0,0 +1,44 @@
From 4c6fe2e2ea62469642ed1d80b16d39e616b25cf5 Mon Sep 17 00:00:00 2001
From: Christian Brabandt <cb@256bit.org>
Date: Sat, 2 Sep 2023 19:30:03 +0200
Subject: [PATCH 21/52] patch 9.0.1846: [security] crash in fullcommand
Problem: crash in fullcommand
Solution: Check for typeval correctly
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
src/ex_docmd.c | 2 +-
src/testdir/test_functions.vim | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 32d52ab21..10d979d49 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -4047,7 +4047,7 @@ f_fullcommand(typval_T *argvars, typval_T *rettv)
|| check_for_opt_bool_arg(argvars, 1) == FAIL))
return;
- name = argvars[0].vval.v_string;
+ name = tv_get_string(&argvars[0]);
if (name == NULL)
return;
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 0eda5de38..ab1dbf3b5 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -2962,4 +2962,9 @@ func Test_virtcol()
bwipe!
endfunc
+func Test_fullcommand()
+ " this used to crash vim
+ call assert_equal('', fullcommand(10))
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
--
2.33.0

View File

@ -0,0 +1,30 @@
From 889f6af37164775192e33b233a90e86fd3df0f57 Mon Sep 17 00:00:00 2001
From: Christian Brabandt <cb@256bit.org>
Date: Sat, 2 Sep 2023 19:43:33 +0200
Subject: [PATCH 22/52] patch 9.0.1847: [security] potential oob write in
do_addsub()
Problem: potential oob write in do_addsub()
Solution: don't overflow buf2, check size in for loop()
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
src/ops.c | 2 +-
1 files changed, 1 insertions(+), 1 deletion(-)
diff --git a/src/ops.c b/src/ops.c
index d46a049fe..f4524d3d7 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -2848,7 +2848,7 @@ do_addsub(
for (bit = bits; bit > 0; bit--)
if ((n >> (bit - 1)) & 0x1) break;
- for (i = 0; bit > 0; bit--)
+ for (i = 0; bit > 0 && i < (NUMBUFLEN - 1); bit--)
buf2[i++] = ((n >> (bit - 1)) & 0x1) ? '1' : '0';
buf2[i] = '\0';
--
2.33.0

View File

@ -0,0 +1,167 @@
From 816fbcc262687b81fc46f82f7bbeb1453addfe0c Mon Sep 17 00:00:00 2001
From: Christian Brabandt <cb@256bit.org>
Date: Thu, 31 Aug 2023 23:52:30 +0200
Subject: [PATCH] patch 9.0.1833: [security] runtime file fixes
Problem: runtime files may execute code in current dir
Solution: only execute, if not run from current directory
The perl, zig and ruby filetype plugins and the zip and gzip autoload
plugins may try to load malicious executable files from the current
working directory. This is especially a problem on windows, where the
current directory is implicitly in your $PATH and windows may even run a
file with the extension `.bat` because of $PATHEXT.
So make sure that we are not trying to execute a file from the current
directory. If this would be the case, error out (for the zip and gzip)
plugins or silently do not run those commands (for the ftplugins).
This assumes, that only the current working directory is bad. For all
other directories, it is assumed that those directories were
intentionally set to the $PATH by the user.
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
runtime/autoload/gzip.vim | 7 +++-
runtime/autoload/zip.vim | 4 +++
runtime/ftplugin/perl.vim | 3 +-
runtime/ftplugin/ruby.vim | 68 ++++++++++++++++++++++-----------------
4 files changed, 51 insertions(+), 31 deletions(-)
diff --git a/runtime/autoload/gzip.vim b/runtime/autoload/gzip.vim
index 95dd9067945af..ac9e37bf85e7e 100644
--- a/runtime/autoload/gzip.vim
+++ b/runtime/autoload/gzip.vim
@@ -9,12 +9,17 @@
fun s:check(cmd)
let name = substitute(a:cmd, '\(\S*\).*', '\1', '')
if !exists("s:have_" . name)
+ " safety check, don't execute anything from the current directory
+ let f = fnamemodify(exepath(name), ":p:h") !=# getcwd()
+ if !f
+ echoerr "Warning: NOT executing " .. name .. " from current directory!"
+ endif
let e = executable(name)
if e < 0
let r = system(name . " --version")
let e = (r !~ "not found" && r != "")
endif
- exe "let s:have_" . name . "=" . e
+ exe "let s:have_" . name . "=" . (e && f)
endif
exe "return s:have_" . name
endfun
diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim
index 8dda30c418838..0331a542aca40 100644
--- a/runtime/autoload/zip.vim
+++ b/runtime/autoload/zip.vim
@@ -57,6 +57,10 @@ if !exists("g:zip_extractcmd")
let g:zip_extractcmd= g:zip_unzipcmd
endif
+if fnamemodify(exepath(g:zip_unzipcmd), ":p:h") ==# getcwd()
+ echoerr "Warning: NOT executing " .. g:zip_unzipcmd .. " from current directory!"
+ finish
+endif
" ----------------
" Functions: {{{1
" ----------------
diff --git a/runtime/ftplugin/perl.vim b/runtime/ftplugin/perl.vim
index d0bdbc0cfb158..edc7b960f12f9 100644
--- a/runtime/ftplugin/perl.vim
+++ b/runtime/ftplugin/perl.vim
@@ -54,7 +54,8 @@ endif
" Set this once, globally.
if !exists("perlpath")
- if executable("perl")
+ " safety check: don't execute perl from current directory
+ if executable("perl") && fnamemodify(exepath("perl"), ":p:h") != getcwd()
try
if &shellxquote != '"'
let perlpath = system('perl -e "print join(q/,/,@INC)"')
diff --git a/runtime/ftplugin/ruby.vim b/runtime/ftplugin/ruby.vim
index 8c1f47731c351..f4e1f60438921 100644
--- a/runtime/ftplugin/ruby.vim
+++ b/runtime/ftplugin/ruby.vim
@@ -99,41 +99,51 @@ function! s:build_path(path) abort
return path
endfunction
-if !exists('b:ruby_version') && !exists('g:ruby_path') && isdirectory(expand('%:p:h'))
- let s:version_file = findfile('.ruby-version', '.;')
- if !empty(s:version_file) && filereadable(s:version_file)
- let b:ruby_version = get(readfile(s:version_file, '', 1), '')
- if !has_key(g:ruby_version_paths, b:ruby_version)
- let g:ruby_version_paths[b:ruby_version] = s:query_path(fnamemodify(s:version_file, ':p:h'))
+let s:execute_ruby = 1
+" Security Check, don't execute ruby from the current directory
+if fnamemodify(exepath("ruby"), ":p:h") ==# getcwd()
+ let s:execute_ruby = 0
+endif
+
+function SetRubyPath()
+ if !exists('b:ruby_version') && !exists('g:ruby_path') && isdirectory(expand('%:p:h'))
+ let s:version_file = findfile('.ruby-version', '.;')
+ if !empty(s:version_file) && filereadable(s:version_file) && s:execute_ruby
+ let b:ruby_version = get(readfile(s:version_file, '', 1), '')
+ if !has_key(g:ruby_version_paths, b:ruby_version)
+ let g:ruby_version_paths[b:ruby_version] = s:query_path(fnamemodify(s:version_file, ':p:h'))
+ endif
endif
endif
-endif
-if exists("g:ruby_path")
- let s:ruby_path = type(g:ruby_path) == type([]) ? join(g:ruby_path, ',') : g:ruby_path
-elseif has_key(g:ruby_version_paths, get(b:, 'ruby_version', ''))
- let s:ruby_paths = g:ruby_version_paths[b:ruby_version]
- let s:ruby_path = s:build_path(s:ruby_paths)
-else
- if !exists('g:ruby_default_path')
- if has("ruby") && has("win32")
- ruby ::VIM::command( 'let g:ruby_default_path = split("%s",",")' % $:.join(%q{,}) )
- elseif executable('ruby') && !empty($HOME)
- let g:ruby_default_path = s:query_path($HOME)
- else
- let g:ruby_default_path = map(split($RUBYLIB,':'), 'v:val ==# "." ? "" : v:val')
+ if exists("g:ruby_path")
+ let s:ruby_path = type(g:ruby_path) == type([]) ? join(g:ruby_path, ',') : g:ruby_path
+ elseif has_key(g:ruby_version_paths, get(b:, 'ruby_version', '')) && s:execute_ruby
+ let s:ruby_paths = g:ruby_version_paths[b:ruby_version]
+ let s:ruby_path = s:build_path(s:ruby_paths)
+ else
+ if !exists('g:ruby_default_path')
+ if has("ruby") && has("win32")
+ ruby ::VIM::command( 'let g:ruby_default_path = split("%s",",")' % $:.join(%q{,}) )
+ elseif executable('ruby') && !empty($HOME) && s:execute_ruby
+ let g:ruby_default_path = s:query_path($HOME)
+ else
+ let g:ruby_default_path = map(split($RUBYLIB,':'), 'v:val ==# "." ? "" : v:val')
+ endif
endif
+ let s:ruby_paths = g:ruby_default_path
+ let s:ruby_path = s:build_path(s:ruby_paths)
endif
- let s:ruby_paths = g:ruby_default_path
- let s:ruby_path = s:build_path(s:ruby_paths)
-endif
-if stridx(&l:path, s:ruby_path) == -1
- let &l:path = s:ruby_path
-endif
-if exists('s:ruby_paths') && stridx(&l:tags, join(map(copy(s:ruby_paths),'v:val."/tags"'),',')) == -1
- let &l:tags = &tags . ',' . join(map(copy(s:ruby_paths),'v:val."/tags"'),',')
-endif
+ if stridx(&l:path, s:ruby_path) == -1
+ let &l:path = s:ruby_path
+ endif
+ if exists('s:ruby_paths') && stridx(&l:tags, join(map(copy(s:ruby_paths),'v:val."/tags"'),',')) == -1
+ let &l:tags = &tags . ',' . join(map(copy(s:ruby_paths),'v:val."/tags"'),',')
+ endif
+endfunction
+
+call SetRubyPath()
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
let b:browsefilter = "Ruby Source Files (*.rb)\t*.rb\n" .

View File

@ -0,0 +1,156 @@
From aa5341477c9f3840d63f709de3b9e5d0266f93d7 Mon Sep 17 00:00:00 2001
From: Bram Moolenaar <Bram@vim.org>
Date: Thu, 15 Sep 2022 21:46:02 +0100
Subject: [PATCH] patch 9.0.0473: fullcommand() only works for the current
script version
Problem: fullcommand() only works for the current script version.
Solution: Add an optional argument for the script version.
---
runtime/doc/builtin.txt | 14 ++++++++++----
src/ex_docmd.c | 30 +++++++++++++++++++++++-------
src/testdir/test_cmdline.vim | 3 +++
src/testdir/test_vim9_builtin.vim | 7 +++++++
4 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index fb8b116010095..53179ca85aba6 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -195,7 +195,7 @@ foldlevel({lnum}) Number fold level at {lnum}
foldtext() String line displayed for closed fold
foldtextresult({lnum}) String text for closed fold at {lnum}
foreground() Number bring the Vim window to the foreground
-fullcommand({name}) String get full command from {name}
+fullcommand({name} [, {vim9}]) String get full command from {name}
funcref({name} [, {arglist}] [, {dict}])
Funcref reference to function {name}
function({name} [, {arglist}] [, {dict}])
@@ -2954,14 +2954,20 @@ foreground() Move the Vim window to the foreground. Useful when sent from
{only in the Win32, Motif and GTK GUI versions and the
Win32 console version}
-fullcommand({name}) *fullcommand()*
+fullcommand({name} [, {vim9}]) *fullcommand()*
Get the full command name from a short abbreviated command
name; see |20.2| for details on command abbreviations.
The string argument {name} may start with a `:` and can
include a [range], these are skipped and not returned.
- Returns an empty string if a command doesn't exist or if it's
- ambiguous (for user-defined commands).
+ Returns an empty string if a command doesn't exist, if it's
+ ambiguous (for user-defined commands) or cannot be shortened
+ this way. |vim9-no-shorten|
+
+ Without the {vim9} argument uses the current script version.
+ If {vim9} is present and FALSE then legacy script rules are
+ used. When {vim9} is present and TRUE then Vim9 rules are
+ used, e.g. "en" is not a short form of "endif".
For example `fullcommand('s')`, `fullcommand('sub')`,
`fullcommand(':%substitute')` all return "substitute".
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 0e5e1db5ecd87..814f1b6f8a5a8 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -4033,20 +4033,31 @@ cmd_exists(char_u *name)
void
f_fullcommand(typval_T *argvars, typval_T *rettv)
{
- exarg_T ea;
- char_u *name;
- char_u *p;
+ exarg_T ea;
+ char_u *name;
+ char_u *p;
+ int vim9script = in_vim9script();
+ int save_cmod_flags = cmdmod.cmod_flags;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+ if (in_vim9script()
+ && (check_for_string_arg(argvars, 0) == FAIL
+ || check_for_opt_bool_arg(argvars, 1) == FAIL))
return;
name = argvars[0].vval.v_string;
if (name == NULL)
return;
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ {
+ vim9script = tv_get_bool(&argvars[1]);
+ cmdmod.cmod_flags &= ~(CMOD_VIM9CMD | CMOD_LEGACY);
+ cmdmod.cmod_flags |= vim9script ? CMOD_VIM9CMD : CMOD_LEGACY;
+ }
+
while (*name == ':')
name++;
name = skip_range(name, TRUE, NULL);
@@ -4054,10 +4065,13 @@ f_fullcommand(typval_T *argvars, typval_T *rettv)
ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
ea.cmdidx = (cmdidx_T)0;
ea.addr_count = 0;
+ ++emsg_silent; // don't complain about using "en" in Vim9 script
p = find_ex_command(&ea, NULL, NULL, NULL);
+ --emsg_silent;
if (p == NULL || ea.cmdidx == CMD_SIZE)
- return;
- if (in_vim9script())
+ goto theend;
+
+ if (vim9script)
{
int res;
@@ -4066,12 +4080,14 @@ f_fullcommand(typval_T *argvars, typval_T *rettv)
--emsg_silent;
if (res == FAIL)
- return;
+ goto theend;
}
rettv->vval.v_string = vim_strsave(IS_USER_CMDIDX(ea.cmdidx)
? get_user_command_name(ea.useridx, ea.cmdidx)
: cmdnames[ea.cmdidx].cmd_name);
+theend:
+ cmdmod.cmod_flags = save_cmod_flags;
}
#endif
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 7febc12269953..27ca8bf841b5c 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -648,6 +648,9 @@ func Test_fullcommand()
\ '3match': 'match',
\ 'aboveleft': 'aboveleft',
\ 'abo': 'aboveleft',
+ \ 'en': 'endif',
+ \ 'end': 'endif',
+ \ 'endi': 'endif',
\ 's': 'substitute',
\ '5s': 'substitute',
\ ':5s': 'substitute',
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 109cb35af6877..dccd99bb321ca 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -1529,6 +1529,13 @@ def Test_fullcommand()
assert_equal('scriptnames', fullcommand('scr'))
assert_equal('', fullcommand('scg'))
fullcommand('')->assert_equal('')
+
+ assert_equal('', fullcommand('en'))
+ legacy call assert_equal('endif', fullcommand('en'))
+ assert_equal('endif', fullcommand('en', 0))
+ legacy call assert_equal('endif', fullcommand('en', 0))
+ assert_equal('', fullcommand('en', 1))
+ legacy call assert_equal('', fullcommand('en', 1))
enddef
def Test_funcref()

View File

@ -0,0 +1,24 @@
From dd44b58f64a173ffc976cc96ccdd00cd5493b273 Mon Sep 17 00:00:00 2001
From: Bram Moolenaar <Bram@vim.org>
Date: Thu, 15 Sep 2022 22:03:57 +0100
Subject: [PATCH] patch 9.0.0474: fullcommand() test failure
Problem: fullcommand() test failure.
Solution: Update function table.
---
src/evalfunc.c | 2 +-
1 files changed, 1 insertions(+), 1 deletion(-)
diff --git a/src/evalfunc.c b/src/evalfunc.c
index cd315629498b0..cab3213469954 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1848,7 +1848,7 @@ static funcentry_T global_functions[] =
ret_string, f_foldtextresult},
{"foreground", 0, 0, 0, NULL,
ret_void, f_foreground},
- {"fullcommand", 1, 1, FEARG_1, arg1_string,
+ {"fullcommand", 1, 2, FEARG_1, arg2_string_bool,
ret_string, f_fullcommand},
{"funcref", 1, 3, FEARG_1, arg3_any_list_dict,
ret_func_unknown, f_funcref},

View File

@ -12,7 +12,7 @@
Name: vim
Epoch: 2
Version: 9.0
Release: 15
Release: 16
Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text.
License: Vim and MIT
URL: http://www.vim.org
@ -96,6 +96,12 @@ Patch6066: backport-vim-7.0-rclocation.patch
Patch6067: backport-CVE-2023-2426.patch
Patch6068: backport-CVE-2023-2609.patch
Patch6069: backport-CVE-2023-2610.patch
Patch6070: backport-CVE-2023-4736.patch
Patch6071: backport-CVE-2023-4733.patch
Patch6072: backport-patch-9.0.0473-fullcommand-only-works-for-the-current-script-version.patch
Patch6073: backport-patch-9.0.0474-fullcommand-testfailure.patch
Patch6074: backport-CVE-2023-4734.patch
Patch6075: backport-CVE-2023-4735.patch
Patch9000: bugfix-rm-modify-info-version.patch
Patch9001: vim-Add-sw64-architecture.patch
@ -504,6 +510,12 @@ LC_ALL=en_US.UTF-8 make -j1 test
%{_mandir}/man1/evim.*
%changelog
* Thu Sep 07 2023 wangjiang <wangjiang37@h-partners.com> - 2:9.0-16
- Type:CVE
- ID:CVE-2023-4736 CVE-2023-4733 CVE-2023-4734 CVE-2023-4735
- SUG:NA
- DESC:fix CVE-2023-4736 CVE-2023-4733 CVE-2023-4734 CVE-2023-4735
* Sat May 13 2023 wangjiang <wangjiang37@h-partners.com> - 2:9.0-15
- Type:CVE
- ID:CVE-2023-2609 CVE-2023-2610