summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Sarmadi <sona.sarmadi@enea.com>2015-02-20 11:31:46 +0100
committerTudor Florea <tudor.florea@enea.com>2015-07-06 20:19:37 +0200
commit0892adf79c73bbfb427846670c480da0912431a2 (patch)
treeddfcf67b235965b8b8ac16b7ab9542941247f244
parentf48f7274bc47c526869eb347532d099f36d28b13 (diff)
downloadpoky-0892adf79c73bbfb427846670c480da0912431a2.tar.gz
eglibc: CVE-2012-3406 Stack overflow in vfprintf
printf() unbound alloca() usage in case of positional parameters + many format specs Changes in the NEWS and ChangeLog files from the original upstream commit have been ignored References http://www.openwall.com/lists/oss-security/2012/07/11/5 https://sourceware.org/bugzilla/show_bug.cgi?id=16617 Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
-rw-r--r--meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch273
-rw-r--r--meta/recipes-core/eglibc/eglibc_2.19.bb1
2 files changed, 274 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..c018bdd6c7
--- /dev/null
+++ b/meta/recipes-core/eglibc/eglibc-2.19/CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
@@ -0,0 +1,273 @@
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 stdio-common/Makefile | 2 +-
11 stdio-common/bug23-2.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
12 stdio-common/bug23-3.c | 50 +++++++++++++++++++++++++++++++++++
13 stdio-common/bug23-4.c | 31 ++++++++++++++++++++++
14 stdio-common/vfprintf.c | 40 ++++++++++++++++++++++++++--
15 create mode 100644 stdio-common/bug23-2.c
16 create mode 100644 stdio-common/bug23-3.c
17 create mode 100644 stdio-common/bug23-4.c
18
19Index: git/stdio-common/bug23-2.c
20===================================================================
21--- /dev/null
22+++ git/stdio-common/bug23-2.c
23@@ -0,0 +1,70 @@
24+#include <stdio.h>
25+#include <string.h>
26+#include <stdlib.h>
27+
28+static const char expected[] = "\
29+\n\
30+a\n\
31+abbcd55\
32+\n\
33+a\n\
34+abbcd55\
35+\n\
36+a\n\
37+abbcd55\
38+\n\
39+a\n\
40+abbcd55\
41+\n\
42+a\n\
43+abbcd55\
44+\n\
45+a\n\
46+abbcd55\
47+\n\
48+a\n\
49+abbcd55\
50+\n\
51+a\n\
52+abbcd55\
53+\n\
54+a\n\
55+abbcd55\
56+\n\
57+a\n\
58+abbcd55\
59+\n\
60+a\n\
61+abbcd55\
62+\n\
63+a\n\
64+abbcd55\
65+\n\
66+a\n\
67+abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
68+
69+static int
70+do_test (void)
71+{
72+ char *buf = malloc (strlen (expected) + 1);
73+ snprintf (buf, strlen (expected) + 1,
74+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
75+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
76+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
77+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
78+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
79+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
80+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
81+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
82+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
83+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
84+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
85+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
86+ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
87+ "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",
88+ "a", "b", "c", "d", 5);
89+ return strcmp (buf, expected) != 0;
90+}
91+
92+#define TEST_FUNCTION do_test ()
93+#include "../test-skeleton.c"
94Index: git/stdio-common/bug23-3.c
95===================================================================
96--- /dev/null
97+++ git/stdio-common/bug23-3.c
98@@ -0,0 +1,50 @@
99+#include <stdio.h>
100+#include <string.h>
101+#include <stdlib.h>
102+
103+int
104+do_test (void)
105+{
106+ size_t instances = 16384;
107+#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
108+ const char *item = "\na\nabbcd55";
109+#define X3 X0 X0 X0 X0 X0 X0 X0 X0
110+#define X6 X3 X3 X3 X3 X3 X3 X3 X3
111+#define X9 X6 X6 X6 X6 X6 X6 X6 X6
112+#define X12 X9 X9 X9 X9 X9 X9 X9 X9
113+#define X14 X12 X12 X12 X12
114+#define TRAILER "%%%%%%%%%%%%%%%%%%%%%%%%%%"
115+#define TRAILER2 TRAILER TRAILER
116+ size_t length = instances * strlen (item) + strlen (TRAILER) + 1;
117+
118+ char *buf = malloc (length + 1);
119+ snprintf (buf, length + 1,
120+ X14 TRAILER2 "\n",
121+ "a", "b", "c", "d", 5);
122+
123+ const char *p = buf;
124+ size_t i;
125+ for (i = 0; i < instances; ++i)
126+ {
127+ const char *expected;
128+ for (expected = item; *expected; ++expected)
129+ {
130+ if (*p != *expected)
131+ {
132+ printf ("mismatch at offset %zu (%zu): expected %d, got %d\n",
133+ (size_t) (p - buf), i, *expected & 0xFF, *p & 0xFF);
134+ return 1;
135+ }
136+ ++p;
137+ }
138+ }
139+ if (strcmp (p, TRAILER "\n") != 0)
140+ {
141+ printf ("mismatch at trailer: [%s]\n", p);
142+ return 1;
143+ }
144+ free (buf);
145+ return 0;
146+}
147+#define TEST_FUNCTION do_test ()
148+#include "../test-skeleton.c"
149Index: git/stdio-common/bug23-4.c
150===================================================================
151--- /dev/null
152+++ git/stdio-common/bug23-4.c
153@@ -0,0 +1,31 @@
154+#include <stdio.h>
155+#include <stdlib.h>
156+#include <string.h>
157+#include <sys/resource.h>
158+
159+#define LIMIT 1000000
160+
161+int
162+main (void)
163+{
164+ struct rlimit lim;
165+ getrlimit (RLIMIT_STACK, &lim);
166+ lim.rlim_cur = 1048576;
167+ setrlimit (RLIMIT_STACK, &lim);
168+ char *fmtstr = malloc (4 * LIMIT + 1);
169+ if (fmtstr == NULL)
170+ abort ();
171+ char *output = malloc (LIMIT + 1);
172+ if (output == NULL)
173+ abort ();
174+ for (size_t i = 0; i < LIMIT; i++)
175+ memcpy (fmtstr + 4 * i, "%1$d", 4);
176+ fmtstr[4 * LIMIT] = '\0';
177+ int ret = snprintf (output, LIMIT + 1, fmtstr, 0);
178+ if (ret != LIMIT)
179+ abort ();
180+ for (size_t i = 0; i < LIMIT; i++)
181+ if (output[i] != '0')
182+ abort ();
183+ return 0;
184+}
185Index: git/stdio-common/vfprintf.c
186===================================================================
187--- git.orig/stdio-common/vfprintf.c
188+++ git/stdio-common/vfprintf.c
189@@ -276,6 +276,12 @@ vfprintf (FILE *s, const CHAR_T *format,
190 /* For the argument descriptions, which may be allocated on the heap. */
191 void *args_malloced = NULL;
192
193+ /* For positional argument handling. */
194+ struct printf_spec *specs;
195+
196+ /* Track if we malloced the SPECS array and thus must free it. */
197+ bool specs_malloced = false;
198+
199 /* This table maps a character into a number representing a
200 class. In each step there is a destination label for each
201 class. */
202@@ -1699,8 +1705,8 @@ do_positional:
203 size_t nspecs = 0;
204 /* A more or less arbitrary start value. */
205 size_t nspecs_size = 32 * sizeof (struct printf_spec);
206- struct printf_spec *specs = alloca (nspecs_size);
207
208+ specs = alloca (nspecs_size);
209 /* The number of arguments the format string requests. This will
210 determine the size of the array needed to store the argument
211 attributes. */
212@@ -1743,11 +1749,39 @@ do_positional:
213 if (nspecs * sizeof (*specs) >= nspecs_size)
214 {
215 /* Extend the array of format specifiers. */
216+ if (nspecs_size * 2 < nspecs_size)
217+ {
218+ __set_errno (ENOMEM);
219+ done = -1;
220+ goto all_done;
221+ }
222 struct printf_spec *old = specs;
223- specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
224+ if (__libc_use_alloca (2 * nspecs_size))
225+ specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
226+ else
227+ {
228+ nspecs_size *= 2;
229+ specs = malloc (nspecs_size);
230+ if (specs == NULL)
231+ {
232+ __set_errno (ENOMEM);
233+ specs = old;
234+ done = -1;
235+ goto all_done;
236+ }
237+ }
238
239 /* Copy the old array's elements to the new space. */
240 memmove (specs, old, nspecs * sizeof (*specs));
241+
242+ /* If we had previously malloc'd space for SPECS, then
243+ release it after the copy is complete. */
244+ if (specs_malloced)
245+ free (old);
246+
247+ /* Now set SPECS_MALLOCED if needed. */
248+ if (!__libc_use_alloca (nspecs_size))
249+ specs_malloced = true;
250 }
251
252 /* Parse the format specifier. */
253@@ -2068,6 +2102,8 @@ do_positional:
254 }
255
256 all_done:
257+ if (specs_malloced)
258+ free (specs);
259 if (__glibc_unlikely (args_malloced != NULL))
260 free (args_malloced);
261 if (__glibc_unlikely (workstart != NULL))
262Index: git/stdio-common/Makefile
263===================================================================
264--- git.orig/stdio-common/Makefile
265+++ git/stdio-common/Makefile
266@@ -66,7 +66,7 @@ tests := tstscanf test_rdwr test-popen t
267 tst-fwrite bug16 bug17 tst-sprintf2 bug18 \
268 bug19 tst-popen2 scanf14 scanf15 bug21 bug22 scanf16 scanf17 \
269 tst-setvbuf1 bug23 bug24 bug-vfprintf-nargs tst-sprintf3 bug25 \
270- tst-printf-round bug26
271+ tst-printf-round bug23-2 bug23-3 bug23-4
272 tests-$(OPTION_EGLIBC_LOCALE_CODE) \
273 += tst-sscanf tst-swprintf test-vfprintf bug14 scanf13 tst-grouping
diff --git a/meta/recipes-core/eglibc/eglibc_2.19.bb b/meta/recipes-core/eglibc/eglibc_2.19.bb
index ba79f27d61..1ef1a429d2 100644
--- a/meta/recipes-core/eglibc/eglibc_2.19.bb
+++ b/meta/recipes-core/eglibc/eglibc_2.19.bb
@@ -27,6 +27,7 @@ SRC_URI = "http://downloads.yoctoproject.org/releases/eglibc/eglibc-${PV}-svnr25
27 file://ppce6500-32b_slow_ieee754_sqrt.patch \ 27 file://ppce6500-32b_slow_ieee754_sqrt.patch \
28 file://CVE-2014-5119.patch \ 28 file://CVE-2014-5119.patch \
29 file://CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch \ 29 file://CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch \
30 file://CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch \
30 " 31 "
31SRC_URI[md5sum] = "197836c2ba42fb146e971222647198dd" 32SRC_URI[md5sum] = "197836c2ba42fb146e971222647198dd"
32SRC_URI[sha256sum] = "baaa030531fc308f7820c46acdf8e1b2f8e3c1f40bcd28b6e440d1c95d170d4c" 33SRC_URI[sha256sum] = "baaa030531fc308f7820c46acdf8e1b2f8e3c1f40bcd28b6e440d1c95d170d4c"