1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #pragma once 30 31 #include <link.h> 32 33 #include <list> 34 #include <memory> 35 #include <string> 36 #include <vector> 37 38 #include "async_safe/CHECK.h" 39 #include "linker_namespaces.h" 40 #include "linker_tls.h" 41 #include "private/bionic_elf_tls.h" 42 #include "private/bionic_globals.h" 43 44 #define FLAG_LINKED 0x00000001 45 #define FLAG_EXE 0x00000004 // The main executable 46 #define FLAG_LINKER 0x00000010 // The linker itself 47 #define FLAG_GNU_HASH 0x00000040 // uses gnu hash 48 #define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller 49 // and should not be unmapped 50 #define FLAG_IMAGE_LINKED 0x00000100 // Is image linked - this is a guard on link_image. 51 // The difference between this flag and 52 // FLAG_LINKED is that FLAG_LINKED 53 // means is set when load_group is 54 // successfully loaded whereas this 55 // flag is set to avoid linking image 56 // when link_image called for the 57 // second time. This situation happens 58 // when load group is crossing 59 // namespace boundary twice and second 60 // local group depends on the same libraries. 61 #define FLAG_RESERVED 0x00000200 // This flag was set when there is at least one 62 // outstanding thread_local dtor 63 // registered with this soinfo. In such 64 // a case the actual unload is 65 // postponed until the last thread_local 66 // destructor associated with this 67 // soinfo is executed and this flag is 68 // unset. 69 #define FLAG_PRELINKED 0x00000400 // prelink_image has successfully processed this soinfo 70 #define FLAG_GLOBALS_TAGGED 0x00000800 // globals have been tagged by MTE. 71 #define FLAG_NEW_SOINFO 0x40000000 // new soinfo format 72 73 #define SOINFO_VERSION 6 74 75 ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr); 76 77 typedef void (*linker_dtor_function_t)(); 78 typedef void (*linker_ctor_function_t)(int, char**, char**); 79 80 // An entry within a SymbolLookupList. 81 struct SymbolLookupLib { 82 uint32_t gnu_maskwords_ = 0; 83 uint32_t gnu_shift2_ = 0; 84 ElfW(Addr)* gnu_bloom_filter_ = nullptr; 85 86 const char* strtab_; 87 size_t strtab_size_; 88 const ElfW(Sym)* symtab_; 89 const ElfW(Versym)* versym_; 90 91 const uint32_t* gnu_chain_; 92 size_t gnu_nbucket_; 93 uint32_t* gnu_bucket_; 94 95 soinfo* si_ = nullptr; 96 needs_sysv_lookupSymbolLookupLib97 bool needs_sysv_lookup() const { return si_ != nullptr && gnu_bloom_filter_ == nullptr; } 98 }; 99 100 // A list of libraries to search for a symbol. 101 class SymbolLookupList { 102 std::vector<SymbolLookupLib> libs_; 103 SymbolLookupLib sole_lib_; 104 const SymbolLookupLib* begin_; 105 const SymbolLookupLib* end_; 106 size_t slow_path_count_ = 0; 107 108 public: 109 explicit SymbolLookupList(soinfo* si); 110 SymbolLookupList(const soinfo_list_t& global_group, const soinfo_list_t& local_group); 111 void set_dt_symbolic_lib(soinfo* symbolic_lib); 112 begin()113 const SymbolLookupLib* begin() const { return begin_; } end()114 const SymbolLookupLib* end() const { return end_; } needs_slow_path()115 bool needs_slow_path() const { return slow_path_count_ > 0; } 116 }; 117 118 class SymbolName { 119 public: SymbolName(const char * name)120 explicit SymbolName(const char* name) 121 : name_(name), has_elf_hash_(false), has_gnu_hash_(false), 122 elf_hash_(0), gnu_hash_(0) { } 123 get_name()124 const char* get_name() { 125 return name_; 126 } 127 128 uint32_t elf_hash(); 129 uint32_t gnu_hash(); 130 131 private: 132 const char* name_; 133 bool has_elf_hash_; 134 bool has_gnu_hash_; 135 uint32_t elf_hash_; 136 uint32_t gnu_hash_; 137 138 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName); 139 }; 140 141 struct version_info { version_infoversion_info142 constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {} 143 144 uint32_t elf_hash; 145 const char* name; 146 const soinfo* target_si; 147 }; 148 149 // TODO(dimitry): remove reference from soinfo member functions to this class. 150 class VersionTracker; 151 152 struct soinfo_tls { 153 TlsSegment segment; 154 size_t module_id = kTlsUninitializedModuleId; 155 }; 156 157 struct soinfo { 158 #if !defined(__LP64__) 159 private: 160 char old_name_[128]; 161 #endif 162 public: 163 const ElfW(Phdr)* phdr; 164 size_t phnum; 165 #if !defined(__LP64__) 166 ElfW(Addr) unused0; // DO NOT USE, maintained for compatibility. 167 #endif 168 ElfW(Addr) base; 169 size_t size; 170 171 #if !defined(__LP64__) 172 uint32_t unused1; // DO NOT USE, maintained for compatibility. 173 #endif 174 175 ElfW(Dyn)* dynamic; 176 177 #if !defined(__LP64__) 178 uint32_t unused2; // DO NOT USE, maintained for compatibility 179 uint32_t unused3; // DO NOT USE, maintained for compatibility 180 #endif 181 182 soinfo* next; 183 private: 184 uint32_t flags_; 185 186 const char* strtab_; 187 ElfW(Sym)* symtab_; 188 189 size_t nbucket_; 190 size_t nchain_; 191 uint32_t* bucket_; 192 uint32_t* chain_; 193 194 #if !defined(__LP64__) 195 ElfW(Addr)** unused4; // DO NOT USE, maintained for compatibility 196 #endif 197 198 #if defined(USE_RELA) 199 ElfW(Rela)* plt_rela_; 200 size_t plt_rela_count_; 201 202 ElfW(Rela)* rela_; 203 size_t rela_count_; 204 #else 205 ElfW(Rel)* plt_rel_; 206 size_t plt_rel_count_; 207 208 ElfW(Rel)* rel_; 209 size_t rel_count_; 210 #endif 211 212 linker_ctor_function_t* preinit_array_; 213 size_t preinit_array_count_; 214 215 linker_ctor_function_t* init_array_; 216 size_t init_array_count_; 217 linker_dtor_function_t* fini_array_; 218 size_t fini_array_count_; 219 220 linker_ctor_function_t init_func_; 221 linker_dtor_function_t fini_func_; 222 223 #if defined(__arm__) 224 public: 225 // ARM EABI section used for stack unwinding. 226 uint32_t* ARM_exidx; 227 size_t ARM_exidx_count; 228 private: 229 #endif 230 size_t ref_count_; 231 public: 232 link_map link_map_head; 233 234 bool constructors_called; 235 236 // When you read a virtual address from the ELF file, add this 237 // value to get the corresponding address in the process' address space. 238 ElfW(Addr) load_bias; 239 240 #if !defined(__LP64__) 241 bool has_text_relocations; 242 #endif 243 bool has_DT_SYMBOLIC; 244 245 public: 246 soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat, 247 off64_t file_offset, int rtld_flags); 248 ~soinfo(); 249 250 void call_constructors(); 251 void call_destructors(); 252 void call_pre_init_constructors(); 253 bool prelink_image(bool deterministic_memtag_globals = false); 254 bool link_image(const SymbolLookupList& lookup_list, soinfo* local_group_root, 255 const android_dlextinfo* extinfo, size_t* relro_fd_offset); 256 bool protect_relro(); 257 258 void tag_globals(bool deterministic_memtag_globals); 259 ElfW(Addr) apply_memtag_if_mte_globals(ElfW(Addr) sym_addr) const; 260 261 void add_child(soinfo* child); 262 void remove_all_links(); 263 264 ino_t get_st_ino() const; 265 dev_t get_st_dev() const; 266 off64_t get_file_offset() const; 267 268 uint32_t get_rtld_flags() const; 269 uint32_t get_dt_flags_1() const; 270 void set_dt_flags_1(uint32_t dt_flags_1); 271 272 soinfo_list_t& get_children(); 273 const soinfo_list_t& get_children() const; 274 275 soinfo_list_t& get_parents(); 276 277 const ElfW(Sym)* find_symbol_by_name(SymbolName& symbol_name, const version_info* vi) const; 278 279 ElfW(Sym)* find_symbol_by_address(const void* addr); 280 resolve_symbol_addresssoinfo281 ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const { 282 if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) { 283 return call_ifunc_resolver(s->st_value + load_bias); 284 } 285 286 return static_cast<ElfW(Addr)>(s->st_value + load_bias); 287 } 288 289 const char* get_string(ElfW(Word) index) const; 290 bool can_unload() const; 291 bool is_gnu_hash() const; 292 is_lp64_or_has_min_versionsoinfo293 inline bool is_lp64_or_has_min_version(uint32_t min_version __unused) const { 294 #if defined(__LP64__) 295 return true; 296 #else 297 return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version; 298 #endif 299 } 300 ElfWsoinfo301 const ElfW(Versym)* get_versym_table() const { 302 return is_lp64_or_has_min_version(2) ? versym_ : nullptr; 303 } 304 305 bool is_linked() const; 306 bool is_linker() const; 307 bool is_main_executable() const; 308 309 void set_linked(); 310 void set_linker_flag(); 311 void set_main_executable(); 312 void set_nodelete(); 313 314 size_t increment_ref_count(); 315 size_t decrement_ref_count(); 316 size_t get_ref_count() const; 317 318 soinfo* get_local_group_root() const; 319 320 void set_soname(const char* soname); 321 const char* get_soname() const; 322 void set_realpath(const char* path); 323 const char* get_realpath() const; 324 const ElfW(Versym)* get_versym(size_t n) const; 325 ElfW(Addr) get_verneed_ptr() const; 326 size_t get_verneed_cnt() const; 327 ElfW(Addr) get_verdef_ptr() const; 328 size_t get_verdef_cnt() const; 329 330 int get_target_sdk_version() const; 331 332 void set_dt_runpath(const char *); 333 const std::vector<std::string>& get_dt_runpath() const; 334 android_namespace_t* get_primary_namespace(); 335 void add_secondary_namespace(android_namespace_t* secondary_ns); 336 android_namespace_list_t& get_secondary_namespaces(); 337 get_tlssoinfo338 soinfo_tls* get_tls() const { 339 return is_lp64_or_has_min_version(5) ? tls_.get() : nullptr; 340 } 341 342 void set_mapped_by_caller(bool reserved_map); 343 bool is_mapped_by_caller() const; 344 345 uintptr_t get_handle() const; 346 void generate_handle(); 347 void* to_handle(); 348 349 SymbolLookupLib get_lookup_lib(); 350 351 void set_gap_start(ElfW(Addr) gap_start); 352 ElfW(Addr) get_gap_start() const; 353 354 void set_gap_size(size_t gap_size); 355 size_t get_gap_size() const; 356 memtag_dynamic_entriessoinfo357 const memtag_dynamic_entries_t* memtag_dynamic_entries() const { 358 #if defined(__aarch64__) 359 return &memtag_dynamic_entries_; 360 #else 361 return nullptr; 362 #endif 363 } memtag_globalssoinfo364 void* memtag_globals() const { 365 const memtag_dynamic_entries_t* entries = memtag_dynamic_entries(); 366 return entries ? entries->memtag_globals : nullptr; 367 } memtag_globalsszsoinfo368 size_t memtag_globalssz() const { 369 const memtag_dynamic_entries_t* entries = memtag_dynamic_entries(); 370 return entries ? entries->memtag_globalssz : 0U; 371 } has_memtag_modesoinfo372 bool has_memtag_mode() const { 373 const memtag_dynamic_entries_t* entries = memtag_dynamic_entries(); 374 return entries ? entries->has_memtag_mode : false; 375 } memtag_modesoinfo376 unsigned memtag_mode() const { 377 const memtag_dynamic_entries_t* entries = memtag_dynamic_entries(); 378 return entries ? entries->memtag_mode : 0U; 379 } memtag_heapsoinfo380 bool memtag_heap() const { 381 const memtag_dynamic_entries_t* entries = memtag_dynamic_entries(); 382 return entries ? entries->memtag_heap : false; 383 } memtag_stacksoinfo384 bool memtag_stack() const { 385 const memtag_dynamic_entries_t* entries = memtag_dynamic_entries(); 386 return entries ? entries->memtag_stack : false; 387 } 388 set_should_pad_segmentssoinfo389 void set_should_pad_segments(bool should_pad_segments) { 390 should_pad_segments_ = should_pad_segments; 391 } should_pad_segmentssoinfo392 bool should_pad_segments() const { return should_pad_segments_; } should_tag_memtag_globalssoinfo393 bool should_tag_memtag_globals() const { 394 return !is_linker() && memtag_globals() && memtag_globalssz() > 0 && __libc_mte_enabled(); 395 } vma_namessoinfo396 std::list<std::string>* vma_names() { 397 #if defined(__aarch64__) 398 return &vma_names_; 399 #else 400 return nullptr; 401 #endif 402 }; 403 set_should_use_16kib_app_compatsoinfo404 void set_should_use_16kib_app_compat(bool should_use_16kib_app_compat) { 405 should_use_16kib_app_compat_ = should_use_16kib_app_compat; 406 } should_use_16kib_app_compatsoinfo407 bool should_use_16kib_app_compat() const { return should_use_16kib_app_compat_; } 408 set_compat_relro_startsoinfo409 void set_compat_relro_start(ElfW(Addr) start) { compat_relro_start_ = start; } compat_relro_startsoinfo410 ElfW(Addr) compat_relro_start() const { return compat_relro_start_; } 411 set_compat_relro_sizesoinfo412 void set_compat_relro_size(ElfW(Addr) size) { compat_relro_size_ = size; } compat_relro_sizesoinfo413 ElfW(Addr) compat_relro_size() const { return compat_relro_start_; } 414 415 private: 416 bool is_image_linked() const; 417 void set_image_linked(); 418 419 const ElfW(Sym)* gnu_lookup(SymbolName& symbol_name, const version_info* vi) const; 420 const ElfW(Sym)* elf_lookup(SymbolName& symbol_name, const version_info* vi) const; 421 ElfW(Sym)* gnu_addr_lookup(const void* addr); 422 ElfW(Sym)* elf_addr_lookup(const void* addr); 423 424 public: 425 bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym, 426 const char* sym_name, const version_info** vi); 427 428 private: 429 bool relocate(const SymbolLookupList& lookup_list); 430 431 // This part of the structure is only available 432 // when FLAG_NEW_SOINFO is set in this->flags. 433 uint32_t version_; 434 435 // version >= 0 436 dev_t st_dev_; 437 ino_t st_ino_; 438 439 // dependency graph 440 soinfo_list_t children_; 441 soinfo_list_t parents_; 442 443 // version >= 1 444 off64_t file_offset_; 445 uint32_t rtld_flags_; 446 uint32_t dt_flags_1_; 447 size_t strtab_size_; 448 449 // version >= 2 450 451 size_t gnu_nbucket_; 452 uint32_t* gnu_bucket_; 453 uint32_t* gnu_chain_; 454 uint32_t gnu_maskwords_; 455 uint32_t gnu_shift2_; 456 ElfW(Addr)* gnu_bloom_filter_; 457 458 soinfo* local_group_root_; 459 460 uint8_t* android_relocs_; 461 size_t android_relocs_size_; 462 463 std::string soname_; 464 std::string realpath_; 465 466 const ElfW(Versym)* versym_; 467 468 ElfW(Addr) verdef_ptr_; 469 size_t verdef_cnt_; 470 471 ElfW(Addr) verneed_ptr_; 472 size_t verneed_cnt_; 473 474 int target_sdk_version_; 475 476 // version >= 3 477 std::vector<std::string> dt_runpath_; 478 android_namespace_t* primary_namespace_; 479 android_namespace_list_t secondary_namespaces_; 480 uintptr_t handle_; 481 482 friend soinfo* get_libdl_info(const soinfo& linker_si); 483 484 // version >= 4 485 ElfW(Relr)* relr_; 486 size_t relr_count_; 487 488 // version >= 5 489 std::unique_ptr<soinfo_tls> tls_; 490 std::vector<TlsDynamicResolverArg> tlsdesc_args_; 491 492 // version >= 6 493 ElfW(Addr) gap_start_; 494 size_t gap_size_; 495 496 // __aarch64__ only, which does not use versioning. 497 memtag_dynamic_entries_t memtag_dynamic_entries_; 498 std::list<std::string> vma_names_; 499 500 // Pad gaps between segments when memory mapping? 501 bool should_pad_segments_ = false; 502 503 // Use app compat mode when loading 4KiB max-page-size ELFs on 16KiB page-size devices? 504 bool should_use_16kib_app_compat_ = false; 505 506 // RELRO region for 16KiB compat loading 507 ElfW(Addr) compat_relro_start_ = 0; 508 ElfW(Addr) compat_relro_size_ = 0; 509 }; 510 511 // This function is used by dlvsym() to calculate hash of sym_ver 512 uint32_t calculate_elf_hash(const char* name); 513 514 const char* fix_dt_needed(const char* dt_needed, const char* sopath); 515 516 const ElfW(Sym)* soinfo_do_lookup(const char* name, const version_info* vi, 517 soinfo** si_found_in, const SymbolLookupList& lookup_list); 518