diff options
Diffstat (limited to 'meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch')
-rw-r--r-- | meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch new file mode 100644 index 0000000000..23ddfcf1bc --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch | |||
@@ -0,0 +1,384 @@ | |||
1 | commit 29866fa186ee3ebda5242221607dba360b2e541e | ||
2 | Author: Nick Clifton <nickc@redhat.com> | ||
3 | Date: Wed Jul 19 11:07:43 2017 +0100 | ||
4 | |||
5 | Fix address violation when attempting to read a corrupt field in a COFF archive header structure. | ||
6 | |||
7 | PR 21786 | ||
8 | * coff-rs6000.c (_bfd_strntol): New function. | ||
9 | (_bfd_strntoll): New function. | ||
10 | (GET_VALUE_IN_FIELD): New macro. | ||
11 | (EQ_VALUE_IN_FIELD): new macro. | ||
12 | (_bfd_xcoff_slurp_armap): Use new macros. | ||
13 | (_bfd_xcoff_archive_p): Likewise. | ||
14 | (_bfd_xcoff_read_ar_hdr): Likewise. | ||
15 | (_bfd_xcoff_openr_next_archived_file): Likewise. | ||
16 | (_bfd_xcoff_stat_arch_elt): Likewise. | ||
17 | |||
18 | commit 6c4e7b6bfbc4679f695106de2817ecf02b27c8be | ||
19 | Author: Nick Clifton <nickc@redhat.com> | ||
20 | Date: Wed Jul 19 16:14:02 2017 +0100 | ||
21 | |||
22 | Extend previous fix to coff-rs6000.c to coff64-rs6000.c | ||
23 | |||
24 | PR 21786 | ||
25 | * coff64-rs6000.c (_bfd_strntol): New function. | ||
26 | (_bfd_strntoll): New function. | ||
27 | (GET_VALUE_IN_FIELD): New macro. | ||
28 | (xcoff64_slurp_armap): Use new macros. | ||
29 | |||
30 | Upstream-Status: backport | ||
31 | |||
32 | CVE: CVE-2017-12451 | ||
33 | Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> | ||
34 | |||
35 | Index: git/bfd/ChangeLog | ||
36 | =================================================================== | ||
37 | --- git.orig/bfd/ChangeLog 2017-08-31 16:07:20.966269193 +0530 | ||
38 | +++ git/bfd/ChangeLog 2017-08-31 16:25:04.423155789 +0530 | ||
39 | @@ -13,6 +13,19 @@ | ||
40 | |||
41 | 2017-07-19 Nick Clifton <nickc@redhat.com> | ||
42 | |||
43 | + PR 21786 | ||
44 | + * coff-rs6000.c (_bfd_strntol): New function. | ||
45 | + (_bfd_strntoll): New function. | ||
46 | + (GET_VALUE_IN_FIELD): New macro. | ||
47 | + (EQ_VALUE_IN_FIELD): new macro. | ||
48 | + (_bfd_xcoff_slurp_armap): Use new macros. | ||
49 | + (_bfd_xcoff_archive_p): Likewise. | ||
50 | + (_bfd_xcoff_read_ar_hdr): Likewise. | ||
51 | + (_bfd_xcoff_openr_next_archived_file): Likewise. | ||
52 | + (_bfd_xcoff_stat_arch_elt): Likewise. | ||
53 | + | ||
54 | +2017-07-19 Nick Clifton <nickc@redhat.com> | ||
55 | + | ||
56 | PR 21787 | ||
57 | * archive.c (bfd_generic_archive_p): If the bfd does not have the | ||
58 | correct magic bytes at the start, set the error to wrong format | ||
59 | Index: git/bfd/coff-rs6000.c | ||
60 | =================================================================== | ||
61 | --- git.orig/bfd/coff-rs6000.c 2017-08-31 16:07:14.278208353 +0530 | ||
62 | +++ git/bfd/coff-rs6000.c 2017-08-31 16:24:05.414696722 +0530 | ||
63 | @@ -203,7 +203,8 @@ | ||
64 | }; | ||
65 | |||
66 | /* Information about one member of an archive. */ | ||
67 | -struct member_layout { | ||
68 | +struct member_layout | ||
69 | +{ | ||
70 | /* The archive member that this structure describes. */ | ||
71 | bfd *member; | ||
72 | |||
73 | @@ -237,7 +238,8 @@ | ||
74 | }; | ||
75 | |||
76 | /* A structure used for iterating over the members of an archive. */ | ||
77 | -struct archive_iterator { | ||
78 | +struct archive_iterator | ||
79 | +{ | ||
80 | /* The archive itself. */ | ||
81 | bfd *archive; | ||
82 | |||
83 | @@ -654,8 +656,6 @@ | ||
84 | end: | ||
85 | return bfd_coff_auxesz (abfd); | ||
86 | } | ||
87 | - | ||
88 | - | ||
89 | |||
90 | /* The XCOFF reloc table. Actually, XCOFF relocations specify the | ||
91 | bitsize and whether they are signed or not, along with a | ||
92 | @@ -663,7 +663,6 @@ | ||
93 | different algorithms for putting in the reloc. Many of these | ||
94 | relocs need special_function entries, which I have not written. */ | ||
95 | |||
96 | - | ||
97 | reloc_howto_type xcoff_howto_table[] = | ||
98 | { | ||
99 | /* 0x00: Standard 32 bit relocation. */ | ||
100 | @@ -1185,6 +1184,51 @@ | ||
101 | /* bfd_xcoff_archive_set_magic (abfd, magic); */ | ||
102 | } | ||
103 | |||
104 | +/* PR 21786: The PE/COFF standard does not require NUL termination for any of | ||
105 | + the ASCII fields in the archive headers. So in order to be able to extract | ||
106 | + numerical values we provide our own versions of strtol and strtoll which | ||
107 | + take a maximum length as an additional parameter. Also - just to save space, | ||
108 | + we omit the endptr return parameter, since we know that it is never used. */ | ||
109 | + | ||
110 | +static long | ||
111 | +_bfd_strntol (const char * nptr, int base, unsigned int maxlen) | ||
112 | +{ | ||
113 | + char buf[24]; /* Should be enough. */ | ||
114 | + | ||
115 | + BFD_ASSERT (maxlen < (sizeof (buf) - 1)); | ||
116 | + | ||
117 | + memcpy (buf, nptr, maxlen); | ||
118 | + buf[maxlen] = 0; | ||
119 | + return strtol (buf, NULL, base); | ||
120 | +} | ||
121 | + | ||
122 | +static long long | ||
123 | +_bfd_strntoll (const char * nptr, int base, unsigned int maxlen) | ||
124 | +{ | ||
125 | + char buf[32]; /* Should be enough. */ | ||
126 | + | ||
127 | + BFD_ASSERT (maxlen < (sizeof (buf) - 1)); | ||
128 | + | ||
129 | + memcpy (buf, nptr, maxlen); | ||
130 | + buf[maxlen] = 0; | ||
131 | + return strtoll (buf, NULL, base); | ||
132 | +} | ||
133 | + | ||
134 | +/* Macro to read an ASCII value stored in an archive header field. */ | ||
135 | +#define GET_VALUE_IN_FIELD(VAR, FIELD) \ | ||
136 | + do \ | ||
137 | + { \ | ||
138 | + (VAR) = sizeof (VAR) > sizeof (long) \ | ||
139 | + ? _bfd_strntoll (FIELD, 10, sizeof FIELD) \ | ||
140 | + : _bfd_strntol (FIELD, 10, sizeof FIELD); \ | ||
141 | + } \ | ||
142 | + while (0) | ||
143 | + | ||
144 | +#define EQ_VALUE_IN_FIELD(VAR, FIELD) \ | ||
145 | + (sizeof (VAR) > sizeof (long) \ | ||
146 | + ? (VAR) ==_bfd_strntoll (FIELD, 10, sizeof FIELD) \ | ||
147 | + : (VAR) == _bfd_strntol (FIELD, 10, sizeof FIELD)) | ||
148 | + | ||
149 | /* Read in the armap of an XCOFF archive. */ | ||
150 | |||
151 | bfd_boolean | ||
152 | @@ -1209,7 +1253,7 @@ | ||
153 | /* This is for the old format. */ | ||
154 | struct xcoff_ar_hdr hdr; | ||
155 | |||
156 | - off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10); | ||
157 | + GET_VALUE_IN_FIELD (off, xcoff_ardata (abfd)->symoff); | ||
158 | if (off == 0) | ||
159 | { | ||
160 | bfd_has_map (abfd) = FALSE; | ||
161 | @@ -1225,12 +1269,12 @@ | ||
162 | return FALSE; | ||
163 | |||
164 | /* Skip the name (normally empty). */ | ||
165 | - namlen = strtol (hdr.namlen, (char **) NULL, 10); | ||
166 | + GET_VALUE_IN_FIELD (namlen, hdr.namlen); | ||
167 | off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG; | ||
168 | if (bfd_seek (abfd, off, SEEK_CUR) != 0) | ||
169 | return FALSE; | ||
170 | |||
171 | - sz = strtol (hdr.size, (char **) NULL, 10); | ||
172 | + GET_VALUE_IN_FIELD (sz, hdr.size); | ||
173 | |||
174 | /* Read in the entire symbol table. */ | ||
175 | contents = (bfd_byte *) bfd_alloc (abfd, sz); | ||
176 | @@ -1264,7 +1308,7 @@ | ||
177 | /* This is for the new format. */ | ||
178 | struct xcoff_ar_hdr_big hdr; | ||
179 | |||
180 | - off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10); | ||
181 | + GET_VALUE_IN_FIELD (off, xcoff_ardata_big (abfd)->symoff); | ||
182 | if (off == 0) | ||
183 | { | ||
184 | bfd_has_map (abfd) = FALSE; | ||
185 | @@ -1280,15 +1324,12 @@ | ||
186 | return FALSE; | ||
187 | |||
188 | /* Skip the name (normally empty). */ | ||
189 | - namlen = strtol (hdr.namlen, (char **) NULL, 10); | ||
190 | + GET_VALUE_IN_FIELD (namlen, hdr.namlen); | ||
191 | off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG; | ||
192 | if (bfd_seek (abfd, off, SEEK_CUR) != 0) | ||
193 | return FALSE; | ||
194 | |||
195 | - /* XXX This actually has to be a call to strtoll (at least on 32-bit | ||
196 | - machines) since the field width is 20 and there numbers with more | ||
197 | - than 32 bits can be represented. */ | ||
198 | - sz = strtol (hdr.size, (char **) NULL, 10); | ||
199 | + GET_VALUE_IN_FIELD (sz, hdr.size); | ||
200 | |||
201 | /* Read in the entire symbol table. */ | ||
202 | contents = (bfd_byte *) bfd_alloc (abfd, sz); | ||
203 | @@ -1393,8 +1434,8 @@ | ||
204 | goto error_ret; | ||
205 | } | ||
206 | |||
207 | - bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, | ||
208 | - (char **) NULL, 10); | ||
209 | + GET_VALUE_IN_FIELD (bfd_ardata (abfd)->first_file_filepos, | ||
210 | + hdr.firstmemoff); | ||
211 | |||
212 | amt = SIZEOF_AR_FILE_HDR; | ||
213 | bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt); | ||
214 | @@ -1469,7 +1510,7 @@ | ||
215 | return NULL; | ||
216 | } | ||
217 | |||
218 | - namlen = strtol (hdr.namlen, (char **) NULL, 10); | ||
219 | + GET_VALUE_IN_FIELD (namlen, hdr.namlen); | ||
220 | amt = SIZEOF_AR_HDR + namlen + 1; | ||
221 | hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt); | ||
222 | if (hdrp == NULL) | ||
223 | @@ -1486,7 +1527,7 @@ | ||
224 | ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0'; | ||
225 | |||
226 | ret->arch_header = (char *) hdrp; | ||
227 | - ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); | ||
228 | + GET_VALUE_IN_FIELD (ret->parsed_size, hdr.size); | ||
229 | ret->filename = (char *) hdrp + SIZEOF_AR_HDR; | ||
230 | } | ||
231 | else | ||
232 | @@ -1501,7 +1542,7 @@ | ||
233 | return NULL; | ||
234 | } | ||
235 | |||
236 | - namlen = strtol (hdr.namlen, (char **) NULL, 10); | ||
237 | + GET_VALUE_IN_FIELD (namlen, hdr.namlen); | ||
238 | amt = SIZEOF_AR_HDR_BIG + namlen + 1; | ||
239 | hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt); | ||
240 | if (hdrp == NULL) | ||
241 | @@ -1518,10 +1559,7 @@ | ||
242 | ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0'; | ||
243 | |||
244 | ret->arch_header = (char *) hdrp; | ||
245 | - /* XXX This actually has to be a call to strtoll (at least on 32-bit | ||
246 | - machines) since the field width is 20 and there numbers with more | ||
247 | - than 32 bits can be represented. */ | ||
248 | - ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); | ||
249 | + GET_VALUE_IN_FIELD (ret->parsed_size, hdr.size); | ||
250 | ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG; | ||
251 | } | ||
252 | |||
253 | @@ -1550,14 +1588,11 @@ | ||
254 | if (last_file == NULL) | ||
255 | filestart = bfd_ardata (archive)->first_file_filepos; | ||
256 | else | ||
257 | - filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, | ||
258 | - 10); | ||
259 | + GET_VALUE_IN_FIELD (filestart, arch_xhdr (last_file)->nextoff); | ||
260 | |||
261 | if (filestart == 0 | ||
262 | - || filestart == strtol (xcoff_ardata (archive)->memoff, | ||
263 | - (char **) NULL, 10) | ||
264 | - || filestart == strtol (xcoff_ardata (archive)->symoff, | ||
265 | - (char **) NULL, 10)) | ||
266 | + || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata (archive)->memoff) | ||
267 | + || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata (archive)->symoff)) | ||
268 | { | ||
269 | bfd_set_error (bfd_error_no_more_archived_files); | ||
270 | return NULL; | ||
271 | @@ -1568,20 +1603,11 @@ | ||
272 | if (last_file == NULL) | ||
273 | filestart = bfd_ardata (archive)->first_file_filepos; | ||
274 | else | ||
275 | - /* XXX These actually have to be a calls to strtoll (at least | ||
276 | - on 32-bit machines) since the fields's width is 20 and | ||
277 | - there numbers with more than 32 bits can be represented. */ | ||
278 | - filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL, | ||
279 | - 10); | ||
280 | - | ||
281 | - /* XXX These actually have to be calls to strtoll (at least on 32-bit | ||
282 | - machines) since the fields's width is 20 and there numbers with more | ||
283 | - than 32 bits can be represented. */ | ||
284 | + GET_VALUE_IN_FIELD (filestart, arch_xhdr_big (last_file)->nextoff); | ||
285 | + | ||
286 | if (filestart == 0 | ||
287 | - || filestart == strtol (xcoff_ardata_big (archive)->memoff, | ||
288 | - (char **) NULL, 10) | ||
289 | - || filestart == strtol (xcoff_ardata_big (archive)->symoff, | ||
290 | - (char **) NULL, 10)) | ||
291 | + || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata_big (archive)->memoff) | ||
292 | + || EQ_VALUE_IN_FIELD (filestart, xcoff_ardata_big (archive)->symoff)) | ||
293 | { | ||
294 | bfd_set_error (bfd_error_no_more_archived_files); | ||
295 | return NULL; | ||
296 | @@ -1606,20 +1632,20 @@ | ||
297 | { | ||
298 | struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd); | ||
299 | |||
300 | - s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); | ||
301 | - s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); | ||
302 | - s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); | ||
303 | - s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); | ||
304 | + GET_VALUE_IN_FIELD (s->st_mtime, hdrp->date); | ||
305 | + GET_VALUE_IN_FIELD (s->st_uid, hdrp->uid); | ||
306 | + GET_VALUE_IN_FIELD (s->st_gid, hdrp->gid); | ||
307 | + GET_VALUE_IN_FIELD (s->st_mode, hdrp->mode); | ||
308 | s->st_size = arch_eltdata (abfd)->parsed_size; | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd); | ||
313 | |||
314 | - s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); | ||
315 | - s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); | ||
316 | - s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); | ||
317 | - s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); | ||
318 | + GET_VALUE_IN_FIELD (s->st_mtime, hdrp->date); | ||
319 | + GET_VALUE_IN_FIELD (s->st_uid, hdrp->uid); | ||
320 | + GET_VALUE_IN_FIELD (s->st_gid, hdrp->gid); | ||
321 | + GET_VALUE_IN_FIELD (s->st_mode, hdrp->mode); | ||
322 | s->st_size = arch_eltdata (abfd)->parsed_size; | ||
323 | } | ||
324 | |||
325 | Index: git/bfd/coff64-rs6000.c | ||
326 | =================================================================== | ||
327 | --- git.orig/bfd/coff64-rs6000.c 2017-08-31 16:07:14.282208390 +0530 | ||
328 | +++ git/bfd/coff64-rs6000.c 2017-08-31 16:28:43.228864485 +0530 | ||
329 | @@ -1852,6 +1852,46 @@ | ||
330 | return NULL; | ||
331 | } | ||
332 | |||
333 | +/* PR 21786: The PE/COFF standard does not require NUL termination for any of | ||
334 | + the ASCII fields in the archive headers. So in order to be able to extract | ||
335 | + numerical values we provide our own versions of strtol and strtoll which | ||
336 | + take a maximum length as an additional parameter. Also - just to save space, | ||
337 | + we omit the endptr return parameter, since we know that it is never used. */ | ||
338 | + | ||
339 | +static long | ||
340 | +_bfd_strntol (const char * nptr, int base, unsigned int maxlen) | ||
341 | +{ | ||
342 | + char buf[24]; /* Should be enough. */ | ||
343 | + | ||
344 | + BFD_ASSERT (maxlen < (sizeof (buf) - 1)); | ||
345 | + | ||
346 | + memcpy (buf, nptr, maxlen); | ||
347 | + buf[maxlen] = 0; | ||
348 | + return strtol (buf, NULL, base); | ||
349 | +} | ||
350 | + | ||
351 | +static long long | ||
352 | +_bfd_strntoll (const char * nptr, int base, unsigned int maxlen) | ||
353 | +{ | ||
354 | + char buf[32]; /* Should be enough. */ | ||
355 | + | ||
356 | + BFD_ASSERT (maxlen < (sizeof (buf) - 1)); | ||
357 | + | ||
358 | + memcpy (buf, nptr, maxlen); | ||
359 | + buf[maxlen] = 0; | ||
360 | + return strtoll (buf, NULL, base); | ||
361 | +} | ||
362 | + | ||
363 | +/* Macro to read an ASCII value stored in an archive header field. */ | ||
364 | +#define GET_VALUE_IN_FIELD(VAR, FIELD) \ | ||
365 | + do \ | ||
366 | + { \ | ||
367 | + (VAR) = sizeof (VAR) > sizeof (long) \ | ||
368 | + ? _bfd_strntoll (FIELD, 10, sizeof FIELD) \ | ||
369 | + : _bfd_strntol (FIELD, 10, sizeof FIELD); \ | ||
370 | + } \ | ||
371 | + while (0) | ||
372 | + | ||
373 | /* Read in the armap of an XCOFF archive. */ | ||
374 | |||
375 | static bfd_boolean | ||
376 | @@ -1892,7 +1932,7 @@ | ||
377 | return FALSE; | ||
378 | |||
379 | /* Skip the name (normally empty). */ | ||
380 | - namlen = strtol (hdr.namlen, (char **) NULL, 10); | ||
381 | + GET_VALUE_IN_FIELD (namlen, hdr.namlen); | ||
382 | pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG; | ||
383 | if (bfd_seek (abfd, pos, SEEK_CUR) != 0) | ||
384 | return FALSE; | ||