tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

grep vs. CVE-2012-5667 (integer type too small)



Hi,

alerted by the oss-security mailing list, I've looked at
CVE-2012-5667, which was triggered by a bug report of an
Ubuntu user.

In short: lines > 2^31 bytes make grep core-dump; the original
reporter claims he also has a proof-of-concept to execute code
inserted by the crafted input file:

<https://bugs.launchpad.net/ubuntu/+source/grep/+bug/1091473>

This affects GNU grep < 2.11. The short test is:

perl -e 'print "x"x(2**31)' | grep x > /dev/null

pkgsrc grep was  upgraded from 2.5.3 to 2.13 after 2012Q1 (I think) 
and later to 2.14. I've added a line for <2.11 to pkg-vulnerabilities.

However, our in-tree GNU grep is 2.5.3-derived, and at least crashable
by the above test.

The discussion on oss-security 
<http://seclists.org/oss-sec/2012/q4/504>
mentions the upstream patch that fixed it:

a) 
<http://git.savannah.gnu.org/cgit/grep.git/commit/?id=cbbc1a45b9f843c811905c97c90a5d31f8e6c189>

and two others that also relate to integer overflow fixes from 2.11:

b) 
<http://git.savannah.gnu.org/cgit/grep.git/commit/?id=4572ea4649d025e51463d48c2d06a1c66134cdb8>
 
(don't call pcre_exec with lines of > 2^31 bytes)

and 

c) 
<http://git.savannah.gnu.org/cgit/grep.git/commit/?id=8fcf61523644df42e1905c81bed26838e0b04f91>

As our in-tree compiles with pcre stuff disabled (actually not
there), I only back-ported a) and c).

My diff is in
<ftp://ftp.netbsd.org/pub/NetBSD/misc/is/gnugrep/CVE-2012-5667/>.
Somebody should proofread it. A few notes below.

Now, how to proceed? I think, as we shipped with gnu grep enabled
in -6, we should probably fix this and pull it up, before thinking 
about usr.bin/grep.

Regards,
        -is


Notes on the backport:

I'm not using - for a) - this patch:

- char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
+ char buf[INT_BUFSIZE_BOUND (intmax_t) + 4];

not only would we need to inport yet another GPLv3 file, I also
think INT_BUFSIZD_BOUND from newer GNU grep lib/intprops.h
give an answer too small by one for signed 64bit types. This might
be compensated by the +4 which actually should be +3 and by not reading
in negative digit strings anyway? (See code below that in grep.c)

Anyway, a still safe size would be ((sizeof(intmax_t)*8+2)/3) - a bit
of slack from rounded up multiplication by 0.30103, if we don't want
to waste roughly 2/3rd of the buffer.

And yes, that code is a horrible hack. Try jot 100 | grep -1 -2 15

-- 
seal your e-mail: http://www.gnupg.org/

Attachment: pgpHwvYOd8gNw.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index