summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch')
-rw-r--r--meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch317
1 files changed, 317 insertions, 0 deletions
diff --git a/meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch b/meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
new file mode 100644
index 0000000000..c94e68266e
--- /dev/null
+++ b/meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
@@ -0,0 +1,317 @@
1From a5357b7ce2a2982c5778435704bcdb55ce3667a0 Mon Sep 17 00:00:00 2001
2From: Jeff Law <law@redhat.com>
3Date: Mon, 15 Dec 2014 10:09:32 +0100
4Subject: [PATCH] CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
5
6A larger number of format specifiers coudld cause a stack overflow,
7potentially allowing to bypass _FORTIFY_SOURCE format string
8protection.
9---
10 ChangeLog | 9 +++++++
11 NEWS | 13 +++++----
12 stdio-common/Makefile | 2 +-
13 stdio-common/bug23-2.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
14 stdio-common/bug23-3.c | 50 +++++++++++++++++++++++++++++++++++
15 stdio-common/bug23-4.c | 31 ++++++++++++++++++++++
16 stdio-common/vfprintf.c | 40 ++++++++++++++++++++++++++--
17 7 files changed, 207 insertions(+), 8 deletions(-)
18 create mode 100644 stdio-common/bug23-2.c
19 create mode 100644 stdio-common/bug23-3.c
20 create mode 100644 stdio-common/bug23-4.c
21
22Index: libc/ChangeLog
23===================================================================
24--- libc.orig/ChangeLog
25+++ libc/ChangeLog
26@@ -1,3 +1,12 @@
27+2014-12-15 Jeff Law <law@redhat.com>
28+
29+ [BZ #16617]
30+ * stdio-common/vfprintf.c (vfprintf): Allocate large specs array
31+ on the heap. (CVE-2012-3406)
32+ * stdio-common/bug23-2.c, stdio-common/bug23-3.c: New file.
33+ * stdio-common/bug23-4.c: New file. Test case by Joseph Myers.
34+ * stdio-common/Makefile (tests): Add bug23-2, bug23-3, bug23-4.
35+
36 2014-11-19 Carlos O'Donell <carlos@redhat.com>
37 Florian Weimer <fweimer@redhat.com>
38 Joseph Myers <joseph@codesourcery.com>
39Index: libc/NEWS
40===================================================================
41--- libc.orig/NEWS
42+++ libc/NEWS
43@@ -26,7 +26,7 @@ Version 2.19
44 16271, 16274, 16283, 16289, 16293, 16314, 16316, 16330, 16337, 16338,
45 16356, 16365, 16366, 16369, 16372, 16375, 16379, 16384, 16385, 16386,
46 16387, 16390, 16394, 16398, 16400, 16407, 16408, 16414, 16430, 16431,
47- 16453, 16474, 16506, 16510, 16529, 17187, 17625.
48+ 16453, 16474, 16506, 16510, 16529, 16619, 17187, 17625.
49
50 * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
51 under certain input conditions resulting in the execution of a shell for
52@@ -34,6 +34,9 @@ Version 2.19
53 implementation now checks WRDE_NOCMD immediately before executing the
54 shell and returns the error WRDE_CMDSUB as expected.
55
56+* CVE-2012-3406 printf-style functions could run into a stack overflow when
57+ processing format strings with a large number of format specifiers.
58+
59 * Slovenian translations for glibc messages have been contributed by the
60 Translation Project's Slovenian team of translators.
61
62Index: libc/stdio-common/bug23-2.c
63===================================================================
64--- /dev/null
65+++ libc/stdio-common/bug23-2.c
66@@ -0,0 +1,70 @@
67+#include <stdio.h>
68+#include <string.h>
69+#include <stdlib.h>
70+
71+static const char expected[] = "\
72+\n\
73+a\n\
74+abbcd55\
75+\n\
76+a\n\
77+abbcd55\
78+\n\
79+a\n\
80+abbcd55\
81+\n\
82+a\n\
83+abbcd55\
84+\n\
85+a\n\
86+abbcd55\
87+\n\
88+a\n\
89+abbcd55\
90+\n\
91+a\n\
92+abbcd55\
93+\n\
94+a\n\
95+abbcd55\
96+\n\
97+a\n\
98+abbcd55\
99+\n\
100+a\n\
101+abbcd55\
102+\n\
103+a\n\
104+abbcd55\
105+\n\
106+a\n\
107+abbcd55\
108+\n\
109+a\n\
110+abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
111+
112+static int
113+do_test (void)
114+{
115+ char *buf = malloc (strlen (expected) + 1);
116+ snprintf (buf, strlen (expected) + 1,
117+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
118+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
119+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
120+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
121+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
122+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
123+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
124+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
125+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
126+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
127+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
128+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
129+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
130+ "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",
131+ "a", "b", "c", "d", 5);
132+ return strcmp (buf, expected) != 0;
133+}
134+
135+#define TEST_FUNCTION do_test ()
136+#include "../test-skeleton.c"
137Index: libc/stdio-common/bug23-3.c
138===================================================================
139--- /dev/null
140+++ libc/stdio-common/bug23-3.c
141@@ -0,0 +1,50 @@
142+#include <stdio.h>
143+#include <string.h>
144+#include <stdlib.h>
145+
146+int
147+do_test (void)
148+{
149+ size_t instances = 16384;
150+#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
151+ const char *item = "\na\nabbcd55";
152+#define X3 X0 X0 X0 X0 X0 X0 X0 X0
153+#define X6 X3 X3 X3 X3 X3 X3 X3 X3
154+#define X9 X6 X6 X6 X6 X6 X6 X6 X6
155+#define X12 X9 X9 X9 X9 X9 X9 X9 X9
156+#define X14 X12 X12 X12 X12
157+#define TRAILER "%%%%%%%%%%%%%%%%%%%%%%%%%%"
158+#define TRAILER2 TRAILER TRAILER
159+ size_t length = instances * strlen (item) + strlen (TRAILER) + 1;
160+
161+ char *buf = malloc (length + 1);
162+ snprintf (buf, length + 1,
163+ X14 TRAILER2 "\n",
164+ "a", "b", "c", "d", 5);
165+
166+ const char *p = buf;
167+ size_t i;
168+ for (i = 0; i < instances; ++i)
169+ {
170+ const char *expected;
171+ for (expected = item; *expected; ++expected)
172+ {
173+ if (*p != *expected)
174+ {
175+ printf ("mismatch at offset %zu (%zu): expected %d, got %d\n",
176+ (size_t) (p - buf), i, *expected & 0xFF, *p & 0xFF);
177+ return 1;
178+ }
179+ ++p;
180+ }
181+ }
182+ if (strcmp (p, TRAILER "\n") != 0)
183+ {
184+ printf ("mismatch at trailer: [%s]\n", p);
185+ return 1;
186+ }
187+ free (buf);
188+ return 0;
189+}
190+#define TEST_FUNCTION do_test ()
191+#include "../test-skeleton.c"
192Index: libc/stdio-common/bug23-4.c
193===================================================================
194--- /dev/null
195+++ libc/stdio-common/bug23-4.c
196@@ -0,0 +1,31 @@
197+#include <stdio.h>
198+#include <stdlib.h>
199+#include <string.h>
200+#include <sys/resource.h>
201+
202+#define LIMIT 1000000
203+
204+int
205+main (void)
206+{
207+ struct rlimit lim;
208+ getrlimit (RLIMIT_STACK, &lim);
209+ lim.rlim_cur = 1048576;
210+ setrlimit (RLIMIT_STACK, &lim);
211+ char *fmtstr = malloc (4 * LIMIT + 1);
212+ if (fmtstr == NULL)
213+ abort ();
214+ char *output = malloc (LIMIT + 1);
215+ if (output == NULL)
216+ abort ();
217+ for (size_t i = 0; i < LIMIT; i++)
218+ memcpy (fmtstr + 4 * i, "%1$d", 4);
219+ fmtstr[4 * LIMIT] = '\0';
220+ int ret = snprintf (output, LIMIT + 1, fmtstr, 0);
221+ if (ret != LIMIT)
222+ abort ();
223+ for (size_t i = 0; i < LIMIT; i++)
224+ if (output[i] != '0')
225+ abort ();
226+ return 0;
227+}
228Index: libc/stdio-common/vfprintf.c
229===================================================================
230--- libc.orig/stdio-common/vfprintf.c
231+++ libc/stdio-common/vfprintf.c
232@@ -276,6 +276,12 @@ vfprintf (FILE *s, const CHAR_T *format,
233 /* For the argument descriptions, which may be allocated on the heap. */
234 void *args_malloced = NULL;
235
236+ /* For positional argument handling. */
237+ struct printf_spec *specs;
238+
239+ /* Track if we malloced the SPECS array and thus must free it. */
240+ bool specs_malloced = false;
241+
242 /* This table maps a character into a number representing a
243 class. In each step there is a destination label for each
244 class. */
245@@ -1698,8 +1704,8 @@ do_positional:
246 size_t nspecs = 0;
247 /* A more or less arbitrary start value. */
248 size_t nspecs_size = 32 * sizeof (struct printf_spec);
249- struct printf_spec *specs = alloca (nspecs_size);
250
251+ specs = alloca (nspecs_size);
252 /* The number of arguments the format string requests. This will
253 determine the size of the array needed to store the argument
254 attributes. */
255@@ -1742,11 +1748,39 @@ do_positional:
256 if (nspecs * sizeof (*specs) >= nspecs_size)
257 {
258 /* Extend the array of format specifiers. */
259+ if (nspecs_size * 2 < nspecs_size)
260+ {
261+ __set_errno (ENOMEM);
262+ done = -1;
263+ goto all_done;
264+ }
265 struct printf_spec *old = specs;
266- specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
267+ if (__libc_use_alloca (2 * nspecs_size))
268+ specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
269+ else
270+ {
271+ nspecs_size *= 2;
272+ specs = malloc (nspecs_size);
273+ if (specs == NULL)
274+ {
275+ __set_errno (ENOMEM);
276+ specs = old;
277+ done = -1;
278+ goto all_done;
279+ }
280+ }
281
282 /* Copy the old array's elements to the new space. */
283 memmove (specs, old, nspecs * sizeof (*specs));
284+
285+ /* If we had previously malloc'd space for SPECS, then
286+ release it after the copy is complete. */
287+ if (specs_malloced)
288+ free (old);
289+
290+ /* Now set SPECS_MALLOCED if needed. */
291+ if (!__libc_use_alloca (nspecs_size))
292+ specs_malloced = true;
293 }
294
295 /* Parse the format specifier. */
296@@ -2067,6 +2101,8 @@ do_positional:
297 }
298
299 all_done:
300+ if (specs_malloced)
301+ free (specs);
302 if (__glibc_unlikely (args_malloced != NULL))
303 free (args_malloced);
304 if (__glibc_unlikely (workstart != NULL))
305Index: libc/stdio-common/Makefile
306===================================================================
307--- libc.orig/stdio-common/Makefile
308+++ libc/stdio-common/Makefile
309@@ -64,7 +64,7 @@ tests := tstscanf test_rdwr test-popen t
310 tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
311 bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17 \
312 tst-setvbuf1 bug23 bug24 bug-vfprintf-nargs tst-sprintf3 bug25 \
313- tst-printf-round bug26
314+ tst-printf-round bug23-2 bug23-3 bug23-4
315 tests-$(OPTION_EGLIBC_LOCALE_CODE) \
316 += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
317 tests-$(OPTION_POSIX_WIDE_CHAR_DEVICE_IO) \