blob: e88a9880f1fefc8c588acee2577aeb1e3fec3d3a [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001Upstream-Status: Backport
2
3Backport patch to fix CVE-2015-1345.
4http://git.savannah.gnu.org/cgit/grep.git/commit/?id=83a95bd
5
6Signed-off-by: Kai Kang <kai.kang@windriver.com>
7---
8From 83a95bd8c8561875b948cadd417c653dbe7ef2e2 Mon Sep 17 00:00:00 2001
9From: Yuliy Pisetsky <ypisetsky@fb.com>
10Date: Thu, 1 Jan 2015 15:36:55 -0800
11Subject: [PATCH] grep -F: fix a heap buffer (read) overrun
12
13grep's read buffer is often filled to its full size, except when
14reading the final buffer of a file. In that case, the number of
15bytes read may be far less than the size of the buffer. However, for
16certain unusual pattern/text combinations, grep -F would mistakenly
17examine bytes in that uninitialized region of memory when searching
18for a match. With carefully chosen inputs, one can cause grep -F to
19read beyond the end of that buffer altogether. This problem arose via
20commit v2.18-90-g73893ff with the introduction of a more efficient
21heuristic using what is now the memchr_kwset function. The use of
22that function in bmexec_trans could leave TP much larger than EP,
23and the subsequent call to bm_delta2_search would mistakenly access
24beyond end of the main input read buffer.
25
26* src/kwset.c (bmexec_trans): When TP reaches or exceeds EP,
27do not call bm_delta2_search.
28* tests/kwset-abuse: New file.
29* tests/Makefile.am (TESTS): Add it.
30* THANKS.in: Update.
31* NEWS (Bug fixes): Mention it.
32
33Prior to this patch, this command would trigger a UMR:
34
35 printf %0360db 0 | valgrind src/grep -F $(printf %019dXb 0)
36
37 Use of uninitialised value of size 8
38 at 0x4142BE: bmexec_trans (kwset.c:657)
39 by 0x4143CA: bmexec (kwset.c:678)
40 by 0x414973: kwsexec (kwset.c:848)
41 by 0x414DC4: Fexecute (kwsearch.c:128)
42 by 0x404E2E: grepbuf (grep.c:1238)
43 by 0x4054BF: grep (grep.c:1417)
44 by 0x405CEB: grepdesc (grep.c:1645)
45 by 0x405EC1: grep_command_line_arg (grep.c:1692)
46 by 0x4077D4: main (grep.c:2570)
47
48See the accompanying test for how to trigger the heap buffer overrun.
49
50Thanks to Nima Aghdaii for testing and finding numerous
51ways to break early iterations of this patch.
52---
53 NEWS | 5 +++++
54 THANKS.in | 1 +
55 src/kwset.c | 2 ++
56 tests/Makefile.am | 1 +
57 tests/kwset-abuse | 32 ++++++++++++++++++++++++++++++++
58 5 files changed, 41 insertions(+)
59 create mode 100755 tests/kwset-abuse
60
61diff --git a/NEWS b/NEWS
62index 975440d..3835d8d 100644
63--- a/NEWS
64+++ b/NEWS
65@@ -2,6 +2,11 @@ GNU grep NEWS -*- outline -*-
66
67 * Noteworthy changes in release ?.? (????-??-??) [?]
68
69+** Bug fixes
70+
71+ grep no longer reads from uninitialized memory or from beyond the end
72+ of the heap-allocated input buffer.
73+
74
75 * Noteworthy changes in release 2.21 (2014-11-23) [stable]
76
77diff --git a/THANKS.in b/THANKS.in
78index aeaf516..624478d 100644
79--- a/THANKS.in
80+++ b/THANKS.in
81@@ -62,6 +62,7 @@ Michael Aichlmayr mikla@nx.com
82 Miles Bader miles@ccs.mt.nec.co.jp
83 Mirraz Mirraz mirraz1@rambler.ru
84 Nelson H. F. Beebe beebe@math.utah.edu
85+Nima Aghdaii naghdaii@fb.com
86 Olaf Kirch okir@ns.lst.de
87 Paul Kimoto kimoto@spacenet.tn.cornell.edu
88 Péter Radics mitchnull@gmail.com
89diff --git a/src/kwset.c b/src/kwset.c
90index 4003c8d..376f7c3 100644
91--- a/src/kwset.c
92+++ b/src/kwset.c
93@@ -643,6 +643,8 @@ bmexec_trans (kwset_t kwset, char const *text, size_t size)
94 if (! tp)
95 return -1;
96 tp++;
97+ if (ep <= tp)
98+ break;
99 }
100 }
101 }
102diff --git a/tests/Makefile.am b/tests/Makefile.am
103index 2cba2cd..0508cd2 100644
104--- a/tests/Makefile.am
105+++ b/tests/Makefile.am
106@@ -75,6 +75,7 @@ TESTS = \
107 inconsistent-range \
108 invalid-multibyte-infloop \
109 khadafy \
110+ kwset-abuse \
111 long-line-vs-2GiB-read \
112 match-lines \
113 max-count-overread \
114diff --git a/tests/kwset-abuse b/tests/kwset-abuse
115new file mode 100755
116index 0000000..6d8ec0c
117--- /dev/null
118+++ b/tests/kwset-abuse
119@@ -0,0 +1,32 @@
120+#! /bin/sh
121+# Evoke a segfault in a hard-to-reach code path of kwset.c.
122+# This bug affected grep versions 2.19 through 2.21.
123+#
124+# Copyright (C) 2015 Free Software Foundation, Inc.
125+#
126+# This program is free software: you can redistribute it and/or modify
127+# it under the terms of the GNU General Public License as published by
128+# the Free Software Foundation, either version 3 of the License, or
129+# (at your option) any later version.
130+
131+# This program is distributed in the hope that it will be useful,
132+# but WITHOUT ANY WARRANTY; without even the implied warranty of
133+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134+# GNU General Public License for more details.
135+
136+# You should have received a copy of the GNU General Public License
137+# along with this program. If not, see <http://www.gnu.org/licenses/>.
138+
139+. "${srcdir=.}/init.sh"; path_prepend_ ../src
140+
141+fail=0
142+
143+# This test case chooses a haystack of size 260,000, since prodding
144+# with gdb showed a reallocation slightly larger than that in fillbuf.
145+# To reach the buggy code, the needle must have length < 1/11 that of
146+# the haystack, and 10,000 is a nice round number that fits the bill.
147+printf '%0260000dXy\n' 0 | grep -F $(printf %010000dy 0)
148+
149+test $? = 1 || fail=1
150+
151+Exit $fail
152--
1532.4.1
154