aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-or1k.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-12-26 00:30:45 +1030
committerAlan Modra <amodra@gmail.com>2016-12-26 13:47:51 +1030
commit5474d94f03aedba2f832006dc7d680cc15792a7b (patch)
tree8fdd2bb1d2a32f1f35ef76199f9d92da95c0ec27 /bfd/elf32-or1k.c
parent9d19e4fdb7c684329c8b1b72796a0071708dabc7 (diff)
downloadfsf-binutils-gdb-5474d94f03aedba2f832006dc7d680cc15792a7b.zip
fsf-binutils-gdb-5474d94f03aedba2f832006dc7d680cc15792a7b.tar.gz
fsf-binutils-gdb-5474d94f03aedba2f832006dc7d680cc15792a7b.tar.bz2
dynrelro section for read-only dynamic symbols copied into executable
Variables defined in shared libraries are copied into an executable's .bss section when code in the executable is non-PIC and thus would require dynamic text relocations to access the variable directly in the shared library. Recent x86 toolchains also copy variables into the executable to gain a small speed improvement. The problem is that if the variable was originally read-only, the copy in .bss is writable, potentially opening a security hole. This patch cures that problem by putting the copy in a section that becomes read-only after ld.so relocation, provided -z relro is in force. The patch also fixes a microblaze linker segfault on attempting to use dynamic bss variables. bfd/ PR ld/20995 * elf-bfd.h (struct elf_link_hash_table): Add sdynrelro and sreldynrelro. (struct elf_backend_data): Add want_dynrelro. * elfxx-target.h (elf_backend_want_dynrelro): Define. (elfNN_bed): Update initializer. * elflink.c (_bfd_elf_create_dynamic_sections): Create sdynrelro and sreldynrelro sections. * elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Place variables copied into the executable from read-only sections into sdynrelro. (elf32_arm_size_dynamic_sections): Handle sdynrelro. (elf32_arm_finish_dynamic_symbol): Select sreldynrelro for dynamic relocs in sdynrelro. (elf_backend_want_dynrelro): Define. * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol) (elf32_hppa_size_dynamic_sections, elf32_hppa_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-i386.c (elf_i386_adjust_dynamic_symbol) (elf_i386_size_dynamic_sections, elf_i386_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-metag.c (elf_metag_adjust_dynamic_symbol) (elf_metag_size_dynamic_sections, elf_metag_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol) (microblaze_elf_size_dynamic_sections) (microblaze_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-nios2.c (nios2_elf32_finish_dynamic_symbol) (nios2_elf32_adjust_dynamic_symbol) (nios2_elf32_size_dynamic_sections) (elf_backend_want_dynrelro): As above. * elf32-or1k.c (or1k_elf_finish_dynamic_symbol) (or1k_elf_adjust_dynamic_symbol, or1k_elf_size_dynamic_sections) (elf_backend_want_dynrelro): As above. * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol) (ppc_elf_size_dynamic_sections, ppc_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-s390.c (elf_s390_adjust_dynamic_symbol) (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol) (elf32_tic6x_size_dynamic_sections) (elf32_tic6x_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol) (tilepro_elf_size_dynamic_sections) (tilepro_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol) (ppc64_elf_size_dynamic_sections, ppc64_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-s390.c (elf_s390_adjust_dynamic_symbol) (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol) (elf_x86_64_size_dynamic_sections) (elf_x86_64_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfnn-aarch64.c (elfNN_aarch64_adjust_dynamic_symbol) (elfNN_aarch64_size_dynamic_sections) (elfNN_aarch64_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfnn-riscv.c (riscv_elf_adjust_dynamic_symbol) (riscv_elf_size_dynamic_sections, riscv_elf_finish_dynamic_symbol) (elf_backend_want_dynrelro): As above. * elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol) (_bfd_mips_elf_size_dynamic_sections) (_bfd_mips_vxworks_finish_dynamic_symbol): As above. * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol) (_bfd_sparc_elf_size_dynamic_sections) (_bfd_sparc_elf_finish_dynamic_symbol): As above. * elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol) (tilegx_elf_size_dynamic_sections) (tilegx_elf_finish_dynamic_symbol): As above. * elf32-mips.c (elf_backend_want_dynrelro): Define. * elf64-mips.c (elf_backend_want_dynrelro): Define. * elf32-sparc.c (elf_backend_want_dynrelro): Define. * elf64-sparc.c (elf_backend_want_dynrelro): Define. * elf32-tilegx.c (elf_backend_want_dynrelro): Define. * elf64-tilegx.c (elf_backend_want_dynrelro): Define. * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol): Tidy. (microblaze_elf_size_dynamic_sections): Handle sdynbss. * elf32-nios2.c (nios2_elf32_size_dynamic_sections): Make use of linker shortcuts to dynamic sections rather than comparing names. Correctly set "got" flag. ld/ PR ld/20995 * testsuite/ld-arm/farcall-mixed-app-v5.d: Update to suit changed stub hash table traversal caused by section id increment. Accept the previous output too. * testsuite/ld-arm/farcall-mixed-app.d: Likewise. * testsuite/ld-arm/farcall-mixed-lib-v4t.d: Likewise. * testsuite/ld-arm/farcall-mixed-lib.d: Likewise. * testsuite/ld-elf/pr20995a.s, * testsuite/ld-elf/pr20995b.s, * testsuite/ld-elf/pr20995.r: New test. * testsuite/ld-elf/elf.exp: Run it.
Diffstat (limited to 'bfd/elf32-or1k.c')
-rw-r--r--bfd/elf32-or1k.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index c75a2ce..7fc6b81 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -1944,17 +1944,16 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- s = bfd_get_section_by_name (h->root.u.def.section->owner,
- ".rela.bss");
- BFD_ASSERT (s != NULL);
-
rela.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_COPY);
rela.r_addend = 0;
- loc = s->contents;
- loc += s->reloc_count * sizeof (Elf32_External_Rela);
+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+ s = htab->root.sreldynrelro;
+ else
+ s = htab->root.srelbss;
+ loc = s->contents + s->reloc_count * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
++s->reloc_count;
}
@@ -1995,7 +1994,7 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_or1k_link_hash_entry *eh;
struct elf_or1k_dyn_relocs *p;
bfd *dynobj;
- asection *s;
+ asection *s, *srel;
dynobj = elf_hash_table (info)->dynobj;
@@ -2098,19 +2097,22 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
if (htab == NULL)
return FALSE;
- s = htab->root.sdynbss;
- BFD_ASSERT (s != NULL);
-
/* We must generate a R_OR1K_COPY reloc to tell the dynamic linker
to copy the initial value out of the dynamic object and into the
runtime process image. We need to remember the offset into the
.rela.bss section we are going to use. */
- if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
{
- asection *srel;
-
+ s = htab->root.sdynrelro;
+ srel = htab->root.sreldynrelro;
+ }
+ else
+ {
+ s = htab->root.sdynbss;
srel = htab->root.srelbss;
- BFD_ASSERT (srel != NULL);
+ }
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
srel->size += sizeof (Elf32_External_Rela);
h->needs_copy = 1;
}
@@ -2472,7 +2474,8 @@ or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (s == htab->root.splt
|| s == htab->root.sgot
|| s == htab->root.sgotplt
- || s == htab->root.sdynbss)
+ || s == htab->root.sdynbss
+ || s == htab->root.sdynrelro)
{
/* Strip this section if we don't need it; see the
comment below. */
@@ -2742,6 +2745,7 @@ elf32_or1k_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
#define elf_backend_want_plt_sym 0
#define elf_backend_got_header_size 12
#define elf_backend_dtrel_excludes_plt 1
+#define elf_backend_want_dynrelro 1
#define bfd_elf32_bfd_link_hash_table_create or1k_elf_link_hash_table_create
#define elf_backend_copy_indirect_symbol or1k_elf_copy_indirect_symbol