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
This commit is contained in:
Elliott Hughes 2019-03-29 21:59:17 -07:00
parent 43f29072a9
commit bfd9d63c74
1 changed files with 11 additions and 11 deletions

View File

@ -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;