summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools
diff options
context:
space:
mode:
authorThiruvadi Rajaraman <trajaraman@mvista.com>2017-08-31 19:00:45 +0530
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-01-07 17:10:07 +0000
commitc2b6a93e14033cbabc728293f7baab210c40449b (patch)
tree4e647dfaba55d8d8fdb6c19986b39b4d4e8cad2b /meta/recipes-devtools
parent1ffd39135ac29b976cb86d30a0e640e782a6cbe9 (diff)
downloadpoky-c2b6a93e14033cbabc728293f7baab210c40449b.tar.gz
binutils: CVE-2017-12451
Source: git://sourceware.org/git/binutils-gdb.git MR: 73840 Type: Security Fix Disposition: Backport from binutils-2_29-branch ChangeID: 582c686f18c059d665189a6a09df3a8cc4a3b093 Description: Fix address violation when attempting to read a corrupt field in a COFF archive header structure. PR 21786 * coff-rs6000.c (_bfd_strntol): New function. (_bfd_strntoll): New function. (GET_VALUE_IN_FIELD): New macro. (EQ_VALUE_IN_FIELD): new macro. (_bfd_xcoff_slurp_armap): Use new macros. (_bfd_xcoff_archive_p): Likewise. (_bfd_xcoff_read_ar_hdr): Likewise. (_bfd_xcoff_openr_next_archived_file): Likewise. (_bfd_xcoff_stat_arch_elt): Likewise. Extend previous fix to coff-rs6000.c to coff64-rs6000.c PR 21786 * coff64-rs6000.c (_bfd_strntol): New function. (_bfd_strntoll): New function. (GET_VALUE_IN_FIELD): New macro. (xcoff64_slurp_armap): Use new macros. Affects: <= 2.29 (From OE-Core rev: 62eeac8e4684c129af6f36aa7c2b91270a5dacde) Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> Reviewed-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools')
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.27.inc1
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2017-12451.patch384
2 files changed, 385 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.27.inc b/meta/recipes-devtools/binutils/binutils-2.27.inc
index 8cb7abc08a..3329a97ecf 100644
--- a/meta/recipes-devtools/binutils/binutils-2.27.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.27.inc
@@ -56,6 +56,7 @@ SRC_URI = "\
56 file://CVE-2017-12448.patch \ 56 file://CVE-2017-12448.patch \
57 file://CVE-2017-12449_12455_12457_1.patch \ 57 file://CVE-2017-12449_12455_12457_1.patch \
58 file://CVE-2017-12449_12455_12457.patch \ 58 file://CVE-2017-12449_12455_12457.patch \
59 file://CVE-2017-12451.patch \
59" 60"
60S = "${WORKDIR}/git" 61S = "${WORKDIR}/git"
61 62
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 @@
1commit 29866fa186ee3ebda5242221607dba360b2e541e
2Author: Nick Clifton <nickc@redhat.com>
3Date: 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
18commit 6c4e7b6bfbc4679f695106de2817ecf02b27c8be
19Author: Nick Clifton <nickc@redhat.com>
20Date: 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
30Upstream-Status: backport
31
32CVE: CVE-2017-12451
33Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com>
34
35Index: 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
59Index: 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
325Index: 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;