mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 18:08:24 +08:00
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.
This commit is contained in:
@ -1954,6 +1954,8 @@ static reloc_howto_type nds32_elf_howto_table[] =
|
|||||||
0xffffffff, /* dst_mask */
|
0xffffffff, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
false), /* pcrel_offset */
|
||||||
|
|
||||||
|
EMPTY_HOWTO (114),
|
||||||
|
|
||||||
HOWTO2 (R_NDS32_TLS_IE_LO12, /* type */
|
HOWTO2 (R_NDS32_TLS_IE_LO12, /* type */
|
||||||
0, /* rightshift */
|
0, /* rightshift */
|
||||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
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 *
|
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)
|
if (code < R_NDS32_RELAX_ENTRY)
|
||||||
{
|
{
|
||||||
BFD_ASSERT (code < ARRAY_SIZE (nds32_elf_howto_table));
|
if (code < ARRAY_SIZE (nds32_elf_howto_table))
|
||||||
return &nds32_elf_howto_table[code];
|
return &nds32_elf_howto_table[code];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((size_t) (code - R_NDS32_RELAX_ENTRY)
|
if (code - R_NDS32_RELAX_ENTRY < ARRAY_SIZE (nds32_elf_relax_howto_table))
|
||||||
>= 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];
|
return &nds32_elf_relax_howto_table[code - R_NDS32_RELAX_ENTRY];
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static reloc_howto_type *
|
static reloc_howto_type *
|
||||||
@ -3228,10 +3223,12 @@ static bool
|
|||||||
nds32_info_to_howto_rel (bfd *abfd, arelent *cache_ptr,
|
nds32_info_to_howto_rel (bfd *abfd, arelent *cache_ptr,
|
||||||
Elf_Internal_Rela *dst)
|
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);
|
cache_ptr->howto = NULL;
|
||||||
if (r_type > R_NDS32_GNU_VTENTRY)
|
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 */
|
/* xgettext:c-format */
|
||||||
_bfd_error_handler (_("%pB: unsupported relocation type %#x"),
|
_bfd_error_handler (_("%pB: unsupported relocation type %#x"),
|
||||||
@ -3239,31 +3236,29 @@ nds32_info_to_howto_rel (bfd *abfd, arelent *cache_ptr,
|
|||||||
bfd_set_error (bfd_error_bad_value);
|
bfd_set_error (bfd_error_bad_value);
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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)
|
Elf_Internal_Rela *dst)
|
||||||
{
|
{
|
||||||
unsigned int r_type = ELF32_R_TYPE (dst->r_info);
|
unsigned int r_type = ELF32_R_TYPE (dst->r_info);
|
||||||
|
|
||||||
if ((r_type == R_NDS32_NONE)
|
cache_ptr->howto = NULL;
|
||||||
|| ((r_type > R_NDS32_GNU_VTENTRY)
|
if (r_type == R_NDS32_NONE
|
||||||
&& (r_type < R_NDS32_max)))
|
|| r_type > R_NDS32_GNU_VTENTRY)
|
||||||
{
|
|
||||||
cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
|
cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
|
||||||
return true;
|
if (cache_ptr->howto == NULL || cache_ptr->howto->name == NULL)
|
||||||
}
|
{
|
||||||
|
|
||||||
/* xgettext:c-format */
|
/* xgettext:c-format */
|
||||||
_bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type);
|
_bfd_error_handler (_("%pB: unsupported relocation type %#x"),
|
||||||
|
abfd, r_type);
|
||||||
bfd_set_error (bfd_error_bad_value);
|
bfd_set_error (bfd_error_bad_value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Support for core dump NOTE sections.
|
/* Support for core dump NOTE sections.
|
||||||
Reference to include/linux/elfcore.h in Linux. */
|
Reference to include/linux/elfcore.h in Linux. */
|
||||||
|
Reference in New Issue
Block a user