diff options
author | Ryan Prichard <rprichard@google.com> | 2019-01-18 04:15:07 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-01-18 04:15:07 +0000 |
commit | 314c0f798983895d81705d7b431cc4651accc8a7 (patch) | |
tree | 376a7bd4524d68fe61570d408116bcb676a530c8 /linker | |
parent | 190626872ab894fb540298950e9200a991f39db1 (diff) | |
parent | bf427f42254f0a8d60dad3d1198c2f589d260cc8 (diff) | |
download | android_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.cpp | 5 | ||||
-rw-r--r-- | linker/linker_soinfo.h | 1 | ||||
-rw-r--r-- | linker/linker_tls.cpp | 24 | ||||
-rw-r--r-- | linker/linker_tls.h | 5 |
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); |