aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2019-04-03 09:12:36 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-04-03 09:12:36 -0700
commit07603294cd37e79d924e9ac59e90d51098f2d5b8 (patch)
treecf01ab7e984f0bf039f731c4a44301f9d9d58cff
parent74ce129f902d61dd3f29a47be5e1855f2b9c4124 (diff)
parentce62c05753424a8d9fd7650408d4cda6c935077b (diff)
downloadbionic-07603294cd37e79d924e9ac59e90d51098f2d5b8.tar.gz
Merge "Fix DLEXT_WRITE_RELRO when loading multiple libs." am: 865866ee2b am: c950489599
am: ce62c05753 Change-Id: I234ee6e837fe2609918cee82121aa3994afbd4d8
-rw-r--r--linker/linker.cpp2
-rw-r--r--linker/linker_phdr.cpp9
-rw-r--r--linker/linker_phdr.h2
-rw-r--r--tests/dlext_test.cpp16
4 files changed, 22 insertions, 7 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index c60ab6a50..306b80014 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3987,7 +3987,7 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
/* Handle serializing/sharing the RELRO segment */
if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
- extinfo->relro_fd) < 0) {
+ extinfo->relro_fd, relro_fd_offset) < 0) {
DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
get_realpath(), strerror(errno));
return false;
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 1aaa17f82..353428730 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -831,16 +831,17 @@ int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table,
* phdr_count -> number of entries in tables
* load_bias -> load bias
* fd -> writable file descriptor to use
+ * file_offset -> pointer to offset into file descriptor to use/update
* Return:
* 0 on error, -1 on failure (error code in errno).
*/
int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
size_t phdr_count,
ElfW(Addr) load_bias,
- int fd) {
+ int fd,
+ size_t* file_offset) {
const ElfW(Phdr)* phdr = phdr_table;
const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
- ssize_t file_offset = 0;
for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
if (phdr->p_type != PT_GNU_RELRO) {
@@ -856,11 +857,11 @@ int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
return -1;
}
void* map = mmap(reinterpret_cast<void*>(seg_page_start), size, PROT_READ,
- MAP_PRIVATE|MAP_FIXED, fd, file_offset);
+ MAP_PRIVATE|MAP_FIXED, fd, *file_offset);
if (map == MAP_FAILED) {
return -1;
}
- file_offset += size;
+ *file_offset += size;
}
return 0;
}
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 9761bc8ca..5d1cfc2bd 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -119,7 +119,7 @@ int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count
ElfW(Addr) load_bias);
int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, int fd);
+ ElfW(Addr) load_bias, int fd, size_t* file_offset);
int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, int fd, size_t* file_offset);
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 1bc503061..3af52d47c 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -450,7 +450,21 @@ protected:
fprintf(stderr, "in child: %s\n", dlerror());
exit(1);
}
- exit(0);
+ fn f = reinterpret_cast<fn>(dlsym(handle, "getRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_EQ(4, f());
+
+ if (recursive) {
+ fn f = reinterpret_cast<fn>(dlsym(handle, "getBiggerRandomNumber"));
+ ASSERT_DL_NOTNULL(f);
+ EXPECT_EQ(8, f());
+ }
+
+ uint32_t* taxicab_number =
+ reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
+ ASSERT_DL_NOTNULL(taxicab_number);
+ EXPECT_EQ(1729U, *taxicab_number);
+ exit(testing::Test::HasFailure());
}
// continuing in parent