aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-08-06 18:35:23 +0930
committerAlan Modra <amodra@gmail.com>2021-08-06 23:06:40 +0930
commita379e7588c5e3a9750bba8c51218cce9225122f5 (patch)
treebb84eca9f003424c9fa0d9236b11ddcbef1d6342
parent352bd3aa1c68137d4a5115183f42c40b75ee05b3 (diff)
downloadfsf-binutils-gdb-a379e7588c5e3a9750bba8c51218cce9225122f5.zip
fsf-binutils-gdb-a379e7588c5e3a9750bba8c51218cce9225122f5.tar.gz
fsf-binutils-gdb-a379e7588c5e3a9750bba8c51218cce9225122f5.tar.bz2
PR28173, nds32_elf_howto_table index out of bounds
Indexing the howto table was seriously broken by a missing entry, and use of assertions about user input rather than testing the input. PR 28173 * elf32-nds32.c (nds32_elf_howto_table): Add missing empty howto. (bfd_elf32_bfd_reloc_type_table_lookup): Replace assertions with range checks. Return NULL if unsupported reloc type. Remove dead code. Take an unsigned int param. (nds32_info_to_howto_rel): Test for NULL howto or howto name return from lookup. Remove assertion. (nds32_info_to_howto): Remove unnecessary ATTRIBUTE_UNUSED. Test for NULL howto or howto name return from lookup.
-rw-r--r--bfd/elf32-nds32.c55
1 files changed, 25 insertions, 30 deletions
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index 5eb0295..0aa7c9e 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -1954,6 +1954,8 @@ static reloc_howto_type nds32_elf_howto_table[] =
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
+ EMPTY_HOWTO (114),
+
HOWTO2 (R_NDS32_TLS_IE_LO12, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
@@ -3184,26 +3186,19 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
}
static reloc_howto_type *
-bfd_elf32_bfd_reloc_type_table_lookup (enum elf_nds32_reloc_type code)
+bfd_elf32_bfd_reloc_type_table_lookup (unsigned int code)
{
if (code < R_NDS32_RELAX_ENTRY)
{
- BFD_ASSERT (code < ARRAY_SIZE (nds32_elf_howto_table));
- return &nds32_elf_howto_table[code];
+ if (code < ARRAY_SIZE (nds32_elf_howto_table))
+ return &nds32_elf_howto_table[code];
}
else
{
- if ((size_t) (code - R_NDS32_RELAX_ENTRY)
- >= ARRAY_SIZE (nds32_elf_relax_howto_table))
- {
- int i = code;
- i += 1;
- }
-
- BFD_ASSERT ((size_t) (code - R_NDS32_RELAX_ENTRY)
- < ARRAY_SIZE (nds32_elf_relax_howto_table));
- return &nds32_elf_relax_howto_table[code - R_NDS32_RELAX_ENTRY];
+ if (code - R_NDS32_RELAX_ENTRY < ARRAY_SIZE (nds32_elf_relax_howto_table))
+ return &nds32_elf_relax_howto_table[code - R_NDS32_RELAX_ENTRY];
}
+ return NULL;
}
static reloc_howto_type *
@@ -3228,10 +3223,12 @@ static bool
nds32_info_to_howto_rel (bfd *abfd, arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
- enum elf_nds32_reloc_type r_type;
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
- r_type = ELF32_R_TYPE (dst->r_info);
- if (r_type > R_NDS32_GNU_VTENTRY)
+ cache_ptr->howto = NULL;
+ if (r_type <= R_NDS32_GNU_VTENTRY)
+ cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
+ if (cache_ptr->howto == NULL || cache_ptr->howto->name == NULL)
{
/* xgettext:c-format */
_bfd_error_handler (_("%pB: unsupported relocation type %#x"),
@@ -3239,30 +3236,28 @@ nds32_info_to_howto_rel (bfd *abfd, arelent *cache_ptr,
bfd_set_error (bfd_error_bad_value);
return false;
}
-
- BFD_ASSERT (ELF32_R_TYPE (dst->r_info) <= R_NDS32_GNU_VTENTRY);
- cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
return true;
}
static bool
-nds32_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+nds32_info_to_howto (bfd *abfd, arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
unsigned int r_type = ELF32_R_TYPE (dst->r_info);
- if ((r_type == R_NDS32_NONE)
- || ((r_type > R_NDS32_GNU_VTENTRY)
- && (r_type < R_NDS32_max)))
+ cache_ptr->howto = NULL;
+ if (r_type == R_NDS32_NONE
+ || r_type > R_NDS32_GNU_VTENTRY)
+ cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
+ if (cache_ptr->howto == NULL || cache_ptr->howto->name == NULL)
{
- cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
- return true;
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
}
-
- /* xgettext:c-format */
- _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type);
- bfd_set_error (bfd_error_bad_value);
- return false;
+ return true;
}
/* Support for core dump NOTE sections.