mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:9.0.2068: [security] overflow in :history (#25794)
Problem: [security] overflow in :history
Solution: Check that value fits into int
The get_list_range() function, used to parse numbers for the :history
and :clist command internally uses long variables to store the numbers.
However function arguments are integer pointers, which can then
overflow.
Check that the return value from the vim_str2nr() function is not larger
than INT_MAX and if yes, bail out with an error. I guess nobody uses a
cmdline/clist history that needs so many entries... (famous last words).
It is only a moderate vulnerability, so impact should be low.
Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-q22m-h7m2-9mgm
9198c1f2b1
N/A patch:
vim-patch:9.0.2073: typo in quickfix.c comments
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
ba6761eafe
commit
9dc440400c
@ -34,6 +34,8 @@
|
|||||||
# include "cmdhist.c.generated.h"
|
# include "cmdhist.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const char e_val_too_large[] = N_("E1510: Value too large: %s");
|
||||||
|
|
||||||
static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL };
|
static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL };
|
||||||
static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; ///< lastused entry
|
static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; ///< lastused entry
|
||||||
/// identifying (unique) number of newest history entry
|
/// identifying (unique) number of newest history entry
|
||||||
@ -637,7 +639,11 @@ void ex_history(exarg_T *eap)
|
|||||||
end = arg;
|
end = arg;
|
||||||
}
|
}
|
||||||
if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL) {
|
if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL) {
|
||||||
semsg(_(e_trailing_arg), end);
|
if (*end != NUL) {
|
||||||
|
semsg(_(e_trailing_arg), end);
|
||||||
|
} else {
|
||||||
|
semsg(_(e_val_too_large), arg);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4241,6 +4241,11 @@ int get_list_range(char **str, int *num1, int *num2)
|
|||||||
if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range
|
if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range
|
||||||
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false, NULL);
|
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false, NULL);
|
||||||
*str += len;
|
*str += len;
|
||||||
|
// overflow
|
||||||
|
if (num > INT_MAX) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
*num1 = (int)num;
|
*num1 = (int)num;
|
||||||
first = true;
|
first = true;
|
||||||
}
|
}
|
||||||
@ -4249,8 +4254,13 @@ int get_list_range(char **str, int *num1, int *num2)
|
|||||||
*str = skipwhite((*str) + 1);
|
*str = skipwhite((*str) + 1);
|
||||||
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false, NULL);
|
vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false, NULL);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
*num2 = (int)num;
|
|
||||||
*str = skipwhite((*str) + len);
|
*str = skipwhite((*str) + len);
|
||||||
|
// overflow
|
||||||
|
if (num > INT_MAX) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*num2 = (int)num;
|
||||||
} else if (!first) { // no number given at all
|
} else if (!first) { // no number given at all
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
@ -254,4 +254,12 @@ func Test_history_crypt_key()
|
|||||||
set key& bs& ts&
|
set key& bs& ts&
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" The following used to overflow and causing an use-after-free
|
||||||
|
func Test_history_max_val()
|
||||||
|
|
||||||
|
set history=10
|
||||||
|
call assert_fails(':history 2147483648', 'E1510:')
|
||||||
|
set history&
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
Loading…
Reference in New Issue
Block a user