0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.0.2142: [security]: stack-buffer-overflow in option callback functions

Problem:  [security]: stack-buffer-overflow in option callback functions
Solution: pass size of errbuf down the call stack, use snprintf()
          instead of sprintf()

We pass the error buffer down to the option callback functions, but in
some parts of the code, we simply use sprintf(buf) to write into the error
buffer, which can overflow.

So let's pass down the length of the error buffer and use sprintf(buf, size)
instead.

Reported by @henices, thanks!

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2023-11-29 11:34:05 +01:00
parent 0fb375aae6
commit b39b240c38
9 changed files with 63 additions and 31 deletions

View File

@@ -1932,6 +1932,7 @@ do_set_option_string(
int cp_val,
char_u *varp_arg,
char *errbuf,
int errbuflen,
int *value_checked,
char **errmsg)
{
@@ -2030,7 +2031,7 @@ do_set_option_string(
// be triggered that can cause havoc.
*errmsg = did_set_string_option(
opt_idx, (char_u **)varp, oldval, newval, errbuf,
opt_flags, op, value_checked);
errbuflen, opt_flags, op, value_checked);
secure = secure_saved;
}
@@ -2287,7 +2288,7 @@ do_set_option_value(
{
// string option
if (do_set_option_string(opt_idx, opt_flags, &arg, nextchar, op,
flags, cp_val, varp, errbuf,
flags, cp_val, varp, errbuf, errbuflen,
&value_checked, &errmsg) == FAIL)
{
if (errmsg != NULL)
@@ -2579,12 +2580,12 @@ do_set(
{
int stopopteval = FALSE;
char *errmsg = NULL;
char errbuf[80];
char errbuf[ERR_BUFLEN];
char_u *startarg = arg;
errmsg = do_set_option(opt_flags, &arg, arg_start, &startarg,
&did_show, &stopopteval, errbuf,
sizeof(errbuf));
ERR_BUFLEN);
if (stopopteval)
break;
@@ -5347,7 +5348,8 @@ set_option_value(
int opt_idx;
char_u *varp;
long_u flags;
static char errbuf[80];
static char errbuf[ERR_BUFLEN];
int errbuflen = ERR_BUFLEN;
opt_idx = findoption(name);
if (opt_idx < 0)
@@ -5390,7 +5392,7 @@ set_option_value(
}
#endif
if (flags & P_STRING)
return set_string_option(opt_idx, string, opt_flags, errbuf);
return set_string_option(opt_idx, string, opt_flags, errbuf, errbuflen);
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
if (varp != NULL) // hidden option is not changed