aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-12-26 22:46:56 +1030
committerAlan Modra <amodra@gmail.com>2023-12-27 16:36:23 +1030
commit3bb1944a5a0527a38702084ac301d9933b0130bb (patch)
tree2582c76c696e90b536d58a279f6397190d0d8d8a /bfd
parent145c21056abeace6b3f6cafb65c29a7812036852 (diff)
downloadgdb-3bb1944a5a0527a38702084ac301d9933b0130bb.zip
gdb-3bb1944a5a0527a38702084ac301d9933b0130bb.tar.gz
gdb-3bb1944a5a0527a38702084ac301d9933b0130bb.tar.bz2
asan: buffer overflow in loongarch_elf_rtype_to_howto
Seen when running ld-loongarch-elf/tlsdesc-dso test. elfxx-loongarch.c:1844:32: runtime error: index 125 out of bounds for type 'loongarch_reloc_howto_type [124]' So either the loongarch_howto_table needs three more LOONGARCH_EMPTY_HOWTO entries, or loongarch_elf_rtype_to_howto should be testing for r_type < ARRAY_SIZE (loongarch_howto_table). I figure it's worth wasting a little more space to get faster lookup. * elfxx-loongarch.c (loongarch_howto_table): Add LOONGARCH_EMPTY_HOWTO entries for 121..123. (loongarch_elf_rtype_to_howto): Don't support slow lookup. Assert exact table size and r_type indexing. Omit return cast. (loongarch_reloc_name_lookup): Omit assertion and return cast. (loongarch_reloc_type_lookup): Likewise.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/elfxx-loongarch.c32
1 files changed, 11 insertions, 21 deletions
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 310e6d6..4fe8cbf 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1776,6 +1776,10 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits. */
"desc_call"), /* larch_reloc_type_name. */
+ LOONGARCH_EMPTY_HOWTO (121),
+ LOONGARCH_EMPTY_HOWTO (122),
+ LOONGARCH_EMPTY_HOWTO (123),
+
/* For pcaddi, ld_pc_hi20 + ld_pc_lo12 can relax to ld_pcrel20_s2. */
LOONGARCH_HOWTO (R_LARCH_TLS_LD_PCREL20_S2, /* type (124). */
2, /* rightshift. */
@@ -1834,19 +1838,11 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
reloc_howto_type *
loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
{
- if(r_type < R_LARCH_count)
+ if (r_type < R_LARCH_count)
{
- /* For search table fast. */
- /*
BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
- */
-
- if (loongarch_howto_table[r_type].howto.type == r_type)
- return (reloc_howto_type *)&loongarch_howto_table[r_type];
-
- for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
- if (loongarch_howto_table[i].howto.type == r_type)
- return (reloc_howto_type *)&loongarch_howto_table[i];
+ BFD_ASSERT (loongarch_howto_table[r_type].howto.type == r_type);
+ return &loongarch_howto_table[r_type].howto;
}
(*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
@@ -1858,19 +1854,14 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
reloc_howto_type *
loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
{
- /*
- BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
- */
-
for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
if (loongarch_howto_table[i].howto.name
&& strcasecmp (loongarch_howto_table[i].howto.name, r_name) == 0)
- return (reloc_howto_type *)&loongarch_howto_table[i];
+ return &loongarch_howto_table[i].howto;
(*_bfd_error_handler) (_("%pB: unsupported relocation type %s"),
abfd, r_name);
bfd_set_error (bfd_error_bad_value);
-
return NULL;
}
@@ -1888,20 +1879,19 @@ loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
{
BFD_ASSERT (BFD_RELOC_LARCH_RELAX - BFD_RELOC_LARCH_B16
== R_LARCH_RELAX - R_LARCH_B16);
- loongarch_reloc_howto_type *ht = NULL;
+ loongarch_reloc_howto_type *ht;
ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16];
BFD_ASSERT (ht->bfd_type == code);
- return (reloc_howto_type *)ht;
+ return &ht->howto;
}
for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
if (loongarch_howto_table[i].bfd_type == code)
- return (reloc_howto_type *)&loongarch_howto_table[i];
+ return &loongarch_howto_table[i].howto;
(*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"),
abfd, code);
bfd_set_error (bfd_error_bad_value);
-
return NULL;
}