Created
August 28, 2015 02:32
-
-
Save steven676/85b290df8942cf0fd5e8 to your computer and use it in GitHub Desktop.
[PATCH 2/2] 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 989a14bfb86608aba038b6786a3ab312bd7aeb6e Mon Sep 17 00:00:00 2001 | |
From: Steven Luo <[email protected]> | |
Date: Sat, 15 Nov 2014 17:58:48 -0800 | |
Subject: [PATCH 2/2] 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 commit: | |
Cleanup: updated comments | |
* 6275f2083415d22a6ce0de55645079cd47e0cc80 | |
Allows targets to reenable this code: | |
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. | |
[[email protected]: update for Android 5.1+] | |
--- | |
linker/Android.mk | 4 ++++ | |
linker/linker.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++---------- | |
2 files changed, 55 insertions(+), 11 deletions(-) | |
diff --git a/linker/Android.mk b/linker/Android.mk | |
index 4298032..84cba0f 100644 | |
--- a/linker/Android.mk | |
+++ b/linker/Android.mk | |
@@ -39,6 +39,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 789040b..c7ef897 100644 | |
--- a/linker/linker.cpp | |
+++ b/linker/linker.cpp | |
@@ -63,6 +63,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 | |
@@ -1469,17 +1470,52 @@ int soinfo::Relocate(ElfW(Rel)* rel, unsigned count) { | |
*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", name); | |
- return -1; | |
+#ifdef TARGET_ALLOW_NON_PIE_EXECUTABLES | |
+ if ((flags & FLAG_EXE) == 0) { | |
+#endif | |
+ /* | |
+ * 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", name); | |
+ return -1; | |
+#ifdef TARGET_ALLOW_NON_PIE_EXECUTABLES | |
+ } | |
+ 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(this, sym_name, &lsi, false); | |
+ | |
+ if (src == NULL) { | |
+ DL_ERR("%s R_ARM_COPY relocation source cannot be resolved", 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?)", name, lsi->name); | |
+ return -1; | |
+ } | |
+ if (s->st_size < src->st_size) { | |
+ DL_ERR("%s R_ARM_COPY relocation size mismatch (%d < %d)", | |
+ 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", name); | |
+ return -1; | |
+ } | |
+ break; | |
+#endif /* TARGET_ALLOW_NON_PIE_EXECUTABLES */ | |
#elif defined(__i386__) | |
case R_386_JMP_SLOT: | |
count_relocation(kRelocAbsolute); | |
@@ -2407,8 +2443,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