aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-08-26 19:43:18 +0930
committerAlan Modra <amodra@gmail.com>2020-08-26 23:23:45 +0930
commit9e51d549d7901be8b999f8dac86c5efd6a7edef2 (patch)
tree2c5b08c02706d4df63a1f2f01e70a58962937a37
parent00bc5e68b2c02fd2b1daacc37850840498595fb0 (diff)
downloadgdb-9e51d549d7901be8b999f8dac86c5efd6a7edef2.zip
gdb-9e51d549d7901be8b999f8dac86c5efd6a7edef2.tar.gz
gdb-9e51d549d7901be8b999f8dac86c5efd6a7edef2.tar.bz2
PR 26484-26488, 26490 UBSAN &h->elf null pointer
PR 26484 PR 26485 PR 26486 PR 26487 PR 26488 PR 26490 * elf64-ppc.c (is_tls_get_addr): Avoid UB &h->elf when h is NULL. (ppc64_elf_tls_setup): Likewise. (branch_reloc_hash_match): Likewise. (build_plt_stub): Likewise. (ppc64_elf_relocate_section): Likewise.
-rw-r--r--bfd/ChangeLog14
-rw-r--r--bfd/elf64-ppc.c44
2 files changed, 40 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 86fccfb..cbce5be 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,19 @@
2020-08-26 Alan Modra <amodra@gmail.com>
+ PR 26484
+ PR 26485
+ PR 26486
+ PR 26487
+ PR 26488
+ PR 26490
+ * elf64-ppc.c (is_tls_get_addr): Avoid UB &h->elf when h is NULL.
+ (ppc64_elf_tls_setup): Likewise.
+ (branch_reloc_hash_match): Likewise.
+ (build_plt_stub): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+
+2020-08-26 Alan Modra <amodra@gmail.com>
+
PR 26478
* mmo.c (mmo_write_symbols_and_terminator): Don't memcpy empty table.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index d144796..06202c9 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5650,8 +5650,10 @@ static bfd_boolean
is_tls_get_addr (struct elf_link_hash_entry *h,
struct ppc_link_hash_table *htab)
{
- return (h == &htab->tls_get_addr_fd->elf || h == &htab->tga_desc_fd->elf
- || h == &htab->tls_get_addr->elf || h == &htab->tga_desc->elf);
+ return (h == (struct elf_link_hash_entry *) htab->tls_get_addr_fd
+ || h == (struct elf_link_hash_entry *) htab->tga_desc_fd
+ || h == (struct elf_link_hash_entry *) htab->tls_get_addr
+ || h == (struct elf_link_hash_entry *) htab->tga_desc);
}
static bfd_boolean func_desc_adjust (struct elf_link_hash_entry *, void *);
@@ -7830,7 +7832,7 @@ ppc64_elf_tls_setup (struct bfd_link_info *info)
if (tga_fd != NULL)
{
htab->tls_get_addr_fd = ppc_elf_hash_entry (opt_fd);
- tga = &htab->tls_get_addr->elf;
+ tga = (struct elf_link_hash_entry *) htab->tls_get_addr;
if (opt != NULL && tga != NULL)
{
tga->root.type = bfd_link_hash_indirect;
@@ -7909,8 +7911,10 @@ branch_reloc_hash_match (const bfd *ibfd,
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
h = elf_follow_link (h);
- if (h == &hash1->elf || h == &hash2->elf
- || h == &hash3->elf || h == &hash4->elf)
+ if (h == (struct elf_link_hash_entry *) hash1
+ || h == (struct elf_link_hash_entry *) hash2
+ || h == (struct elf_link_hash_entry *) hash3
+ || h == (struct elf_link_hash_entry *) hash4)
return TRUE;
}
return FALSE;
@@ -10945,7 +10949,8 @@ build_plt_stub (struct ppc_link_hash_table *htab,
if (!ALWAYS_USE_FAKE_DEP
&& plt_load_toc
&& plt_thread_safe
- && !(is_tls_get_addr (&stub_entry->h->elf, htab)
+ && !(stub_entry->h != NULL
+ && is_tls_get_addr (&stub_entry->h->elf, htab)
&& htab->params->tls_get_addr_opt))
{
bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1;
@@ -15686,6 +15691,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
if (stub_entry->stub_type == ppc_stub_plt_call
&& !htab->opd_abi
&& htab->params->plt_localentry0 != 0
+ && h != NULL
&& is_elfv2_localentry0 (&h->elf))
{
/* The function doesn't use or change r2. */
@@ -15948,7 +15954,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x8000 < 0x10000
- && SYMBOL_REFERENCES_LOCAL (info, &h->elf))
+ && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
{
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
if ((insn & (0x3fu << 26 | 0x3)) == 58u << 26 /* ld */)
@@ -15968,7 +15974,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x80008000ULL < 0x100000000ULL
- && SYMBOL_REFERENCES_LOCAL (info, &h->elf))
+ && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
{
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
if ((insn & (0x3fu << 26 | 0x3)) == 58u << 26 /* ld */)
@@ -15994,7 +16000,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
+ input_section->output_section->vma
+ input_section->output_offset);
if (!(relocation - from + (1ULL << 33) < 1ULL << 34
- && SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
+ && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))))
break;
offset = rel->r_offset;
@@ -16018,7 +16024,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
&& rel + 1 < relend
&& rel[1].r_offset == rel->r_offset
&& rel[1].r_info == ELF64_R_INFO (0, R_PPC64_PCREL_OPT)
- && SYMBOL_REFERENCES_LOCAL (info, &h->elf))
+ && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
{
offset = rel->r_offset;
pinsn = bfd_get_32 (input_bfd, contents + offset);
@@ -16144,7 +16150,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
struct got_entry *ent;
if (tls_type == (TLS_TLS | TLS_LD)
- && SYMBOL_REFERENCES_LOCAL (info, &h->elf))
+ && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
ent = ppc64_tlsld_got (input_bfd);
else
{
@@ -16220,7 +16226,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|| !UNDEFWEAK_NO_DYNAMIC_RELOC (info, &h->elf))
&& !(tls_type != 0
&& bfd_link_executable (info)
- && SYMBOL_REFERENCES_LOCAL (info, &h->elf))))
+ && (h == NULL
+ || SYMBOL_REFERENCES_LOCAL (info,
+ &h->elf)))))
relgot = ppc64_elf_tdata (ent->owner)->relgot;
if (relgot != NULL)
{
@@ -16619,7 +16627,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
if (skip)
memset (&outrel, 0, sizeof outrel);
- else if (!SYMBOL_REFERENCES_LOCAL (info, &h->elf)
+ else if (h != NULL
+ && !SYMBOL_REFERENCES_LOCAL (info, &h->elf)
&& !is_opd
&& r_type != R_PPC64_TOC)
{
@@ -17220,11 +17229,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
&& (h->elf.root.type == bfd_link_hash_undefweak
|| h->elf.root.type == bfd_link_hash_undefined)
&& is_branch_reloc (r_type))))
- info->callbacks->reloc_overflow (info, &h->elf.root,
- sym_name, reloc_name,
- orig_rel.r_addend,
- input_bfd, input_section,
- rel->r_offset);
+ info->callbacks->reloc_overflow
+ (info, (struct bfd_link_hash_entry *) h, sym_name,
+ reloc_name, orig_rel.r_addend, input_bfd, input_section,
+ rel->r_offset);
}
else
{