public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] opcodes: don't assume ELF in riscv, csky, rl78, mep disassemblers
@ 2022-04-30  4:17 Thomas Hebb
  2022-04-30  6:44 ` Alan Modra
  0 siblings, 1 reply; 2+ messages in thread
From: Thomas Hebb @ 2022-04-30  4:17 UTC (permalink / raw)
  To: binutils; +Cc: Thomas Hebb

Currently, the get_disassembler() implementations for riscv, csky, and
rl78--and mep_print_insn() for mep--access ELF variants of union fields
without first checking that the bfd actually represents an ELF. This
causes undefined behavior and crashes when disassembling non-ELF files
(the "binary" BFD, for example).

For riscv, commit 113bb7618a4b ("RISC-V: PR27814, Objdump crashes when
disassembling a non-ELF RISC-V binary.") previously attempted to fix
this issue. That fix only added a NULL check for backend_data, though,
meaning the bug could still occur were a non-ELF backend_data to be
present.

Fix the issue properly for riscv, plus the three other architectures
with similar bugs, by ensuring the file flavour is ELF before accessing
ELF-specific data structures.

Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
---
I do not have an FSF copyright assignment, but I don't believe this
patch requires one. Ignoring whitespace changes and generated files,
this patch consists of four one-line bug fixes, all of which fix the
same bug, just for different architectures. According to the FSF's
guidance on Legally Significant Changes, this doesn't constitute one
since the meaningful changes are less than 15 lines.

 cpu/mep.opc         | 13 ++++++++-----
 opcodes/csky-dis.c  |  2 +-
 opcodes/mep-dis.c   | 13 ++++++++-----
 opcodes/riscv-dis.c | 32 ++++++++++++++------------------
 opcodes/rl78-dis.c  |  2 +-
 5 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/cpu/mep.opc b/cpu/mep.opc
index 6ad0c5879e8..278b4454c33 100644
--- a/cpu/mep.opc
+++ b/cpu/mep.opc
@@ -1451,12 +1451,15 @@ mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
   if (info->section && info->section->owner)
     {
       bfd *abfd = info->section->owner;
-      mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
-      /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
+      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+	{
+	  mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
+	  /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
 
-      cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
-      if (cop_type == EF_MEP_COP_IVC2)
-	ivc2 = 1;
+	  cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
+	  if (cop_type == EF_MEP_COP_IVC2)
+	    ivc2 = 1;
+	}
     }
 
   /* Picking the right ISA bitmask for the current context is tricky.  */
diff --git a/opcodes/csky-dis.c b/opcodes/csky-dis.c
index 96163166fc3..b7c833623e5 100644
--- a/opcodes/csky-dis.c
+++ b/opcodes/csky-dis.c
@@ -239,7 +239,7 @@ csky_get_disassembler (bfd *abfd)
 {
   obj_attribute *attr;
   const char *sec_name = NULL;
-  if (!abfd)
+  if (!abfd || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
     dis_info.isa = CSKY_DEFAULT_ISA;
   else
     {
diff --git a/opcodes/mep-dis.c b/opcodes/mep-dis.c
index 188ee298202..c56e90dcc6f 100644
--- a/opcodes/mep-dis.c
+++ b/opcodes/mep-dis.c
@@ -647,12 +647,15 @@ mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
   if (info->section && info->section->owner)
     {
       bfd *abfd = info->section->owner;
-      mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
-      /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
+      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+	{
+	  mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
+	  /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
 
-      cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
-      if (cop_type == EF_MEP_COP_IVC2)
-	ivc2 = 1;
+	  cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
+	  if (cop_type == EF_MEP_COP_IVC2)
+	    ivc2 = 1;
+	}
     }
 
   /* Picking the right ISA bitmask for the current context is tricky.  */
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index bfaefa3fb47..8be5020ffcc 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -1002,25 +1002,21 @@ riscv_get_disassembler (bfd *abfd)
 {
   const char *default_arch = "rv64gc";
 
-  if (abfd)
+  if (abfd && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
     {
-      const struct elf_backend_data *ebd = get_elf_backend_data (abfd);
-      if (ebd)
-	{
-	  const char *sec_name = ebd->obj_attrs_section;
-	  if (bfd_get_section_by_name (abfd, sec_name) != NULL)
-	    {
-	      obj_attribute *attr = elf_known_obj_attributes_proc (abfd);
-	      unsigned int Tag_a = Tag_RISCV_priv_spec;
-	      unsigned int Tag_b = Tag_RISCV_priv_spec_minor;
-	      unsigned int Tag_c = Tag_RISCV_priv_spec_revision;
-	      riscv_get_priv_spec_class_from_numbers (attr[Tag_a].i,
-						      attr[Tag_b].i,
-						      attr[Tag_c].i,
-						      &default_priv_spec);
-	      default_arch = attr[Tag_RISCV_arch].s;
-	    }
-	}
+      const char *sec_name = get_elf_backend_data (abfd)->obj_attrs_section;
+      if (bfd_get_section_by_name (abfd, sec_name) != NULL)
+        {
+	  obj_attribute *attr = elf_known_obj_attributes_proc (abfd);
+	  unsigned int Tag_a = Tag_RISCV_priv_spec;
+	  unsigned int Tag_b = Tag_RISCV_priv_spec_minor;
+	  unsigned int Tag_c = Tag_RISCV_priv_spec_revision;
+	  riscv_get_priv_spec_class_from_numbers (attr[Tag_a].i,
+						  attr[Tag_b].i,
+						  attr[Tag_c].i,
+						  &default_priv_spec);
+          default_arch = attr[Tag_RISCV_arch].s;
+        }
     }
 
   riscv_release_subset_list (&riscv_subsets);
diff --git a/opcodes/rl78-dis.c b/opcodes/rl78-dis.c
index cc08a298688..2d7ffb26eba 100644
--- a/opcodes/rl78-dis.c
+++ b/opcodes/rl78-dis.c
@@ -408,7 +408,7 @@ rl78_get_disassembler (bfd *abfd)
 {
   int cpu = E_FLAG_RL78_ANY_CPU;
 
-  if (abfd != NULL)
+  if (abfd != NULL && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
     cpu = abfd->tdata.elf_obj_data->elf_header->e_flags & E_FLAG_RL78_CPU_MASK;
 
   switch (cpu)
-- 
2.35.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] opcodes: don't assume ELF in riscv, csky, rl78, mep disassemblers
  2022-04-30  4:17 [PATCH] opcodes: don't assume ELF in riscv, csky, rl78, mep disassemblers Thomas Hebb
@ 2022-04-30  6:44 ` Alan Modra
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2022-04-30  6:44 UTC (permalink / raw)
  To: Thomas Hebb; +Cc: binutils

On Fri, Apr 29, 2022 at 09:17:58PM -0700, Thomas Hebb via Binutils wrote:
> Currently, the get_disassembler() implementations for riscv, csky, and
> rl78--and mep_print_insn() for mep--access ELF variants of union fields
> without first checking that the bfd actually represents an ELF. This
> causes undefined behavior and crashes when disassembling non-ELF files
> (the "binary" BFD, for example).

Thanks, committed.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-04-30  6:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-30  4:17 [PATCH] opcodes: don't assume ELF in riscv, csky, rl78, mep disassemblers Thomas Hebb
2022-04-30  6:44 ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).