diff options
author | Alan Modra <amodra@gmail.com> | 2021-08-06 18:35:23 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-08-06 23:06:40 +0930 |
commit | a379e7588c5e3a9750bba8c51218cce9225122f5 (patch) | |
tree | bb84eca9f003424c9fa0d9236b11ddcbef1d6342 /bfd/elf32-nds32.c | |
parent | 352bd3aa1c68137d4a5115183f42c40b75ee05b3 (diff) | |
download | fsf-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.
Diffstat (limited to 'bfd/elf32-nds32.c')
-rw-r--r-- | bfd/elf32-nds32.c | 55 |
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. |