From fdd58dc338b5d1797bb7f44f2602ed60b1c7b911 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 16 Jul 2019 14:50:41 -0700 Subject: 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 --- tests/grep.test | 13 +++++++++++++ toys/posix/grep.c | 15 ++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/tests/grep.test b/tests/grep.test index 68c8dd85..76f406c8 100755 --- a/tests/grep.test +++ b/tests/grep.test @@ -184,3 +184,16 @@ ln -s ../dir sub/link testing "" "grep -rh hello sub" "" "" "" testing "" "grep -Rh hello sub" "hello\n" "" "" rm -rf sub real + +# -F multiple matches +testing "-F multiple" "grep -F h input" "this is hello\nthis is world\n" \ + "missing\nthis is hello\nthis is world\nmissing" "" +testing "-Fi multiple" "grep -Fi h input" "this is HELLO\nthis is WORLD\n" \ + "missing\nthis is HELLO\nthis is WORLD\nmissing" "" +testing "-F empty multiple" "grep -Fi '' input" \ + "missing\nthis is HELLO\nthis is WORLD\nmissing\n" \ + "missing\nthis is HELLO\nthis is WORLD\nmissing" "" +testing "-Fx" "grep -Fx h input" "h\n" \ + "missing\nH\nthis is hello\nthis is world\nh\nmissing" "" +testing "-Fix" "grep -Fix h input" "H\nh\n" \ + "missing\nH\nthis is HELLO\nthis is WORLD\nh\nmissing" "" 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); -- cgit v1.2.3