SHA256
3
0
forked from pool/binutils
binutils/fix-security-bugs.diff

763 lines
24 KiB
Diff
Raw Normal View History

This contains a merge of the following commits.
It fixes bnc#1029907, bnc#1029908, bnc#1029909 and more.
commit 03f7786e2f440b9892b1c34a58fb26222ce1b493
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 13:08:32 2017 +0000
Fix readelf writing to illegal addresses whilst processing corrupt input files containing symbol-difference relocations.
PR binutils/21137
* readelf.c (target_specific_reloc_handling): Add end parameter.
Check for buffer overflow before writing relocated values.
(apply_relocations): Pass end to target_specific_reloc_handling.
commit f84ce13b6708801ca1d6289b7c4003e2f5a6d7f9
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 14:03:22 2017 +0000
Fix read-after-free error in readelf when processing multiple, relocated sections in an MSP430 binary.
PR binutils/21139
* readelf.c (target_specific_reloc_handling): Add num_syms
parameter. Check for symbol table overflow before accessing
symbol value. If reloc pointer is NULL, discard all saved state.
(apply_relocations): Pass num_syms to target_specific_reloc_handling.
Call target_specific_reloc_handling with a NULL reloc pointer
after processing all of the relocs.
commit 0ee3043f58aae078a1ecc54b7be2810cae39a718
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 14:17:07 2017 +0000
Fix access violation when reporting sections that could not be dumped.
PR binutils/21147
* readelf.c (process_section_contents): Fix off by one error
reporting un-dumped sections.
commit 4aeb00ad3cc6a29b32f0a4e42c2f64d55e25b76d
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 14:35:24 2017 +0000
Fix check for buffer overflow when processing version information.
PR binutils/21148
* readelf.c (process_version_sections): Include size of auxillary
version information when checking for buffer overflow.
commit ebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 14:52:48 2017 +0000
Fix invalid memory access attempting to read the compression header of a too-small compressed section.
PR binutils/21149
* readelf.c (get_compression_header): Add size parameter. Check
size against sizeof compression header before attempting to
extract the header.
(process_section_headers): Pass size to get_compression_header.
(dump_section_as_strings): Likewise.
(dump_section_as_bytes): Likewise.
(load_specific_debug_section): Likewise.
commit f055032e4e922f1e1a5e11026c7c2669fa2a7d19
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 15:04:37 2017 +0000
Fix invalid read of section contents whilst processing a corrupt binary.
PR binutils/21135
* readelf.c (dump_section_as_bytes): Handle the case where
uncompress_section_contents returns false.
commit 1835f746a7c7fff70a2cc03a051b14fdc6b3f73f
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 15:19:48 2017 +0000
Extend previous patch to cover uncompress_section_contents returning FALSE to other callers.
PR binutils/21135
(dump_section_as_bytes, load_specific_debug_section): Likewise.
commit c12214021dedefcc2320827bcc1751f2d94ca2c6
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 17:23:10 2017 +0000
Fix illegal memory access bug in nm when run on a corrupt binary.
PR binutils/21150
* nm.c (file_symbol): Add test of string length before testing
string characters.
commit d11135f55294d75099ad03f81bacbe8ae93a6b28
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 13 17:51:27 2017 +0000
Fix invalid memory access in the BFD library's DWARF parser.
PR binutils/21151
* dwarf2.c (_bfd_dwarf2_find_nearest_line): Check for an invalid
unit length field.
commit b32e566ba6ee02687c6def22ade0899076adf7dd
Author: Nick Clifton <nickc@redhat.com>
Date: Tue Feb 14 13:24:09 2017 +0000
Fix illegal memory access problems with readelf processing corrupt RL78 binaries.
PR binutils/21155
* readelf.c (IN_RANGE): New macro. Tests for an address + offset
being within a given range.
(target_specific_reloc_handling): Use macro to test for underflow
as well as overflow of reloc offset.
commit a2dea0b20bc66a4c287c3c50002b8c3b3e9d953a
Author: Nick Clifton <nickc@redhat.com>
Date: Tue Feb 14 14:07:29 2017 +0000
Fix handling of corrupt STABS enum type strings.
PR binutils/21157
* stabs.c (parse_stab_enum_type): Check for corrupt NAME:VALUE
pairs.
(parse_number): Exit early if passed an empty string.
commit 92134dc19b4bf6407a88a306b771c9c6c88658d6
Author: Nick Clifton <nickc@redhat.com>
Date: Tue Feb 14 14:17:09 2017 +0000
Fix an illegal memory access parsing corrupt STABD debug information.
PR binutils/21158
* rddbg.c (read_symbol_stabs_debugging_info): Check for a null or
empty symbol name.
commit bc303e5d6c2dd33086478f80fd1d3096d4e1bc01
Author: Nick Clifton <nickc@redhat.com>
Date: Tue Feb 14 15:10:34 2017 +0000
Fix invalid memory access displayiing contents of sections.
PR binutils/21159
* readelf.c (dump_section_as_strings): Reset the start address if
no decompression is perfromed.
(dump_section_as_bytes): Likewise.
commit b814a36d3440de95f2ac6eaa4fc7935c322ea456
Author: Nick Clifton <nickc@redhat.com>
Date: Fri Feb 17 15:59:45 2017 +0000
Fix illegal memory accesses in readelf when parsing a corrupt binary.
PR binutils/21156
* readelf.c (find_section_in_set): Test for invalid section
indicies.
commit 43a444f9c5bfd44b4304eafd78338e21d54bea14
Author: Nick Clifton <nickc@redhat.com>
Date: Mon Feb 20 14:40:39 2017 +0000
Fix another memory access error in readelf when parsing a corrupt binary.
PR binutils/21156
* dwarf.c (cu_tu_indexes_read): Move into...
(load_cu_tu_indexes): ... here. Change the variable into
tri-state. Change the function into boolean, returning
false if the indicies could not be loaded.
(find_cu_tu_set): Return NULL if the indicies could not be
loaded.
commit 6438d1be9e9b6802a465c70c76b9cec7e23270f3
Author: Nick Clifton <nickc@redhat.com>
Date: Fri Feb 17 11:39:20 2017 +0000
Fix potential illegal memory access in ZLIB because of an erroneous declaration of the size of the input buffer.
* compress.c (bfd_get_full_section_contents): Remember to reduce
compressed size by the sizeof the compression header when
decompressing the contents.
Index: binutils-2.28/binutils/readelf.c
===================================================================
--- binutils-2.28.orig/binutils/readelf.c 2017-03-02 09:23:53.000000000 +0100
+++ binutils-2.28/binutils/readelf.c 2017-03-17 16:24:11.000000000 +0100
@@ -675,8 +675,14 @@ find_section_in_set (const char * name,
if (set != NULL)
{
while ((i = *set++) > 0)
- if (streq (SECTION_NAME (section_headers + i), name))
- return section_headers + i;
+ {
+ /* See PR 21156 for a reproducer. */
+ if (i >= elf_header.e_shnum)
+ continue; /* FIXME: Should we issue an error message ? */
+
+ if (streq (SECTION_NAME (section_headers + i), name))
+ return section_headers + i;
+ }
}
return find_section (name);
@@ -5708,12 +5714,18 @@ get_elf_section_flags (bfd_vma sh_flags)
}
static unsigned int
-get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf)
+get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
{
if (is_32bit_elf)
{
Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
+ if (size < sizeof (* echdr))
+ {
+ error (_("Compressed section is too small even for a compression header\n"));
+ return 0;
+ }
+
chdr->ch_type = BYTE_GET (echdr->ch_type);
chdr->ch_size = BYTE_GET (echdr->ch_size);
chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
@@ -5723,6 +5735,12 @@ get_compression_header (Elf_Internal_Chd
{
Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
+ if (size < sizeof (* echdr))
+ {
+ error (_("Compressed section is too small even for a compression header\n"));
+ return 0;
+ }
+
chdr->ch_type = BYTE_GET (echdr->ch_type);
chdr->ch_size = BYTE_GET (echdr->ch_size);
chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
@@ -6304,7 +6322,7 @@ process_section_headers (FILE * file)
{
Elf_Internal_Chdr chdr;
- (void) get_compression_header (&chdr, buf);
+ (void) get_compression_header (&chdr, buf, sizeof (buf));
if (chdr.ch_type == ELFCOMPRESS_ZLIB)
printf (" ZLIB, ");
@@ -10012,7 +10030,7 @@ process_version_sections (FILE * file)
ent.vd_ndx, ent.vd_cnt);
/* Check for overflow. */
- if (ent.vd_aux > (size_t) (endbuf - vstart))
+ if (ent.vd_aux + sizeof (* eaux) > (size_t) (endbuf - vstart))
break;
vstart += ent.vd_aux;
@@ -11577,16 +11595,32 @@ process_syminfo (FILE * file ATTRIBUTE_U
return 1;
}
+#define IN_RANGE(START,END,ADDR,OFF) \
+ (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
+
/* Check to see if the given reloc needs to be handled in a target specific
manner. If so then process the reloc and return TRUE otherwise return
- FALSE. */
+ FALSE.
+
+ If called with reloc == NULL, then this is a signal that reloc processing
+ for the current section has finished, and any saved state should be
+ discarded. */
static bfd_boolean
target_specific_reloc_handling (Elf_Internal_Rela * reloc,
unsigned char * start,
- Elf_Internal_Sym * symtab)
+ unsigned char * end,
+ Elf_Internal_Sym * symtab,
+ unsigned long num_syms)
{
- unsigned int reloc_type = get_reloc_type (reloc->r_info);
+ unsigned int reloc_type = 0;
+ unsigned long sym_index = 0;
+
+ if (reloc)
+ {
+ reloc_type = get_reloc_type (reloc->r_info);
+ sym_index = get_reloc_symindex (reloc->r_info);
+ }
switch (elf_header.e_machine)
{
@@ -11595,6 +11629,12 @@ target_specific_reloc_handling (Elf_Inte
{
static Elf_Internal_Sym * saved_sym = NULL;
+ if (reloc == NULL)
+ {
+ saved_sym = NULL;
+ return TRUE;
+ }
+
switch (reloc_type)
{
case 10: /* R_MSP430_SYM_DIFF */
@@ -11602,7 +11642,12 @@ target_specific_reloc_handling (Elf_Inte
break;
/* Fall through. */
case 21: /* R_MSP430X_SYM_DIFF */
- saved_sym = symtab + get_reloc_symindex (reloc->r_info);
+ /* PR 21139. */
+ if (sym_index >= num_syms)
+ error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
+ sym_index);
+ else
+ saved_sym = symtab + sym_index;
return TRUE;
case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
@@ -11624,13 +11669,24 @@ target_specific_reloc_handling (Elf_Inte
handle_sym_diff:
if (saved_sym != NULL)
{
+ int reloc_size = reloc_type == 1 ? 4 : 2;
bfd_vma value;
- value = reloc->r_addend
- + (symtab[get_reloc_symindex (reloc->r_info)].st_value
- - saved_sym->st_value);
+ if (sym_index >= num_syms)
+ error (_("MSP430 reloc contains invalid symbol index %lu\n"),
+ sym_index);
+ else
+ {
+ value = reloc->r_addend + (symtab[sym_index].st_value
+ - saved_sym->st_value);
- byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
+ if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
+ byte_put (start + reloc->r_offset, value, reloc_size);
+ else
+ /* PR 21137 */
+ error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
+ (long) reloc->r_offset);
+ }
saved_sym = NULL;
return TRUE;
@@ -11650,24 +11706,45 @@ target_specific_reloc_handling (Elf_Inte
{
static Elf_Internal_Sym * saved_sym = NULL;
+ if (reloc == NULL)
+ {
+ saved_sym = NULL;
+ return TRUE;
+ }
+
switch (reloc_type)
{
case 34: /* R_MN10300_ALIGN */
return TRUE;
case 33: /* R_MN10300_SYM_DIFF */
- saved_sym = symtab + get_reloc_symindex (reloc->r_info);
+ if (sym_index >= num_syms)
+ error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
+ sym_index);
+ else
+ saved_sym = symtab + sym_index;
return TRUE;
+
case 1: /* R_MN10300_32 */
case 2: /* R_MN10300_16 */
if (saved_sym != NULL)
{
+ int reloc_size = reloc_type == 1 ? 4 : 2;
bfd_vma value;
- value = reloc->r_addend
- + (symtab[get_reloc_symindex (reloc->r_info)].st_value
- - saved_sym->st_value);
+ if (sym_index >= num_syms)
+ error (_("MN10300 reloc contains invalid symbol index %lu\n"),
+ sym_index);
+ else
+ {
+ value = reloc->r_addend + (symtab[sym_index].st_value
+ - saved_sym->st_value);
- byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
+ if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
+ byte_put (start + reloc->r_offset, value, reloc_size);
+ else
+ error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
+ (long) reloc->r_offset);
+ }
saved_sym = NULL;
return TRUE;
@@ -11687,12 +11764,24 @@ target_specific_reloc_handling (Elf_Inte
static bfd_vma saved_sym2 = 0;
static bfd_vma value;
+ if (reloc == NULL)
+ {
+ saved_sym1 = saved_sym2 = 0;
+ return TRUE;
+ }
+
switch (reloc_type)
{
case 0x80: /* R_RL78_SYM. */
saved_sym1 = saved_sym2;
- saved_sym2 = symtab[get_reloc_symindex (reloc->r_info)].st_value;
- saved_sym2 += reloc->r_addend;
+ if (sym_index >= num_syms)
+ error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
+ sym_index);
+ else
+ {
+ saved_sym2 = symtab[sym_index].st_value;
+ saved_sym2 += reloc->r_addend;
+ }
return TRUE;
case 0x83: /* R_RL78_OPsub. */
@@ -11702,12 +11791,20 @@ target_specific_reloc_handling (Elf_Inte
break;
case 0x41: /* R_RL78_ABS32. */
- byte_put (start + reloc->r_offset, value, 4);
+ if (IN_RANGE (start, end, start + reloc->r_offset, 4))
+ byte_put (start + reloc->r_offset, value, 4);
+ else
+ error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
+ (long) reloc->r_offset);
value = 0;
return TRUE;
case 0x43: /* R_RL78_ABS16. */
- byte_put (start + reloc->r_offset, value, 2);
+ if (IN_RANGE (start, end, start + reloc->r_offset, 2))
+ byte_put (start + reloc->r_offset, value, 2);
+ else
+ error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
+ (long) reloc->r_offset);
value = 0;
return TRUE;
@@ -12324,7 +12421,7 @@ apply_relocations (void *
reloc_type = get_reloc_type (rp->r_info);
- if (target_specific_reloc_handling (rp, start, symtab))
+ if (target_specific_reloc_handling (rp, start, end, symtab, num_syms))
continue;
else if (is_none_reloc (reloc_type))
continue;
@@ -12420,6 +12517,9 @@ apply_relocations (void *
}
free (symtab);
+ /* Let the target specific reloc processing code know that
+ we have finished with these relocs. */
+ target_specific_reloc_handling (NULL, NULL, NULL, NULL, 0);
if (relocs_return)
{
@@ -12548,7 +12648,8 @@ dump_section_as_strings (Elf_Internal_Sh
{
Elf_Internal_Chdr chdr;
unsigned int compression_header_size
- = get_compression_header (& chdr, (unsigned char *) start);
+ = get_compression_header (& chdr, (unsigned char *) start,
+ num_bytes);
if (chdr.ch_type != ELFCOMPRESS_ZLIB)
{
@@ -12583,10 +12684,20 @@ dump_section_as_strings (Elf_Internal_Sh
new_size -= 12;
}
- if (uncompressed_size
- && uncompress_section_contents (& start,
- uncompressed_size, & new_size))
- num_bytes = new_size;
+ if (uncompressed_size)
+ {
+ if (uncompress_section_contents (& start,
+ uncompressed_size, & new_size))
+ num_bytes = new_size;
+ else
+ {
+ error (_("Unable to decompress section %s\n"),
+ printable_section_name (section));
+ return;
+ }
+ }
+ else
+ start = real_start;
}
/* If the section being dumped has relocations against it the user might
@@ -12682,7 +12793,7 @@ dump_section_as_bytes (Elf_Internal_Shdr
{
Elf_Internal_Chdr chdr;
unsigned int compression_header_size
- = get_compression_header (& chdr, start);
+ = get_compression_header (& chdr, start, section_size);
if (chdr.ch_type != ELFCOMPRESS_ZLIB)
{
@@ -12717,10 +12828,23 @@ dump_section_as_bytes (Elf_Internal_Shdr
new_size -= 12;
}
- if (uncompressed_size
- && uncompress_section_contents (& start, uncompressed_size,
- & new_size))
- section_size = new_size;
+ if (uncompressed_size)
+ {
+ if (uncompress_section_contents (& start, uncompressed_size,
+ & new_size))
+ {
+ section_size = new_size;
+ }
+ else
+ {
+ error (_("Unable to decompress section %s\n"),
+ printable_section_name (section));
+ /* FIXME: Print the section anyway ? */
+ return;
+ }
+ }
+ else
+ start = real_start;
}
if (relocate)
@@ -12835,7 +12959,7 @@ load_specific_debug_section (enum dwarf_
return 0;
}
- compression_header_size = get_compression_header (&chdr, start);
+ compression_header_size = get_compression_header (&chdr, start, size);
if (chdr.ch_type != ELFCOMPRESS_ZLIB)
{
@@ -12870,15 +12994,24 @@ load_specific_debug_section (enum dwarf_
size -= 12;
}
- if (uncompressed_size
- && uncompress_section_contents (&start, uncompressed_size,
- &size))
- {
- /* Free the compressed buffer, update the section buffer
- and the section size if uncompress is successful. */
- free (section->start);
- section->start = start;
+ if (uncompressed_size)
+ {
+ if (uncompress_section_contents (&start, uncompressed_size,
+ &size))
+ {
+ /* Free the compressed buffer, update the section buffer
+ and the section size if uncompress is successful. */
+ free (section->start);
+ section->start = start;
+ }
+ else
+ {
+ error (_("Unable to decompress section %s\n"),
+ printable_section_name (sec));
+ return 0;
+ }
}
+
section->size = size;
}
@@ -13077,9 +13210,12 @@ process_section_contents (FILE * file)
/* Check to see if the user requested a
dump of a section that does not exist. */
- while (i++ < num_dump_sects)
- if (dump_sects[i])
- warn (_("Section %d was not dumped because it does not exist!\n"), i);
+ while (i < num_dump_sects)
+ {
+ if (dump_sects[i])
+ warn (_("Section %d was not dumped because it does not exist!\n"), i);
+ i++;
+ }
}
static void
Index: binutils-2.28/binutils/nm.c
===================================================================
--- binutils-2.28.orig/binutils/nm.c 2017-03-02 09:23:53.000000000 +0100
+++ binutils-2.28/binutils/nm.c 2017-03-17 16:24:11.000000000 +0100
@@ -685,7 +685,8 @@ size_forward1 (const void *P_x, const vo
#define file_symbol(s, sn, snl) \
(((s)->flags & BSF_FILE) != 0 \
- || ((sn)[(snl) - 2] == '.' \
+ || ((snl) > 2 \
+ && (sn)[(snl) - 2] == '.' \
&& ((sn)[(snl) - 1] == 'o' \
|| (sn)[(snl) - 1] == 'a')))
Index: binutils-2.28/bfd/dwarf2.c
===================================================================
--- binutils-2.28.orig/bfd/dwarf2.c 2017-03-02 09:23:53.000000000 +0100
+++ binutils-2.28/bfd/dwarf2.c 2017-03-17 16:24:11.000000000 +0100
@@ -4288,6 +4288,10 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
{
bfd_byte * new_ptr;
+ /* PR 21151 */
+ if (stash->info_ptr + length > stash->info_ptr_end)
+ return FALSE;
+
each = parse_comp_unit (stash, length, info_ptr_unit,
offset_size);
if (!each)
Index: binutils-2.28/binutils/stabs.c
===================================================================
--- binutils-2.28.orig/binutils/stabs.c 2017-03-02 09:23:53.000000000 +0100
+++ binutils-2.28/binutils/stabs.c 2017-03-17 16:24:11.000000000 +0100
@@ -232,6 +232,10 @@ parse_number (const char **pp, bfd_boole
orig = *pp;
+ /* Stop early if we are passed an empty string. */
+ if (*orig == 0)
+ return (bfd_vma) 0;
+
errno = 0;
ul = strtoul (*pp, (char **) pp, 0);
if (ul + 1 != 0 || errno == 0)
@@ -1975,9 +1979,17 @@ parse_stab_enum_type (void *dhandle, con
bfd_signed_vma val;
p = *pp;
- while (*p != ':')
+ while (*p != ':' && *p != 0)
++p;
+ if (*p == 0)
+ {
+ bad_stab (orig);
+ free (names);
+ free (values);
+ return DEBUG_TYPE_NULL;
+ }
+
name = savestring (*pp, p - *pp);
*pp = p + 1;
Index: binutils-2.28/binutils/rddbg.c
===================================================================
--- binutils-2.28.orig/binutils/rddbg.c 2017-03-02 09:23:53.000000000 +0100
+++ binutils-2.28/binutils/rddbg.c 2017-03-17 16:24:11.000000000 +0100
@@ -299,7 +299,10 @@ read_symbol_stabs_debugging_info (bfd *a
*pfound = TRUE;
s = i.name;
+ if (s == NULL || strlen (s) < 1)
+ return FALSE;
f = NULL;
+
while (s[strlen (s) - 1] == '\\'
&& ps + 1 < symend)
{
Index: binutils-2.28/binutils/dwarf.c
===================================================================
--- binutils-2.28.orig/binutils/dwarf.c 2017-03-02 09:23:53.000000000 +0100
+++ binutils-2.28/binutils/dwarf.c 2017-03-17 16:24:11.000000000 +0100
@@ -76,7 +76,6 @@ int dwarf_check = 0;
as a zero-terminated list of section indexes comprising one set of debug
sections from a .dwo file. */
-static int cu_tu_indexes_read = 0;
static unsigned int *shndx_pool = NULL;
static unsigned int shndx_pool_size = 0;
static unsigned int shndx_pool_used = 0;
@@ -99,7 +98,7 @@ static int tu_count = 0;
static struct cu_tu_set *cu_sets = NULL;
static struct cu_tu_set *tu_sets = NULL;
-static void load_cu_tu_indexes (void *file);
+static bfd_boolean load_cu_tu_indexes (void *);
/* Values for do_debug_lines. */
#define FLAG_DEBUG_LINES_RAW 1
@@ -2715,7 +2714,7 @@ load_debug_info (void * file)
return num_debug_info_entries;
/* If this is a DWARF package file, load the CU and TU indexes. */
- load_cu_tu_indexes (file);
+ (void) load_cu_tu_indexes (file);
if (load_debug_section (info, file)
&& process_debug_info (&debug_displays [info].section, file, abbrev, 1, 0))
@@ -7378,21 +7377,27 @@ process_cu_tu_index (struct dwarf_sectio
section sets that we can use to associate a .debug_info.dwo section
with its associated .debug_abbrev.dwo section in a .dwp file. */
-static void
+static bfd_boolean
load_cu_tu_indexes (void *file)
{
+ static int cu_tu_indexes_read = -1; /* Tri-state variable. */
+
/* If we have already loaded (or tried to load) the CU and TU indexes
then do not bother to repeat the task. */
- if (cu_tu_indexes_read)
- return;
-
- if (load_debug_section (dwp_cu_index, file))
- process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0);
+ if (cu_tu_indexes_read == -1)
+ {
+ cu_tu_indexes_read = TRUE;
+
+ if (load_debug_section (dwp_cu_index, file))
+ if (! process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0))
+ cu_tu_indexes_read = FALSE;
- if (load_debug_section (dwp_tu_index, file))
- process_cu_tu_index (&debug_displays [dwp_tu_index].section, 0);
+ if (load_debug_section (dwp_tu_index, file))
+ if (! process_cu_tu_index (&debug_displays [dwp_tu_index].section, 0))
+ cu_tu_indexes_read = FALSE;
+ }
- cu_tu_indexes_read = 1;
+ return (bfd_boolean) cu_tu_indexes_read;
}
/* Find the set of sections that includes section SHNDX. */
@@ -7402,7 +7407,8 @@ find_cu_tu_set (void *file, unsigned int
{
unsigned int i;
- load_cu_tu_indexes (file);
+ if (! load_cu_tu_indexes (file))
+ return NULL;
/* Find SHNDX in the shndx pool. */
for (i = 0; i < shndx_pool_used; i++)
Index: binutils-2.28/bfd/compress.c
===================================================================
--- binutils-2.28.orig/bfd/compress.c 2017-03-02 09:23:53.000000000 +0100
+++ binutils-2.28/bfd/compress.c 2017-03-17 16:24:11.000000000 +0100
@@ -300,7 +300,7 @@ bfd_get_full_section_contents (bfd *abfd
SHF_COMPRESSED section. */
compression_header_size = 12;
if (!decompress_contents (compressed_buffer + compression_header_size,
- sec->compressed_size, p, sz))
+ sec->compressed_size - compression_header_size, p, sz))
{
bfd_set_error (bfd_error_bad_value);
if (p != *ptr)