summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch')
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch161
1 files changed, 161 insertions, 0 deletions
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