(-cc: my @google.com email) Hi, Junio C Hamano wrote: > Subject: sideband: do not read beyond the end of input > > The caller of maybe_colorize_sideband() gives a counted buffer > <src,n>, but the callee checked *src as if it were a NUL terminated > buffer. If src[] had all isspace() bytes in it, we would have made > n negative, and then (1) called number of strncasecmp() to see if > the remaining bytes in src[] matched keywords, reading beyond the > end of the array, and/or (2) called strbuf_add() with negative > count, most likely triggering the "you want to use way too much > memory" error due to unsigned integer overflow. > > Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> > --- > sideband.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) This indeed avoids the "you want to use way too much memory" error when I apply it. > --- a/sideband.c > +++ b/sideband.c > @@ -75,7 +75,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) Not about this patch: should the 'n' parameter be a size_t instead of an int? It doesn't matter in practice (since the caller has an int, it can never be more than INT_MAX) but it might make the intent clearer. Based on inspecting the caller, using an int seems fine. > return; > } > > - while (isspace(*src)) { > + while (0 < n && isspace(*src)) { Yes, we need to check 'n && isspace(*src)' to avoid overflowing the buffer if it consists entirely of spaces. > strbuf_addch(dest, *src); > src++; > n--; > @@ -84,6 +84,9 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) > for (i = 0; i < ARRAY_SIZE(keywords); i++) { > struct keyword_entry *p = keywords + i; > int len = strlen(p->keyword); > + > + if (n <= len) > + continue; Using <= instead of < since we look at the character after the word as well. Good. > /* > * Match case insensitively, so we colorize output from existing > * servers regardless of the case that they use for their > * messages. We only highlight the word precisely, so > * "successful" stays uncolored. > */ > if (!strncasecmp(p->keyword, src, len) && !isalnum(src[len])) { Not about this patch: should this check "&& src[len] == ':'" instead, as discussed upthread? > @@ -100,8 +103,8 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) > } > } > > - strbuf_add(dest, src, n); > + if (0 < n) > + strbuf_add(dest, src, n); This check seems unnecessary. strbuf_add can cope fine with !n. Should we put assert(n >= 0); or even if (n < 0) BUG(); instead, since the earlier part of the fix guarantees that n >= 0? Thanks for the careful work. With or without such a change, Reviewed-by: Jonathan Nieder <jrnieder@xxxxxxxxx> Thanks.