summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2018-08-08 13:47:28 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-08-15 10:22:45 +0100
commit3552c38b32021aa24f6de6914cd37b622ab70f05 (patch)
tree433ff70ea7b5bb811bba7fa3c2478b2855ef5dc5
parent1b709e6837dca57e8416fd6066b5a3d821a13fca (diff)
downloadpoky-3552c38b32021aa24f6de6914cd37b622ab70f05.tar.gz
Binutils: Security fix for CVE-2018-7568
Affects: <= 2.30 (From OE-Core rev: d407e48c7e925806e162bb91e9b14088acedb05c) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.29.1.inc2
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch161
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch73
3 files changed, 236 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.29.1.inc b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
index 13389a1d30..ceb8e85579 100644
--- a/meta/recipes-devtools/binutils/binutils-2.29.1.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
@@ -73,6 +73,8 @@ SRC_URI = "\
73 file://CVE-2018-6323.patch \ 73 file://CVE-2018-6323.patch \
74 file://CVE-2018-6759.patch \ 74 file://CVE-2018-6759.patch \
75 file://CVE-2018-7208.patch \ 75 file://CVE-2018-7208.patch \
76 file://CVE-2018-7568_p1.patch \
77 file://CVE-2018-7568_p2.patch \
76" 78"
77S = "${WORKDIR}/git" 79S = "${WORKDIR}/git"
78 80
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch
new file mode 100644
index 0000000000..b014080a7e
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch
@@ -0,0 +1,161 @@
1From 1da5c9a485f3dcac4c45e96ef4b7dae5948314b5 Mon Sep 17 00:00:00 2001
2From: Alan Modra <amodra@gmail.com>
3Date: Mon, 25 Sep 2017 20:20:38 +0930
4Subject: [PATCH] PR22202, buffer overflow in parse_die
5
6There was a complete lack of sanity checking in dwarf1.c
7
8 PR 22202
9 * dwarf1.c (parse_die): Sanity check pointer against section limit
10 before dereferencing.
11 (parse_line_table): Likewise.
12
13Upstream-Status: Backport
14Affects: <= 2.30
15CVE: CVE-2018-7568 patch1
16Signed-off-by: Armin Kuster <akuster@mvista.com>
17
18---
19 bfd/ChangeLog | 7 +++++++
20 bfd/dwarf1.c | 56 ++++++++++++++++++++++++++++++++++++++------------------
21 2 files changed, 45 insertions(+), 18 deletions(-)
22
23Index: git/bfd/dwarf1.c
24===================================================================
25--- git.orig/bfd/dwarf1.c
26+++ git/bfd/dwarf1.c
27@@ -189,11 +189,14 @@ parse_die (bfd * abfd,
28 memset (aDieInfo, 0, sizeof (* aDieInfo));
29
30 /* First comes the length. */
31- aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr);
32+ if (xptr + 4 > aDiePtrEnd)
33+ return FALSE;
34+ aDieInfo->length = bfd_get_32 (abfd, xptr);
35 xptr += 4;
36 if (aDieInfo->length == 0
37- || (this_die + aDieInfo->length) >= aDiePtrEnd)
38+ || this_die + aDieInfo->length > aDiePtrEnd)
39 return FALSE;
40+ aDiePtrEnd = this_die + aDieInfo->length;
41 if (aDieInfo->length < 6)
42 {
43 /* Just padding bytes. */
44@@ -202,18 +205,20 @@ parse_die (bfd * abfd,
45 }
46
47 /* Then the tag. */
48- aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr);
49+ if (xptr + 2 > aDiePtrEnd)
50+ return FALSE;
51+ aDieInfo->tag = bfd_get_16 (abfd, xptr);
52 xptr += 2;
53
54 /* Then the attributes. */
55- while (xptr < (this_die + aDieInfo->length))
56+ while (xptr + 2 <= aDiePtrEnd)
57 {
58 unsigned short attr;
59
60 /* Parse the attribute based on its form. This section
61 must handle all dwarf1 forms, but need only handle the
62 actual attributes that we care about. */
63- attr = bfd_get_16 (abfd, (bfd_byte *) xptr);
64+ attr = bfd_get_16 (abfd, xptr);
65 xptr += 2;
66
67 switch (FORM_FROM_ATTR (attr))
68@@ -223,12 +228,15 @@ parse_die (bfd * abfd,
69 break;
70 case FORM_DATA4:
71 case FORM_REF:
72- if (attr == AT_sibling)
73- aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr);
74- else if (attr == AT_stmt_list)
75+ if (xptr + 4 <= aDiePtrEnd)
76 {
77- aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr);
78- aDieInfo->has_stmt_list = 1;
79+ if (attr == AT_sibling)
80+ aDieInfo->sibling = bfd_get_32 (abfd, xptr);
81+ else if (attr == AT_stmt_list)
82+ {
83+ aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr);
84+ aDieInfo->has_stmt_list = 1;
85+ }
86 }
87 xptr += 4;
88 break;
89@@ -236,22 +244,29 @@ parse_die (bfd * abfd,
90 xptr += 8;
91 break;
92 case FORM_ADDR:
93- if (attr == AT_low_pc)
94- aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
95- else if (attr == AT_high_pc)
96- aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
97+ if (xptr + 4 <= aDiePtrEnd)
98+ {
99+ if (attr == AT_low_pc)
100+ aDieInfo->low_pc = bfd_get_32 (abfd, xptr);
101+ else if (attr == AT_high_pc)
102+ aDieInfo->high_pc = bfd_get_32 (abfd, xptr);
103+ }
104 xptr += 4;
105 break;
106 case FORM_BLOCK2:
107- xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr);
108+ if (xptr + 2 <= aDiePtrEnd)
109+ xptr += bfd_get_16 (abfd, xptr);
110+ xptr += 2;
111 break;
112 case FORM_BLOCK4:
113- xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr);
114+ if (xptr + 4 <= aDiePtrEnd)
115+ xptr += bfd_get_32 (abfd, xptr);
116+ xptr += 4;
117 break;
118 case FORM_STRING:
119 if (attr == AT_name)
120 aDieInfo->name = (char *) xptr;
121- xptr += strlen ((char *) xptr) + 1;
122+ xptr += strnlen ((char *) xptr, aDiePtrEnd - xptr) + 1;
123 break;
124 }
125 }
126@@ -290,7 +305,7 @@ parse_line_table (struct dwarf1_debug* s
127 }
128
129 xptr = stash->line_section + aUnit->stmt_list_offset;
130- if (xptr < stash->line_section_end)
131+ if (xptr + 8 <= stash->line_section_end)
132 {
133 unsigned long eachLine;
134 bfd_byte *tblend;
135@@ -318,6 +333,11 @@ parse_line_table (struct dwarf1_debug* s
136
137 for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
138 {
139+ if (xptr + 10 > stash->line_section_end)
140+ {
141+ aUnit->line_count = eachLine;
142+ break;
143+ }
144 /* A line number. */
145 aUnit->linenumber_table[eachLine].linenumber
146 = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
147Index: git/bfd/ChangeLog
148===================================================================
149--- git.orig/bfd/ChangeLog
150+++ git/bfd/ChangeLog
151@@ -1,3 +1,10 @@
152+2017-09-25 Alan Modra <amodra@gmail.com>
153+
154+ PR 22202
155+ * dwarf1.c (parse_die): Sanity check pointer against section limit
156+ before dereferencing.
157+ (parse_line_table): Likewise.
158+
159 2018-01-29 Alan Modra <amodra@gmail.com>
160
161 PR 22741
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch
new file mode 100644
index 0000000000..b5511d7d8a
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch
@@ -0,0 +1,73 @@
1From eef104664efb52965d85a28bc3fc7c77e52e48e2 Mon Sep 17 00:00:00 2001
2From: Nick Clifton <nickc@redhat.com>
3Date: Wed, 28 Feb 2018 10:13:54 +0000
4Subject: [PATCH] Fix potential integer overflow when reading corrupt dwarf1
5 debug information.
6
7 PR 22894
8 * dwarf1.c (parse_die): Check the length of form blocks before
9 advancing the data pointer.
10
11Upstream-Status: Backport
12Affects: <= 2.30
13CVE: CVE-2018-7568 patch2
14Signed-off-by: Armin Kuster <akuster@mvista.com>
15
16---
17 bfd/ChangeLog | 6 ++++++
18 bfd/dwarf1.c | 17 +++++++++++++++--
19 2 files changed, 21 insertions(+), 2 deletions(-)
20
21Index: git/bfd/dwarf1.c
22===================================================================
23--- git.orig/bfd/dwarf1.c
24+++ git/bfd/dwarf1.c
25@@ -213,6 +213,7 @@ parse_die (bfd * abfd,
26 /* Then the attributes. */
27 while (xptr + 2 <= aDiePtrEnd)
28 {
29+ unsigned int block_len;
30 unsigned short attr;
31
32 /* Parse the attribute based on its form. This section
33@@ -255,12 +256,24 @@ parse_die (bfd * abfd,
34 break;
35 case FORM_BLOCK2:
36 if (xptr + 2 <= aDiePtrEnd)
37- xptr += bfd_get_16 (abfd, xptr);
38+ {
39+ block_len = bfd_get_16 (abfd, xptr);
40+ if (xptr + block_len > aDiePtrEnd
41+ || xptr + block_len < xptr)
42+ return FALSE;
43+ xptr += block_len;
44+ }
45 xptr += 2;
46 break;
47 case FORM_BLOCK4:
48 if (xptr + 4 <= aDiePtrEnd)
49- xptr += bfd_get_32 (abfd, xptr);
50+ {
51+ block_len = bfd_get_32 (abfd, xptr);
52+ if (xptr + block_len > aDiePtrEnd
53+ || xptr + block_len < xptr)
54+ return FALSE;
55+ xptr += block_len;
56+ }
57 xptr += 4;
58 break;
59 case FORM_STRING:
60Index: git/bfd/ChangeLog
61===================================================================
62--- git.orig/bfd/ChangeLog
63+++ git/bfd/ChangeLog
64@@ -1,3 +1,9 @@
65+2018-02-28 Nick Clifton <nickc@redhat.com>
66+
67+ PR 22894
68+ * dwarf1.c (parse_die): Check the length of form blocks before
69+ advancing the data pointer.
70+
71 2017-09-25 Alan Modra <amodra@gmail.com>
72
73 PR 22202