aboutsummaryrefslogtreecommitdiffstats
path: root/linker
diff options
context:
space:
mode:
authorRyan Prichard <rprichard@google.com>2019-01-18 04:15:07 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-01-18 04:15:07 +0000
commit314c0f798983895d81705d7b431cc4651accc8a7 (patch)
tree376a7bd4524d68fe61570d408116bcb676a530c8 /linker
parent190626872ab894fb540298950e9200a991f39db1 (diff)
parentbf427f42254f0a8d60dad3d1198c2f589d260cc8 (diff)
downloadandroid_bionic-314c0f798983895d81705d7b431cc4651accc8a7.tar.gz
android_bionic-314c0f798983895d81705d7b431cc4651accc8a7.tar.bz2
android_bionic-314c0f798983895d81705d7b431cc4651accc8a7.zip
Merge "Fix soinfo_tls::module dangling reference"
Diffstat (limited to 'linker')
-rw-r--r--linker/linker.cpp5
-rw-r--r--linker/linker_soinfo.h1
-rw-r--r--linker/linker_tls.cpp24
-rw-r--r--linker/linker_tls.h5
4 files changed, 24 insertions, 11 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 6687d235e..412b8eb8e 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -2925,8 +2925,9 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r
// Unresolved weak relocation. Leave tpoff at 0 to resolve
// &weak_tls_symbol to __get_tls().
} else if (soinfo_tls* lsi_tls = lsi->get_tls()) {
- if (lsi_tls->module->static_offset != SIZE_MAX) {
- tpoff += lsi_tls->module->static_offset - tls_tp_base;
+ const TlsModule& mod = get_tls_module(lsi_tls->module_id);
+ if (mod.static_offset != SIZE_MAX) {
+ tpoff += mod.static_offset - tls_tp_base;
} else {
DL_ERR("TLS symbol \"%s\" in dlopened \"%s\" referenced from \"%s\" using IE access model",
sym_name, lsi->get_realpath(), get_realpath());
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 87e385db3..14571de5b 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -110,7 +110,6 @@ static constexpr size_t kUninitializedModuleId = 0;
struct soinfo_tls {
TlsSegment segment;
size_t module_id = kUninitializedModuleId;
- TlsModule* module = nullptr;
};
#if defined(__work_around_b_24465209__)
diff --git a/linker/linker_tls.cpp b/linker/linker_tls.cpp
index a50d92671..0d1796b63 100644
--- a/linker/linker_tls.cpp
+++ b/linker/linker_tls.cpp
@@ -41,6 +41,9 @@
static bool g_static_tls_finished;
static std::vector<TlsModule> g_tls_modules;
+static inline size_t module_id_to_idx(size_t id) { return id - 1; }
+static inline size_t module_idx_to_id(size_t idx) { return idx + 1; }
+
static size_t get_unused_module_index() {
for (size_t i = 0; i < g_tls_modules.size(); ++i) {
if (g_tls_modules[i].soinfo_ptr == nullptr) {
@@ -59,13 +62,11 @@ static void register_tls_module(soinfo* si, size_t static_offset) {
ScopedWriteLock locker(&__libc_shared_globals()->tls_modules.rwlock);
size_t module_idx = get_unused_module_index();
- TlsModule* module = &g_tls_modules[module_idx];
soinfo_tls* si_tls = si->get_tls();
- si_tls->module_id = module_idx + 1;
- si_tls->module = module;
+ si_tls->module_id = module_idx_to_id(module_idx);
- *module = {
+ g_tls_modules[module_idx] = {
.segment = si_tls->segment,
.static_offset = static_offset,
.first_generation = ++__libc_shared_globals()->tls_modules.generation,
@@ -77,11 +78,18 @@ static void unregister_tls_module(soinfo* si) {
ScopedWriteLock locker(&__libc_shared_globals()->tls_modules.rwlock);
soinfo_tls* si_tls = si->get_tls();
- CHECK(si_tls->module->static_offset == SIZE_MAX);
- CHECK(si_tls->module->soinfo_ptr == si);
- *si_tls->module = {};
+ TlsModule& mod = g_tls_modules[module_id_to_idx(si_tls->module_id)];
+ CHECK(mod.static_offset == SIZE_MAX);
+ CHECK(mod.soinfo_ptr == si);
+ mod = {};
si_tls->module_id = kUninitializedModuleId;
- si_tls->module = nullptr;
+}
+
+// The reference is valid until a TLS module is registered or unregistered.
+const TlsModule& get_tls_module(size_t module_id) {
+ size_t module_idx = module_id_to_idx(module_id);
+ CHECK(module_idx < g_tls_modules.size());
+ return g_tls_modules[module_idx];
}
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
diff --git a/linker/linker_tls.h b/linker/linker_tls.h
index 4f4833731..fbb1dcf52 100644
--- a/linker/linker_tls.h
+++ b/linker/linker_tls.h
@@ -28,6 +28,9 @@
#pragma once
+#include <stdlib.h>
+
+struct TlsModule;
struct soinfo;
void linker_setup_exe_static_tls(const char* progname);
@@ -35,3 +38,5 @@ void linker_finalize_static_tls();
void register_soinfo_tls(soinfo* si);
void unregister_soinfo_tls(soinfo* si);
+
+const TlsModule& get_tls_module(size_t module_id);