• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 #include <android/api-level.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <inttypes.h>
33 #include <pthread.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/mman.h>
38 #include <sys/param.h>
39 #include <sys/vfs.h>
40 #include <unistd.h>
41 
42 #include <new>
43 #include <string>
44 #include <unordered_map>
45 #include <vector>
46 
47 // Private C library headers.
48 #include "private/ScopeGuard.h"
49 
50 #include "linker.h"
51 #include "linker_block_allocator.h"
52 #include "linker_cfi.h"
53 #include "linker_config.h"
54 #include "linker_gdb_support.h"
55 #include "linker_globals.h"
56 #include "linker_debug.h"
57 #include "linker_dlwarning.h"
58 #include "linker_main.h"
59 #include "linker_namespaces.h"
60 #include "linker_sleb128.h"
61 #include "linker_phdr.h"
62 #include "linker_relocs.h"
63 #include "linker_reloc_iterators.h"
64 #include "linker_utils.h"
65 
66 #include "android-base/strings.h"
67 #include "android-base/stringprintf.h"
68 #include "ziparchive/zip_archive.h"
69 
70 // Override macros to use C++ style casts.
71 #undef ELF_ST_TYPE
72 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
73 
74 static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
75 static std::unordered_map<std::string, android_namespace_t*> g_exported_namespaces;
76 
77 static LinkerTypeAllocator<soinfo> g_soinfo_allocator;
78 static LinkerTypeAllocator<LinkedListEntry<soinfo>> g_soinfo_links_allocator;
79 
80 static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
81 static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
82 
83 static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt";
84 
85 #if defined(__LP64__)
86 static const char* const kSystemLibDir     = "/system/lib64";
87 static const char* const kVendorLibDir     = "/vendor/lib64";
88 static const char* const kAsanSystemLibDir = "/data/asan/system/lib64";
89 static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib64";
90 #else
91 static const char* const kSystemLibDir     = "/system/lib";
92 static const char* const kVendorLibDir     = "/vendor/lib";
93 static const char* const kAsanSystemLibDir = "/data/asan/system/lib";
94 static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib";
95 #endif
96 
97 static const char* const kAsanLibDirPrefix = "/data/asan";
98 
99 static const char* const kDefaultLdPaths[] = {
100   kSystemLibDir,
101   kVendorLibDir,
102   nullptr
103 };
104 
105 static const char* const kAsanDefaultLdPaths[] = {
106   kAsanSystemLibDir,
107   kSystemLibDir,
108   kAsanVendorLibDir,
109   kVendorLibDir,
110   nullptr
111 };
112 
113 // Is ASAN enabled?
114 static bool g_is_asan = false;
115 
116 static CFIShadowWriter g_cfi_shadow;
117 
get_cfi_shadow()118 CFIShadowWriter* get_cfi_shadow() {
119   return &g_cfi_shadow;
120 }
121 
is_system_library(const std::string & realpath)122 static bool is_system_library(const std::string& realpath) {
123   for (const auto& dir : g_default_namespace.get_default_library_paths()) {
124     if (file_is_in_dir(realpath, dir)) {
125       return true;
126     }
127   }
128   return false;
129 }
130 
131 // Checks if the file exists and not a directory.
file_exists(const char * path)132 static bool file_exists(const char* path) {
133   struct stat s;
134 
135   if (stat(path, &s) != 0) {
136     return false;
137   }
138 
139   return S_ISREG(s.st_mode);
140 }
141 
resolve_soname(const std::string & name)142 static std::string resolve_soname(const std::string& name) {
143   // We assume that soname equals to basename here
144 
145   // TODO(dimitry): consider having honest absolute-path -> soname resolution
146   // note that since we might end up refusing to load this library because
147   // it is not in shared libs list we need to get the soname without actually loading
148   // the library.
149   //
150   // On the other hand there are several places where we already assume that
151   // soname == basename in particular for any not-loaded library mentioned
152   // in DT_NEEDED list.
153   return basename(name.c_str());
154 }
155 
maybe_accessible_via_namespace_links(android_namespace_t * ns,const char * name)156 static bool maybe_accessible_via_namespace_links(android_namespace_t* ns, const char* name) {
157   std::string soname = resolve_soname(name);
158   for (auto& ns_link : ns->linked_namespaces()) {
159     if (ns_link.is_accessible(soname.c_str())) {
160       return true;
161     }
162   }
163 
164   return false;
165 }
166 
167 // TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
168 // gradually remove libraries from this list until it is gone.
is_greylisted(android_namespace_t * ns,const char * name,const soinfo * needed_by)169 static bool is_greylisted(android_namespace_t* ns, const char* name, const soinfo* needed_by) {
170   static const char* const kLibraryGreyList[] = {
171     "libandroid_runtime.so",
172     "libbinder.so",
173     "libcrypto.so",
174     "libcutils.so",
175     "libexpat.so",
176     "libgui.so",
177     "libmedia.so",
178     "libnativehelper.so",
179     "libskia.so",
180     "libssl.so",
181     "libstagefright.so",
182     "libsqlite.so",
183     "libui.so",
184     "libutils.so",
185     "libvorbisidec.so",
186     nullptr
187   };
188 
189   // If you're targeting N, you don't get the greylist.
190   if (g_greylist_disabled || get_application_target_sdk_version() >= __ANDROID_API_N__) {
191     return false;
192   }
193 
194   // if the library needed by a system library - implicitly assume it
195   // is greylisted unless it is in the list of shared libraries for one or
196   // more linked namespaces
197   if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) {
198     return !maybe_accessible_via_namespace_links(ns, name);
199   }
200 
201   // if this is an absolute path - make sure it points to /system/lib(64)
202   if (name[0] == '/' && dirname(name) == kSystemLibDir) {
203     // and reduce the path to basename
204     name = basename(name);
205   }
206 
207   for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) {
208     if (strcmp(name, kLibraryGreyList[i]) == 0) {
209       return true;
210     }
211   }
212 
213   return false;
214 }
215 // END OF WORKAROUND
216 
217 static std::vector<std::string> g_ld_preload_names;
218 
219 static bool g_anonymous_namespace_initialized;
220 
221 #if STATS
222 struct linker_stats_t {
223   int count[kRelocMax];
224 };
225 
226 static linker_stats_t linker_stats;
227 
count_relocation(RelocationKind kind)228 void count_relocation(RelocationKind kind) {
229   ++linker_stats.count[kind];
230 }
231 #else
count_relocation(RelocationKind)232 void count_relocation(RelocationKind) {
233 }
234 #endif
235 
236 #if COUNT_PAGES
237 uint32_t bitmask[4096];
238 #endif
239 
notify_gdb_of_load(soinfo * info)240 static void notify_gdb_of_load(soinfo* info) {
241   if (info->is_linker() || info->is_main_executable()) {
242     // gdb already knows about the linker and the main executable.
243     return;
244   }
245 
246   link_map* map = &(info->link_map_head);
247 
248   map->l_addr = info->load_bias;
249   // link_map l_name field is not const.
250   map->l_name = const_cast<char*>(info->get_realpath());
251   map->l_ld = info->dynamic;
252 
253   CHECK(map->l_name != nullptr);
254   CHECK(map->l_name[0] != '\0');
255 
256   notify_gdb_of_load(map);
257 }
258 
notify_gdb_of_unload(soinfo * info)259 static void notify_gdb_of_unload(soinfo* info) {
260   notify_gdb_of_unload(&(info->link_map_head));
261 }
262 
alloc()263 LinkedListEntry<soinfo>* SoinfoListAllocator::alloc() {
264   return g_soinfo_links_allocator.alloc();
265 }
266 
free(LinkedListEntry<soinfo> * entry)267 void SoinfoListAllocator::free(LinkedListEntry<soinfo>* entry) {
268   g_soinfo_links_allocator.free(entry);
269 }
270 
alloc()271 LinkedListEntry<android_namespace_t>* NamespaceListAllocator::alloc() {
272   return g_namespace_list_allocator.alloc();
273 }
274 
free(LinkedListEntry<android_namespace_t> * entry)275 void NamespaceListAllocator::free(LinkedListEntry<android_namespace_t>* entry) {
276   g_namespace_list_allocator.free(entry);
277 }
278 
soinfo_alloc(android_namespace_t * ns,const char * name,struct stat * file_stat,off64_t file_offset,uint32_t rtld_flags)279 soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
280                      struct stat* file_stat, off64_t file_offset,
281                      uint32_t rtld_flags) {
282   if (strlen(name) >= PATH_MAX) {
283     DL_ERR("library name \"%s\" too long", name);
284     return nullptr;
285   }
286 
287   TRACE("name %s: allocating soinfo for ns=%p", name, ns);
288 
289   soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(ns, name, file_stat,
290                                                        file_offset, rtld_flags);
291 
292   solist_add_soinfo(si);
293 
294   si->generate_handle();
295   ns->add_soinfo(si);
296 
297   TRACE("name %s: allocated soinfo @ %p", name, si);
298   return si;
299 }
300 
soinfo_free(soinfo * si)301 static void soinfo_free(soinfo* si) {
302   if (si == nullptr) {
303     return;
304   }
305 
306   if (si->base != 0 && si->size != 0) {
307     if (!si->is_mapped_by_caller()) {
308       munmap(reinterpret_cast<void*>(si->base), si->size);
309     } else {
310       // remap the region as PROT_NONE, MAP_ANONYMOUS | MAP_NORESERVE
311       mmap(reinterpret_cast<void*>(si->base), si->size, PROT_NONE,
312            MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
313     }
314   }
315 
316   TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
317 
318   if (!solist_remove_soinfo(si)) {
319     // TODO (dimitry): revisit this - for now preserving the logic
320     // but it does not look right, abort if soinfo is not in the list instead?
321     return;
322   }
323 
324   // clear links to/from si
325   si->remove_all_links();
326 
327   si->~soinfo();
328   g_soinfo_allocator.free(si);
329 }
330 
parse_path(const char * path,const char * delimiters,std::vector<std::string> * resolved_paths)331 static void parse_path(const char* path, const char* delimiters,
332                        std::vector<std::string>* resolved_paths) {
333   std::vector<std::string> paths;
334   split_path(path, delimiters, &paths);
335   resolve_paths(paths, resolved_paths);
336 }
337 
parse_LD_LIBRARY_PATH(const char * path)338 static void parse_LD_LIBRARY_PATH(const char* path) {
339   std::vector<std::string> ld_libary_paths;
340   parse_path(path, ":", &ld_libary_paths);
341   g_default_namespace.set_ld_library_paths(std::move(ld_libary_paths));
342 }
343 
realpath_fd(int fd,std::string * realpath)344 static bool realpath_fd(int fd, std::string* realpath) {
345   std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
346   __libc_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
347   if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
348     PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
349     return false;
350   }
351 
352   *realpath = &buf[0];
353   return true;
354 }
355 
356 #if defined(__arm__)
357 
358 // For a given PC, find the .so that it belongs to.
359 // Returns the base address of the .ARM.exidx section
360 // for that .so, and the number of 8-byte entries
361 // in that section (via *pcount).
362 //
363 // Intended to be called by libc's __gnu_Unwind_Find_exidx().
do_dl_unwind_find_exidx(_Unwind_Ptr pc,int * pcount)364 _Unwind_Ptr do_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
365   uintptr_t addr = reinterpret_cast<uintptr_t>(pc);
366 
367   for (soinfo* si = solist_get_head(); si != 0; si = si->next) {
368     if ((addr >= si->base) && (addr < (si->base + si->size))) {
369         *pcount = si->ARM_exidx_count;
370         return reinterpret_cast<_Unwind_Ptr>(si->ARM_exidx);
371     }
372   }
373   *pcount = 0;
374   return nullptr;
375 }
376 
377 #endif
378 
379 // Here, we only have to provide a callback to iterate across all the
380 // loaded libraries. gcc_eh does the rest.
do_dl_iterate_phdr(int (* cb)(dl_phdr_info * info,size_t size,void * data),void * data)381 int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
382   int rv = 0;
383   for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
384     dl_phdr_info dl_info;
385     dl_info.dlpi_addr = si->link_map_head.l_addr;
386     dl_info.dlpi_name = si->link_map_head.l_name;
387     dl_info.dlpi_phdr = si->phdr;
388     dl_info.dlpi_phnum = si->phnum;
389     rv = cb(&dl_info, sizeof(dl_phdr_info), data);
390     if (rv != 0) {
391       break;
392     }
393   }
394   return rv;
395 }
396 
397 
soinfo_do_lookup(soinfo * si_from,const char * name,const version_info * vi,soinfo ** si_found_in,const soinfo_list_t & global_group,const soinfo_list_t & local_group,const ElfW (Sym)** symbol)398 bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
399                       soinfo** si_found_in, const soinfo_list_t& global_group,
400                       const soinfo_list_t& local_group, const ElfW(Sym)** symbol) {
401   SymbolName symbol_name(name);
402   const ElfW(Sym)* s = nullptr;
403 
404   /* "This element's presence in a shared object library alters the dynamic linker's
405    * symbol resolution algorithm for references within the library. Instead of starting
406    * a symbol search with the executable file, the dynamic linker starts from the shared
407    * object itself. If the shared object fails to supply the referenced symbol, the
408    * dynamic linker then searches the executable file and other shared objects as usual."
409    *
410    * http://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html
411    *
412    * Note that this is unlikely since static linker avoids generating
413    * relocations for -Bsymbolic linked dynamic executables.
414    */
415   if (si_from->has_DT_SYMBOLIC) {
416     DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
417     if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
418       return false;
419     }
420 
421     if (s != nullptr) {
422       *si_found_in = si_from;
423     }
424   }
425 
426   // 1. Look for it in global_group
427   if (s == nullptr) {
428     bool error = false;
429     global_group.visit([&](soinfo* global_si) {
430       DEBUG("%s: looking up %s in %s (from global group)",
431           si_from->get_realpath(), name, global_si->get_realpath());
432       if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
433         error = true;
434         return false;
435       }
436 
437       if (s != nullptr) {
438         *si_found_in = global_si;
439         return false;
440       }
441 
442       return true;
443     });
444 
445     if (error) {
446       return false;
447     }
448   }
449 
450   // 2. Look for it in the local group
451   if (s == nullptr) {
452     bool error = false;
453     local_group.visit([&](soinfo* local_si) {
454       if (local_si == si_from && si_from->has_DT_SYMBOLIC) {
455         // we already did this - skip
456         return true;
457       }
458 
459       DEBUG("%s: looking up %s in %s (from local group)",
460           si_from->get_realpath(), name, local_si->get_realpath());
461       if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
462         error = true;
463         return false;
464       }
465 
466       if (s != nullptr) {
467         *si_found_in = local_si;
468         return false;
469       }
470 
471       return true;
472     });
473 
474     if (error) {
475       return false;
476     }
477   }
478 
479   if (s != nullptr) {
480     TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
481                "found in %s, base = %p, load bias = %p",
482                si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
483                (*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
484                reinterpret_cast<void*>((*si_found_in)->load_bias));
485   }
486 
487   *symbol = s;
488   return true;
489 }
490 
ProtectedDataGuard()491 ProtectedDataGuard::ProtectedDataGuard() {
492   if (ref_count_++ == 0) {
493     protect_data(PROT_READ | PROT_WRITE);
494   }
495 
496   if (ref_count_ == 0) { // overflow
497     __libc_fatal("Too many nested calls to dlopen()");
498   }
499 }
500 
~ProtectedDataGuard()501 ProtectedDataGuard::~ProtectedDataGuard() {
502   if (--ref_count_ == 0) {
503     protect_data(PROT_READ);
504   }
505 }
506 
protect_data(int protection)507 void ProtectedDataGuard::protect_data(int protection) {
508   g_soinfo_allocator.protect_all(protection);
509   g_soinfo_links_allocator.protect_all(protection);
510   g_namespace_allocator.protect_all(protection);
511   g_namespace_list_allocator.protect_all(protection);
512 }
513 
514 size_t ProtectedDataGuard::ref_count_ = 0;
515 
516 // Each size has it's own allocator.
517 template<size_t size>
518 class SizeBasedAllocator {
519  public:
alloc()520   static void* alloc() {
521     return allocator_.alloc();
522   }
523 
free(void * ptr)524   static void free(void* ptr) {
525     allocator_.free(ptr);
526   }
527 
528  private:
529   static LinkerBlockAllocator allocator_;
530 };
531 
532 template<size_t size>
533 LinkerBlockAllocator SizeBasedAllocator<size>::allocator_(size);
534 
535 template<typename T>
536 class TypeBasedAllocator {
537  public:
alloc()538   static T* alloc() {
539     return reinterpret_cast<T*>(SizeBasedAllocator<sizeof(T)>::alloc());
540   }
541 
free(T * ptr)542   static void free(T* ptr) {
543     SizeBasedAllocator<sizeof(T)>::free(ptr);
544   }
545 };
546 
547 class LoadTask {
548  public:
549   struct deleter_t {
operator ()LoadTask::deleter_t550     void operator()(LoadTask* t) {
551       t->~LoadTask();
552       TypeBasedAllocator<LoadTask>::free(t);
553     }
554   };
555 
556   static deleter_t deleter;
557 
create(const char * name,soinfo * needed_by,std::unordered_map<const soinfo *,ElfReader> * readers_map)558   static LoadTask* create(const char* name,
559                           soinfo* needed_by,
560                           std::unordered_map<const soinfo*, ElfReader>* readers_map) {
561     LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
562     return new (ptr) LoadTask(name, needed_by, readers_map);
563   }
564 
get_name() const565   const char* get_name() const {
566     return name_;
567   }
568 
get_needed_by() const569   soinfo* get_needed_by() const {
570     return needed_by_;
571   }
572 
get_soinfo() const573   soinfo* get_soinfo() const {
574     return si_;
575   }
576 
set_soinfo(soinfo * si)577   void set_soinfo(soinfo* si) {
578     si_ = si;
579   }
580 
get_file_offset() const581   off64_t get_file_offset() const {
582     return file_offset_;
583   }
584 
set_file_offset(off64_t offset)585   void set_file_offset(off64_t offset) {
586     file_offset_ = offset;
587   }
588 
get_fd() const589   int get_fd() const {
590     return fd_;
591   }
592 
set_fd(int fd,bool assume_ownership)593   void set_fd(int fd, bool assume_ownership) {
594     fd_ = fd;
595     close_fd_ = assume_ownership;
596   }
597 
get_extinfo() const598   const android_dlextinfo* get_extinfo() const {
599     return extinfo_;
600   }
601 
set_extinfo(const android_dlextinfo * extinfo)602   void set_extinfo(const android_dlextinfo* extinfo) {
603     extinfo_ = extinfo;
604   }
605 
is_dt_needed() const606   bool is_dt_needed() const {
607     return is_dt_needed_;
608   }
609 
set_dt_needed(bool is_dt_needed)610   void set_dt_needed(bool is_dt_needed) {
611     is_dt_needed_ = is_dt_needed;
612   }
613 
get_elf_reader() const614   const ElfReader& get_elf_reader() const {
615     CHECK(si_ != nullptr);
616     return (*elf_readers_map_)[si_];
617   }
618 
get_elf_reader()619   ElfReader& get_elf_reader() {
620     CHECK(si_ != nullptr);
621     return (*elf_readers_map_)[si_];
622   }
623 
get_readers_map()624   std::unordered_map<const soinfo*, ElfReader>* get_readers_map() {
625     return elf_readers_map_;
626   }
627 
read(const char * realpath,off64_t file_size)628   bool read(const char* realpath, off64_t file_size) {
629     ElfReader& elf_reader = get_elf_reader();
630     return elf_reader.Read(realpath, fd_, file_offset_, file_size);
631   }
632 
load()633   bool load() {
634     ElfReader& elf_reader = get_elf_reader();
635     if (!elf_reader.Load(extinfo_)) {
636       return false;
637     }
638 
639     si_->base = elf_reader.load_start();
640     si_->size = elf_reader.load_size();
641     si_->set_mapped_by_caller(elf_reader.is_mapped_by_caller());
642     si_->load_bias = elf_reader.load_bias();
643     si_->phnum = elf_reader.phdr_count();
644     si_->phdr = elf_reader.loaded_phdr();
645 
646     return true;
647   }
648 
649  private:
LoadTask(const char * name,soinfo * needed_by,std::unordered_map<const soinfo *,ElfReader> * readers_map)650   LoadTask(const char* name,
651            soinfo* needed_by,
652            std::unordered_map<const soinfo*, ElfReader>* readers_map)
653     : name_(name), needed_by_(needed_by), si_(nullptr),
654       fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
655       is_dt_needed_(false) {}
656 
~LoadTask()657   ~LoadTask() {
658     if (fd_ != -1 && close_fd_) {
659       close(fd_);
660     }
661   }
662 
663   const char* name_;
664   soinfo* needed_by_;
665   soinfo* si_;
666   const android_dlextinfo* extinfo_;
667   int fd_;
668   bool close_fd_;
669   off64_t file_offset_;
670   std::unordered_map<const soinfo*, ElfReader>* elf_readers_map_;
671   // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
672   bool is_dt_needed_;
673   // END OF WORKAROUND
674 
675   DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
676 };
677 
678 LoadTask::deleter_t LoadTask::deleter;
679 
680 template <typename T>
681 using linked_list_t = LinkedList<T, TypeBasedAllocator<LinkedListEntry<T>>>;
682 
683 typedef linked_list_t<soinfo> SoinfoLinkedList;
684 typedef linked_list_t<const char> StringLinkedList;
685 typedef std::vector<LoadTask*> LoadTaskList;
686 
687 enum walk_action_result_t : uint32_t {
688   kWalkStop = 0,
689   kWalkContinue = 1,
690   kWalkSkip = 2
691 };
692 
693 // This function walks down the tree of soinfo dependencies
694 // in breadth-first order and
695 //   * calls action(soinfo* si) for each node, and
696 //   * terminates walk if action returns kWalkStop
697 //   * skips children of the node if action
698 //     return kWalkSkip
699 //
700 // walk_dependencies_tree returns false if walk was terminated
701 // by the action and true otherwise.
702 template<typename F>
walk_dependencies_tree(soinfo * root_soinfos[],size_t root_soinfos_size,F action)703 static bool walk_dependencies_tree(soinfo* root_soinfos[], size_t root_soinfos_size, F action) {
704   SoinfoLinkedList visit_list;
705   SoinfoLinkedList visited;
706 
707   for (size_t i = 0; i < root_soinfos_size; ++i) {
708     visit_list.push_back(root_soinfos[i]);
709   }
710 
711   soinfo* si;
712   while ((si = visit_list.pop_front()) != nullptr) {
713     if (visited.contains(si)) {
714       continue;
715     }
716 
717     walk_action_result_t result = action(si);
718 
719     if (result == kWalkStop) {
720       return false;
721     }
722 
723     visited.push_back(si);
724 
725     if (result != kWalkSkip) {
726       si->get_children().for_each([&](soinfo* child) {
727         visit_list.push_back(child);
728       });
729     }
730   }
731 
732   return true;
733 }
734 
735 
ElfW(Sym)736 static const ElfW(Sym)* dlsym_handle_lookup(android_namespace_t* ns,
737                                             soinfo* root,
738                                             soinfo* skip_until,
739                                             soinfo** found,
740                                             SymbolName& symbol_name,
741                                             const version_info* vi) {
742   const ElfW(Sym)* result = nullptr;
743   bool skip_lookup = skip_until != nullptr;
744 
745   walk_dependencies_tree(&root, 1, [&](soinfo* current_soinfo) {
746     if (skip_lookup) {
747       skip_lookup = current_soinfo != skip_until;
748       return kWalkContinue;
749     }
750 
751     if (!ns->is_accessible(current_soinfo)) {
752       return kWalkSkip;
753     }
754 
755     if (!current_soinfo->find_symbol_by_name(symbol_name, vi, &result)) {
756       result = nullptr;
757       return kWalkStop;
758     }
759 
760     if (result != nullptr) {
761       *found = current_soinfo;
762       return kWalkStop;
763     }
764 
765     return kWalkContinue;
766   });
767 
768   return result;
769 }
770 
771 static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
772                                             const char* name,
773                                             const version_info* vi,
774                                             soinfo** found,
775                                             soinfo* caller,
776                                             void* handle);
777 
778 // This is used by dlsym(3).  It performs symbol lookup only within the
779 // specified soinfo object and its dependencies in breadth first order.
ElfW(Sym)780 static const ElfW(Sym)* dlsym_handle_lookup(soinfo* si,
781                                             soinfo** found,
782                                             const char* name,
783                                             const version_info* vi) {
784   // According to man dlopen(3) and posix docs in the case when si is handle
785   // of the main executable we need to search not only in the executable and its
786   // dependencies but also in all libraries loaded with RTLD_GLOBAL.
787   //
788   // Since RTLD_GLOBAL is always set for the main executable and all dt_needed shared
789   // libraries and they are loaded in breath-first (correct) order we can just execute
790   // dlsym(RTLD_DEFAULT, ...); instead of doing two stage lookup.
791   if (si == solist_get_somain()) {
792     return dlsym_linear_lookup(&g_default_namespace, name, vi, found, nullptr, RTLD_DEFAULT);
793   }
794 
795   SymbolName symbol_name(name);
796   // note that the namespace is not the namespace associated with caller_addr
797   // we use ns associated with root si intentionally here. Using caller_ns
798   // causes problems when user uses dlopen_ext to open a library in the separate
799   // namespace and then calls dlsym() on the handle.
800   return dlsym_handle_lookup(si->get_primary_namespace(), si, nullptr, found, symbol_name, vi);
801 }
802 
803 /* This is used by dlsym(3) to performs a global symbol lookup. If the
804    start value is null (for RTLD_DEFAULT), the search starts at the
805    beginning of the global solist. Otherwise the search starts at the
806    specified soinfo (for RTLD_NEXT).
807  */
ElfW(Sym)808 static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
809                                             const char* name,
810                                             const version_info* vi,
811                                             soinfo** found,
812                                             soinfo* caller,
813                                             void* handle) {
814   SymbolName symbol_name(name);
815 
816   auto& soinfo_list = ns->soinfo_list();
817   auto start = soinfo_list.begin();
818 
819   if (handle == RTLD_NEXT) {
820     if (caller == nullptr) {
821       return nullptr;
822     } else {
823       auto it = soinfo_list.find(caller);
824       CHECK (it != soinfo_list.end());
825       start = ++it;
826     }
827   }
828 
829   const ElfW(Sym)* s = nullptr;
830   for (auto it = start, end = soinfo_list.end(); it != end; ++it) {
831     soinfo* si = *it;
832     // Do not skip RTLD_LOCAL libraries in dlsym(RTLD_DEFAULT, ...)
833     // if the library is opened by application with target api level < M.
834     // See http://b/21565766
835     if ((si->get_rtld_flags() & RTLD_GLOBAL) == 0 &&
836         si->get_target_sdk_version() >= __ANDROID_API_M__) {
837       continue;
838     }
839 
840     if (!si->find_symbol_by_name(symbol_name, vi, &s)) {
841       return nullptr;
842     }
843 
844     if (s != nullptr) {
845       *found = si;
846       break;
847     }
848   }
849 
850   // If not found - use dlsym_handle_lookup for caller's
851   // local_group unless it is part of the global group in which
852   // case we already did it.
853   if (s == nullptr && caller != nullptr &&
854       (caller->get_rtld_flags() & RTLD_GLOBAL) == 0) {
855     soinfo* local_group_root = caller->get_local_group_root();
856 
857     return dlsym_handle_lookup(local_group_root->get_primary_namespace(),
858                                local_group_root,
859                                (handle == RTLD_NEXT) ? caller : nullptr,
860                                found,
861                                symbol_name,
862                                vi);
863   }
864 
865   if (s != nullptr) {
866     TRACE_TYPE(LOOKUP, "%s s->st_value = %p, found->base = %p",
867                name, reinterpret_cast<void*>(s->st_value), reinterpret_cast<void*>((*found)->base));
868   }
869 
870   return s;
871 }
872 
find_containing_library(const void * p)873 soinfo* find_containing_library(const void* p) {
874   ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p);
875   for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
876     if (address >= si->base && address - si->base < si->size) {
877       return si;
878     }
879   }
880   return nullptr;
881 }
882 
883 class ZipArchiveCache {
884  public:
ZipArchiveCache()885   ZipArchiveCache() {}
886   ~ZipArchiveCache();
887 
888   bool get_or_open(const char* zip_path, ZipArchiveHandle* handle);
889  private:
890   DISALLOW_COPY_AND_ASSIGN(ZipArchiveCache);
891 
892   std::unordered_map<std::string, ZipArchiveHandle> cache_;
893 };
894 
get_or_open(const char * zip_path,ZipArchiveHandle * handle)895 bool ZipArchiveCache::get_or_open(const char* zip_path, ZipArchiveHandle* handle) {
896   std::string key(zip_path);
897 
898   auto it = cache_.find(key);
899   if (it != cache_.end()) {
900     *handle = it->second;
901     return true;
902   }
903 
904   int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
905   if (fd == -1) {
906     return false;
907   }
908 
909   if (OpenArchiveFd(fd, "", handle) != 0) {
910     // invalid zip-file (?)
911     CloseArchive(handle);
912     close(fd);
913     return false;
914   }
915 
916   cache_[key] = *handle;
917   return true;
918 }
919 
~ZipArchiveCache()920 ZipArchiveCache::~ZipArchiveCache() {
921   for (const auto& it : cache_) {
922     CloseArchive(it.second);
923   }
924 }
925 
open_library_in_zipfile(ZipArchiveCache * zip_archive_cache,const char * const input_path,off64_t * file_offset,std::string * realpath)926 static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache,
927                                    const char* const input_path,
928                                    off64_t* file_offset, std::string* realpath) {
929   std::string normalized_path;
930   if (!normalize_path(input_path, &normalized_path)) {
931     return -1;
932   }
933 
934   const char* const path = normalized_path.c_str();
935   TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
936 
937   // Treat an '!/' separator inside a path as the separator between the name
938   // of the zip file on disk and the subdirectory to search within it.
939   // For example, if path is "foo.zip!/bar/bas/x.so", then we search for
940   // "bar/bas/x.so" within "foo.zip".
941   const char* const separator = strstr(path, kZipFileSeparator);
942   if (separator == nullptr) {
943     return -1;
944   }
945 
946   char buf[512];
947   if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
948     PRINT("Warning: ignoring very long library path: %s", path);
949     return -1;
950   }
951 
952   buf[separator - path] = '\0';
953 
954   const char* zip_path = buf;
955   const char* file_path = &buf[separator - path + 2];
956   int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
957   if (fd == -1) {
958     return -1;
959   }
960 
961   ZipArchiveHandle handle;
962   if (!zip_archive_cache->get_or_open(zip_path, &handle)) {
963     // invalid zip-file (?)
964     close(fd);
965     return -1;
966   }
967 
968   ZipEntry entry;
969 
970   if (FindEntry(handle, ZipString(file_path), &entry) != 0) {
971     // Entry was not found.
972     close(fd);
973     return -1;
974   }
975 
976   // Check if it is properly stored
977   if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
978     close(fd);
979     return -1;
980   }
981 
982   *file_offset = entry.offset;
983 
984   if (realpath_fd(fd, realpath)) {
985     *realpath += separator;
986   } else {
987     PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
988           normalized_path.c_str());
989     *realpath = normalized_path;
990   }
991 
992   return fd;
993 }
994 
format_path(char * buf,size_t buf_size,const char * path,const char * name)995 static bool format_path(char* buf, size_t buf_size, const char* path, const char* name) {
996   int n = __libc_format_buffer(buf, buf_size, "%s/%s", path, name);
997   if (n < 0 || n >= static_cast<int>(buf_size)) {
998     PRINT("Warning: ignoring very long library path: %s/%s", path, name);
999     return false;
1000   }
1001 
1002   return true;
1003 }
1004 
open_library_on_paths(ZipArchiveCache * zip_archive_cache,const char * name,off64_t * file_offset,const std::vector<std::string> & paths,std::string * realpath)1005 static int open_library_on_paths(ZipArchiveCache* zip_archive_cache,
1006                                  const char* name, off64_t* file_offset,
1007                                  const std::vector<std::string>& paths,
1008                                  std::string* realpath) {
1009   for (const auto& path : paths) {
1010     char buf[512];
1011     if (!format_path(buf, sizeof(buf), path.c_str(), name)) {
1012       continue;
1013     }
1014 
1015     int fd = -1;
1016     if (strstr(buf, kZipFileSeparator) != nullptr) {
1017       fd = open_library_in_zipfile(zip_archive_cache, buf, file_offset, realpath);
1018     }
1019 
1020     if (fd == -1) {
1021       fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC));
1022       if (fd != -1) {
1023         *file_offset = 0;
1024         if (!realpath_fd(fd, realpath)) {
1025           PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", buf);
1026           *realpath = buf;
1027         }
1028       }
1029     }
1030 
1031     if (fd != -1) {
1032       return fd;
1033     }
1034   }
1035 
1036   return -1;
1037 }
1038 
open_library(android_namespace_t * ns,ZipArchiveCache * zip_archive_cache,const char * name,soinfo * needed_by,off64_t * file_offset,std::string * realpath)1039 static int open_library(android_namespace_t* ns,
1040                         ZipArchiveCache* zip_archive_cache,
1041                         const char* name, soinfo *needed_by,
1042                         off64_t* file_offset, std::string* realpath) {
1043   TRACE("[ opening %s ]", name);
1044 
1045   // If the name contains a slash, we should attempt to open it directly and not search the paths.
1046   if (strchr(name, '/') != nullptr) {
1047     int fd = -1;
1048 
1049     if (strstr(name, kZipFileSeparator) != nullptr) {
1050       fd = open_library_in_zipfile(zip_archive_cache, name, file_offset, realpath);
1051     }
1052 
1053     if (fd == -1) {
1054       fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
1055       if (fd != -1) {
1056         *file_offset = 0;
1057         if (!realpath_fd(fd, realpath)) {
1058           PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", name);
1059           *realpath = name;
1060         }
1061       }
1062     }
1063 
1064     return fd;
1065   }
1066 
1067   // Otherwise we try LD_LIBRARY_PATH first, and fall back to the default library path
1068   int fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_ld_library_paths(), realpath);
1069   if (fd == -1 && needed_by != nullptr) {
1070     fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath);
1071     // Check if the library is accessible
1072     if (fd != -1 && !ns->is_accessible(*realpath)) {
1073       fd = -1;
1074     }
1075   }
1076 
1077   if (fd == -1) {
1078     fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
1079   }
1080 
1081   // TODO(dimitry): workaround for http://b/26394120 (the grey-list)
1082   if (fd == -1 && ns->is_greylist_enabled() && is_greylisted(ns, name, needed_by)) {
1083     // try searching for it on default_namespace default_library_path
1084     fd = open_library_on_paths(zip_archive_cache, name, file_offset,
1085                                g_default_namespace.get_default_library_paths(), realpath);
1086   }
1087   // END OF WORKAROUND
1088 
1089   return fd;
1090 }
1091 
fix_dt_needed(const char * dt_needed,const char * sopath __unused)1092 const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
1093 #if !defined(__LP64__)
1094   // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
1095   if (get_application_target_sdk_version() < __ANDROID_API_M__) {
1096     const char* bname = basename(dt_needed);
1097     if (bname != dt_needed) {
1098       DL_WARN("library \"%s\" has invalid DT_NEEDED entry \"%s\"", sopath, dt_needed);
1099       add_dlwarning(sopath, "invalid DT_NEEDED entry",  dt_needed);
1100     }
1101 
1102     return bname;
1103   }
1104 #endif
1105   return dt_needed;
1106 }
1107 
1108 template<typename F>
for_each_dt_needed(const ElfReader & elf_reader,F action)1109 static void for_each_dt_needed(const ElfReader& elf_reader, F action) {
1110   for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
1111     if (d->d_tag == DT_NEEDED) {
1112       action(fix_dt_needed(elf_reader.get_string(d->d_un.d_val), elf_reader.name()));
1113     }
1114   }
1115 }
1116 
find_loaded_library_by_inode(android_namespace_t * ns,const struct stat & file_stat,off64_t file_offset,bool search_linked_namespaces,soinfo ** candidate)1117 static bool find_loaded_library_by_inode(android_namespace_t* ns,
1118                                          const struct stat& file_stat,
1119                                          off64_t file_offset,
1120                                          bool search_linked_namespaces,
1121                                          soinfo** candidate) {
1122 
1123   auto predicate = [&](soinfo* si) {
1124     return si->get_st_dev() != 0 &&
1125            si->get_st_ino() != 0 &&
1126            si->get_st_dev() == file_stat.st_dev &&
1127            si->get_st_ino() == file_stat.st_ino &&
1128            si->get_file_offset() == file_offset;
1129   };
1130 
1131   *candidate = ns->soinfo_list().find_if(predicate);
1132 
1133   if (*candidate == nullptr && search_linked_namespaces) {
1134     for (auto& link : ns->linked_namespaces()) {
1135       android_namespace_t* linked_ns = link.linked_namespace();
1136       soinfo* si = linked_ns->soinfo_list().find_if(predicate);
1137 
1138       if (si != nullptr && link.is_accessible(si->get_soname())) {
1139         *candidate = si;
1140         return true;
1141       }
1142     }
1143   }
1144 
1145   return *candidate != nullptr;
1146 }
1147 
load_library(android_namespace_t * ns,LoadTask * task,LoadTaskList * load_tasks,int rtld_flags,const std::string & realpath,bool search_linked_namespaces)1148 static bool load_library(android_namespace_t* ns,
1149                          LoadTask* task,
1150                          LoadTaskList* load_tasks,
1151                          int rtld_flags,
1152                          const std::string& realpath,
1153                          bool search_linked_namespaces) {
1154   off64_t file_offset = task->get_file_offset();
1155   const char* name = task->get_name();
1156   const android_dlextinfo* extinfo = task->get_extinfo();
1157 
1158   if ((file_offset % PAGE_SIZE) != 0) {
1159     DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
1160     return false;
1161   }
1162   if (file_offset < 0) {
1163     DL_ERR("file offset for the library \"%s\" is negative: %" PRId64, name, file_offset);
1164     return false;
1165   }
1166 
1167   struct stat file_stat;
1168   if (TEMP_FAILURE_RETRY(fstat(task->get_fd(), &file_stat)) != 0) {
1169     DL_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
1170     return false;
1171   }
1172   if (file_offset >= file_stat.st_size) {
1173     DL_ERR("file offset for the library \"%s\" >= file size: %" PRId64 " >= %" PRId64,
1174         name, file_offset, file_stat.st_size);
1175     return false;
1176   }
1177 
1178   // Check for symlink and other situations where
1179   // file can have different names, unless ANDROID_DLEXT_FORCE_LOAD is set
1180   if (extinfo == nullptr || (extinfo->flags & ANDROID_DLEXT_FORCE_LOAD) == 0) {
1181     soinfo* si = nullptr;
1182     if (find_loaded_library_by_inode(ns, file_stat, file_offset, search_linked_namespaces, &si)) {
1183       TRACE("library \"%s\" is already loaded under different name/path \"%s\" - "
1184             "will return existing soinfo", name, si->get_realpath());
1185       task->set_soinfo(si);
1186       return true;
1187     }
1188   }
1189 
1190   if ((rtld_flags & RTLD_NOLOAD) != 0) {
1191     DL_ERR("library \"%s\" wasn't loaded and RTLD_NOLOAD prevented it", name);
1192     return false;
1193   }
1194 
1195   struct statfs fs_stat;
1196   if (TEMP_FAILURE_RETRY(fstatfs(task->get_fd(), &fs_stat)) != 0) {
1197     DL_ERR("unable to fstatfs file for the library \"%s\": %s", name, strerror(errno));
1198     return false;
1199   }
1200 
1201   // do not check accessibility using realpath if fd is located on tmpfs
1202   // this enables use of memfd_create() for apps
1203   if ((fs_stat.f_type != TMPFS_MAGIC) && (!ns->is_accessible(realpath))) {
1204     // TODO(dimitry): workaround for http://b/26394120 - the grey-list
1205 
1206     // TODO(dimitry) before O release: add a namespace attribute to have this enabled
1207     // only for classloader-namespaces
1208     const soinfo* needed_by = task->is_dt_needed() ? task->get_needed_by() : nullptr;
1209     if (is_greylisted(ns, name, needed_by)) {
1210       // print warning only if needed by non-system library
1211       if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) {
1212         const soinfo* needed_or_dlopened_by = task->get_needed_by();
1213         const char* sopath = needed_or_dlopened_by == nullptr ? "(unknown)" :
1214                                                       needed_or_dlopened_by->get_realpath();
1215         DL_WARN("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the namespace \"%s\""
1216                 " - the access is temporarily granted as a workaround for http://b/26394120, note that the access"
1217                 " will be removed in future releases of Android.",
1218                 name, realpath.c_str(), sopath, ns->get_name());
1219         add_dlwarning(sopath, "unauthorized access to",  name);
1220       }
1221     } else {
1222       // do not load libraries if they are not accessible for the specified namespace.
1223       const char* needed_or_dlopened_by = task->get_needed_by() == nullptr ?
1224                                           "(unknown)" :
1225                                           task->get_needed_by()->get_realpath();
1226 
1227       DL_ERR("library \"%s\" needed or dlopened by \"%s\" is not accessible for the namespace \"%s\"",
1228              name, needed_or_dlopened_by, ns->get_name());
1229 
1230       // do not print this if a library is in the list of shared libraries for linked namespaces
1231       if (!maybe_accessible_via_namespace_links(ns, name)) {
1232         PRINT("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the"
1233               " namespace: [name=\"%s\", ld_library_paths=\"%s\", default_library_paths=\"%s\","
1234               " permitted_paths=\"%s\"]",
1235               name, realpath.c_str(),
1236               needed_or_dlopened_by,
1237               ns->get_name(),
1238               android::base::Join(ns->get_ld_library_paths(), ':').c_str(),
1239               android::base::Join(ns->get_default_library_paths(), ':').c_str(),
1240               android::base::Join(ns->get_permitted_paths(), ':').c_str());
1241       }
1242       return false;
1243     }
1244   }
1245 
1246   soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);
1247   if (si == nullptr) {
1248     return false;
1249   }
1250 
1251   task->set_soinfo(si);
1252 
1253   // Read the ELF header and some of the segments.
1254   if (!task->read(realpath.c_str(), file_stat.st_size)) {
1255     soinfo_free(si);
1256     task->set_soinfo(nullptr);
1257     return false;
1258   }
1259 
1260   // find and set DT_RUNPATH and dt_soname
1261   // Note that these field values are temporary and are
1262   // going to be overwritten on soinfo::prelink_image
1263   // with values from PT_LOAD segments.
1264   const ElfReader& elf_reader = task->get_elf_reader();
1265   for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
1266     if (d->d_tag == DT_RUNPATH) {
1267       si->set_dt_runpath(elf_reader.get_string(d->d_un.d_val));
1268     }
1269     if (d->d_tag == DT_SONAME) {
1270       si->set_soname(elf_reader.get_string(d->d_un.d_val));
1271     }
1272   }
1273 
1274   for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
1275     load_tasks->push_back(LoadTask::create(name, si, task->get_readers_map()));
1276   });
1277 
1278   return true;
1279 }
1280 
load_library(android_namespace_t * ns,LoadTask * task,ZipArchiveCache * zip_archive_cache,LoadTaskList * load_tasks,int rtld_flags,bool search_linked_namespaces)1281 static bool load_library(android_namespace_t* ns,
1282                          LoadTask* task,
1283                          ZipArchiveCache* zip_archive_cache,
1284                          LoadTaskList* load_tasks,
1285                          int rtld_flags,
1286                          bool search_linked_namespaces) {
1287   const char* name = task->get_name();
1288   soinfo* needed_by = task->get_needed_by();
1289   const android_dlextinfo* extinfo = task->get_extinfo();
1290 
1291   off64_t file_offset;
1292   std::string realpath;
1293   if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
1294     file_offset = 0;
1295     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
1296       file_offset = extinfo->library_fd_offset;
1297     }
1298 
1299     if (!realpath_fd(extinfo->library_fd, &realpath)) {
1300       PRINT("warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
1301             "Will use given name.", name);
1302       realpath = name;
1303     }
1304 
1305     task->set_fd(extinfo->library_fd, false);
1306     task->set_file_offset(file_offset);
1307     return load_library(ns, task, load_tasks, rtld_flags, realpath, search_linked_namespaces);
1308   }
1309 
1310   // Open the file.
1311   int fd = open_library(ns, zip_archive_cache, name, needed_by, &file_offset, &realpath);
1312   if (fd == -1) {
1313     DL_ERR("library \"%s\" not found", name);
1314     return false;
1315   }
1316 
1317   task->set_fd(fd, true);
1318   task->set_file_offset(file_offset);
1319 
1320   return load_library(ns, task, load_tasks, rtld_flags, realpath, search_linked_namespaces);
1321 }
1322 
find_loaded_library_by_soname(android_namespace_t * ns,const char * name,soinfo ** candidate)1323 static bool find_loaded_library_by_soname(android_namespace_t* ns,
1324                                           const char* name,
1325                                           soinfo** candidate) {
1326   return !ns->soinfo_list().visit([&](soinfo* si) {
1327     const char* soname = si->get_soname();
1328     if (soname != nullptr && (strcmp(name, soname) == 0)) {
1329       *candidate = si;
1330       return false;
1331     }
1332 
1333     return true;
1334   });
1335 }
1336 
1337 // Returns true if library was found and false otherwise
find_loaded_library_by_soname(android_namespace_t * ns,const char * name,bool search_linked_namespaces,soinfo ** candidate)1338 static bool find_loaded_library_by_soname(android_namespace_t* ns,
1339                                          const char* name,
1340                                          bool search_linked_namespaces,
1341                                          soinfo** candidate) {
1342   *candidate = nullptr;
1343 
1344   // Ignore filename with path.
1345   if (strchr(name, '/') != nullptr) {
1346     return false;
1347   }
1348 
1349   bool found = find_loaded_library_by_soname(ns, name, candidate);
1350 
1351   if (!found && search_linked_namespaces) {
1352     // if a library was not found - look into linked namespaces
1353     for (auto& link : ns->linked_namespaces()) {
1354       if (!link.is_accessible(name)) {
1355         continue;
1356       }
1357 
1358       android_namespace_t* linked_ns = link.linked_namespace();
1359 
1360       if (find_loaded_library_by_soname(linked_ns, name, candidate)) {
1361         return true;
1362       }
1363     }
1364   }
1365 
1366   return found;
1367 }
1368 
find_library_in_linked_namespace(const android_namespace_link_t & namespace_link,LoadTask * task,int rtld_flags)1369 static bool find_library_in_linked_namespace(const android_namespace_link_t& namespace_link,
1370                                              LoadTask* task,
1371                                              int rtld_flags) {
1372   android_namespace_t* ns = namespace_link.linked_namespace();
1373 
1374   soinfo* candidate;
1375   bool loaded = false;
1376 
1377   std::string soname;
1378   if (find_loaded_library_by_soname(ns, task->get_name(), false, &candidate)) {
1379     loaded = true;
1380     soname = candidate->get_soname();
1381   } else {
1382     soname = resolve_soname(task->get_name());
1383   }
1384 
1385   if (!namespace_link.is_accessible(soname.c_str())) {
1386     // the library is not accessible via namespace_link
1387     return false;
1388   }
1389 
1390   // if library is already loaded - return it
1391   if (loaded) {
1392     task->set_soinfo(candidate);
1393     return true;
1394   }
1395 
1396   // try to load the library - once namespace boundary is crossed
1397   // we need to load a library within separate load_group
1398   // to avoid using symbols from foreign namespace while.
1399   //
1400   // All symbols during relocation should be resolved within a
1401   // namespace to preserve library locality to a namespace.
1402   const char* name = task->get_name();
1403   if (find_libraries(ns,
1404                      task->get_needed_by(),
1405                      &name,
1406                      1,
1407                      &candidate,
1408                      nullptr /* ld_preloads */,
1409                      0 /* ld_preload_count*/,
1410                      rtld_flags,
1411                      nullptr /* extinfo*/,
1412                      false /* add_as_children */,
1413                      false /* search_linked_namespaces */)) {
1414     task->set_soinfo(candidate);
1415     return true;
1416   }
1417 
1418   return false;
1419 }
1420 
find_library_internal(android_namespace_t * ns,LoadTask * task,ZipArchiveCache * zip_archive_cache,LoadTaskList * load_tasks,int rtld_flags,bool search_linked_namespaces)1421 static bool find_library_internal(android_namespace_t* ns,
1422                                   LoadTask* task,
1423                                   ZipArchiveCache* zip_archive_cache,
1424                                   LoadTaskList* load_tasks,
1425                                   int rtld_flags,
1426                                   bool search_linked_namespaces) {
1427   soinfo* candidate;
1428 
1429   if (find_loaded_library_by_soname(ns, task->get_name(), search_linked_namespaces, &candidate)) {
1430     task->set_soinfo(candidate);
1431     return true;
1432   }
1433 
1434   // Library might still be loaded, the accurate detection
1435   // of this fact is done by load_library.
1436   TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]",
1437       task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
1438 
1439   if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, search_linked_namespaces)) {
1440     return true;
1441   }
1442 
1443   if (search_linked_namespaces) {
1444     // if a library was not found - look into linked namespaces
1445     for (auto& linked_namespace : ns->linked_namespaces()) {
1446       if (find_library_in_linked_namespace(linked_namespace,
1447                                            task,
1448                                            rtld_flags)) {
1449         return true;
1450       }
1451     }
1452   }
1453 
1454   return false;
1455 }
1456 
1457 static void soinfo_unload(soinfo* si);
1458 static void soinfo_unload(soinfo* soinfos[], size_t count);
1459 
1460 // TODO: this is slightly unusual way to construct
1461 // the global group for relocation. Not every RTLD_GLOBAL
1462 // library is included in this group for backwards-compatibility
1463 // reasons.
1464 //
1465 // This group consists of the main executable, LD_PRELOADs
1466 // and libraries with the DF_1_GLOBAL flag set.
make_global_group(android_namespace_t * ns)1467 static soinfo_list_t make_global_group(android_namespace_t* ns) {
1468   soinfo_list_t global_group;
1469   ns->soinfo_list().for_each([&](soinfo* si) {
1470     if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
1471       global_group.push_back(si);
1472     }
1473   });
1474 
1475   return global_group;
1476 }
1477 
1478 // This function provides a list of libraries to be shared
1479 // by the namespace. For the default namespace this is the global
1480 // group (see make_global_group). For all others this is a group
1481 // of RTLD_GLOBAL libraries (which includes the global group from
1482 // the default namespace).
get_shared_group(android_namespace_t * ns)1483 static soinfo_list_t get_shared_group(android_namespace_t* ns) {
1484   if (ns == &g_default_namespace) {
1485     return make_global_group(ns);
1486   }
1487 
1488   soinfo_list_t shared_group;
1489   ns->soinfo_list().for_each([&](soinfo* si) {
1490     if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
1491       shared_group.push_back(si);
1492     }
1493   });
1494 
1495   return shared_group;
1496 }
1497 
shuffle(std::vector<LoadTask * > * v)1498 static void shuffle(std::vector<LoadTask*>* v) {
1499   for (size_t i = 0, size = v->size(); i < size; ++i) {
1500     size_t n = size - i;
1501     size_t r = arc4random_uniform(n);
1502     std::swap((*v)[n-1], (*v)[r]);
1503   }
1504 }
1505 
1506 // add_as_children - add first-level loaded libraries (i.e. library_names[], but
1507 // not their transitive dependencies) as children of the start_with library.
1508 // This is false when find_libraries is called for dlopen(), when newly loaded
1509 // libraries must form a disjoint tree.
find_libraries(android_namespace_t * ns,soinfo * start_with,const char * const library_names[],size_t library_names_count,soinfo * soinfos[],std::vector<soinfo * > * ld_preloads,size_t ld_preloads_count,int rtld_flags,const android_dlextinfo * extinfo,bool add_as_children,bool search_linked_namespaces)1510 bool find_libraries(android_namespace_t* ns,
1511                     soinfo* start_with,
1512                     const char* const library_names[],
1513                     size_t library_names_count,
1514                     soinfo* soinfos[],
1515                     std::vector<soinfo*>* ld_preloads,
1516                     size_t ld_preloads_count,
1517                     int rtld_flags,
1518                     const android_dlextinfo* extinfo,
1519                     bool add_as_children,
1520                     bool search_linked_namespaces) {
1521   // Step 0: prepare.
1522   LoadTaskList load_tasks;
1523   std::unordered_map<const soinfo*, ElfReader> readers_map;
1524 
1525   for (size_t i = 0; i < library_names_count; ++i) {
1526     const char* name = library_names[i];
1527     load_tasks.push_back(LoadTask::create(name, start_with, &readers_map));
1528   }
1529 
1530   // Construct global_group.
1531   soinfo_list_t global_group = make_global_group(ns);
1532 
1533   // If soinfos array is null allocate one on stack.
1534   // The array is needed in case of failure; for example
1535   // when library_names[] = {libone.so, libtwo.so} and libone.so
1536   // is loaded correctly but libtwo.so failed for some reason.
1537   // In this case libone.so should be unloaded on return.
1538   // See also implementation of failure_guard below.
1539 
1540   if (soinfos == nullptr) {
1541     size_t soinfos_size = sizeof(soinfo*)*library_names_count;
1542     soinfos = reinterpret_cast<soinfo**>(alloca(soinfos_size));
1543     memset(soinfos, 0, soinfos_size);
1544   }
1545 
1546   // list of libraries to link - see step 2.
1547   size_t soinfos_count = 0;
1548 
1549   auto scope_guard = make_scope_guard([&]() {
1550     for (LoadTask* t : load_tasks) {
1551       LoadTask::deleter(t);
1552     }
1553   });
1554 
1555   auto failure_guard = make_scope_guard([&]() {
1556     // Housekeeping
1557     soinfo_unload(soinfos, soinfos_count);
1558   });
1559 
1560   ZipArchiveCache zip_archive_cache;
1561 
1562   // Step 1: expand the list of load_tasks to include
1563   // all DT_NEEDED libraries (do not load them just yet)
1564   for (size_t i = 0; i<load_tasks.size(); ++i) {
1565     LoadTask* task = load_tasks[i];
1566     soinfo* needed_by = task->get_needed_by();
1567 
1568     bool is_dt_needed = needed_by != nullptr && (needed_by != start_with || add_as_children);
1569     task->set_extinfo(is_dt_needed ? nullptr : extinfo);
1570     task->set_dt_needed(is_dt_needed);
1571 
1572     if (!find_library_internal(ns,
1573                                task,
1574                                &zip_archive_cache,
1575                                &load_tasks,
1576                                rtld_flags,
1577                                search_linked_namespaces || is_dt_needed)) {
1578       return false;
1579     }
1580 
1581     soinfo* si = task->get_soinfo();
1582 
1583     if (is_dt_needed) {
1584       needed_by->add_child(si);
1585 
1586       if (si->is_linked()) {
1587         si->increment_ref_count();
1588       }
1589     }
1590 
1591     // When ld_preloads is not null, the first
1592     // ld_preloads_count libs are in fact ld_preloads.
1593     if (ld_preloads != nullptr && soinfos_count < ld_preloads_count) {
1594       ld_preloads->push_back(si);
1595     }
1596 
1597     if (soinfos_count < library_names_count) {
1598       soinfos[soinfos_count++] = si;
1599     }
1600   }
1601 
1602   // Step 2: Load libraries in random order (see b/24047022)
1603   LoadTaskList load_list;
1604   for (auto&& task : load_tasks) {
1605     soinfo* si = task->get_soinfo();
1606     auto pred = [&](const LoadTask* t) {
1607       return t->get_soinfo() == si;
1608     };
1609 
1610     if (!si->is_linked() &&
1611         std::find_if(load_list.begin(), load_list.end(), pred) == load_list.end() ) {
1612       load_list.push_back(task);
1613     }
1614   }
1615   shuffle(&load_list);
1616 
1617   for (auto&& task : load_list) {
1618     if (!task->load()) {
1619       return false;
1620     }
1621   }
1622 
1623   // Step 3: pre-link all DT_NEEDED libraries in breadth first order.
1624   for (auto&& task : load_tasks) {
1625     soinfo* si = task->get_soinfo();
1626     if (!si->is_linked() && !si->prelink_image()) {
1627       return false;
1628     }
1629   }
1630 
1631   // Step 4: Add LD_PRELOADed libraries to the global group for
1632   // future runs. There is no need to explicitly add them to
1633   // the global group for this run because they are going to
1634   // appear in the local group in the correct order.
1635   if (ld_preloads != nullptr) {
1636     for (auto&& si : *ld_preloads) {
1637       si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
1638     }
1639   }
1640 
1641 
1642   // Step 5: link libraries.
1643   soinfo_list_t local_group;
1644   walk_dependencies_tree(
1645       (start_with != nullptr && add_as_children) ? &start_with : soinfos,
1646       (start_with != nullptr && add_as_children) ? 1 : soinfos_count,
1647       [&] (soinfo* si) {
1648     if (ns->is_accessible(si)) {
1649       local_group.push_back(si);
1650       return kWalkContinue;
1651     } else {
1652       return kWalkSkip;
1653     }
1654   });
1655 
1656   bool linked = local_group.visit([&](soinfo* si) {
1657     if (!si->is_linked()) {
1658       if (!si->link_image(global_group, local_group, extinfo) ||
1659           !get_cfi_shadow()->AfterLoad(si, solist_get_head())) {
1660         return false;
1661       }
1662     }
1663 
1664     return true;
1665   });
1666 
1667   if (linked) {
1668     local_group.for_each([](soinfo* si) {
1669       if (!si->is_linked()) {
1670         si->set_linked();
1671       }
1672     });
1673 
1674     failure_guard.disable();
1675   }
1676 
1677   return linked;
1678 }
1679 
find_library(android_namespace_t * ns,const char * name,int rtld_flags,const android_dlextinfo * extinfo,soinfo * needed_by)1680 static soinfo* find_library(android_namespace_t* ns,
1681                             const char* name, int rtld_flags,
1682                             const android_dlextinfo* extinfo,
1683                             soinfo* needed_by) {
1684   soinfo* si;
1685 
1686   if (name == nullptr) {
1687     si = solist_get_somain();
1688   } else if (!find_libraries(ns,
1689                              needed_by,
1690                              &name,
1691                              1,
1692                              &si,
1693                              nullptr,
1694                              0,
1695                              rtld_flags,
1696                              extinfo,
1697                              false /* add_as_children */,
1698                              true /* search_linked_namespaces */)) {
1699     return nullptr;
1700   }
1701 
1702   si->increment_ref_count();
1703 
1704   return si;
1705 }
1706 
soinfo_unload(soinfo * root)1707 static void soinfo_unload(soinfo* root) {
1708   if (root->is_linked()) {
1709     root = root->get_local_group_root();
1710   }
1711 
1712   ScopedTrace trace((std::string("unload ") + root->get_realpath()).c_str());
1713 
1714   if (!root->can_unload()) {
1715     TRACE("not unloading \"%s\" - the binary is flagged with NODELETE", root->get_realpath());
1716     return;
1717   }
1718 
1719   soinfo_unload(&root, 1);
1720 }
1721 
soinfo_unload(soinfo * soinfos[],size_t count)1722 static void soinfo_unload(soinfo* soinfos[], size_t count) {
1723   // Note that the library can be loaded but not linked;
1724   // in which case there is no root but we still need
1725   // to walk the tree and unload soinfos involved.
1726   //
1727   // This happens on unsuccessful dlopen, when one of
1728   // the DT_NEEDED libraries could not be linked/found.
1729   if (count == 0) {
1730     return;
1731   }
1732 
1733   soinfo_list_t unload_list;
1734   for (size_t i = 0; i < count; ++i) {
1735     soinfo* si = soinfos[i];
1736 
1737     if (si->can_unload()) {
1738       size_t ref_count = si->is_linked() ? si->decrement_ref_count() : 0;
1739       if (ref_count == 0) {
1740         unload_list.push_back(si);
1741       } else {
1742         TRACE("not unloading '%s' group, decrementing ref_count to %zd",
1743             si->get_realpath(), ref_count);
1744       }
1745     } else {
1746       TRACE("not unloading '%s' - the binary is flagged with NODELETE", si->get_realpath());
1747       return;
1748     }
1749   }
1750 
1751   // This is used to identify soinfos outside of the load-group
1752   // note that we cannot have > 1 in the array and have any of them
1753   // linked. This is why we can safely use the first one.
1754   soinfo* root = soinfos[0];
1755 
1756   soinfo_list_t local_unload_list;
1757   soinfo_list_t external_unload_list;
1758   soinfo* si = nullptr;
1759 
1760   while ((si = unload_list.pop_front()) != nullptr) {
1761     if (local_unload_list.contains(si)) {
1762       continue;
1763     }
1764 
1765     local_unload_list.push_back(si);
1766 
1767     if (si->has_min_version(0)) {
1768       soinfo* child = nullptr;
1769       while ((child = si->get_children().pop_front()) != nullptr) {
1770         TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
1771             child->get_realpath(), child);
1772 
1773         child->get_parents().remove(si);
1774 
1775         if (local_unload_list.contains(child)) {
1776           continue;
1777         } else if (child->is_linked() && child->get_local_group_root() != root) {
1778           external_unload_list.push_back(child);
1779         } else if (child->get_parents().empty()) {
1780           unload_list.push_back(child);
1781         }
1782       }
1783     } else {
1784 #if !defined(__work_around_b_24465209__)
1785       __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
1786 #else
1787       PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
1788       for_each_dt_needed(si, [&] (const char* library_name) {
1789         TRACE("deprecated (old format of soinfo): %s needs to unload %s",
1790             si->get_realpath(), library_name);
1791 
1792         soinfo* needed = find_library(si->get_primary_namespace(),
1793                                       library_name, RTLD_NOLOAD, nullptr, nullptr);
1794 
1795         if (needed != nullptr) {
1796           // Not found: for example if symlink was deleted between dlopen and dlclose
1797           // Since we cannot really handle errors at this point - print and continue.
1798           PRINT("warning: couldn't find %s needed by %s on unload.",
1799               library_name, si->get_realpath());
1800           return;
1801         } else if (local_unload_list.contains(needed)) {
1802           // already visited
1803           return;
1804         } else if (needed->is_linked() && needed->get_local_group_root() != root) {
1805           // external group
1806           external_unload_list.push_back(needed);
1807         } else {
1808           // local group
1809           unload_list.push_front(needed);
1810         }
1811       });
1812 #endif
1813     }
1814   }
1815 
1816   local_unload_list.for_each([](soinfo* si) {
1817     si->call_destructors();
1818   });
1819 
1820   while ((si = local_unload_list.pop_front()) != nullptr) {
1821     notify_gdb_of_unload(si);
1822     get_cfi_shadow()->BeforeUnload(si);
1823     soinfo_free(si);
1824   }
1825 
1826   while ((si = external_unload_list.pop_front()) != nullptr) {
1827     soinfo_unload(si);
1828   }
1829 }
1830 
symbol_display_name(const char * sym_name,const char * sym_ver)1831 static std::string symbol_display_name(const char* sym_name, const char* sym_ver) {
1832   if (sym_ver == nullptr) {
1833     return sym_name;
1834   }
1835 
1836   return std::string(sym_name) + ", version " + sym_ver;
1837 }
1838 
get_caller_namespace(soinfo * caller)1839 static android_namespace_t* get_caller_namespace(soinfo* caller) {
1840   return caller != nullptr ? caller->get_primary_namespace() : g_anonymous_namespace;
1841 }
1842 
do_android_get_LD_LIBRARY_PATH(char * buffer,size_t buffer_size)1843 void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
1844   // Use basic string manipulation calls to avoid snprintf.
1845   // snprintf indirectly calls pthread_getspecific to get the size of a buffer.
1846   // When debug malloc is enabled, this call returns 0. This in turn causes
1847   // snprintf to do nothing, which causes libraries to fail to load.
1848   // See b/17302493 for further details.
1849   // Once the above bug is fixed, this code can be modified to use
1850   // snprintf again.
1851   const auto& default_ld_paths = g_default_namespace.get_default_library_paths();
1852 
1853   size_t required_size = 0;
1854   for (const auto& path : default_ld_paths) {
1855     required_size += path.size() + 1;
1856   }
1857 
1858   if (buffer_size < required_size) {
1859     __libc_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: "
1860                  "buffer len %zu, required len %zu", buffer_size, required_size);
1861   }
1862 
1863   char* end = buffer;
1864   for (size_t i = 0; i < default_ld_paths.size(); ++i) {
1865     if (i > 0) *end++ = ':';
1866     end = stpcpy(end, default_ld_paths[i].c_str());
1867   }
1868 }
1869 
do_android_update_LD_LIBRARY_PATH(const char * ld_library_path)1870 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
1871   parse_LD_LIBRARY_PATH(ld_library_path);
1872 }
1873 
android_dlextinfo_to_string(const android_dlextinfo * info)1874 static std::string android_dlextinfo_to_string(const android_dlextinfo* info) {
1875   if (info == nullptr) {
1876     return "(null)";
1877   }
1878 
1879   return android::base::StringPrintf("[flags=0x%" PRIx64 ","
1880                                      " reserved_addr=%p,"
1881                                      " reserved_size=0x%zx,"
1882                                      " relro_fd=%d,"
1883                                      " library_fd=%d,"
1884                                      " library_fd_offset=0x%" PRIx64 ","
1885                                      " library_namespace=%s@%p]",
1886                                      info->flags,
1887                                      info->reserved_addr,
1888                                      info->reserved_size,
1889                                      info->relro_fd,
1890                                      info->library_fd,
1891                                      info->library_fd_offset,
1892                                      (info->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0 ?
1893                                         (info->library_namespace != nullptr ?
1894                                           info->library_namespace->get_name() : "(null)") : "(n/a)",
1895                                      (info->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0 ?
1896                                         info->library_namespace : nullptr);
1897 }
1898 
do_dlopen(const char * name,int flags,const android_dlextinfo * extinfo,const void * caller_addr)1899 void* do_dlopen(const char* name, int flags,
1900                 const android_dlextinfo* extinfo,
1901                 const void* caller_addr) {
1902   std::string trace_prefix = std::string("dlopen: ") + (name == nullptr ? "(nullptr)" : name);
1903   ScopedTrace trace(trace_prefix.c_str());
1904   ScopedTrace loading_trace((trace_prefix + " - loading and linking").c_str());
1905   soinfo* const caller = find_containing_library(caller_addr);
1906   android_namespace_t* ns = get_caller_namespace(caller);
1907 
1908   LD_LOG(kLogDlopen,
1909          "dlopen(name=\"%s\", flags=0x%x, extinfo=%s, caller=\"%s\", caller_ns=%s@%p) ...",
1910          name,
1911          flags,
1912          android_dlextinfo_to_string(extinfo).c_str(),
1913          caller == nullptr ? "(null)" : caller->get_realpath(),
1914          ns == nullptr ? "(null)" : ns->get_name(),
1915          ns);
1916 
1917   auto failure_guard = make_scope_guard([&]() {
1918     LD_LOG(kLogDlopen, "... dlopen failed: %s", linker_get_error_buffer());
1919   });
1920 
1921   if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {
1922     DL_ERR("invalid flags to dlopen: %x", flags);
1923     return nullptr;
1924   }
1925 
1926   if (extinfo != nullptr) {
1927     if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {
1928       DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags);
1929       return nullptr;
1930     }
1931 
1932     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 &&
1933         (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
1934       DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without "
1935           "ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);
1936       return nullptr;
1937     }
1938 
1939     if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 &&
1940         (extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) {
1941       DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not "
1942              "compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT");
1943       return nullptr;
1944     }
1945 
1946     if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) {
1947       if (extinfo->library_namespace == nullptr) {
1948         DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null");
1949         return nullptr;
1950       }
1951       ns = extinfo->library_namespace;
1952     }
1953   }
1954 
1955   std::string asan_name_holder;
1956 
1957   const char* translated_name = name;
1958   if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') {
1959     char translated_path[PATH_MAX];
1960     if (realpath(translated_name, translated_path) != nullptr) {
1961       asan_name_holder = std::string(kAsanLibDirPrefix) + translated_path;
1962       if (file_exists(asan_name_holder.c_str())) {
1963         translated_name = asan_name_holder.c_str();
1964         PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
1965       }
1966     }
1967   }
1968 
1969   ProtectedDataGuard guard;
1970   soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
1971   loading_trace.End();
1972 
1973   if (si != nullptr) {
1974     void* handle = si->to_handle();
1975     LD_LOG(kLogDlopen,
1976            "... dlopen calling constructors: realpath=\"%s\", soname=\"%s\", handle=%p",
1977            si->get_realpath(), si->get_soname(), handle);
1978     si->call_constructors();
1979     failure_guard.disable();
1980     LD_LOG(kLogDlopen,
1981            "... dlopen successful: realpath=\"%s\", soname=\"%s\", handle=%p",
1982            si->get_realpath(), si->get_soname(), handle);
1983     return handle;
1984   }
1985 
1986   return nullptr;
1987 }
1988 
do_dladdr(const void * addr,Dl_info * info)1989 int do_dladdr(const void* addr, Dl_info* info) {
1990   // Determine if this address can be found in any library currently mapped.
1991   soinfo* si = find_containing_library(addr);
1992   if (si == nullptr) {
1993     return 0;
1994   }
1995 
1996   memset(info, 0, sizeof(Dl_info));
1997 
1998   info->dli_fname = si->get_realpath();
1999   // Address at which the shared object is loaded.
2000   info->dli_fbase = reinterpret_cast<void*>(si->base);
2001 
2002   // Determine if any symbol in the library contains the specified address.
2003   ElfW(Sym)* sym = si->find_symbol_by_address(addr);
2004   if (sym != nullptr) {
2005     info->dli_sname = si->get_string(sym->st_name);
2006     info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
2007   }
2008 
2009   return 1;
2010 }
2011 
soinfo_from_handle(void * handle)2012 static soinfo* soinfo_from_handle(void* handle) {
2013   if ((reinterpret_cast<uintptr_t>(handle) & 1) != 0) {
2014     auto it = g_soinfo_handles_map.find(reinterpret_cast<uintptr_t>(handle));
2015     if (it == g_soinfo_handles_map.end()) {
2016       return nullptr;
2017     } else {
2018       return it->second;
2019     }
2020   }
2021 
2022   return static_cast<soinfo*>(handle);
2023 }
2024 
do_dlsym(void * handle,const char * sym_name,const char * sym_ver,const void * caller_addr,void ** symbol)2025 bool do_dlsym(void* handle,
2026               const char* sym_name,
2027               const char* sym_ver,
2028               const void* caller_addr,
2029               void** symbol) {
2030   ScopedTrace trace("dlsym");
2031 #if !defined(__LP64__)
2032   if (handle == nullptr) {
2033     DL_ERR("dlsym failed: library handle is null");
2034     return false;
2035   }
2036 #endif
2037 
2038   soinfo* found = nullptr;
2039   const ElfW(Sym)* sym = nullptr;
2040   soinfo* caller = find_containing_library(caller_addr);
2041   android_namespace_t* ns = get_caller_namespace(caller);
2042   soinfo* si = nullptr;
2043   if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
2044     si = soinfo_from_handle(handle);
2045   }
2046 
2047   LD_LOG(kLogDlsym,
2048          "dlsym(handle=%p(\"%s\"), sym_name=\"%s\", sym_ver=\"%s\", caller=\"%s\", caller_ns=%s@%p) ...",
2049          handle,
2050          si != nullptr ? si->get_realpath() : "n/a",
2051          sym_name,
2052          sym_ver,
2053          caller == nullptr ? "(null)" : caller->get_realpath(),
2054          ns == nullptr ? "(null)" : ns->get_name(),
2055          ns);
2056 
2057   auto failure_guard = make_scope_guard([&]() {
2058     LD_LOG(kLogDlsym, "... dlsym failed: %s", linker_get_error_buffer());
2059   });
2060 
2061   if (sym_name == nullptr) {
2062     DL_ERR("dlsym failed: symbol name is null");
2063     return false;
2064   }
2065 
2066   version_info vi_instance;
2067   version_info* vi = nullptr;
2068 
2069   if (sym_ver != nullptr) {
2070     vi_instance.name = sym_ver;
2071     vi_instance.elf_hash = calculate_elf_hash(sym_ver);
2072     vi = &vi_instance;
2073   }
2074 
2075   if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
2076     sym = dlsym_linear_lookup(ns, sym_name, vi, &found, caller, handle);
2077   } else {
2078     if (si == nullptr) {
2079       DL_ERR("dlsym failed: invalid handle: %p", handle);
2080       return false;
2081     }
2082     sym = dlsym_handle_lookup(si, &found, sym_name, vi);
2083   }
2084 
2085   if (sym != nullptr) {
2086     uint32_t bind = ELF_ST_BIND(sym->st_info);
2087 
2088     if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
2089       *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
2090       failure_guard.disable();
2091       LD_LOG(kLogDlsym,
2092              "... dlsym successful: sym_name=\"%s\", sym_ver=\"%s\", found in=\"%s\", address=%p",
2093              sym_name, sym_ver, found->get_soname(), *symbol);
2094       return true;
2095     }
2096 
2097     DL_ERR("symbol \"%s\" found but not global", symbol_display_name(sym_name, sym_ver).c_str());
2098     return false;
2099   }
2100 
2101   DL_ERR("undefined symbol: %s", symbol_display_name(sym_name, sym_ver).c_str());
2102   return false;
2103 }
2104 
do_dlclose(void * handle)2105 int do_dlclose(void* handle) {
2106   ScopedTrace trace("dlclose");
2107   ProtectedDataGuard guard;
2108   soinfo* si = soinfo_from_handle(handle);
2109   if (si == nullptr) {
2110     DL_ERR("invalid handle: %p", handle);
2111     return -1;
2112   }
2113 
2114   soinfo_unload(si);
2115   return 0;
2116 }
2117 
init_anonymous_namespace(const char * shared_lib_sonames,const char * library_search_path)2118 bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path) {
2119   if (g_anonymous_namespace_initialized) {
2120     DL_ERR("anonymous namespace has already been initialized.");
2121     return false;
2122   }
2123 
2124   ProtectedDataGuard guard;
2125 
2126   // create anonymous namespace
2127   // When the caller is nullptr - create_namespace will take global group
2128   // from the anonymous namespace, which is fine because anonymous namespace
2129   // is still pointing to the default one.
2130   android_namespace_t* anon_ns =
2131       create_namespace(nullptr,
2132                        "(anonymous)",
2133                        nullptr,
2134                        library_search_path,
2135                        ANDROID_NAMESPACE_TYPE_ISOLATED,
2136                        nullptr,
2137                        &g_default_namespace);
2138 
2139   if (anon_ns == nullptr) {
2140     return false;
2141   }
2142 
2143   if (!link_namespaces(anon_ns, &g_default_namespace, shared_lib_sonames)) {
2144     return false;
2145   }
2146 
2147   g_anonymous_namespace = anon_ns;
2148   g_anonymous_namespace_initialized = true;
2149 
2150   return true;
2151 }
2152 
add_soinfos_to_namespace(const soinfo_list_t & soinfos,android_namespace_t * ns)2153 static void add_soinfos_to_namespace(const soinfo_list_t& soinfos, android_namespace_t* ns) {
2154   ns->add_soinfos(soinfos);
2155   for (auto si : soinfos) {
2156     si->add_secondary_namespace(ns);
2157   }
2158 }
2159 
create_namespace(const void * caller_addr,const char * name,const char * ld_library_path,const char * default_library_path,uint64_t type,const char * permitted_when_isolated_path,android_namespace_t * parent_namespace)2160 android_namespace_t* create_namespace(const void* caller_addr,
2161                                       const char* name,
2162                                       const char* ld_library_path,
2163                                       const char* default_library_path,
2164                                       uint64_t type,
2165                                       const char* permitted_when_isolated_path,
2166                                       android_namespace_t* parent_namespace) {
2167   if (parent_namespace == nullptr) {
2168     // if parent_namespace is nullptr -> set it to the caller namespace
2169     soinfo* caller_soinfo = find_containing_library(caller_addr);
2170 
2171     parent_namespace = caller_soinfo != nullptr ?
2172                        caller_soinfo->get_primary_namespace() :
2173                        g_anonymous_namespace;
2174   }
2175 
2176   ProtectedDataGuard guard;
2177   std::vector<std::string> ld_library_paths;
2178   std::vector<std::string> default_library_paths;
2179   std::vector<std::string> permitted_paths;
2180 
2181   parse_path(ld_library_path, ":", &ld_library_paths);
2182   parse_path(default_library_path, ":", &default_library_paths);
2183   parse_path(permitted_when_isolated_path, ":", &permitted_paths);
2184 
2185   android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
2186   ns->set_name(name);
2187   ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
2188   ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0);
2189 
2190   if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
2191     // append parent namespace paths.
2192     std::copy(parent_namespace->get_ld_library_paths().begin(),
2193               parent_namespace->get_ld_library_paths().end(),
2194               back_inserter(ld_library_paths));
2195 
2196     std::copy(parent_namespace->get_default_library_paths().begin(),
2197               parent_namespace->get_default_library_paths().end(),
2198               back_inserter(default_library_paths));
2199 
2200     std::copy(parent_namespace->get_permitted_paths().begin(),
2201               parent_namespace->get_permitted_paths().end(),
2202               back_inserter(permitted_paths));
2203 
2204     // If shared - clone the parent namespace
2205     add_soinfos_to_namespace(parent_namespace->soinfo_list(), ns);
2206     // and copy parent namespace links
2207     for (auto& link : parent_namespace->linked_namespaces()) {
2208       ns->add_linked_namespace(link.linked_namespace(), link.shared_lib_sonames());
2209     }
2210   } else {
2211     // If not shared - copy only the shared group
2212     add_soinfos_to_namespace(get_shared_group(parent_namespace), ns);
2213   }
2214 
2215   ns->set_ld_library_paths(std::move(ld_library_paths));
2216   ns->set_default_library_paths(std::move(default_library_paths));
2217   ns->set_permitted_paths(std::move(permitted_paths));
2218 
2219   return ns;
2220 }
2221 
link_namespaces(android_namespace_t * namespace_from,android_namespace_t * namespace_to,const char * shared_lib_sonames)2222 bool link_namespaces(android_namespace_t* namespace_from,
2223                      android_namespace_t* namespace_to,
2224                      const char* shared_lib_sonames) {
2225   if (namespace_to == nullptr) {
2226     namespace_to = &g_default_namespace;
2227   }
2228 
2229   if (namespace_from == nullptr) {
2230     DL_ERR("error linking namespaces: namespace_from is null.");
2231     return false;
2232   }
2233 
2234   if (shared_lib_sonames == nullptr || shared_lib_sonames[0] == '\0') {
2235     DL_ERR("error linking namespaces \"%s\"->\"%s\": the list of shared libraries is empty.",
2236            namespace_from->get_name(), namespace_to->get_name());
2237     return false;
2238   }
2239 
2240   auto sonames = android::base::Split(shared_lib_sonames, ":");
2241   std::unordered_set<std::string> sonames_set(sonames.begin(), sonames.end());
2242 
2243   ProtectedDataGuard guard;
2244   namespace_from->add_linked_namespace(namespace_to, sonames_set);
2245 
2246   return true;
2247 }
2248 
call_ifunc_resolver(ElfW (Addr)resolver_addr)2249 ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr) {
2250   typedef ElfW(Addr) (*ifunc_resolver_t)(void);
2251   ifunc_resolver_t ifunc_resolver = reinterpret_cast<ifunc_resolver_t>(resolver_addr);
2252   ElfW(Addr) ifunc_addr = ifunc_resolver();
2253   TRACE_TYPE(RELO, "Called ifunc_resolver@%p. The result is %p",
2254       ifunc_resolver, reinterpret_cast<void*>(ifunc_addr));
2255 
2256   return ifunc_addr;
2257 }
2258 
get_version_info(ElfW (Versym)source_symver) const2259 const version_info* VersionTracker::get_version_info(ElfW(Versym) source_symver) const {
2260   if (source_symver < 2 ||
2261       source_symver >= version_infos.size() ||
2262       version_infos[source_symver].name == nullptr) {
2263     return nullptr;
2264   }
2265 
2266   return &version_infos[source_symver];
2267 }
2268 
add_version_info(size_t source_index,ElfW (Word)elf_hash,const char * ver_name,const soinfo * target_si)2269 void VersionTracker::add_version_info(size_t source_index,
2270                                       ElfW(Word) elf_hash,
2271                                       const char* ver_name,
2272                                       const soinfo* target_si) {
2273   if (source_index >= version_infos.size()) {
2274     version_infos.resize(source_index+1);
2275   }
2276 
2277   version_infos[source_index].elf_hash = elf_hash;
2278   version_infos[source_index].name = ver_name;
2279   version_infos[source_index].target_si = target_si;
2280 }
2281 
init_verneed(const soinfo * si_from)2282 bool VersionTracker::init_verneed(const soinfo* si_from) {
2283   uintptr_t verneed_ptr = si_from->get_verneed_ptr();
2284 
2285   if (verneed_ptr == 0) {
2286     return true;
2287   }
2288 
2289   size_t verneed_cnt = si_from->get_verneed_cnt();
2290 
2291   for (size_t i = 0, offset = 0; i<verneed_cnt; ++i) {
2292     const ElfW(Verneed)* verneed = reinterpret_cast<ElfW(Verneed)*>(verneed_ptr + offset);
2293     size_t vernaux_offset = offset + verneed->vn_aux;
2294     offset += verneed->vn_next;
2295 
2296     if (verneed->vn_version != 1) {
2297       DL_ERR("unsupported verneed[%zd] vn_version: %d (expected 1)", i, verneed->vn_version);
2298       return false;
2299     }
2300 
2301     const char* target_soname = si_from->get_string(verneed->vn_file);
2302     // find it in dependencies
2303     soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) {
2304       return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0;
2305     });
2306 
2307     if (target_si == nullptr) {
2308       DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
2309           target_soname, i, si_from->get_realpath());
2310       return false;
2311     }
2312 
2313     for (size_t j = 0; j<verneed->vn_cnt; ++j) {
2314       const ElfW(Vernaux)* vernaux = reinterpret_cast<ElfW(Vernaux)*>(verneed_ptr + vernaux_offset);
2315       vernaux_offset += vernaux->vna_next;
2316 
2317       const ElfW(Word) elf_hash = vernaux->vna_hash;
2318       const char* ver_name = si_from->get_string(vernaux->vna_name);
2319       ElfW(Half) source_index = vernaux->vna_other;
2320 
2321       add_version_info(source_index, elf_hash, ver_name, target_si);
2322     }
2323   }
2324 
2325   return true;
2326 }
2327 
2328 template <typename F>
for_each_verdef(const soinfo * si,F functor)2329 static bool for_each_verdef(const soinfo* si, F functor) {
2330   if (!si->has_min_version(2)) {
2331     return true;
2332   }
2333 
2334   uintptr_t verdef_ptr = si->get_verdef_ptr();
2335   if (verdef_ptr == 0) {
2336     return true;
2337   }
2338 
2339   size_t offset = 0;
2340 
2341   size_t verdef_cnt = si->get_verdef_cnt();
2342   for (size_t i = 0; i<verdef_cnt; ++i) {
2343     const ElfW(Verdef)* verdef = reinterpret_cast<ElfW(Verdef)*>(verdef_ptr + offset);
2344     size_t verdaux_offset = offset + verdef->vd_aux;
2345     offset += verdef->vd_next;
2346 
2347     if (verdef->vd_version != 1) {
2348       DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
2349           i, verdef->vd_version, si->get_realpath());
2350       return false;
2351     }
2352 
2353     if ((verdef->vd_flags & VER_FLG_BASE) != 0) {
2354       // "this is the version of the file itself.  It must not be used for
2355       //  matching a symbol. It can be used to match references."
2356       //
2357       // http://www.akkadia.org/drepper/symbol-versioning
2358       continue;
2359     }
2360 
2361     if (verdef->vd_cnt == 0) {
2362       DL_ERR("invalid verdef[%zd] vd_cnt == 0 (version without a name)", i);
2363       return false;
2364     }
2365 
2366     const ElfW(Verdaux)* verdaux = reinterpret_cast<ElfW(Verdaux)*>(verdef_ptr + verdaux_offset);
2367 
2368     if (functor(i, verdef, verdaux) == true) {
2369       break;
2370     }
2371   }
2372 
2373   return true;
2374 }
2375 
find_verdef_version_index(const soinfo * si,const version_info * vi,ElfW (Versym)* versym)2376 bool find_verdef_version_index(const soinfo* si, const version_info* vi, ElfW(Versym)* versym) {
2377   if (vi == nullptr) {
2378     *versym = kVersymNotNeeded;
2379     return true;
2380   }
2381 
2382   *versym = kVersymGlobal;
2383 
2384   return for_each_verdef(si,
2385     [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
2386       if (verdef->vd_hash == vi->elf_hash &&
2387           strcmp(vi->name, si->get_string(verdaux->vda_name)) == 0) {
2388         *versym = verdef->vd_ndx;
2389         return true;
2390       }
2391 
2392       return false;
2393     }
2394   );
2395 }
2396 
init_verdef(const soinfo * si_from)2397 bool VersionTracker::init_verdef(const soinfo* si_from) {
2398   return for_each_verdef(si_from,
2399     [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
2400       add_version_info(verdef->vd_ndx, verdef->vd_hash,
2401           si_from->get_string(verdaux->vda_name), si_from);
2402       return false;
2403     }
2404   );
2405 }
2406 
init(const soinfo * si_from)2407 bool VersionTracker::init(const soinfo* si_from) {
2408   if (!si_from->has_min_version(2)) {
2409     return true;
2410   }
2411 
2412   return init_verneed(si_from) && init_verdef(si_from);
2413 }
2414 
2415 // TODO (dimitry): Methods below need to be moved out of soinfo
2416 // and in more isolated file in order minimize dependencies on
2417 // unnecessary object in the linker binary. Consider making them
2418 // independent from soinfo (?).
lookup_version_info(const VersionTracker & version_tracker,ElfW (Word)sym,const char * sym_name,const version_info ** vi)2419 bool soinfo::lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
2420                                  const char* sym_name, const version_info** vi) {
2421   const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
2422   ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
2423 
2424   if (sym_ver != VER_NDX_LOCAL && sym_ver != VER_NDX_GLOBAL) {
2425     *vi = version_tracker.get_version_info(sym_ver);
2426 
2427     if (*vi == nullptr) {
2428       DL_ERR("cannot find verneed/verdef for version index=%d "
2429           "referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_realpath());
2430       return false;
2431     }
2432   } else {
2433     // there is no version info
2434     *vi = nullptr;
2435   }
2436 
2437   return true;
2438 }
2439 
2440 #if !defined(__mips__)
2441 #if defined(USE_RELA)
get_addend(ElfW (Rela)* rela,ElfW (Addr)reloc_addr __unused)2442 static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr __unused) {
2443   return rela->r_addend;
2444 }
2445 #else
get_addend(ElfW (Rel)* rel,ElfW (Addr)reloc_addr)2446 static ElfW(Addr) get_addend(ElfW(Rel)* rel, ElfW(Addr) reloc_addr) {
2447   if (ELFW(R_TYPE)(rel->r_info) == R_GENERIC_RELATIVE ||
2448       ELFW(R_TYPE)(rel->r_info) == R_GENERIC_IRELATIVE) {
2449     return *reinterpret_cast<ElfW(Addr)*>(reloc_addr);
2450   }
2451   return 0;
2452 }
2453 #endif
2454 
2455 template<typename ElfRelIteratorT>
relocate(const VersionTracker & version_tracker,ElfRelIteratorT && rel_iterator,const soinfo_list_t & global_group,const soinfo_list_t & local_group)2456 bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
2457                       const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
2458   for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
2459     const auto rel = rel_iterator.next();
2460     if (rel == nullptr) {
2461       return false;
2462     }
2463 
2464     ElfW(Word) type = ELFW(R_TYPE)(rel->r_info);
2465     ElfW(Word) sym = ELFW(R_SYM)(rel->r_info);
2466 
2467     ElfW(Addr) reloc = static_cast<ElfW(Addr)>(rel->r_offset + load_bias);
2468     ElfW(Addr) sym_addr = 0;
2469     const char* sym_name = nullptr;
2470     ElfW(Addr) addend = get_addend(rel, reloc);
2471 
2472     DEBUG("Processing \"%s\" relocation at index %zd", get_realpath(), idx);
2473     if (type == R_GENERIC_NONE) {
2474       continue;
2475     }
2476 
2477     const ElfW(Sym)* s = nullptr;
2478     soinfo* lsi = nullptr;
2479 
2480     if (sym != 0) {
2481       sym_name = get_string(symtab_[sym].st_name);
2482       const version_info* vi = nullptr;
2483 
2484       if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
2485         return false;
2486       }
2487 
2488       if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
2489         return false;
2490       }
2491 
2492       if (s == nullptr) {
2493         // We only allow an undefined symbol if this is a weak reference...
2494         s = &symtab_[sym];
2495         if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
2496           DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
2497           return false;
2498         }
2499 
2500         /* IHI0044C AAELF 4.5.1.1:
2501 
2502            Libraries are not searched to resolve weak references.
2503            It is not an error for a weak reference to remain unsatisfied.
2504 
2505            During linking, the value of an undefined weak reference is:
2506            - Zero if the relocation type is absolute
2507            - The address of the place if the relocation is pc-relative
2508            - The address of nominal base address if the relocation
2509              type is base-relative.
2510          */
2511 
2512         switch (type) {
2513           case R_GENERIC_JUMP_SLOT:
2514           case R_GENERIC_GLOB_DAT:
2515           case R_GENERIC_RELATIVE:
2516           case R_GENERIC_IRELATIVE:
2517 #if defined(__aarch64__)
2518           case R_AARCH64_ABS64:
2519           case R_AARCH64_ABS32:
2520           case R_AARCH64_ABS16:
2521 #elif defined(__x86_64__)
2522           case R_X86_64_32:
2523           case R_X86_64_64:
2524 #elif defined(__arm__)
2525           case R_ARM_ABS32:
2526 #elif defined(__i386__)
2527           case R_386_32:
2528 #endif
2529             /*
2530              * The sym_addr was initialized to be zero above, or the relocation
2531              * code below does not care about value of sym_addr.
2532              * No need to do anything.
2533              */
2534             break;
2535 #if defined(__x86_64__)
2536           case R_X86_64_PC32:
2537             sym_addr = reloc;
2538             break;
2539 #elif defined(__i386__)
2540           case R_386_PC32:
2541             sym_addr = reloc;
2542             break;
2543 #endif
2544           default:
2545             DL_ERR("unknown weak reloc type %d @ %p (%zu)", type, rel, idx);
2546             return false;
2547         }
2548       } else { // We got a definition.
2549 #if !defined(__LP64__)
2550         // When relocating dso with text_relocation .text segment is
2551         // not executable. We need to restore elf flags before resolving
2552         // STT_GNU_IFUNC symbol.
2553         bool protect_segments = has_text_relocations &&
2554                                 lsi == this &&
2555                                 ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC;
2556         if (protect_segments) {
2557           if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
2558             DL_ERR("can't protect segments for \"%s\": %s",
2559                    get_realpath(), strerror(errno));
2560             return false;
2561           }
2562         }
2563 #endif
2564         sym_addr = lsi->resolve_symbol_address(s);
2565 #if !defined(__LP64__)
2566         if (protect_segments) {
2567           if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
2568             DL_ERR("can't unprotect loadable segments for \"%s\": %s",
2569                    get_realpath(), strerror(errno));
2570             return false;
2571           }
2572         }
2573 #endif
2574       }
2575       count_relocation(kRelocSymbol);
2576     }
2577 
2578     switch (type) {
2579       case R_GENERIC_JUMP_SLOT:
2580         count_relocation(kRelocAbsolute);
2581         MARK(rel->r_offset);
2582         TRACE_TYPE(RELO, "RELO JMP_SLOT %16p <- %16p %s\n",
2583                    reinterpret_cast<void*>(reloc),
2584                    reinterpret_cast<void*>(sym_addr + addend), sym_name);
2585 
2586         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
2587         break;
2588       case R_GENERIC_GLOB_DAT:
2589         count_relocation(kRelocAbsolute);
2590         MARK(rel->r_offset);
2591         TRACE_TYPE(RELO, "RELO GLOB_DAT %16p <- %16p %s\n",
2592                    reinterpret_cast<void*>(reloc),
2593                    reinterpret_cast<void*>(sym_addr + addend), sym_name);
2594         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
2595         break;
2596       case R_GENERIC_RELATIVE:
2597         count_relocation(kRelocRelative);
2598         MARK(rel->r_offset);
2599         TRACE_TYPE(RELO, "RELO RELATIVE %16p <- %16p\n",
2600                    reinterpret_cast<void*>(reloc),
2601                    reinterpret_cast<void*>(load_bias + addend));
2602         *reinterpret_cast<ElfW(Addr)*>(reloc) = (load_bias + addend);
2603         break;
2604       case R_GENERIC_IRELATIVE:
2605         count_relocation(kRelocRelative);
2606         MARK(rel->r_offset);
2607         TRACE_TYPE(RELO, "RELO IRELATIVE %16p <- %16p\n",
2608                     reinterpret_cast<void*>(reloc),
2609                     reinterpret_cast<void*>(load_bias + addend));
2610         {
2611 #if !defined(__LP64__)
2612           // When relocating dso with text_relocation .text segment is
2613           // not executable. We need to restore elf flags for this
2614           // particular call.
2615           if (has_text_relocations) {
2616             if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
2617               DL_ERR("can't protect segments for \"%s\": %s",
2618                      get_realpath(), strerror(errno));
2619               return false;
2620             }
2621           }
2622 #endif
2623           ElfW(Addr) ifunc_addr = call_ifunc_resolver(load_bias + addend);
2624 #if !defined(__LP64__)
2625           // Unprotect it afterwards...
2626           if (has_text_relocations) {
2627             if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
2628               DL_ERR("can't unprotect loadable segments for \"%s\": %s",
2629                      get_realpath(), strerror(errno));
2630               return false;
2631             }
2632           }
2633 #endif
2634           *reinterpret_cast<ElfW(Addr)*>(reloc) = ifunc_addr;
2635         }
2636         break;
2637 
2638 #if defined(__aarch64__)
2639       case R_AARCH64_ABS64:
2640         count_relocation(kRelocAbsolute);
2641         MARK(rel->r_offset);
2642         TRACE_TYPE(RELO, "RELO ABS64 %16llx <- %16llx %s\n",
2643                    reloc, sym_addr + addend, sym_name);
2644         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
2645         break;
2646       case R_AARCH64_ABS32:
2647         count_relocation(kRelocAbsolute);
2648         MARK(rel->r_offset);
2649         TRACE_TYPE(RELO, "RELO ABS32 %16llx <- %16llx %s\n",
2650                    reloc, sym_addr + addend, sym_name);
2651         {
2652           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
2653           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
2654           if ((min_value <= (sym_addr + addend)) &&
2655               ((sym_addr + addend) <= max_value)) {
2656             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
2657           } else {
2658             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
2659                    sym_addr + addend, min_value, max_value);
2660             return false;
2661           }
2662         }
2663         break;
2664       case R_AARCH64_ABS16:
2665         count_relocation(kRelocAbsolute);
2666         MARK(rel->r_offset);
2667         TRACE_TYPE(RELO, "RELO ABS16 %16llx <- %16llx %s\n",
2668                    reloc, sym_addr + addend, sym_name);
2669         {
2670           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
2671           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
2672           if ((min_value <= (sym_addr + addend)) &&
2673               ((sym_addr + addend) <= max_value)) {
2674             *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
2675           } else {
2676             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
2677                    sym_addr + addend, min_value, max_value);
2678             return false;
2679           }
2680         }
2681         break;
2682       case R_AARCH64_PREL64:
2683         count_relocation(kRelocRelative);
2684         MARK(rel->r_offset);
2685         TRACE_TYPE(RELO, "RELO REL64 %16llx <- %16llx - %16llx %s\n",
2686                    reloc, sym_addr + addend, rel->r_offset, sym_name);
2687         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
2688         break;
2689       case R_AARCH64_PREL32:
2690         count_relocation(kRelocRelative);
2691         MARK(rel->r_offset);
2692         TRACE_TYPE(RELO, "RELO REL32 %16llx <- %16llx - %16llx %s\n",
2693                    reloc, sym_addr + addend, rel->r_offset, sym_name);
2694         {
2695           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
2696           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
2697           if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
2698               ((sym_addr + addend - rel->r_offset) <= max_value)) {
2699             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
2700           } else {
2701             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
2702                    sym_addr + addend - rel->r_offset, min_value, max_value);
2703             return false;
2704           }
2705         }
2706         break;
2707       case R_AARCH64_PREL16:
2708         count_relocation(kRelocRelative);
2709         MARK(rel->r_offset);
2710         TRACE_TYPE(RELO, "RELO REL16 %16llx <- %16llx - %16llx %s\n",
2711                    reloc, sym_addr + addend, rel->r_offset, sym_name);
2712         {
2713           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
2714           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
2715           if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
2716               ((sym_addr + addend - rel->r_offset) <= max_value)) {
2717             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
2718           } else {
2719             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
2720                    sym_addr + addend - rel->r_offset, min_value, max_value);
2721             return false;
2722           }
2723         }
2724         break;
2725 
2726       case R_AARCH64_COPY:
2727         /*
2728          * ET_EXEC is not supported so this should not happen.
2729          *
2730          * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
2731          *
2732          * Section 4.6.11 "Dynamic relocations"
2733          * R_AARCH64_COPY may only appear in executable objects where e_type is
2734          * set to ET_EXEC.
2735          */
2736         DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
2737         return false;
2738       case R_AARCH64_TLS_TPREL64:
2739         TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
2740                    reloc, (sym_addr + addend), rel->r_offset);
2741         break;
2742       case R_AARCH64_TLS_DTPREL32:
2743         TRACE_TYPE(RELO, "RELO TLS_DTPREL32 *** %16llx <- %16llx - %16llx\n",
2744                    reloc, (sym_addr + addend), rel->r_offset);
2745         break;
2746 #elif defined(__x86_64__)
2747       case R_X86_64_32:
2748         count_relocation(kRelocRelative);
2749         MARK(rel->r_offset);
2750         TRACE_TYPE(RELO, "RELO R_X86_64_32 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
2751                    static_cast<size_t>(sym_addr), sym_name);
2752         *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend;
2753         break;
2754       case R_X86_64_64:
2755         count_relocation(kRelocRelative);
2756         MARK(rel->r_offset);
2757         TRACE_TYPE(RELO, "RELO R_X86_64_64 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
2758                    static_cast<size_t>(sym_addr), sym_name);
2759         *reinterpret_cast<Elf64_Addr*>(reloc) = sym_addr + addend;
2760         break;
2761       case R_X86_64_PC32:
2762         count_relocation(kRelocRelative);
2763         MARK(rel->r_offset);
2764         TRACE_TYPE(RELO, "RELO R_X86_64_PC32 %08zx <- +%08zx (%08zx - %08zx) %s",
2765                    static_cast<size_t>(reloc), static_cast<size_t>(sym_addr - reloc),
2766                    static_cast<size_t>(sym_addr), static_cast<size_t>(reloc), sym_name);
2767         *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend - reloc;
2768         break;
2769 #elif defined(__arm__)
2770       case R_ARM_ABS32:
2771         count_relocation(kRelocAbsolute);
2772         MARK(rel->r_offset);
2773         TRACE_TYPE(RELO, "RELO ABS %08x <- %08x %s", reloc, sym_addr, sym_name);
2774         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
2775         break;
2776       case R_ARM_REL32:
2777         count_relocation(kRelocRelative);
2778         MARK(rel->r_offset);
2779         TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x - %08x %s",
2780                    reloc, sym_addr, rel->r_offset, sym_name);
2781         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr - rel->r_offset;
2782         break;
2783       case R_ARM_COPY:
2784         /*
2785          * ET_EXEC is not supported so this should not happen.
2786          *
2787          * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
2788          *
2789          * Section 4.6.1.10 "Dynamic relocations"
2790          * R_ARM_COPY may only appear in executable objects where e_type is
2791          * set to ET_EXEC.
2792          */
2793         DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
2794         return false;
2795 #elif defined(__i386__)
2796       case R_386_32:
2797         count_relocation(kRelocRelative);
2798         MARK(rel->r_offset);
2799         TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s", reloc, sym_addr, sym_name);
2800         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
2801         break;
2802       case R_386_PC32:
2803         count_relocation(kRelocRelative);
2804         MARK(rel->r_offset);
2805         TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s",
2806                    reloc, (sym_addr - reloc), sym_addr, reloc, sym_name);
2807         *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr - reloc);
2808         break;
2809 #endif
2810       default:
2811         DL_ERR("unknown reloc type %d @ %p (%zu)", type, rel, idx);
2812         return false;
2813     }
2814   }
2815   return true;
2816 }
2817 #endif  // !defined(__mips__)
2818 
2819 // An empty list of soinfos
2820 static soinfo_list_t g_empty_list;
2821 
prelink_image()2822 bool soinfo::prelink_image() {
2823   /* Extract dynamic section */
2824   ElfW(Word) dynamic_flags = 0;
2825   phdr_table_get_dynamic_section(phdr, phnum, load_bias, &dynamic, &dynamic_flags);
2826 
2827   /* We can't log anything until the linker is relocated */
2828   bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
2829   if (!relocating_linker) {
2830     INFO("[ Linking \"%s\" ]", get_realpath());
2831     DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
2832   }
2833 
2834   if (dynamic == nullptr) {
2835     if (!relocating_linker) {
2836       DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
2837     }
2838     return false;
2839   } else {
2840     if (!relocating_linker) {
2841       DEBUG("dynamic = %p", dynamic);
2842     }
2843   }
2844 
2845 #if defined(__arm__)
2846   (void) phdr_table_get_arm_exidx(phdr, phnum, load_bias,
2847                                   &ARM_exidx, &ARM_exidx_count);
2848 #endif
2849 
2850   // Extract useful information from dynamic section.
2851   // Note that: "Except for the DT_NULL element at the end of the array,
2852   // and the relative order of DT_NEEDED elements, entries may appear in any order."
2853   //
2854   // source: http://www.sco.com/developers/gabi/1998-04-29/ch5.dynamic.html
2855   uint32_t needed_count = 0;
2856   for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
2857     DEBUG("d = %p, d[0](tag) = %p d[1](val) = %p",
2858           d, reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
2859     switch (d->d_tag) {
2860       case DT_SONAME:
2861         // this is parsed after we have strtab initialized (see below).
2862         break;
2863 
2864       case DT_HASH:
2865         nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
2866         nchain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
2867         bucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8);
2868         chain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8 + nbucket_ * 4);
2869         break;
2870 
2871       case DT_GNU_HASH:
2872         gnu_nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
2873         // skip symndx
2874         gnu_maskwords_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[2];
2875         gnu_shift2_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[3];
2876 
2877         gnu_bloom_filter_ = reinterpret_cast<ElfW(Addr)*>(load_bias + d->d_un.d_ptr + 16);
2878         gnu_bucket_ = reinterpret_cast<uint32_t*>(gnu_bloom_filter_ + gnu_maskwords_);
2879         // amend chain for symndx = header[1]
2880         gnu_chain_ = gnu_bucket_ + gnu_nbucket_ -
2881             reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
2882 
2883         if (!powerof2(gnu_maskwords_)) {
2884           DL_ERR("invalid maskwords for gnu_hash = 0x%x, in \"%s\" expecting power to two",
2885               gnu_maskwords_, get_realpath());
2886           return false;
2887         }
2888         --gnu_maskwords_;
2889 
2890         flags_ |= FLAG_GNU_HASH;
2891         break;
2892 
2893       case DT_STRTAB:
2894         strtab_ = reinterpret_cast<const char*>(load_bias + d->d_un.d_ptr);
2895         break;
2896 
2897       case DT_STRSZ:
2898         strtab_size_ = d->d_un.d_val;
2899         break;
2900 
2901       case DT_SYMTAB:
2902         symtab_ = reinterpret_cast<ElfW(Sym)*>(load_bias + d->d_un.d_ptr);
2903         break;
2904 
2905       case DT_SYMENT:
2906         if (d->d_un.d_val != sizeof(ElfW(Sym))) {
2907           DL_ERR("invalid DT_SYMENT: %zd in \"%s\"",
2908               static_cast<size_t>(d->d_un.d_val), get_realpath());
2909           return false;
2910         }
2911         break;
2912 
2913       case DT_PLTREL:
2914 #if defined(USE_RELA)
2915         if (d->d_un.d_val != DT_RELA) {
2916           DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_RELA", get_realpath());
2917           return false;
2918         }
2919 #else
2920         if (d->d_un.d_val != DT_REL) {
2921           DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_REL", get_realpath());
2922           return false;
2923         }
2924 #endif
2925         break;
2926 
2927       case DT_JMPREL:
2928 #if defined(USE_RELA)
2929         plt_rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
2930 #else
2931         plt_rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
2932 #endif
2933         break;
2934 
2935       case DT_PLTRELSZ:
2936 #if defined(USE_RELA)
2937         plt_rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
2938 #else
2939         plt_rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
2940 #endif
2941         break;
2942 
2943       case DT_PLTGOT:
2944 #if defined(__mips__)
2945         // Used by mips and mips64.
2946         plt_got_ = reinterpret_cast<ElfW(Addr)**>(load_bias + d->d_un.d_ptr);
2947 #endif
2948         // Ignore for other platforms... (because RTLD_LAZY is not supported)
2949         break;
2950 
2951       case DT_DEBUG:
2952         // Set the DT_DEBUG entry to the address of _r_debug for GDB
2953         // if the dynamic table is writable
2954 // FIXME: not working currently for N64
2955 // The flags for the LOAD and DYNAMIC program headers do not agree.
2956 // The LOAD section containing the dynamic table has been mapped as
2957 // read-only, but the DYNAMIC header claims it is writable.
2958 #if !(defined(__mips__) && defined(__LP64__))
2959         if ((dynamic_flags & PF_W) != 0) {
2960           d->d_un.d_val = reinterpret_cast<uintptr_t>(&_r_debug);
2961         }
2962 #endif
2963         break;
2964 #if defined(USE_RELA)
2965       case DT_RELA:
2966         rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
2967         break;
2968 
2969       case DT_RELASZ:
2970         rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
2971         break;
2972 
2973       case DT_ANDROID_RELA:
2974         android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
2975         break;
2976 
2977       case DT_ANDROID_RELASZ:
2978         android_relocs_size_ = d->d_un.d_val;
2979         break;
2980 
2981       case DT_ANDROID_REL:
2982         DL_ERR("unsupported DT_ANDROID_REL in \"%s\"", get_realpath());
2983         return false;
2984 
2985       case DT_ANDROID_RELSZ:
2986         DL_ERR("unsupported DT_ANDROID_RELSZ in \"%s\"", get_realpath());
2987         return false;
2988 
2989       case DT_RELAENT:
2990         if (d->d_un.d_val != sizeof(ElfW(Rela))) {
2991           DL_ERR("invalid DT_RELAENT: %zd", static_cast<size_t>(d->d_un.d_val));
2992           return false;
2993         }
2994         break;
2995 
2996       // ignored (see DT_RELCOUNT comments for details)
2997       case DT_RELACOUNT:
2998         break;
2999 
3000       case DT_REL:
3001         DL_ERR("unsupported DT_REL in \"%s\"", get_realpath());
3002         return false;
3003 
3004       case DT_RELSZ:
3005         DL_ERR("unsupported DT_RELSZ in \"%s\"", get_realpath());
3006         return false;
3007 
3008 #else
3009       case DT_REL:
3010         rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
3011         break;
3012 
3013       case DT_RELSZ:
3014         rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
3015         break;
3016 
3017       case DT_RELENT:
3018         if (d->d_un.d_val != sizeof(ElfW(Rel))) {
3019           DL_ERR("invalid DT_RELENT: %zd", static_cast<size_t>(d->d_un.d_val));
3020           return false;
3021         }
3022         break;
3023 
3024       case DT_ANDROID_REL:
3025         android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
3026         break;
3027 
3028       case DT_ANDROID_RELSZ:
3029         android_relocs_size_ = d->d_un.d_val;
3030         break;
3031 
3032       case DT_ANDROID_RELA:
3033         DL_ERR("unsupported DT_ANDROID_RELA in \"%s\"", get_realpath());
3034         return false;
3035 
3036       case DT_ANDROID_RELASZ:
3037         DL_ERR("unsupported DT_ANDROID_RELASZ in \"%s\"", get_realpath());
3038         return false;
3039 
3040       // "Indicates that all RELATIVE relocations have been concatenated together,
3041       // and specifies the RELATIVE relocation count."
3042       //
3043       // TODO: Spec also mentions that this can be used to optimize relocation process;
3044       // Not currently used by bionic linker - ignored.
3045       case DT_RELCOUNT:
3046         break;
3047 
3048       case DT_RELA:
3049         DL_ERR("unsupported DT_RELA in \"%s\"", get_realpath());
3050         return false;
3051 
3052       case DT_RELASZ:
3053         DL_ERR("unsupported DT_RELASZ in \"%s\"", get_realpath());
3054         return false;
3055 
3056 #endif
3057       case DT_INIT:
3058         init_func_ = reinterpret_cast<linker_ctor_function_t>(load_bias + d->d_un.d_ptr);
3059         DEBUG("%s constructors (DT_INIT) found at %p", get_realpath(), init_func_);
3060         break;
3061 
3062       case DT_FINI:
3063         fini_func_ = reinterpret_cast<linker_dtor_function_t>(load_bias + d->d_un.d_ptr);
3064         DEBUG("%s destructors (DT_FINI) found at %p", get_realpath(), fini_func_);
3065         break;
3066 
3067       case DT_INIT_ARRAY:
3068         init_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
3069         DEBUG("%s constructors (DT_INIT_ARRAY) found at %p", get_realpath(), init_array_);
3070         break;
3071 
3072       case DT_INIT_ARRAYSZ:
3073         init_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
3074         break;
3075 
3076       case DT_FINI_ARRAY:
3077         fini_array_ = reinterpret_cast<linker_dtor_function_t*>(load_bias + d->d_un.d_ptr);
3078         DEBUG("%s destructors (DT_FINI_ARRAY) found at %p", get_realpath(), fini_array_);
3079         break;
3080 
3081       case DT_FINI_ARRAYSZ:
3082         fini_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
3083         break;
3084 
3085       case DT_PREINIT_ARRAY:
3086         preinit_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
3087         DEBUG("%s constructors (DT_PREINIT_ARRAY) found at %p", get_realpath(), preinit_array_);
3088         break;
3089 
3090       case DT_PREINIT_ARRAYSZ:
3091         preinit_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
3092         break;
3093 
3094       case DT_TEXTREL:
3095 #if defined(__LP64__)
3096         DL_ERR("\"%s\" has text relocations", get_realpath());
3097         return false;
3098 #else
3099         has_text_relocations = true;
3100         break;
3101 #endif
3102 
3103       case DT_SYMBOLIC:
3104         has_DT_SYMBOLIC = true;
3105         break;
3106 
3107       case DT_NEEDED:
3108         ++needed_count;
3109         break;
3110 
3111       case DT_FLAGS:
3112         if (d->d_un.d_val & DF_TEXTREL) {
3113 #if defined(__LP64__)
3114           DL_ERR("\"%s\" has text relocations", get_realpath());
3115           return false;
3116 #else
3117           has_text_relocations = true;
3118 #endif
3119         }
3120         if (d->d_un.d_val & DF_SYMBOLIC) {
3121           has_DT_SYMBOLIC = true;
3122         }
3123         break;
3124 
3125       case DT_FLAGS_1:
3126         set_dt_flags_1(d->d_un.d_val);
3127 
3128         if ((d->d_un.d_val & ~SUPPORTED_DT_FLAGS_1) != 0) {
3129           DL_WARN("\"%s\" has unsupported flags DT_FLAGS_1=%p", get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
3130         }
3131         break;
3132 #if defined(__mips__)
3133       case DT_MIPS_RLD_MAP:
3134         // Set the DT_MIPS_RLD_MAP entry to the address of _r_debug for GDB.
3135         {
3136           r_debug** dp = reinterpret_cast<r_debug**>(load_bias + d->d_un.d_ptr);
3137           *dp = &_r_debug;
3138         }
3139         break;
3140       case DT_MIPS_RLD_MAP_REL:
3141         // Set the DT_MIPS_RLD_MAP_REL entry to the address of _r_debug for GDB.
3142         {
3143           r_debug** dp = reinterpret_cast<r_debug**>(
3144               reinterpret_cast<ElfW(Addr)>(d) + d->d_un.d_val);
3145           *dp = &_r_debug;
3146         }
3147         break;
3148 
3149       case DT_MIPS_RLD_VERSION:
3150       case DT_MIPS_FLAGS:
3151       case DT_MIPS_BASE_ADDRESS:
3152       case DT_MIPS_UNREFEXTNO:
3153         break;
3154 
3155       case DT_MIPS_SYMTABNO:
3156         mips_symtabno_ = d->d_un.d_val;
3157         break;
3158 
3159       case DT_MIPS_LOCAL_GOTNO:
3160         mips_local_gotno_ = d->d_un.d_val;
3161         break;
3162 
3163       case DT_MIPS_GOTSYM:
3164         mips_gotsym_ = d->d_un.d_val;
3165         break;
3166 #endif
3167       // Ignored: "Its use has been superseded by the DF_BIND_NOW flag"
3168       case DT_BIND_NOW:
3169         break;
3170 
3171       case DT_VERSYM:
3172         versym_ = reinterpret_cast<ElfW(Versym)*>(load_bias + d->d_un.d_ptr);
3173         break;
3174 
3175       case DT_VERDEF:
3176         verdef_ptr_ = load_bias + d->d_un.d_ptr;
3177         break;
3178       case DT_VERDEFNUM:
3179         verdef_cnt_ = d->d_un.d_val;
3180         break;
3181 
3182       case DT_VERNEED:
3183         verneed_ptr_ = load_bias + d->d_un.d_ptr;
3184         break;
3185 
3186       case DT_VERNEEDNUM:
3187         verneed_cnt_ = d->d_un.d_val;
3188         break;
3189 
3190       case DT_RUNPATH:
3191         // this is parsed after we have strtab initialized (see below).
3192         break;
3193 
3194       default:
3195         if (!relocating_linker) {
3196           DL_WARN("\"%s\" unused DT entry: type %p arg %p", get_realpath(),
3197               reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
3198         }
3199         break;
3200     }
3201   }
3202 
3203 #if defined(__mips__) && !defined(__LP64__)
3204   if (!mips_check_and_adjust_fp_modes()) {
3205     return false;
3206   }
3207 #endif
3208 
3209   DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p",
3210         reinterpret_cast<void*>(base), strtab_, symtab_);
3211 
3212   // Sanity checks.
3213   if (relocating_linker && needed_count != 0) {
3214     DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries");
3215     return false;
3216   }
3217   if (nbucket_ == 0 && gnu_nbucket_ == 0) {
3218     DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
3219         "(new hash type from the future?)", get_realpath());
3220     return false;
3221   }
3222   if (strtab_ == 0) {
3223     DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
3224     return false;
3225   }
3226   if (symtab_ == 0) {
3227     DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
3228     return false;
3229   }
3230 
3231   // second pass - parse entries relying on strtab
3232   for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
3233     switch (d->d_tag) {
3234       case DT_SONAME:
3235         set_soname(get_string(d->d_un.d_val));
3236         break;
3237       case DT_RUNPATH:
3238         set_dt_runpath(get_string(d->d_un.d_val));
3239         break;
3240     }
3241   }
3242 
3243   // Before M release linker was using basename in place of soname.
3244   // In the case when dt_soname is absent some apps stop working
3245   // because they can't find dt_needed library by soname.
3246   // This workaround should keep them working. (applies only
3247   // for apps targeting sdk version < M). Make an exception for
3248   // the main executable and linker; they do not need to have dt_soname
3249   if (soname_ == nullptr &&
3250       this != solist_get_somain() &&
3251       (flags_ & FLAG_LINKER) == 0 &&
3252       get_application_target_sdk_version() < __ANDROID_API_M__) {
3253     soname_ = basename(realpath_.c_str());
3254     DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
3255         get_realpath(), soname_);
3256     // Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
3257   }
3258   return true;
3259 }
3260 
link_image(const soinfo_list_t & global_group,const soinfo_list_t & local_group,const android_dlextinfo * extinfo)3261 bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
3262                         const android_dlextinfo* extinfo) {
3263 
3264   local_group_root_ = local_group.front();
3265   if (local_group_root_ == nullptr) {
3266     local_group_root_ = this;
3267   }
3268 
3269   if ((flags_ & FLAG_LINKER) == 0 && local_group_root_ == this) {
3270     target_sdk_version_ = get_application_target_sdk_version();
3271   }
3272 
3273   VersionTracker version_tracker;
3274 
3275   if (!version_tracker.init(this)) {
3276     return false;
3277   }
3278 
3279 #if !defined(__LP64__)
3280   if (has_text_relocations) {
3281     // Fail if app is targeting M or above.
3282     if (get_application_target_sdk_version() >= __ANDROID_API_M__) {
3283       DL_ERR_AND_LOG("\"%s\" has text relocations", get_realpath());
3284       return false;
3285     }
3286     // Make segments writable to allow text relocations to work properly. We will later call
3287     // phdr_table_protect_segments() after all of them are applied.
3288     DL_WARN("\"%s\" has text relocations. This is wasting memory and prevents "
3289             "security hardening. Please fix.", get_realpath());
3290     add_dlwarning(get_realpath(), "text relocations");
3291     if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
3292       DL_ERR("can't unprotect loadable segments for \"%s\": %s",
3293              get_realpath(), strerror(errno));
3294       return false;
3295     }
3296   }
3297 #endif
3298 
3299   if (android_relocs_ != nullptr) {
3300     // check signature
3301     if (android_relocs_size_ > 3 &&
3302         android_relocs_[0] == 'A' &&
3303         android_relocs_[1] == 'P' &&
3304         android_relocs_[2] == 'S' &&
3305         android_relocs_[3] == '2') {
3306       DEBUG("[ android relocating %s ]", get_realpath());
3307 
3308       bool relocated = false;
3309       const uint8_t* packed_relocs = android_relocs_ + 4;
3310       const size_t packed_relocs_size = android_relocs_size_ - 4;
3311 
3312       relocated = relocate(
3313           version_tracker,
3314           packed_reloc_iterator<sleb128_decoder>(
3315             sleb128_decoder(packed_relocs, packed_relocs_size)),
3316           global_group, local_group);
3317 
3318       if (!relocated) {
3319         return false;
3320       }
3321     } else {
3322       DL_ERR("bad android relocation header.");
3323       return false;
3324     }
3325   }
3326 
3327 #if defined(USE_RELA)
3328   if (rela_ != nullptr) {
3329     DEBUG("[ relocating %s ]", get_realpath());
3330     if (!relocate(version_tracker,
3331             plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
3332       return false;
3333     }
3334   }
3335   if (plt_rela_ != nullptr) {
3336     DEBUG("[ relocating %s plt ]", get_realpath());
3337     if (!relocate(version_tracker,
3338             plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
3339       return false;
3340     }
3341   }
3342 #else
3343   if (rel_ != nullptr) {
3344     DEBUG("[ relocating %s ]", get_realpath());
3345     if (!relocate(version_tracker,
3346             plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
3347       return false;
3348     }
3349   }
3350   if (plt_rel_ != nullptr) {
3351     DEBUG("[ relocating %s plt ]", get_realpath());
3352     if (!relocate(version_tracker,
3353             plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
3354       return false;
3355     }
3356   }
3357 #endif
3358 
3359 #if defined(__mips__)
3360   if (!mips_relocate_got(version_tracker, global_group, local_group)) {
3361     return false;
3362   }
3363 #endif
3364 
3365   DEBUG("[ finished linking %s ]", get_realpath());
3366 
3367 #if !defined(__LP64__)
3368   if (has_text_relocations) {
3369     // All relocations are done, we can protect our segments back to read-only.
3370     if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
3371       DL_ERR("can't protect segments for \"%s\": %s",
3372              get_realpath(), strerror(errno));
3373       return false;
3374     }
3375   }
3376 #endif
3377 
3378   // We can also turn on GNU RELRO protection if we're not linking the dynamic linker
3379   // itself --- it can't make system calls yet, and will have to call protect_relro later.
3380   if (!is_linker() && !protect_relro()) {
3381     return false;
3382   }
3383 
3384   /* Handle serializing/sharing the RELRO segment */
3385   if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
3386     if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
3387                                        extinfo->relro_fd) < 0) {
3388       DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
3389              get_realpath(), strerror(errno));
3390       return false;
3391     }
3392   } else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
3393     if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
3394                                  extinfo->relro_fd) < 0) {
3395       DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
3396              get_realpath(), strerror(errno));
3397       return false;
3398     }
3399   }
3400 
3401   notify_gdb_of_load(this);
3402   return true;
3403 }
3404 
protect_relro()3405 bool soinfo::protect_relro() {
3406   if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
3407     DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
3408            get_realpath(), strerror(errno));
3409     return false;
3410   }
3411   return true;
3412 }
3413 
init_default_namespace_no_config(bool is_asan)3414 static void init_default_namespace_no_config(bool is_asan) {
3415   g_default_namespace.set_isolated(false);
3416   auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
3417 
3418   char real_path[PATH_MAX];
3419   std::vector<std::string> ld_default_paths;
3420   for (size_t i = 0; default_ld_paths[i] != nullptr; ++i) {
3421     if (realpath(default_ld_paths[i], real_path) != nullptr) {
3422       ld_default_paths.push_back(real_path);
3423     } else {
3424       ld_default_paths.push_back(default_ld_paths[i]);
3425     }
3426   }
3427 
3428   g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
3429 }
3430 
init_default_namespace(const char * executable_path)3431 void init_default_namespace(const char* executable_path) {
3432   g_default_namespace.set_name("(default)");
3433 
3434   soinfo* somain = solist_get_somain();
3435 
3436   const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
3437                                                        somain->load_bias);
3438   const char* bname = basename(interp);
3439 
3440   g_is_asan = bname != nullptr &&
3441               (strcmp(bname, "linker_asan") == 0 ||
3442                strcmp(bname, "linker_asan64") == 0);
3443 
3444   const Config* config = nullptr;
3445 
3446   std::string error_msg;
3447 
3448   if (!Config::read_binary_config(kLdConfigFilePath,
3449                                   executable_path,
3450                                   g_is_asan,
3451                                   &config,
3452                                   &error_msg)) {
3453     if (!error_msg.empty()) {
3454       DL_WARN("error reading config file \"%s\" for \"%s\" (will use default configuration): %s",
3455               kLdConfigFilePath,
3456               executable_path,
3457               error_msg.c_str());
3458     }
3459     config = nullptr;
3460   }
3461 
3462   if (config == nullptr) {
3463     init_default_namespace_no_config(g_is_asan);
3464     return;
3465   }
3466 
3467   const auto& namespace_configs = config->namespace_configs();
3468   std::unordered_map<std::string, android_namespace_t*> namespaces;
3469 
3470   // 1. Initialize default namespace
3471   const NamespaceConfig* default_ns_config = config->default_namespace_config();
3472 
3473   g_default_namespace.set_isolated(default_ns_config->isolated());
3474   g_default_namespace.set_default_library_paths(default_ns_config->search_paths());
3475   g_default_namespace.set_permitted_paths(default_ns_config->permitted_paths());
3476 
3477   namespaces[default_ns_config->name()] = &g_default_namespace;
3478 
3479   // 2. Initialize other namespaces
3480 
3481   for (auto& ns_config : namespace_configs) {
3482     if (namespaces.find(ns_config->name()) != namespaces.end()) {
3483       continue;
3484     }
3485 
3486     android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
3487     ns->set_name(ns_config->name());
3488     ns->set_isolated(ns_config->isolated());
3489     ns->set_default_library_paths(ns_config->search_paths());
3490     ns->set_permitted_paths(ns_config->permitted_paths());
3491 
3492     namespaces[ns_config->name()] = ns;
3493     if (ns_config->visible()) {
3494       g_exported_namespaces[ns_config->name()] = ns;
3495     }
3496   }
3497 
3498   // 3. Establish links between namespaces
3499   for (auto& ns_config : namespace_configs) {
3500     auto it_from = namespaces.find(ns_config->name());
3501     CHECK(it_from != namespaces.end());
3502     android_namespace_t* namespace_from = it_from->second;
3503     for (const NamespaceLinkConfig& ns_link : ns_config->links()) {
3504       auto it_to = namespaces.find(ns_link.ns_name());
3505       CHECK(it_to != namespaces.end());
3506       android_namespace_t* namespace_to = it_to->second;
3507       link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
3508     }
3509   }
3510   // we can no longer rely on the fact that libdl.so is part of default namespace
3511   // this is why we want to add ld-android.so to all namespaces from ld.config.txt
3512   soinfo* ld_android_so = solist_get_head();
3513   for (auto it : namespaces) {
3514     it.second->add_soinfo(ld_android_so);
3515     // TODO (dimitry): somain and ld_preloads should probably be added to all of these namespaces too?
3516   }
3517 
3518   set_application_target_sdk_version(config->target_sdk_version());
3519 }
3520 
3521 // This function finds a namespace exported in ld.config.txt by its name.
3522 // A namespace can be exported by setting .visible property to true.
get_exported_namespace(const char * name)3523 android_namespace_t* get_exported_namespace(const char* name) {
3524   if (name == nullptr) {
3525     return nullptr;
3526   }
3527   auto it = g_exported_namespaces.find(std::string(name));
3528   if (it == g_exported_namespaces.end()) {
3529     return nullptr;
3530   }
3531   return it->second;
3532 }
3533