binutils: Security fix for CVE-2017-8398
Affects: <= 2.28 (From OE-Core rev: 8bbed39afd0d4197e39db587f41cd301726c2958) Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
parent
640706066c
commit
5d2f47f2a2
|
@ -49,6 +49,7 @@ SRC_URI = "\
|
|||
file://CVE-2017-8394.patch \
|
||||
file://CVE-2017-8395.patch \
|
||||
file://CVE-2017-8396_8397.patch \
|
||||
file://CVE-2017-8398.patch \
|
||||
"
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
From d949ff5607b9f595e0eed2ff15fbe5eb84eb3a34 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Clifton <nickc@redhat.com>
|
||||
Date: Fri, 28 Apr 2017 10:28:04 +0100
|
||||
Subject: [PATCH] Fix heap-buffer overflow bugs caused when dumping debug
|
||||
information from a corrupt binary.
|
||||
|
||||
PR binutils/21438
|
||||
* dwarf.c (process_extended_line_op): Do not assume that the
|
||||
string extracted from the section is NUL terminated.
|
||||
(fetch_indirect_string): If the string retrieved from the section
|
||||
is not NUL terminated, return an error message.
|
||||
(fetch_indirect_line_string): Likewise.
|
||||
(fetch_indexed_string): Likewise.
|
||||
|
||||
Upstream-Status: Backport
|
||||
CVE: CVE-2017-8398
|
||||
Signed-off-by: Armin Kuster <akuster@mvista.com>
|
||||
|
||||
---
|
||||
binutils/ChangeLog | 10 +++++++++
|
||||
binutils/dwarf.c | 66 +++++++++++++++++++++++++++++++++++++++++-------------
|
||||
2 files changed, 60 insertions(+), 16 deletions(-)
|
||||
|
||||
Index: git/binutils/dwarf.c
|
||||
===================================================================
|
||||
--- git.orig/binutils/dwarf.c
|
||||
+++ git/binutils/dwarf.c
|
||||
@@ -472,15 +472,20 @@ process_extended_line_op (unsigned char
|
||||
printf (_(" Entry\tDir\tTime\tSize\tName\n"));
|
||||
printf (" %d\t", ++state_machine_regs.last_file_entry);
|
||||
|
||||
- name = data;
|
||||
- data += strnlen ((char *) data, end - data) + 1;
|
||||
- printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
|
||||
- data += bytes_read;
|
||||
- printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
|
||||
- data += bytes_read;
|
||||
- printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
|
||||
- data += bytes_read;
|
||||
- printf ("%s\n\n", name);
|
||||
+ {
|
||||
+ size_t l;
|
||||
+
|
||||
+ name = data;
|
||||
+ l = strnlen ((char *) data, end - data);
|
||||
+ data += len + 1;
|
||||
+ printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
|
||||
+ data += bytes_read;
|
||||
+ printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
|
||||
+ data += bytes_read;
|
||||
+ printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
|
||||
+ data += bytes_read;
|
||||
+ printf ("%.*s\n\n", (int) l, name);
|
||||
+ }
|
||||
|
||||
if (((unsigned int) (data - orig_data) != len) || data == end)
|
||||
warn (_("DW_LNE_define_file: Bad opcode length\n"));
|
||||
@@ -597,18 +602,27 @@ static const unsigned char *
|
||||
fetch_indirect_string (dwarf_vma offset)
|
||||
{
|
||||
struct dwarf_section *section = &debug_displays [str].section;
|
||||
+ const unsigned char * ret;
|
||||
|
||||
if (section->start == NULL)
|
||||
return (const unsigned char *) _("<no .debug_str section>");
|
||||
|
||||
- if (offset > section->size)
|
||||
+ if (offset >= section->size)
|
||||
{
|
||||
warn (_("DW_FORM_strp offset too big: %s\n"),
|
||||
dwarf_vmatoa ("x", offset));
|
||||
return (const unsigned char *) _("<offset is too big>");
|
||||
}
|
||||
+ ret = section->start + offset;
|
||||
+ /* Unfortunately we cannot rely upon the .debug_str section ending with a
|
||||
+ NUL byte. Since our caller is expecting to receive a well formed C
|
||||
+ string we test for the lack of a terminating byte here. */
|
||||
+ if (strnlen ((const char *) ret, section->size - offset)
|
||||
+ == section->size - offset)
|
||||
+ ret = (const unsigned char *)
|
||||
+ _("<no NUL byte at end of .debug_str section>");
|
||||
|
||||
- return (const unsigned char *) section->start + offset;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -621,6 +635,7 @@ fetch_indexed_string (dwarf_vma idx, str
|
||||
struct dwarf_section *str_section = &debug_displays [str_sec_idx].section;
|
||||
dwarf_vma index_offset = idx * offset_size;
|
||||
dwarf_vma str_offset;
|
||||
+ const char * ret;
|
||||
|
||||
if (index_section->start == NULL)
|
||||
return (dwo ? _("<no .debug_str_offsets.dwo section>")
|
||||
@@ -628,7 +643,7 @@ fetch_indexed_string (dwarf_vma idx, str
|
||||
|
||||
if (this_set != NULL)
|
||||
index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS];
|
||||
- if (index_offset > index_section->size)
|
||||
+ if (index_offset >= index_section->size)
|
||||
{
|
||||
warn (_("DW_FORM_GNU_str_index offset too big: %s\n"),
|
||||
dwarf_vmatoa ("x", index_offset));
|
||||
@@ -641,14 +656,22 @@ fetch_indexed_string (dwarf_vma idx, str
|
||||
|
||||
str_offset = byte_get (index_section->start + index_offset, offset_size);
|
||||
str_offset -= str_section->address;
|
||||
- if (str_offset > str_section->size)
|
||||
+ if (str_offset >= str_section->size)
|
||||
{
|
||||
warn (_("DW_FORM_GNU_str_index indirect offset too big: %s\n"),
|
||||
dwarf_vmatoa ("x", str_offset));
|
||||
return _("<indirect index offset is too big>");
|
||||
}
|
||||
|
||||
- return (const char *) str_section->start + str_offset;
|
||||
+ ret = (const char *) str_section->start + str_offset;
|
||||
+ /* Unfortunately we cannot rely upon str_section ending with a NUL byte.
|
||||
+ Since our caller is expecting to receive a well formed C string we test
|
||||
+ for the lack of a terminating byte here. */
|
||||
+ if (strnlen (ret, str_section->size - str_offset)
|
||||
+ == str_section->size - str_offset)
|
||||
+ ret = (const char *) _("<no NUL byte at end of section>");
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static const char *
|
||||
Index: git/binutils/ChangeLog
|
||||
===================================================================
|
||||
--- git.orig/binutils/ChangeLog
|
||||
+++ git/binutils/ChangeLog
|
||||
@@ -1,3 +1,13 @@
|
||||
+2017-04-28 Nick Clifton <nickc@redhat.com>
|
||||
+
|
||||
+ PR binutils/21438
|
||||
+ * dwarf.c (process_extended_line_op): Do not assume that the
|
||||
+ string extracted from the section is NUL terminated.
|
||||
+ (fetch_indirect_string): If the string retrieved from the section
|
||||
+ is not NUL terminated, return an error message.
|
||||
+ (fetch_indirect_line_string): Likewise.
|
||||
+ (fetch_indexed_string): Likewise.
|
||||
+
|
||||
2017-02-14 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/21157
|
Loading…
Reference in New Issue