diff options
author | Alan Modra <amodra@gmail.com> | 2023-06-01 23:31:47 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-06-02 09:41:49 +0930 |
commit | 74a965d8e09217f3d8f8295c9126b77cdd62b798 (patch) | |
tree | fc28edb8fc77b293015a3ca3792dda85421dfa85 /binutils | |
parent | 56e4ccc924d47c30e7446efe771397d2de141762 (diff) | |
download | binutils-74a965d8e09217f3d8f8295c9126b77cdd62b798.zip binutils-74a965d8e09217f3d8f8295c9126b77cdd62b798.tar.gz binutils-74a965d8e09217f3d8f8295c9126b77cdd62b798.tar.bz2 |
loongarch readelf support
This fixes two buffer overflows found by fuzzers.
* readelf.c (target_specific_reloc_handling): Sanity check
loongarch reloc symbol index. Don't apply reloc after errors.
Reduce translation work of "invalid symbol index" error message.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/readelf.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c index 7292dd0..042d230 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -14028,24 +14028,32 @@ target_specific_reloc_handling (Filedata *filedata, "ULEB128 value\n"), (long) reloc->r_offset); - if (107 == reloc_type) - value += (reloc->r_addend + symtab[sym_index].st_value); - else if (108 == reloc_type) - value -= (reloc->r_addend + symtab[sym_index].st_value); - - /* Write uleb128 value to p. */ - bfd_byte c; - bfd_byte *p = start + reloc->r_offset; - do + else if (sym_index >= num_syms) + error (_("%s reloc contains invalid symbol index " + "%" PRIu64 "\n"), + (reloc_type == 107 + ? "R_LARCH_ADD_ULEB128" + : "R_LARCH_SUB_ULEB128"), + sym_index); + else { - c = value & 0x7f; - if (reloc_size > 1) - c |= 0x80; - *(p++) = c; - value >>= 7; - reloc_size--; + if (reloc_type == 107) + value += reloc->r_addend + symtab[sym_index].st_value; + else + value -= reloc->r_addend + symtab[sym_index].st_value; + + /* Write uleb128 value to p. */ + bfd_byte *p = start + reloc->r_offset; + do + { + bfd_byte c = value & 0x7f; + value >>= 7; + if (--reloc_size != 0) + c |= 0x80; + *p++ = c; + } + while (reloc_size); } - while (reloc_size); return true; } @@ -14075,8 +14083,8 @@ target_specific_reloc_handling (Filedata *filedata, case 23: /* R_MSP430X_GNU_SUB_ULEB128 */ /* PR 21139. */ if (sym_index >= num_syms) - error (_("MSP430 SYM_DIFF reloc contains invalid symbol index" - " %" PRIu64 "\n"), sym_index); + error (_("%s reloc contains invalid symbol index " + "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index); else saved_sym = symtab + sym_index; return true; @@ -14126,9 +14134,8 @@ target_specific_reloc_handling (Filedata *filedata, " contains invalid ULEB128 value\n"), reloc->r_offset); else if (sym_index >= num_syms) - error (_("MSP430 reloc contains invalid symbol index " - "%" PRIu64 "\n"), - sym_index); + error (_("%s reloc contains invalid symbol index " + "%" PRIu64 "\n"), "MSP430", sym_index); else { value = reloc->r_addend + (symtab[sym_index].st_value @@ -14173,9 +14180,8 @@ target_specific_reloc_handling (Filedata *filedata, return true; case 33: /* R_MN10300_SYM_DIFF */ if (sym_index >= num_syms) - error (_("MN10300_SYM_DIFF reloc contains invalid symbol index " - "%" PRIu64 "\n"), - sym_index); + error (_("%s reloc contains invalid symbol index " + "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index); else saved_sym = symtab + sym_index; return true; @@ -14188,9 +14194,8 @@ target_specific_reloc_handling (Filedata *filedata, uint64_t value; if (sym_index >= num_syms) - error (_("MN10300 reloc contains invalid symbol index " - "%" PRIu64 "\n"), - sym_index); + error (_("%s reloc contains invalid symbol index " + "%" PRIu64 "\n"), "MN10300", sym_index); else { value = reloc->r_addend + (symtab[sym_index].st_value @@ -14233,8 +14238,8 @@ target_specific_reloc_handling (Filedata *filedata, case 0x80: /* R_RL78_SYM. */ saved_sym1 = saved_sym2; if (sym_index >= num_syms) - error (_("RL78_SYM reloc contains invalid symbol index " - "%" PRIu64 "\n"), sym_index); + error (_("%s reloc contains invalid symbol index " + "%" PRIu64 "\n"), "RL78_SYM", sym_index); else { saved_sym2 = symtab[sym_index].st_value; |