diff --git a/binutils-CVE-2017-12799.patch b/binutils-CVE-2017-12799.patch new file mode 100644 index 0000000..8b953b3 --- /dev/null +++ b/binutils-CVE-2017-12799.patch @@ -0,0 +1,11 @@ +--- binutils.orig/bfd/elf.c 2018-05-31 10:14:28.057641463 +0100 ++++ binutils-2.29/bfd/elf.c 2018-05-31 11:56:03.883865081 +0100 +@@ -10977,7 +10977,7 @@ elf_read_notes (bfd *abfd, file_ptr offs + { + char *buf; + +- if (size <= 0) ++ if (size == 0 || (size + 1) == 0) + return TRUE; + + if (bfd_seek (abfd, offset, SEEK_SET) != 0) diff --git a/binutils-CVE-2017-12967.patch b/binutils-CVE-2017-12967.patch new file mode 100644 index 0000000..ce36593 --- /dev/null +++ b/binutils-CVE-2017-12967.patch @@ -0,0 +1,11 @@ +--- binutils.orig/bfd/tekhex.c 2018-05-31 10:14:28.056641473 +0100 ++++ binutils-2.29/bfd/tekhex.c 2018-05-31 11:41:13.185681254 +0100 +@@ -307,7 +307,7 @@ getsym (char *dstp, char **srcp, unsigne + len = hex_value (*src++); + if (len == 0) + len = 16; +- for (i = 0; i < len && src < endp; i++) ++ for (i = 0; i < len && (src + i) < endp; i++) + dstp[i] = src[i]; + dstp[i] = 0; + *srcp = src + i; diff --git a/binutils-CVE-2017-13757.patch b/binutils-CVE-2017-13757.patch new file mode 100644 index 0000000..04c9260 --- /dev/null +++ b/binutils-CVE-2017-13757.patch @@ -0,0 +1,132 @@ +diff -rup binutils.orig/bfd/elf32-i386.c binutils-2.29/bfd/elf32-i386.c +--- binutils.orig/bfd/elf32-i386.c 2018-05-31 10:14:28.059641441 +0100 ++++ binutils-2.29/bfd/elf32-i386.c 2018-05-31 10:15:09.362194799 +0100 +@@ -6376,7 +6376,7 @@ elf_i386_get_synthetic_symtab (bfd *abfd + for (j = 0; plts[j].name != NULL; j++) + { + plt = bfd_get_section_by_name (abfd, plts[j].name); +- if (plt == NULL) ++ if (plt == NULL || plt->size == 0) + continue; + + /* Get the PLT section contents. */ +@@ -6392,7 +6392,9 @@ elf_i386_get_synthetic_symtab (bfd *abfd + + /* Check what kind of PLT it is. */ + plt_type = plt_unknown; +- if (plts[j].type == plt_unknown) ++ if (plts[j].type == plt_unknown ++ && (plt->size >= (lazy_plt->plt0_entry_size ++ + lazy_plt->plt_entry_size))) + { + /* Match lazy PLT first. */ + if (memcmp (plt_contents, lazy_plt->plt0_entry, +@@ -6401,7 +6403,7 @@ elf_i386_get_synthetic_symtab (bfd *abfd + /* The fist entry in the lazy IBT PLT is the same as the + normal lazy PLT. */ + if (lazy_ibt_plt != NULL +- && (memcmp (plt_contents + lazy_ibt_plt->plt_entry_size, ++ && (memcmp (plt_contents + lazy_ibt_plt->plt0_entry_size, + lazy_ibt_plt->plt_entry, + lazy_ibt_plt->plt_got_offset) == 0)) + plt_type = plt_lazy | plt_second; +@@ -6414,7 +6416,7 @@ elf_i386_get_synthetic_symtab (bfd *abfd + /* The fist entry in the PIC lazy IBT PLT is the same as + the normal PIC lazy PLT. */ + if (lazy_ibt_plt != NULL +- && (memcmp (plt_contents + lazy_ibt_plt->plt_entry_size, ++ && (memcmp (plt_contents + lazy_ibt_plt->plt0_entry_size, + lazy_ibt_plt->pic_plt_entry, + lazy_ibt_plt->plt_got_offset) == 0)) + plt_type = plt_lazy | plt_pic | plt_second; +@@ -6424,7 +6426,8 @@ elf_i386_get_synthetic_symtab (bfd *abfd + } + + if (non_lazy_plt != NULL +- && (plt_type == plt_unknown || plt_type == plt_non_lazy)) ++ && (plt_type == plt_unknown || plt_type == plt_non_lazy) ++ && plt->size >= non_lazy_plt->plt_entry_size) + { + /* Match non-lazy PLT. */ + if (memcmp (plt_contents, non_lazy_plt->plt_entry, +@@ -6436,7 +6439,8 @@ elf_i386_get_synthetic_symtab (bfd *abfd + } + + if ((non_lazy_ibt_plt != NULL) +- && (plt_type == plt_unknown || plt_type == plt_second)) ++ && (plt_type == plt_unknown || plt_type == plt_second) ++ && plt->size >= non_lazy_ibt_plt->plt_entry_size) + { + if (memcmp (plt_contents, + non_lazy_ibt_plt->plt_entry, +@@ -6494,6 +6498,9 @@ elf_i386_get_synthetic_symtab (bfd *abfd + got_addr = (bfd_vma) -1; + } + ++ if (count == 0) ++ return -1; ++ + size = count * sizeof (asymbol); + s = *ret = (asymbol *) bfd_zmalloc (size); + if (s == NULL) +Only in binutils-2.29/bfd/: elf32-i386.c.orig +diff -rup binutils.orig/bfd/elf64-x86-64.c binutils-2.29/bfd/elf64-x86-64.c +--- binutils.orig/bfd/elf64-x86-64.c 2018-05-31 10:14:28.078641236 +0100 ++++ binutils-2.29/bfd/elf64-x86-64.c 2018-05-31 10:15:25.284022632 +0100 +@@ -6756,7 +6756,7 @@ elf_x86_64_get_synthetic_symtab (bfd *ab + for (j = 0; plts[j].name != NULL; j++) + { + plt = bfd_get_section_by_name (abfd, plts[j].name); +- if (plt == NULL) ++ if (plt == NULL || plt->size == 0) + continue; + + /* Get the PLT section contents. */ +@@ -6772,7 +6772,9 @@ elf_x86_64_get_synthetic_symtab (bfd *ab + + /* Check what kind of PLT it is. */ + plt_type = plt_unknown; +- if (plts[j].type == plt_unknown) ++ if (plts[j].type == plt_unknown ++ && (plt->size >= (lazy_plt->plt_entry_size ++ + lazy_plt->plt_entry_size))) + { + /* Match lazy PLT first. Need to check the first two + instructions. */ +@@ -6800,7 +6802,8 @@ elf_x86_64_get_synthetic_symtab (bfd *ab + } + + if (non_lazy_plt != NULL +- && (plt_type == plt_unknown || plt_type == plt_non_lazy)) ++ && (plt_type == plt_unknown || plt_type == plt_non_lazy) ++ && plt->size >= non_lazy_plt->plt_entry_size) + { + /* Match non-lazy PLT. */ + if (memcmp (plt_contents, non_lazy_plt->plt_entry, +@@ -6811,6 +6814,7 @@ elf_x86_64_get_synthetic_symtab (bfd *ab + if (plt_type == plt_unknown || plt_type == plt_second) + { + if (non_lazy_bnd_plt != NULL ++ && plt->size >= non_lazy_bnd_plt->plt_entry_size + && (memcmp (plt_contents, non_lazy_bnd_plt->plt_entry, + non_lazy_bnd_plt->plt_got_offset) == 0)) + { +@@ -6819,6 +6823,7 @@ elf_x86_64_get_synthetic_symtab (bfd *ab + non_lazy_plt = non_lazy_bnd_plt; + } + else if (non_lazy_ibt_plt != NULL ++ && plt->size >= non_lazy_ibt_plt->plt_entry_size + && (memcmp (plt_contents, + non_lazy_ibt_plt->plt_entry, + non_lazy_ibt_plt->plt_got_offset) == 0)) +@@ -6864,6 +6869,9 @@ elf_x86_64_get_synthetic_symtab (bfd *ab + plts[j].contents = plt_contents; + } + ++ if (count == 0) ++ return -1; ++ + size = count * sizeof (asymbol); + s = *ret = (asymbol *) bfd_zmalloc (size); + if (s == NULL) +Only in binutils-2.29/bfd/: elf64-x86-64.c.orig diff --git a/binutils-CVE-2017-14333.patch b/binutils-CVE-2017-14333.patch new file mode 100644 index 0000000..236d5f2 --- /dev/null +++ b/binutils-CVE-2017-14333.patch @@ -0,0 +1,224 @@ +--- binutils.orig/binutils/readelf.c 2018-05-31 10:14:28.019641872 +0100 ++++ binutils-2.29/binutils/readelf.c 2018-05-31 10:57:28.912460915 +0100 +@@ -10154,9 +10154,8 @@ process_version_sections (FILE * file) + case SHT_GNU_verdef: + { + Elf_External_Verdef * edefs; +- unsigned int idx; +- unsigned int cnt; +- unsigned int end; ++ unsigned long idx; ++ unsigned long cnt; + char * endbuf; + + found = TRUE; +@@ -10178,23 +10177,16 @@ process_version_sections (FILE * file) + break; + endbuf = (char *) edefs + section->sh_size; + +- /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */ +- end = (section->sh_info < section->sh_size +- ? section->sh_info : section->sh_size); +- for (idx = cnt = 0; cnt < end; ++cnt) ++ for (idx = cnt = 0; cnt < section->sh_info; ++cnt) + { + char * vstart; + Elf_External_Verdef * edef; + Elf_Internal_Verdef ent; + Elf_External_Verdaux * eaux; + Elf_Internal_Verdaux aux; +- unsigned int isum; ++ unsigned long isum; + int j; + +- /* Check for very large indices. */ +- if (idx > (size_t) (endbuf - (char *) edefs)) +- break; +- + vstart = ((char *) edefs) + idx; + if (vstart + sizeof (*edef) > endbuf) + break; +@@ -10209,19 +10201,20 @@ process_version_sections (FILE * file) + ent.vd_aux = BYTE_GET (edef->vd_aux); + ent.vd_next = BYTE_GET (edef->vd_next); + +- printf (_(" %#06x: Rev: %d Flags: %s"), ++ printf (_(" %#06lx: Rev: %d Flags: %s"), + idx, ent.vd_version, get_ver_flags (ent.vd_flags)); + + printf (_(" Index: %d Cnt: %d "), + ent.vd_ndx, ent.vd_cnt); + +- /* Check for overflow and underflow. */ +- if (ent.vd_aux + sizeof (* eaux) > (size_t) (endbuf - vstart) +- || (vstart + ent.vd_aux < vstart)) ++ /* Check for overflow. */ ++ if (ent.vd_aux > (size_t) (endbuf - vstart)) + break; + + vstart += ent.vd_aux; + ++ if (vstart + sizeof (*eaux) > endbuf) ++ break; + eaux = (Elf_External_Verdaux *) vstart; + + aux.vda_name = BYTE_GET (eaux->vda_name); +@@ -10236,6 +10229,14 @@ process_version_sections (FILE * file) + + for (j = 1; j < ent.vd_cnt; j++) + { ++ if (aux.vda_next < sizeof (*eaux) ++ && !(j == ent.vd_cnt - 1 && aux.vda_next == 0)) ++ { ++ warn (_("Invalid vda_next field of %lx\n"), ++ aux.vda_next); ++ j = ent.vd_cnt; ++ break; ++ } + /* Check for overflow. */ + if (aux.vda_next > (size_t) (endbuf - vstart)) + break; +@@ -10243,18 +10244,18 @@ process_version_sections (FILE * file) + isum += aux.vda_next; + vstart += aux.vda_next; + +- eaux = (Elf_External_Verdaux *) vstart; + if (vstart + sizeof (*eaux) > endbuf) + break; ++ eaux = (Elf_External_Verdaux *) vstart; + + aux.vda_name = BYTE_GET (eaux->vda_name); + aux.vda_next = BYTE_GET (eaux->vda_next); + + if (VALID_DYNAMIC_NAME (aux.vda_name)) +- printf (_(" %#06x: Parent %d: %s\n"), ++ printf (_(" %#06lx: Parent %d: %s\n"), + isum, j, GET_DYNAMIC_NAME (aux.vda_name)); + else +- printf (_(" %#06x: Parent %d, name index: %ld\n"), ++ printf (_(" %#06lx: Parent %d, name index: %ld\n"), + isum, j, aux.vda_name); + } + +@@ -10263,7 +10264,14 @@ process_version_sections (FILE * file) + + /* PR 17531: + file: id:000001,src:000172+005151,op:splice,rep:2. */ +- if (idx + ent.vd_next < idx) ++ if (ent.vd_next < sizeof (*edef) ++ && !(cnt == section->sh_info - 1 && ent.vd_next == 0)) ++ { ++ warn (_("Invalid vd_next field of %lx\n"), ent.vd_next); ++ cnt = section->sh_info; ++ break; ++ } ++ if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx))) + break; + + idx += ent.vd_next; +@@ -10279,8 +10287,8 @@ process_version_sections (FILE * file) + case SHT_GNU_verneed: + { + Elf_External_Verneed * eneed; +- unsigned int idx; +- unsigned int cnt; ++ unsigned long idx; ++ unsigned long cnt; + char * endbuf; + + found = TRUE; +@@ -10306,13 +10314,10 @@ process_version_sections (FILE * file) + { + Elf_External_Verneed * entry; + Elf_Internal_Verneed ent; +- unsigned int isum; ++ unsigned long isum; + int j; + char * vstart; + +- if (idx > (size_t) (endbuf - (char *) eneed)) +- break; +- + vstart = ((char *) eneed) + idx; + if (vstart + sizeof (*entry) > endbuf) + break; +@@ -10325,7 +10330,7 @@ process_version_sections (FILE * file) + ent.vn_aux = BYTE_GET (entry->vn_aux); + ent.vn_next = BYTE_GET (entry->vn_next); + +- printf (_(" %#06x: Version: %d"), idx, ent.vn_version); ++ printf (_(" %#06lx: Version: %d"), idx, ent.vn_version); + + if (VALID_DYNAMIC_NAME (ent.vn_file)) + printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file)); +@@ -10355,24 +10360,26 @@ process_version_sections (FILE * file) + aux.vna_next = BYTE_GET (eaux->vna_next); + + if (VALID_DYNAMIC_NAME (aux.vna_name)) +- printf (_(" %#06x: Name: %s"), ++ printf (_(" %#06lx: Name: %s"), + isum, GET_DYNAMIC_NAME (aux.vna_name)); + else +- printf (_(" %#06x: Name index: %lx"), ++ printf (_(" %#06lx: Name index: %lx"), + isum, aux.vna_name); + + printf (_(" Flags: %s Version: %d\n"), + get_ver_flags (aux.vna_flags), aux.vna_other); + +- /* Check for overflow. */ +- if (aux.vna_next > (size_t) (endbuf - vstart) +- || (aux.vna_next == 0 && j < ent.vn_cnt - 1)) ++ if (aux.vna_next < sizeof (*eaux) ++ && !(j == ent.vn_cnt - 1 && aux.vna_next == 0)) + { + warn (_("Invalid vna_next field of %lx\n"), + aux.vna_next); + j = ent.vn_cnt; + break; + } ++ /* Check for overflow. */ ++ if (aux.vna_next > (size_t) (endbuf - vstart)) ++ break; + isum += aux.vna_next; + vstart += aux.vna_next; + } +@@ -10380,12 +10387,15 @@ process_version_sections (FILE * file) + if (j < ent.vn_cnt) + warn (_("Missing Version Needs auxillary information\n")); + +- if (ent.vn_next == 0 && cnt < section->sh_info - 1) ++ if (ent.vn_next < sizeof (*entry) ++ && !(cnt == section->sh_info - 1 && ent.vn_next == 0)) + { +- warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n")); ++ warn (_("Invalid vn_next field of %lx\n"), ent.vn_next); + cnt = section->sh_info; + break; + } ++ if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx))) ++ break; + idx += ent.vn_next; + } + +@@ -12859,7 +12869,9 @@ dump_section_as_strings (Elf_Internal_Sh + real_start = start = (unsigned char *) get_section_contents (section, + file); + if (start == NULL) +- return FALSE; ++ /* PR 21820: Do not fail if the section was empty. */ ++ return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE; ++ + num_bytes = section->sh_size; + + printf (_("\nString dump of section '%s':\n"), printable_section_name (section)); +@@ -13005,7 +13017,8 @@ dump_section_as_bytes (Elf_Internal_Shdr + + real_start = start = (unsigned char *) get_section_contents (section, file); + if (start == NULL) +- return FALSE; ++ /* PR 21820: Do not fail if the section was empty. */ ++ return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE; + + section_size = section->sh_size; + diff --git a/binutils.spec b/binutils.spec index 3927873..8af7a02 100644 --- a/binutils.spec +++ b/binutils.spec @@ -54,7 +54,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.29 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -160,6 +160,22 @@ Patch14: binutils-speed-up-objdump.patch # Lifetime: Fixed in 2.31. Patch15: binutils-ifunc-relocs-in-notes.patch +# Purpose: Fix a seg-fault induced when parsing corrupt x86 binaries. +# Lifetime: Fixed in 2.29.1. +Patch16: binutils-CVE-2017-13757.patch + +# Purpose: Fix a seg-fault induced when parsing ELF version information. +# Lifetime: Fixed in 2.29.1. +Patch17: binutils-CVE-2017-14333.patch + +# Purpose: Fix a seg-fault induced when parsing corrupt TEKHEX format files. +# Lifetime: Fixed in 2.29.1. +Patch18: binutils-CVE-2017-12967.patch + +# Purpose: Fix a seg-fault induced when parsing corrupt ELF format files. +# Lifetime: Fixed in 2.29.1. +Patch19: binutils-CVE-2017-12799.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -297,6 +313,10 @@ using libelf instead of BFD. %patch13 -p1 %patch14 -p1 %patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -705,6 +725,12 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Thu May 31 2018 Nick Clifton 2.29-1-15 +- Fix a seg-fault that can occur when parsing corrupt x86 binaries. (#1487762) +- Fix a seg-fault that can occur when parsing ELF version information. (#1492130) +- Fix a seg-fault that can occur when parsing corrupt TEKHEX files. (#1484527) +- Fix a seg-fault that can occur when parsing corrupt ELF files. (#1480343) + * Fri Mar 09 2018 Nick Clifton 2.29-1-14 - Treat relocs against s390x IFUNC symbols in note sections as relocs against the FUNC symbol instead. (#1553705)