From d81b3b275dff99561cbe5905ca63a1c72fa54a17 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Thu, 19 Jun 2014 08:08:12 -0700 Subject: [PATCH] Reenable support for non-PIE executables On Nakasi builds, /system/bin/tf_daemon is a pre-compiled vendor supplied binary. When support for non-PIE executables was removed, that daemon failed to start, which induced a number of bugs. * keystore is broken * CTS runs will hang after a certain period of time Temporarily reenable non-PIE support for 32-bit platforms until Nakasi is fixed. This rolls back the following commits: Cleanup: updated comments * 6275f2083415d22a6ce0de55645079cd47e0cc80 Cleanup: remove AARCH/ARM_COPY relocation support * b906e13c55c9fe9b4157ba548534a0230434882b And restricts the following patch to 64 bit only: Remove support for non-PIE executables * 2aebf5429bb1241a3298b5b642d38f73124c2026 Bug: 14566672 Bug: 15086752 Bug: 15732002 Change-Id: Ia2501aa14bd30feb4a6ce66bdb7c9f066dba0b5f --- linker/linker.cpp | 113 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 22 deletions(-) diff --git a/linker/linker.cpp b/linker/linker.cpp index a22233dc6..e202aaf83 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -59,6 +59,7 @@ * * open issues / todo: * + * - are we doing everything we should for ARM_COPY relocations? * - cleaner error reporting * - after linking, set as much stuff as possible to READONLY * and NOEXEC @@ -1037,17 +1038,52 @@ static int soinfo_relocate(soinfo* si, ElfW(Rela)* rela, unsigned count, soinfo* break; case R_AARCH64_COPY: - /* - * ET_EXEC is not supported so this should not happen. - * - * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf - * - * Section 4.7.1.10 "Dynamic relocations" - * R_AARCH64_COPY may only appear in executable objects where e_type is - * set to ET_EXEC. - */ - DL_ERR("%s R_AARCH64_COPY relocations are not supported", si->name); - return -1; + if ((si->flags & FLAG_EXE) == 0) { + /* + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf + * + * Section 4.7.1.10 "Dynamic relocations" + * R_AARCH64_COPY may only appear in executable objects where e_type is + * set to ET_EXEC. + * + * FLAG_EXE is set for both ET_DYN and ET_EXEC executables. + * We should explicitly disallow ET_DYN executables from having + * R_AARCH64_COPY relocations. + */ + DL_ERR("%s R_AARCH64_COPY relocations only supported for ET_EXEC", si->name); + return -1; + } + count_relocation(kRelocCopy); + MARK(rela->r_offset); + TRACE_TYPE(RELO, "RELO COPY %16llx <- %lld @ %16llx %s\n", + reloc, + s->st_size, + (sym_addr + rela->r_addend), + sym_name); + if (reloc == (sym_addr + rela->r_addend)) { + ElfW(Sym)* src = soinfo_do_lookup(NULL, sym_name, &lsi, needed); + + if (src == NULL) { + DL_ERR("%s R_AARCH64_COPY relocation source cannot be resolved", si->name); + return -1; + } + if (lsi->has_DT_SYMBOLIC) { + DL_ERR("%s invalid R_AARCH64_COPY relocation against DT_SYMBOLIC shared " + "library %s (built with -Bsymbolic?)", si->name, lsi->name); + return -1; + } + if (s->st_size < src->st_size) { + DL_ERR("%s R_AARCH64_COPY relocation size mismatch (%lld < %lld)", + si->name, s->st_size, src->st_size); + return -1; + } + memcpy(reinterpret_cast(reloc), + reinterpret_cast(src->st_value + lsi->load_bias), src->st_size); + } else { + DL_ERR("%s R_AARCH64_COPY relocation target cannot be resolved", si->name); + return -1; + } + break; case R_AARCH64_TLS_TPREL64: TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n", reloc, (sym_addr + rela->r_addend), rela->r_offset); @@ -1225,17 +1261,48 @@ static int soinfo_relocate(soinfo* si, ElfW(Rel)* rel, unsigned count, soinfo* n *reinterpret_cast(reloc) += sym_addr - rel->r_offset; break; case R_ARM_COPY: - /* - * ET_EXEC is not supported so this should not happen. - * - * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf - * - * Section 4.7.1.10 "Dynamic relocations" - * R_ARM_COPY may only appear in executable objects where e_type is - * set to ET_EXEC. - */ - DL_ERR("%s R_ARM_COPY relocations are not supported", si->name); - return -1; + if ((si->flags & FLAG_EXE) == 0) { + /* + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf + * + * Section 4.7.1.10 "Dynamic relocations" + * R_ARM_COPY may only appear in executable objects where e_type is + * set to ET_EXEC. + * + * TODO: FLAG_EXE is set for both ET_DYN and ET_EXEC executables. + * We should explicitly disallow ET_DYN executables from having + * R_ARM_COPY relocations. + */ + DL_ERR("%s R_ARM_COPY relocations only supported for ET_EXEC", si->name); + return -1; + } + count_relocation(kRelocCopy); + MARK(rel->r_offset); + TRACE_TYPE(RELO, "RELO %08x <- %d @ %08x %s", reloc, s->st_size, sym_addr, sym_name); + if (reloc == sym_addr) { + ElfW(Sym)* src = soinfo_do_lookup(NULL, sym_name, &lsi, needed); + + if (src == NULL) { + DL_ERR("%s R_ARM_COPY relocation source cannot be resolved", si->name); + return -1; + } + if (lsi->has_DT_SYMBOLIC) { + DL_ERR("%s invalid R_ARM_COPY relocation against DT_SYMBOLIC shared " + "library %s (built with -Bsymbolic?)", si->name, lsi->name); + return -1; + } + if (s->st_size < src->st_size) { + DL_ERR("%s R_ARM_COPY relocation size mismatch (%d < %d)", + si->name, s->st_size, src->st_size); + return -1; + } + memcpy(reinterpret_cast(reloc), + reinterpret_cast(src->st_value + lsi->load_bias), src->st_size); + } else { + DL_ERR("%s R_ARM_COPY relocation target cannot be resolved", si->name); + return -1; + } + break; #elif defined(__i386__) case R_386_JMP_SLOT: count_relocation(kRelocAbsolute); @@ -2105,11 +2172,13 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( si->dynamic = NULL; si->ref_count = 1; +#if defined(__LP64__) ElfW(Ehdr)* elf_hdr = reinterpret_cast(si->base); if (elf_hdr->e_type != ET_DYN) { __libc_format_fd(2, "error: only position independent executables (PIE) are supported.\n"); exit(EXIT_FAILURE); } +#endif // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid). parse_LD_LIBRARY_PATH(ldpath_env);