Created
May 18, 2015 02:40
-
-
Save steven676/5dedaca96df0d894560b to your computer and use it in GitHub Desktop.
[PATCH] Allow targets to reenable support for non-PIE executables
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From eba25085e5d1a44b595d0439d350a3e6b4a0684f Mon Sep 17 00:00:00 2001 | |
From: Steven Luo <[email protected]> | |
Date: Sat, 15 Nov 2014 17:58:48 -0800 | |
Subject: [PATCH] Allow targets to reenable support for non-PIE executables | |
Many legacy devices have non-PIE binary blob executables which are never | |
going to be updated by the manufacturer; allow the dynamic linker to | |
load these executables so that they can work. | |
This rolls back the following commits: | |
Cleanup: updated comments | |
* 6275f2083415d22a6ce0de55645079cd47e0cc80 | |
Cleanup: remove AARCH/ARM_COPY relocation support | |
* b906e13c55c9fe9b4157ba548534a0230434882b | |
And allows targets to disable this behavior if necessary: | |
Remove support for non-PIE executables | |
* 2aebf5429bb1241a3298b5b642d38f73124c2026 | |
Derived from AOSP Change-Id Ia2501aa14bd30feb4a6ce66bdb7c9f066dba0b5f. | |
--- | |
linker/Android.mk | 4 ++ | |
linker/linker.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++---------- | |
2 files changed, 97 insertions(+), 22 deletions(-) | |
diff --git a/linker/Android.mk b/linker/Android.mk | |
index 5853c90..14cee90 100644 | |
--- a/linker/Android.mk | |
+++ b/linker/Android.mk | |
@@ -38,6 +38,10 @@ LOCAL_CPPFLAGS += \ | |
# We need to access Bionic private headers in the linker. | |
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/ | |
+ifeq ($(TARGET_ALLOW_NON_PIE_EXECUTABLES),true) | |
+ LOCAL_CFLAGS += -DTARGET_ALLOW_NON_PIE_EXECUTABLES | |
+endif | |
+ | |
# we don't want crtbegin.o (because we have begin.o), so unset it | |
# just for this module | |
LOCAL_NO_CRT := true | |
diff --git a/linker/linker.cpp b/linker/linker.cpp | |
index cf65705..3f0ba92 100644 | |
--- a/linker/linker.cpp | |
+++ b/linker/linker.cpp | |
@@ -60,6 +60,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 | |
@@ -1117,17 +1118,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<void*>(reloc), | |
+ reinterpret_cast<void*>(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); | |
@@ -1305,17 +1341,48 @@ static int soinfo_relocate(soinfo* si, ElfW(Rel)* rel, unsigned count, soinfo* n | |
*reinterpret_cast<ElfW(Addr)*>(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<void*>(reloc), | |
+ reinterpret_cast<void*>(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); | |
@@ -2179,8 +2246,12 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( | |
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base); | |
if (elf_hdr->e_type != ET_DYN) { | |
+#ifdef TARGET_ALLOW_NON_PIE_EXECUTABLES | |
+ __libc_format_fd(2, "WARNING: legacy non-PIE executable, ASLR disabled\n"); | |
+#else | |
__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). | |
-- | |
1.7.10.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
My git on my phone displays an error like this :error Only position independent executetable (PIE) are supported.