diff options
author | Alan Modra <amodra@gmail.com> | 2021-08-06 17:26:14 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-08-06 23:02:27 +0930 |
commit | 352bd3aa1c68137d4a5115183f42c40b75ee05b3 (patch) | |
tree | d202236bdae4f73c88a48c8d1fdaf65720b2c6cc /bfd | |
parent | 8179e388b60acc6ac35b40cd154f8d56234d1c3b (diff) | |
download | gdb-352bd3aa1c68137d4a5115183f42c40b75ee05b3.zip gdb-352bd3aa1c68137d4a5115183f42c40b75ee05b3.tar.gz gdb-352bd3aa1c68137d4a5115183f42c40b75ee05b3.tar.bz2 |
PR28172, bfin_pcrel24_reloc heap-buffer-overflow
bfin pcrel24 relocs are weird, they apply to the reloc address minus
two. That means reloc addresses of 0 and 1 are invalid. Check that,
and fix other reloc range checking.
PR 28172
* elf32-bfin.c (bfin_pcrel24_reloc): Correct reloc range check.
(bfin_imm16_reloc, bfin_byte4_reloc, bfin_bfd_reloc): Likewise.
(bfin_final_link_relocate): Likewise.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elf32-bfin.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index 9310412..037da60 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -59,8 +59,9 @@ bfin_pcrel24_reloc (bfd *abfd, reloc_howto_type *howto = reloc_entry->howto; asection *output_section; bool relocatable = (output_bfd != NULL); + bfd_size_type limit = bfd_get_section_limit_octets (abfd, input_section); - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (addr - 2 > limit || limit - (addr - 2) < 2) return bfd_reloc_outofrange; if (bfd_is_und_section (symbol->section) @@ -156,9 +157,10 @@ bfin_imm16_reloc (bfd *abfd, reloc_howto_type *howto = reloc_entry->howto; asection *output_section; bool relocatable = (output_bfd != NULL); + bfd_size_type limit = bfd_get_section_limit_octets (abfd, input_section); /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (reloc_addr > limit || limit - reloc_addr < 2) return bfd_reloc_outofrange; if (bfd_is_und_section (symbol->section) @@ -227,9 +229,10 @@ bfin_byte4_reloc (bfd *abfd, bfd_vma output_base = 0; asection *output_section; bool relocatable = (output_bfd != NULL); + bfd_size_type limit = bfd_get_section_limit_octets (abfd, input_section); /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (addr > limit || limit - addr < 4) return bfd_reloc_outofrange; if (bfd_is_und_section (symbol->section) @@ -294,9 +297,10 @@ bfin_bfd_reloc (bfd *abfd, reloc_howto_type *howto = reloc_entry->howto; asection *output_section; bool relocatable = (output_bfd != NULL); + bfd_size_type limit = bfd_get_section_limit_octets (abfd, input_section); /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (addr > limit || limit - addr < howto->size + 1u) return bfd_reloc_outofrange; if (bfd_is_und_section (symbol->section) @@ -1316,8 +1320,10 @@ bfin_final_link_relocate (Elf_Internal_Rela *rel, reloc_howto_type *howto, { bfd_reloc_status_type r = bfd_reloc_ok; bfd_vma x; + bfd_size_type limit = bfd_get_section_limit_octets (input_bfd, + input_section); - if (address > bfd_get_section_limit (input_bfd, input_section)) + if (address - 2 > limit || limit - (address - 2) < 4) return bfd_reloc_outofrange; value += addend; |