From bfd9d63c74a55d094850b82112b54fe42c3edfa4 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 29 Mar 2019 21:59:17 -0700 Subject: [PATCH] grep: fix ASan heap-buffer-overflow. Like the regular fgetln(), grep_fgetln() doesn't NUL-terminate the string, which regexec() doesn't like. ASan just gained the ability to intercept regexec(), which is why we didn't find this previously. Bug: http://b/129089665 Test: adb shell grep -R /system -e "abc" Test: toybox grep tests Change-Id: Id707cea66a873b83bd763a3dcdf726ac7d062ce0 --- toolbox/upstream-netbsd/usr.bin/grep/file.c | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/toolbox/upstream-netbsd/usr.bin/grep/file.c b/toolbox/upstream-netbsd/usr.bin/grep/file.c index ef057ba15..428bf583b 100644 --- a/toolbox/upstream-netbsd/usr.bin/grep/file.c +++ b/toolbox/upstream-netbsd/usr.bin/grep/file.c @@ -63,7 +63,7 @@ static gzFile gzbufdesc; static BZFILE* bzbufdesc; #endif -static unsigned char buffer[MAXBUFSIZ]; +static unsigned char buffer[MAXBUFSIZ + 1]; static unsigned char *bufpos; static size_t bufrem; @@ -128,7 +128,7 @@ grep_refill(struct file *f) return (0); } -static inline int +static inline void grep_lnbufgrow(size_t newlen) { @@ -136,8 +136,6 @@ grep_lnbufgrow(size_t newlen) lnbuf = grep_realloc(lnbuf, newlen); lnbuflen = newlen; } - - return (0); } char * @@ -162,20 +160,22 @@ grep_fgetln(struct file *f, size_t *lenp) /* Look for a newline in the remaining part of the buffer */ if ((p = memchr(bufpos, line_sep, bufrem)) != NULL) { ++p; /* advance over newline */ - ret = (char *)bufpos; len = p - bufpos; + grep_lnbufgrow(len + 1); + memcpy(lnbuf, bufpos, len); + lnbuf[len] = '\0'; + *lenp = len; bufrem -= len; bufpos = p; - *lenp = len; - return (ret); + return ((char *)lnbuf); } /* We have to copy the current buffered data to the line buffer */ for (len = bufrem, off = 0; ; len += bufrem) { /* Make sure there is room for more data */ - if (grep_lnbufgrow(len + LNBUFBUMP)) - goto error; + grep_lnbufgrow(len + LNBUFBUMP); memcpy(lnbuf + off, bufpos, len - off); + lnbuf[len] = '\0'; off = len; if (grep_refill(f) != 0) goto error; @@ -188,9 +188,9 @@ grep_fgetln(struct file *f, size_t *lenp) ++p; diff = p - bufpos; len += diff; - if (grep_lnbufgrow(len)) - goto error; + grep_lnbufgrow(len + 1); memcpy(lnbuf + off, bufpos, diff); + lnbuf[off + diff] = '\0'; bufrem -= diff; bufpos = p; break;