aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-08-06 17:26:14 +0930
committerAlan Modra <amodra@gmail.com>2021-08-06 23:02:27 +0930
commit352bd3aa1c68137d4a5115183f42c40b75ee05b3 (patch)
treed202236bdae4f73c88a48c8d1fdaf65720b2c6cc /bfd
parent8179e388b60acc6ac35b40cd154f8d56234d1c3b (diff)
downloadgdb-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.c16
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;