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(-)
From 2c0908076a42da515e9654bd0de0158c6d5565e7 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <[email protected]>
Date: Tue, 16 Jul 2019 14:50:41 -0700
Subject: [PATCH] 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);
-- 
2.22.0.510.g264f2c817a-goog

_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to