Fix a seg-fault that can occur when parsing corrupt x86 binaries. Fix a seg-fault that can occur when parsing ELF version information. Fix a seg-fault that can occur when parsing corrupt TEKHEX files. Fix a seg-fault that can occur when parsing corrupt ELF files.
Resolves: #1487762 Resolves: #1492130 Resolves: #1484527 Resolves: #1480343
This commit is contained in:
parent
488c472281
commit
1212c94cbd
11
binutils-CVE-2017-12799.patch
Normal file
11
binutils-CVE-2017-12799.patch
Normal file
@ -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)
|
11
binutils-CVE-2017-12967.patch
Normal file
11
binutils-CVE-2017-12967.patch
Normal file
@ -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;
|
132
binutils-CVE-2017-13757.patch
Normal file
132
binutils-CVE-2017-13757.patch
Normal file
@ -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
|
224
binutils-CVE-2017-14333.patch
Normal file
224
binutils-CVE-2017-14333.patch
Normal file
@ -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;
|
||||
|
@ -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 <nickc@redhat.com> 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 <nickc@redhat.com> 2.29-1-14
|
||||
- Treat relocs against s390x IFUNC symbols in note sections as relocs against the FUNC symbol instead. (#1553705)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user