[Bug 197555] [patch] bsdgrep segfaults with --color and overlapping patterns

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Feb 12 02:11:27 UTC 2015


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197555

            Bug ID: 197555
           Summary: [patch] bsdgrep segfaults with --color and overlapping
                    patterns
           Product: Base System
           Version: 10.1-RELEASE
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: bin
          Assignee: freebsd-bugs at FreeBSD.org
          Reporter: loadzero.dev at gmail.com

Created attachment 152888
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=152888&action=edit
add an assert to printline to aid debugging

My machine details

uname -a

FreeBSD vagrant-freebsd-10 10.1-RELEASE FreeBSD 10.1-RELEASE #0 r274401: Tue
Nov 11 21:02:49 UTC 2014    
root at releng1.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64

On my 10.1 x86-64 machine, /usr/bin/bsdgrep segfaults when I use it like this

echo i860 | bsdgrep --color -e i860 -e i86
i860
i860
Segmentation fault (core dumped)

With color disabled, it gives the correct output

echo i860 | bsdgrep -e i860 -e i86 
i860

this is the same binary from the 10.1 x86-64 release iso

openssl md5 /usr/bin/bsdgrep
MD5(/usr/bin/bsdgrep)= 46015e84adebfbaab878a40e8e99ecfd

gdb shows this (for the released binary)

echo i860 > /tmp/p
gdb --args /usr/bin/bsdgrep --color -e i860 -e i86 /tmp/p

Program received signal SIGSEGV, Segmentation fault.
0x00000008011cca60 in memchr () from /lib/libc.so.7
(gdb) bt
#0  0x00000008011cca60 in memchr () from /lib/libc.so.7
#1  0x00000008011cc599 in fwrite () from /lib/libc.so.7
#2  0x00000008011cc43d in fwrite () from /lib/libc.so.7
#3  0x0000000000404d63 in ?? ()
#4  0x00000000004047ca in ?? ()
#5  0x00000000004038a5 in ?? ()
#6  0x00000000004023bf in ?? ()
#7  0x0000000800629000 in ?? ()
#8  0x0000000000000000 in ?? ()

I have built a debug binary from STABLE, here is the svn info

svn info
Path: .
Working Copy Root Path: /usr/home/vagrant/stable/src
URL: http://svn.freebsd.org/base/stable/10/usr.bin/grep
Relative URL: ^/stable/10/usr.bin/grep
Repository Root: http://svn.freebsd.org/base
Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
Revision: 278579
Node Kind: directory
Schedule: normal
Last Changed Author: delphij
Last Changed Rev: 278175
Last Changed Date: 2015-02-04 00:45:02 +0000 (Wed, 04 Feb 2015)

gdb gives this backtrace

Starting program: /usr/home/vagrant/stable/src/usr.bin/grep/bsdgrep --color -e
i860 -e i86 /tmp/p
i860
i860

Program received signal SIGSEGV, Segmentation fault.
0x00000008011d1a60 in memchr () from /lib/libc.so.7
(gdb) bt
#0  0x00000008011d1a60 in memchr () from /lib/libc.so.7
#1  0x00000008011d1599 in fwrite () from /lib/libc.so.7
#2  0x00000008011d143d in fwrite () from /lib/libc.so.7
#3  0x00000000004062fc in printline (line=0x7fffffffe878, sep=58,
matches=0x7fffffffe710, m=2) at util.c:469
#4  0x0000000000405eef in procline (l=0x7fffffffe878, nottext=0) at util.c:366
#5  0x0000000000405588 in procfile (fn=0x7fffffffed69 "/tmp/p") at util.c:231
#6  0x0000000000404292 in main (argc=7, argv=0x7fffffffeab8) at grep.c:738
(gdb) 

valgrind gives a similar result

valgrind --db-attach=yes --track-origins=yes ./bsdgrep --color -e i860 -epi86
/tmp/ 
==60168== Memcheck, a memory error detector
==60168== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==60168== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==60168== Command: ./bsdgrep --color -e i860 -e i86 /tmp/p
==60168== 
i860
==60168== Conditional jump or move depends on uninitialised value(s)
==60168==    at 0x1020E54: memchr (in
/usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==60168==    by 0x1BC8598: ??? (in /lib/libc.so.7)
==60168==    by 0x1BC843C: fwrite (in /lib/libc.so.7)
==60168==    by 0x4062FB: printline (util.c:469)
==60168==    by 0x405EEE: procline (util.c:366)
==60168==    by 0x405587: procfile (util.c:231)
==60168==    by 0x404291: main (grep.c:738)
==60168==  Uninitialised value was created by a heap allocation
==60168==    at 0x101D2B3: malloc (in
/usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==60168==    by 0x405814: grep_malloc (util.c:390)
==60168==    by 0x402CBA: grep_open (file.c:285)
==60168==    by 0x40535A: procfile (util.c:194)
==60168==    by 0x404291: main (grep.c:738)
==60168== 
==60168==

After poking around in the code, it appears that the bug manifests inside
printline util.c:469

i is 1
matches[i].rm_so is a reg_off_t (int) with value 0
a is a size_t with value 4

so fwrite gets handed a really large bogus size parameter of size_t (-4)

464         putchar(sep);
465     /* --color and -o */
466     if ((oflag || color) && m > 0) {
467         for (i = 0; i < m; i++) {
468             if (!oflag)
469                 fwrite(line->dat + a, matches[i].rm_so - a, 1,
470                     stdout);
471             if (color) 
472                 fprintf(stdout, "\33[%sm\33[K", color);
473 
474                 fwrite(line->dat + matches[i].rm_so, 

It appears that printline is not expecting any overlapping matches, but it has
been handed two with these offsets

rm_so 0 rm_eo 4 
rm_so 0 rm_eo 3

So, either the bug is in the handling printing of the matches, or in the
generation of them. 
It possibly relates to https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197531

I have attached a patch to aid in debugging.

As a side note, I first ran into this bug on Mac OSX, where they are using a
variant of bsdgrep as the the default grep

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list