* PR28307, segfault in ppc64_elf_toc64_reloc
@ 2021-09-07 1:25 Alan Modra
0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2021-09-07 1:25 UTC (permalink / raw)
To: binutils
Adds missing bfd_reloc_offset_in_range checks to various relocation
special_functions.
PR 28307
* elf32-ppc.c (ppc_elf_addr16_ha_reloc): Range check reloc offset.
* elf64-ppc.c (ppc64_elf_ha_reloc, ppc64_elf_brtaken_reloc): Likewise.
(ppc64_elf_toc64_reloc, ppc64_elf_prefix_reloc): Likewise.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 93fbadf61bc..dd45da9d6a3 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -959,6 +959,10 @@ ppc_elf_addr16_ha_reloc (bfd *abfd,
value >>= 16;
octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+ input_section, octets))
+ return bfd_reloc_outofrange;
+
insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
insn &= ~0x1fffc1;
insn |= (value & 0xffc1) | ((value & 0x3e) << 15);
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 55c5e500d06..520804a0e1c 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -1435,6 +1435,10 @@ ppc64_elf_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
value = (bfd_signed_vma) value >> 16;
octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+ input_section, octets))
+ return bfd_reloc_outofrange;
+
insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
insn &= ~0x1fffc1;
insn |= (value & 0xffc1) | ((value & 0x3e) << 15);
@@ -1510,6 +1514,10 @@ ppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
input_section, output_bfd, error_message);
octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+ input_section, octets))
+ return bfd_reloc_outofrange;
+
insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
insn &= ~(0x01 << 21);
r_type = reloc_entry->howto->type;
@@ -1655,11 +1663,15 @@ ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
+ octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+ input_section, octets))
+ return bfd_reloc_outofrange;
+
TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
if (TOCstart == 0)
TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
- octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
return bfd_reloc_ok;
}
@@ -1671,14 +1683,20 @@ ppc64_elf_prefix_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
{
uint64_t insn;
bfd_vma targ;
+ bfd_size_type octets;
if (output_bfd != NULL)
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
input_section, output_bfd, error_message);
- insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
+ input_section, octets))
+ return bfd_reloc_outofrange;
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
insn <<= 32;
- insn |= bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address + 4);
+ insn |= bfd_get_32 (abfd, (bfd_byte *) data + octets + 4);
targ = (symbol->section->output_section->vma
+ symbol->section->output_offset
@@ -1697,8 +1715,8 @@ ppc64_elf_prefix_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
targ >>= reloc_entry->howto->rightshift;
insn &= ~reloc_entry->howto->dst_mask;
insn |= ((targ << 16) | (targ & 0xffff)) & reloc_entry->howto->dst_mask;
- bfd_put_32 (abfd, insn >> 32, (bfd_byte *) data + reloc_entry->address);
- bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address + 4);
+ bfd_put_32 (abfd, insn >> 32, (bfd_byte *) data + octets);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + octets + 4);
if (reloc_entry->howto->complain_on_overflow == complain_overflow_signed
&& (targ + (1ULL << (reloc_entry->howto->bitsize - 1))
>= 1ULL << reloc_entry->howto->bitsize))
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-09-07 1:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-07 1:25 PR28307, segfault in ppc64_elf_toc64_reloc Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).