From 1e19e656a97caf61f26ab4f52339b9413d3bb29f Mon Sep 17 00:00:00 2001 From: Thiruvadi Rajaraman Date: Wed, 20 Sep 2017 13:52:00 +0530 Subject: binutils: CVE-2017-8398 Source: git://sourceware.org/git/binutils-gdb.git MR: 74127 Type: Security Fix Disposition: Backport from binutils-2_29 ChangeID: 410078b468de6dc1c908342283a6abe5bdf38d54 Description: 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. Affects: <= 2.29 Author: Nick Clifton Signed-off-by: Thiruvadi Rajaraman Reviewed-by: Armin Kuster Signed-off-by: Armin Kuster Signed-off-by: Armin Kuster --- meta/recipes-devtools/binutils/binutils-2.27.inc | 1 + .../binutils/binutils/CVE-2017-8398.patch | 147 +++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch (limited to 'meta/recipes-devtools') diff --git a/meta/recipes-devtools/binutils/binutils-2.27.inc b/meta/recipes-devtools/binutils/binutils-2.27.inc index a455b0192c..35e26fc0dd 100644 --- a/meta/recipes-devtools/binutils/binutils-2.27.inc +++ b/meta/recipes-devtools/binutils/binutils-2.27.inc @@ -75,6 +75,7 @@ SRC_URI = "\ file://CVE-2017-8421.patch \ file://CVE-2017-8394_1.patch \ file://CVE-2017-8394.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..23d5085b16 --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-8398.patch @@ -0,0 +1,147 @@ +commit d949ff5607b9f595e0eed2ff15fbe5eb84eb3a34 +Author: Nick Clifton +Date: Fri Apr 28 10:28:04 2017 +0100 + + 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: Thiruvadi Rajaraman + +Index: git/binutils/dwarf.c +=================================================================== +--- git.orig/binutils/dwarf.c 2017-09-20 13:40:17.148898512 +0530 ++++ git/binutils/dwarf.c 2017-09-20 13:45:17.564730907 +0530 +@@ -472,15 +472,20 @@ + 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,28 @@ + 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 *) _(""); + } + +- return (const unsigned char *) section->start + offset; ++ 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 ret; + } + + static const char * +@@ -621,6 +636,7 @@ + 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 +644,7 @@ + + 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 +657,22 @@ + + 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 2017-09-20 13:40:18.900898599 +0530 ++++ git/binutils/ChangeLog 2017-09-20 13:48:02.976503560 +0530 +@@ -10,6 +10,16 @@ + * objdump.c (dump_relocs_in_section): Check for an excessive + number of relocs before attempting to dump them. + ++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 -- cgit 1.2.3-korg