public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Thomas Hebb <tommyhebb@gmail.com>
To: binutils@sourceware.org
Cc: Thomas Hebb <tommyhebb@gmail.com>
Subject: [PATCH] opcodes: don't assume ELF in riscv, csky, rl78, mep disassemblers
Date: Fri, 29 Apr 2022 21:17:58 -0700	[thread overview]
Message-ID: <3f8a2c44c944c304bee9be9d53aefcb00b238a11.1651292115.git.tommyhebb@gmail.com> (raw)

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


             reply	other threads:[~2022-04-30  4:18 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-30  4:17 Thomas Hebb [this message]
2022-04-30  6:44 ` Alan Modra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3f8a2c44c944c304bee9be9d53aefcb00b238a11.1651292115.git.tommyhebb@gmail.com \
    --to=tommyhebb@gmail.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).