• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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