1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
From cfd14a500e0485374596234de4db10e88ebc7618 Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Mon, 26 Jun 2017 15:25:08 +0100
Subject: [PATCH] Fix address violations when atempting to parse fuzzed
binaries.
PR binutils/21665
bfd * opncls.c (get_build_id): Check that the section is beig enough
to contain the whole note.
* compress.c (bfd_get_full_section_contents): Check for and reject
a section whoes size is greater than the size of the entire file.
* elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not
contain a notes section.
binutils* objdump.c (disassemble_section): Skip any section that is bigger
than the entire file.
Upstream-Status: Backport
CVE: CVE-2017-9955 #1
Signed-off-by: Armin Kuster <akuster@mvista.com>
---
bfd/ChangeLog | 10 ++++++++++
bfd/compress.c | 6 ++++++
bfd/elf32-v850.c | 4 +++-
bfd/opncls.c | 18 ++++++++++++++++--
binutils/ChangeLog | 6 ++++++
binutils/objdump.c | 4 ++--
6 files changed, 43 insertions(+), 5 deletions(-)
Index: git/bfd/compress.c
===================================================================
--- git.orig/bfd/compress.c
+++ git/bfd/compress.c
@@ -239,6 +239,12 @@ bfd_get_full_section_contents (bfd *abfd
*ptr = NULL;
return TRUE;
}
+ else if (bfd_get_file_size (abfd) > 0
+ && sz > (bfd_size_type) bfd_get_file_size (abfd))
+ {
+ *ptr = NULL;
+ return FALSE;
+ }
switch (sec->compress_status)
{
Index: git/bfd/elf32-v850.c
===================================================================
--- git.orig/bfd/elf32-v850.c
+++ git/bfd/elf32-v850.c
@@ -2450,7 +2450,9 @@ v850_elf_copy_notes (bfd *ibfd, bfd *obf
BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont));
if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL)
- BFD_ASSERT (bfd_malloc_and_get_section (obfd, onotes, & ocont));
+ /* If the output is being stripped then it is possible for
+ the notes section to disappear. In this case do nothing. */
+ return;
/* Copy/overwrite notes from the input to the output. */
memcpy (ocont, icont, bfd_section_size (obfd, onotes));
Index: git/bfd/opncls.c
===================================================================
--- git.orig/bfd/opncls.c
+++ git/bfd/opncls.c
@@ -1776,6 +1776,7 @@ get_build_id (bfd *abfd)
Elf_External_Note *enote;
bfd_byte *contents;
asection *sect;
+ bfd_size_type size;
BFD_ASSERT (abfd);
@@ -1790,8 +1791,9 @@ get_build_id (bfd *abfd)
return NULL;
}
+ size = bfd_get_section_size (sect);
/* FIXME: Should we support smaller build-id notes ? */
- if (bfd_get_section_size (sect) < 0x24)
+ if (size < 0x24)
{
bfd_set_error (bfd_error_invalid_operation);
return NULL;
@@ -1804,6 +1806,17 @@ get_build_id (bfd *abfd)
return NULL;
}
+ /* FIXME: Paranoia - allow for compressed build-id sections.
+ Maybe we should complain if this size is different from
+ the one obtained above... */
+ size = bfd_get_section_size (sect);
+ if (size < sizeof (Elf_External_Note))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ free (contents);
+ return NULL;
+ }
+
enote = (Elf_External_Note *) contents;
inote.type = H_GET_32 (abfd, enote->type);
inote.namesz = H_GET_32 (abfd, enote->namesz);
@@ -1815,7 +1828,8 @@ get_build_id (bfd *abfd)
if (inote.descsz == 0
|| inote.type != NT_GNU_BUILD_ID
|| inote.namesz != 4 /* sizeof "GNU" */
- || strcmp (inote.namedata, "GNU") != 0)
+ || strncmp (inote.namedata, "GNU", 4) != 0
+ || size < (12 + BFD_ALIGN (inote.namesz, 4) + inote.descsz))
{
free (contents);
bfd_set_error (bfd_error_invalid_operation);
Index: git/binutils/objdump.c
===================================================================
--- git.orig/binutils/objdump.c
+++ git/binutils/objdump.c
@@ -2048,7 +2048,7 @@ disassemble_section (bfd *abfd, asection
return;
datasize = bfd_get_section_size (section);
- if (datasize == 0)
+ if (datasize == 0 || datasize >= (bfd_size_type) bfd_get_file_size (abfd))
return;
if (start_address == (bfd_vma) -1
@@ -2912,7 +2912,7 @@ dump_target_specific (bfd *abfd)
static void
dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
{
- bfd_byte *data = 0;
+ bfd_byte *data = NULL;
bfd_size_type datasize;
bfd_vma addr_offset;
bfd_vma start_offset;
Index: git/bfd/ChangeLog
===================================================================
--- git.orig/bfd/ChangeLog
+++ git/bfd/ChangeLog
@@ -1,4 +1,14 @@
2017-06-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/21665
+ * opncls.c (get_build_id): Check that the section is beig enough
+ to contain the whole note.
+ * compress.c (bfd_get_full_section_contents): Check for and reject
+ a section whoes size is greater than the size of the entire file.
+ * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not
+ contain a notes section.
+
+2017-06-26 Nick Clifton <nickc@redhat.com>
PR binutils/21670
* tekhex.c (getvalue): Check for the source pointer exceeding the
Index: git/binutils/ChangeLog
===================================================================
--- git.orig/binutils/ChangeLog
+++ git/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/21665
+ * objdump.c (disassemble_section): Skip any section that is bigger
+ than the entire file.
+
2017-04-03 Nick Clifton <nickc@redhat.com>
PR binutils/21345
|