aboutsummaryrefslogtreecommitdiffstats
path: root/linker/linker.cpp
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2015-04-01 21:18:48 +0000
committerDimitry Ivanov <dimitry@google.com>2015-04-01 21:18:48 +0000
commit56be6ed9e4ac99fdd920090ee89c57e3cf55e885 (patch)
treeddb0b8ad32f7929c5553114c181cbbd09c3f278f /linker/linker.cpp
parentcb00add1b382d1e3045876d7e1ccbee2fdce976b (diff)
downloadandroid_bionic-56be6ed9e4ac99fdd920090ee89c57e3cf55e885.tar.gz
android_bionic-56be6ed9e4ac99fdd920090ee89c57e3cf55e885.tar.bz2
android_bionic-56be6ed9e4ac99fdd920090ee89c57e3cf55e885.zip
Revert "Remove text-relocation support for lp32"
This reverts commit cb00add1b382d1e3045876d7e1ccbee2fdce976b. Bug: 20020312 Bug: 20013628 Change-Id: I8baa3d4b6c7fef50c9e2531257d5b96762099eb3
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r--linker/linker.cpp38
1 files changed, 36 insertions, 2 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 49c10a7f7..ebf125e1f 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -2297,8 +2297,13 @@ bool soinfo::prelink_image() {
break;
case DT_TEXTREL:
- DL_ERR("text relocations (DT_TEXTREL) found in the ELF file \"%s\"", name);
+#if defined(__LP64__)
+ DL_ERR("text relocations (DT_TEXTREL) found in 64-bit ELF file \"%s\"", name);
return false;
+#else
+ has_text_relocations = true;
+ break;
+#endif
case DT_SYMBOLIC:
has_DT_SYMBOLIC = true;
@@ -2310,8 +2315,12 @@ bool soinfo::prelink_image() {
case DT_FLAGS:
if (d->d_un.d_val & DF_TEXTREL) {
- DL_ERR("text relocations (DF_TEXTREL) found in the ELF file \"%s\"", name);
+#if defined(__LP64__)
+ DL_ERR("text relocations (DF_TEXTREL) found in 64-bit ELF file \"%s\"", name);
return false;
+#else
+ has_text_relocations = true;
+#endif
}
if (d->d_un.d_val & DF_SYMBOLIC) {
has_DT_SYMBOLIC = true;
@@ -2420,6 +2429,20 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
local_group_root_ = this;
}
+#if !defined(__LP64__)
+ if (has_text_relocations) {
+ // Make segments writable to allow text relocations to work properly. We will later call
+ // phdr_table_protect_segments() after all of them are applied and all constructors are run.
+ DL_WARN("%s has text relocations. This is wasting memory and prevents "
+ "security hardening. Please fix.", name);
+ if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't unprotect loadable segments for \"%s\": %s",
+ name, strerror(errno));
+ return false;
+ }
+ }
+#endif
+
if (android_relocs_ != nullptr) {
// check signature
if (android_relocs_size_ > 3 &&
@@ -2490,6 +2513,17 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
DEBUG("[ finished linking %s ]", name);
+#if !defined(__LP64__)
+ if (has_text_relocations) {
+ // All relocations are done, we can protect our segments back to read-only.
+ if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
+ DL_ERR("can't protect segments for \"%s\": %s",
+ name, strerror(errno));
+ return false;
+ }
+ }
+#endif
+
/* We can also turn on GNU RELRO protection */
if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",