diff --git a/meta/recipes-devtools/binutils/binutils-2.28.inc b/meta/recipes-devtools/binutils/binutils-2.28.inc index ca78a30bb7..d58d7b86cc 100644 --- a/meta/recipes-devtools/binutils/binutils-2.28.inc +++ b/meta/recipes-devtools/binutils/binutils-2.28.inc @@ -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" diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch new file mode 100644 index 0000000000..5b9acc8cfa --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch @@ -0,0 +1,147 @@ +From d949ff5607b9f595e0eed2ff15fbe5eb84eb3a34 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +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 + +--- + 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 *) _(""); + +- 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 *) _(""); + } ++ 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 *) ++ _(""); + +- 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 ? _("") +@@ -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 _(""); + } + +- 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 *) _(""); ++ ++ 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 ++ ++ 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 + + PR binutils/21157