CRUX-ARM : Home

Home :: Documentation :: Download :: Development :: Community :: Ports :: Packages :: Bugs :: Links :: About :: Donors
glibc: updated to 2.19-5 Added CVE patches
[ports/core-arm.git] / glibc / CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
1 From 6143805bb45e716829d86851e9372f55a136064b Mon Sep 17 00:00:00 2001
2 From: Jeff Law <law@redhat.com>
3 Date: Mon, 15 Dec 2014 10:09:32 +0100
4 Subject: [PATCH 35/37] CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
5
6 A larger number of format specifiers coudld cause a stack overflow,
7 potentially allowing to bypass _FORTIFY_SOURCE format string
8 protection.
9
10 Conflicts:
11 ChangeLog
12 NEWS
13 ---
14 ChangeLog | 13 +++++++++
15 NEWS | 57 ++++++++++++++++++++++++++++++++++++++++
16 stdio-common/Makefile | 2 +-
17 stdio-common/bug23-2.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
18 stdio-common/bug23-3.c | 50 +++++++++++++++++++++++++++++++++++
19 stdio-common/bug23-4.c | 31 ++++++++++++++++++++++
20 stdio-common/vfprintf.c | 40 ++++++++++++++++++++++++++--
21 7 files changed, 260 insertions(+), 3 deletions(-)
22 create mode 100644 stdio-common/bug23-2.c
23 create mode 100644 stdio-common/bug23-3.c
24 create mode 100644 stdio-common/bug23-4.c
25
26 diff --git a/stdio-common/bug23-2.c b/stdio-common/bug23-2.c
27 new file mode 100644
28 index 0000000..9e0cfe6
29 --- /dev/null
30 +++ b/stdio-common/bug23-2.c
31 @@ -0,0 +1,70 @@
32 +#include <stdio.h>
33 +#include <string.h>
34 +#include <stdlib.h>
35 +
36 +static const char expected[] = "\
37 +\n\
38 +a\n\
39 +abbcd55\
40 +\n\
41 +a\n\
42 +abbcd55\
43 +\n\
44 +a\n\
45 +abbcd55\
46 +\n\
47 +a\n\
48 +abbcd55\
49 +\n\
50 +a\n\
51 +abbcd55\
52 +\n\
53 +a\n\
54 +abbcd55\
55 +\n\
56 +a\n\
57 +abbcd55\
58 +\n\
59 +a\n\
60 +abbcd55\
61 +\n\
62 +a\n\
63 +abbcd55\
64 +\n\
65 +a\n\
66 +abbcd55\
67 +\n\
68 +a\n\
69 +abbcd55\
70 +\n\
71 +a\n\
72 +abbcd55\
73 +\n\
74 +a\n\
75 +abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
76 +
77 +static int
78 +do_test (void)
79 +{
80 + char *buf = malloc (strlen (expected) + 1);
81 + snprintf (buf, strlen (expected) + 1,
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%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
88 + "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
89 + "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
90 + "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
91 + "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
92 + "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
93 + "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
94 + "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
95 + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",
96 + "a", "b", "c", "d", 5);
97 + return strcmp (buf, expected) != 0;
98 +}
99 +
100 +#define TEST_FUNCTION do_test ()
101 +#include "../test-skeleton.c"
102 diff --git a/stdio-common/bug23-3.c b/stdio-common/bug23-3.c
103 new file mode 100644
104 index 0000000..57c8cef
105 --- /dev/null
106 +++ b/stdio-common/bug23-3.c
107 @@ -0,0 +1,50 @@
108 +#include <stdio.h>
109 +#include <string.h>
110 +#include <stdlib.h>
111 +
112 +int
113 +do_test (void)
114 +{
115 + size_t instances = 16384;
116 +#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
117 + const char *item = "\na\nabbcd55";
118 +#define X3 X0 X0 X0 X0 X0 X0 X0 X0
119 +#define X6 X3 X3 X3 X3 X3 X3 X3 X3
120 +#define X9 X6 X6 X6 X6 X6 X6 X6 X6
121 +#define X12 X9 X9 X9 X9 X9 X9 X9 X9
122 +#define X14 X12 X12 X12 X12
123 +#define TRAILER "%%%%%%%%%%%%%%%%%%%%%%%%%%"
124 +#define TRAILER2 TRAILER TRAILER
125 + size_t length = instances * strlen (item) + strlen (TRAILER) + 1;
126 +
127 + char *buf = malloc (length + 1);
128 + snprintf (buf, length + 1,
129 + X14 TRAILER2 "\n",
130 + "a", "b", "c", "d", 5);
131 +
132 + const char *p = buf;
133 + size_t i;
134 + for (i = 0; i < instances; ++i)
135 + {
136 + const char *expected;
137 + for (expected = item; *expected; ++expected)
138 + {
139 + if (*p != *expected)
140 + {
141 + printf ("mismatch at offset %zu (%zu): expected %d, got %d\n",
142 + (size_t) (p - buf), i, *expected & 0xFF, *p & 0xFF);
143 + return 1;
144 + }
145 + ++p;
146 + }
147 + }
148 + if (strcmp (p, TRAILER "\n") != 0)
149 + {
150 + printf ("mismatch at trailer: [%s]\n", p);
151 + return 1;
152 + }
153 + free (buf);
154 + return 0;
155 +}
156 +#define TEST_FUNCTION do_test ()
157 +#include "../test-skeleton.c"
158 diff --git a/stdio-common/bug23-4.c b/stdio-common/bug23-4.c
159 new file mode 100644
160 index 0000000..a478564
161 --- /dev/null
162 +++ b/stdio-common/bug23-4.c
163 @@ -0,0 +1,31 @@
164 +#include <stdio.h>
165 +#include <stdlib.h>
166 +#include <string.h>
167 +#include <sys/resource.h>
168 +
169 +#define LIMIT 1000000
170 +
171 +int
172 +main (void)
173 +{
174 + struct rlimit lim;
175 + getrlimit (RLIMIT_STACK, &lim);
176 + lim.rlim_cur = 1048576;
177 + setrlimit (RLIMIT_STACK, &lim);
178 + char *fmtstr = malloc (4 * LIMIT + 1);
179 + if (fmtstr == NULL)
180 + abort ();
181 + char *output = malloc (LIMIT + 1);
182 + if (output == NULL)
183 + abort ();
184 + for (size_t i = 0; i < LIMIT; i++)
185 + memcpy (fmtstr + 4 * i, "%1$d", 4);
186 + fmtstr[4 * LIMIT] = '\0';
187 + int ret = snprintf (output, LIMIT + 1, fmtstr, 0);
188 + if (ret != LIMIT)
189 + abort ();
190 + for (size_t i = 0; i < LIMIT; i++)
191 + if (output[i] != '0')
192 + abort ();
193 + return 0;
194 +}
195 diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
196 index f7e5f61..f423be6 100644
197 --- a/stdio-common/vfprintf.c
198 +++ b/stdio-common/vfprintf.c
199 @@ -263,6 +263,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
200 /* For the argument descriptions, which may be allocated on the heap. */
201 void *args_malloced = NULL;
202
203 + /* For positional argument handling. */
204 + struct printf_spec *specs;
205 +
206 + /* Track if we malloced the SPECS array and thus must free it. */
207 + bool specs_malloced = false;
208 +
209 /* This table maps a character into a number representing a
210 class. In each step there is a destination label for each
211 class. */
212 @@ -1678,8 +1684,8 @@ do_positional:
213 size_t nspecs = 0;
214 /* A more or less arbitrary start value. */
215 size_t nspecs_size = 32 * sizeof (struct printf_spec);
216 - struct printf_spec *specs = alloca (nspecs_size);
217
218 + specs = alloca (nspecs_size);
219 /* The number of arguments the format string requests. This will
220 determine the size of the array needed to store the argument
221 attributes. */
222 @@ -1720,11 +1726,39 @@ do_positional:
223 if (nspecs * sizeof (*specs) >= nspecs_size)
224 {
225 /* Extend the array of format specifiers. */
226 + if (nspecs_size * 2 < nspecs_size)
227 + {
228 + __set_errno (ENOMEM);
229 + done = -1;
230 + goto all_done;
231 + }
232 struct printf_spec *old = specs;
233 - specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
234 + if (__libc_use_alloca (2 * nspecs_size))
235 + specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
236 + else
237 + {
238 + nspecs_size *= 2;
239 + specs = malloc (nspecs_size);
240 + if (specs == NULL)
241 + {
242 + __set_errno (ENOMEM);
243 + specs = old;
244 + done = -1;
245 + goto all_done;
246 + }
247 + }
248
249 /* Copy the old array's elements to the new space. */
250 memmove (specs, old, nspecs * sizeof (*specs));
251 +
252 + /* If we had previously malloc'd space for SPECS, then
253 + release it after the copy is complete. */
254 + if (specs_malloced)
255 + free (old);
256 +
257 + /* Now set SPECS_MALLOCED if needed. */
258 + if (!__libc_use_alloca (nspecs_size))
259 + specs_malloced = true;
260 }
261
262 /* Parse the format specifier. */
263 @@ -2045,6 +2079,8 @@ do_positional:
264 }
265
266 all_done:
267 + if (specs_malloced)
268 + free (specs);
269 if (__glibc_unlikely (args_malloced != NULL))
270 free (args_malloced);
271 if (__glibc_unlikely (workstart != NULL))
272 --
273 2.2.1
274