aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-11-19 14:53:44 +1030
committerAlan Modra <amodra@gmail.com>2019-11-19 15:31:48 +1030
commitdd68a12bc4b19c50c31fe357335bb8ee9a3322fc (patch)
treecb7ca99d9ebd27d86aa0fd0ac26eb022522da14b
parentf14080d440fab16dcb498c1a46864a5a1be37aaa (diff)
downloadgdb-dd68a12bc4b19c50c31fe357335bb8ee9a3322fc.zip
gdb-dd68a12bc4b19c50c31fe357335bb8ee9a3322fc.tar.gz
gdb-dd68a12bc4b19c50c31fe357335bb8ee9a3322fc.tar.bz2
PR25191, internal error in _bfd_elf_set_section_contents
This PR copies a fuzzed PE input file to ELF output, in the process confusing the ELF backend by copying COFF-only section flags to the output. SEC_COFF_SHARED has the same value as SEC_ELF_COMPRESS. One approach to fixing this problem is of course not to reuse flag bits, but we've run out. So this patch only copies section flags that are in the bfd_applicable_section_flags set when changing the flavour of the output file. PR 25191 * objcopy.c (is_nondebug_keep_contents_section): Use bfd_get_flavour. (copy_object): Likewise. (setup_section): Likewise. If flavour of input and output files differ, restrict section flags to the intersection of input and output bfd_applicable_section_flags.
-rw-r--r--binutils/ChangeLog9
-rw-r--r--binutils/objcopy.c25
2 files changed, 24 insertions, 10 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index bf6d20e..4fabf0c 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,14 @@
2019-11-19 Alan Modra <amodra@gmail.com>
+ PR 25191
+ * objcopy.c (is_nondebug_keep_contents_section): Use bfd_get_flavour.
+ (copy_object): Likewise.
+ (setup_section): Likewise. If flavour of input and output files
+ differ, restrict section flags to the intersection of input and
+ output bfd_applicable_section_flags.
+
+2019-11-19 Alan Modra <amodra@gmail.com>
+
* bucomm.c (bfd_nonfatal_message): Add a space between program
name and file.
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index ea6eb64..551378d 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -1421,16 +1421,16 @@ static bfd_boolean
is_nondebug_keep_contents_section (bfd *ibfd, asection *isection)
{
/* Always keep ELF note sections. */
- if (ibfd->xvec->flavour == bfd_target_elf_flavour)
- return (elf_section_type (isection) == SHT_NOTE);
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+ return elf_section_type (isection) == SHT_NOTE;
/* Always keep the .buildid section for PE/COFF.
Strictly, this should be written "always keep the section storing the debug
directory", but that may be the .text section for objects produced by some
tools, which it is not sensible to keep. */
- if (ibfd->xvec->flavour == bfd_target_coff_flavour)
- return (strcmp (bfd_section_name (isection), ".buildid") == 0);
+ if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour)
+ return strcmp (bfd_section_name (isection), ".buildid") == 0;
return FALSE;
}
@@ -2585,7 +2585,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
return FALSE;
}
- if (ibfd->xvec->flavour != bfd_target_elf_flavour)
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
{
if ((do_debug_sections & compress) != 0
&& do_debug_sections != compress)
@@ -2683,7 +2683,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
pe_data_type *pe = pe_data (obfd);
/* Copy PE parameters before changing them. */
- if (ibfd->xvec->flavour == bfd_target_coff_flavour
+ if (bfd_get_flavour (ibfd) == bfd_target_coff_flavour
&& bfd_pei_p (ibfd))
pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
@@ -3922,11 +3922,16 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
/* Get the, possibly new, name of the output section. */
name = bfd_section_name (isection);
flags = bfd_section_flags (isection);
+ if (bfd_get_flavour (ibfd) != bfd_get_flavour (obfd))
+ {
+ flags &= bfd_applicable_section_flags (ibfd);
+ flags &= bfd_applicable_section_flags (obfd);
+ }
name = find_section_rename (name, &flags);
/* Prefix sections. */
- if ((prefix_alloc_sections_string)
- && (bfd_section_flags (isection) & SEC_ALLOC))
+ if (prefix_alloc_sections_string
+ && (bfd_section_flags (isection) & SEC_ALLOC) != 0)
prefix = prefix_alloc_sections_string;
else if (prefix_sections_string)
prefix = prefix_sections_string;
@@ -3952,7 +3957,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
&& !is_nondebug_keep_contents_section (ibfd, isection))
{
flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
- if (obfd->xvec->flavour == bfd_target_elf_flavour)
+ if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
{
make_nobits = TRUE;
@@ -4055,7 +4060,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
if (gsym != NULL)
{
gsym->flags |= BSF_KEEP;
- if (ibfd->xvec->flavour == bfd_target_elf_flavour)
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
elf_group_id (isection) = gsym;
}
}