From: Alan Modra Date: Fri, 17 Dec 2021 03:02:36 +0000 (+1030) Subject: asan: heap-buffer-overflow in bpf_elf_generic_reloc X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9b54b561858b3fb265f57d2b4ddf35fba2603069;p=binutils-gdb.git asan: heap-buffer-overflow in bpf_elf_generic_reloc The bpf reloc howtos are a bit weird, using bitpos to specify an offset from r_offset that is outside the size of the reloc as given by howto.size. That means bfd_get_reloc_size gives the wrong answer for range checking, and thus bfd_reloc_offset_in_range can't be used. * elf64-bpf.c (bpf_elf_generic_reloc): Handle bitpos offset reloc range checking. --- diff --git a/bfd/elf64-bpf.c b/bfd/elf64-bpf.c index beabad79aff..4e5f9d1e2f7 100644 --- a/bfd/elf64-bpf.c +++ b/bfd/elf64-bpf.c @@ -608,15 +608,16 @@ bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, bfd_byte *where; /* Sanity check that the address is in range. */ + bfd_size_type end = bfd_get_section_limit_octets (abfd, input_section); + bfd_size_type reloc_size; if (reloc_entry->howto->type == R_BPF_INSN_64) - { - bfd_size_type end = bfd_get_section_limit_octets (abfd, input_section); - if (reloc_entry->address > end - || end - reloc_entry->address < 16) - return bfd_reloc_outofrange; - } - else if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section, - reloc_entry->address)) + reloc_size = 16; + else + reloc_size = (reloc_entry->howto->bitsize + + reloc_entry->howto->bitpos) / 8; + + if (reloc_entry->address > end + || end - reloc_entry->address < reloc_size) return bfd_reloc_outofrange; /* Get the symbol value. */