aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/grep.c
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-07-16 14:50:41 -0700
committerRob Landley <rob@landley.net>2019-07-16 23:10:54 -0500
commitfdd58dc338b5d1797bb7f44f2602ed60b1c7b911 (patch)
tree3344059ce510d11bb919ce4b107f1dce74291a6d /toys/posix/grep.c
parenta61cb72deaefe4e6d6ac97a3776ea3c58502766d (diff)
downloadtoybox-fdd58dc338b5d1797bb7f44f2602ed60b1c7b911.tar.gz
grep: fix two bugs found by hwasan.
The first bug appeared as a memory overwrite, but was actually visible without hwasan: basically any `grep -F` that let to multiple matches on the same line was broken. The second bug was another memory overwrite, visible when I ran the existing grep tests. Bug: http://b/137573082
Diffstat (limited to 'toys/posix/grep.c')
-rw-r--r--toys/posix/grep.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/toys/posix/grep.c b/toys/posix/grep.c
index b92294ed..54d72c13 100644
--- a/toys/posix/grep.c
+++ b/toys/posix/grep.c
@@ -177,18 +177,19 @@ static void do_grep(int fd, char *name)
if (FLAG(x)) {
if (!(FLAG(i) ? strcasecmp : strcmp)(seek->arg, line)) s = line;
} else if (!*seek->arg) {
+ // No need to set fseek.next because this will match every line.
seek = &fseek;
fseek.arg = s = line;
- } else if (FLAG(i)) s = strcasestr(line, seek->arg);
- else s = strstr(line, seek->arg);
+ } else if (FLAG(i)) s = strcasestr(start, seek->arg);
+ else s = strstr(start, seek->arg);
if (s) break;
}
if (s) {
rc = 0;
- mm->rm_so = (s-line);
- mm->rm_eo = (s-line)+strlen(seek->arg);
+ mm->rm_so = (s-start);
+ mm->rm_eo = (s-start)+strlen(seek->arg);
} else rc = 1;
// Handle regex matches
@@ -274,7 +275,7 @@ static void do_grep(int fd, char *name)
if (!FLAG(c)) {
long bcount = 1 + offset + (start-line) + (FLAG(o) ? mm->rm_so : 0);
-
+
if (bin) printf("Binary file %s matches\n", name);
else if (FLAG(o))
outline(start+mm->rm_so, ':', name, lcount, bcount,
@@ -282,7 +283,7 @@ static void do_grep(int fd, char *name)
else {
while (dlb) {
struct double_list *dl = dlist_pop(&dlb);
- unsigned *uu = (void *)(dl->data+((strlen(dl->data)+1)|3)+1);
+ unsigned *uu = (void *)(dl->data+((strlen(dl->data)+1)|3));
outline(dl->data, '-', name, lcount-before, uu[0]+1, uu[1]);
free(dl->data);
@@ -328,7 +329,7 @@ static void do_grep(int fd, char *name)
unsigned *uu, ul = (ulen+1)|3;
line = xrealloc(line, ul+8);
- uu = (void *)(line+ul+1);
+ uu = (void *)(line+ul);
uu[0] = offset-len;
uu[1] = ulen;
dlist_add(&dlb, line);