diff options
author | Torne (Richard Coles) <torne@google.com> | 2019-04-03 09:12:36 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-04-03 09:12:36 -0700 |
commit | 07603294cd37e79d924e9ac59e90d51098f2d5b8 (patch) | |
tree | cf01ab7e984f0bf039f731c4a44301f9d9d58cff | |
parent | 74ce129f902d61dd3f29a47be5e1855f2b9c4124 (diff) | |
parent | ce62c05753424a8d9fd7650408d4cda6c935077b (diff) | |
download | bionic-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.cpp | 2 | ||||
-rw-r--r-- | linker/linker_phdr.cpp | 9 | ||||
-rw-r--r-- | linker/linker_phdr.h | 2 | ||||
-rw-r--r-- | tests/dlext_test.cpp | 16 |
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 |