diff options
author | Dimitry Ivanov <dimitry@google.com> | 2015-04-01 21:18:48 +0000 |
---|---|---|
committer | Dimitry Ivanov <dimitry@google.com> | 2015-04-01 21:18:48 +0000 |
commit | 56be6ed9e4ac99fdd920090ee89c57e3cf55e885 (patch) | |
tree | ddb0b8ad32f7929c5553114c181cbbd09c3f278f /linker/linker.cpp | |
parent | cb00add1b382d1e3045876d7e1ccbee2fdce976b (diff) | |
download | android_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.cpp | 38 |
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", |