config.c: avoid integer truncation in `copy_or_rename_section_in_file()`

There are a couple of spots within `copy_or_rename_section_in_file()`
that incorrectly use an `int` to track an offset within a string, which
may truncate or wrap around to a negative value.

Historically it was impossible to have a line longer than 1024 bytes
anyway, since we used fgets() with a fixed-size buffer of exactly that
length. But the recent change to use a strbuf permits us to read lines
of arbitrary length, so it's possible for a malicious input to cause us
to overflow past INT_MAX and do an out-of-bounds array read.

Practically speaking, however, this should never happen, since it
requires 2GB section names or values, which are unrealistic in
non-malicious circumstances.

Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
maint
Taylor Blau 2023-04-06 14:28:53 -04:00 committed by Johannes Schindelin
parent a5bb10fd5e
commit e91cfe6085
1 changed files with 5 additions and 5 deletions

View File

@ -3027,9 +3027,10 @@ void git_config_set_multivar(const char *key, const char *value,
flags); flags);
} }


static int section_name_match (const char *buf, const char *name) static size_t section_name_match (const char *buf, const char *name)
{ {
int i = 0, j = 0, dot = 0; size_t i = 0, j = 0;
int dot = 0;
if (buf[i] != '[') if (buf[i] != '[')
return 0; return 0;
for (i = 1; buf[i] && buf[i] != ']'; i++) { for (i = 1; buf[i] && buf[i] != ']'; i++) {
@ -3133,15 +3134,14 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
} }


while (!strbuf_getwholeline(&buf, config_file, '\n')) { while (!strbuf_getwholeline(&buf, config_file, '\n')) {
unsigned i; size_t i, length;
int length;
int is_section = 0; int is_section = 0;
char *output = buf.buf; char *output = buf.buf;
for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++) for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++)
; /* do nothing */ ; /* do nothing */
if (buf.buf[i] == '[') { if (buf.buf[i] == '[') {
/* it's a section */ /* it's a section */
int offset; size_t offset;
is_section = 1; is_section = 1;


/* /*