• 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 <unistd.h>
40 
41 #include <new>
42 #include <string>
43 #include <unordered_map>
44 #include <vector>
45 
46 // Private C library headers.
47 #include "private/bionic_globals.h"
48 #include "private/bionic_tls.h"
49 #include "private/KernelArgumentBlock.h"
50 #include "private/ScopedPthreadMutexLocker.h"
51 #include "private/ScopeGuard.h"
52 
53 #include "linker.h"
54 #include "linker_block_allocator.h"
55 #include "linker_gdb_support.h"
56 #include "linker_debug.h"
57 #include "linker_dlwarning.h"
58 #include "linker_sleb128.h"
59 #include "linker_phdr.h"
60 #include "linker_relocs.h"
61 #include "linker_reloc_iterators.h"
62 #include "linker_utils.h"
63 
64 #include "android-base/strings.h"
65 #include "ziparchive/zip_archive.h"
66 
67 extern void __libc_init_globals(KernelArgumentBlock&);
68 extern void __libc_init_AT_SECURE(KernelArgumentBlock&);
69 
70 extern "C" void _start();
71 
72 // Override macros to use C++ style casts.
73 #undef ELF_ST_TYPE
74 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
75 
76 struct android_namespace_t {
77  public:
android_namespace_tandroid_namespace_t78   android_namespace_t() : name_(nullptr), is_isolated_(false) {}
79 
get_nameandroid_namespace_t80   const char* get_name() const { return name_; }
set_nameandroid_namespace_t81   void set_name(const char* name) { name_ = name; }
82 
is_isolatedandroid_namespace_t83   bool is_isolated() const { return is_isolated_; }
set_isolatedandroid_namespace_t84   void set_isolated(bool isolated) { is_isolated_ = isolated; }
85 
get_ld_library_pathsandroid_namespace_t86   const std::vector<std::string>& get_ld_library_paths() const {
87     return ld_library_paths_;
88   }
set_ld_library_pathsandroid_namespace_t89   void set_ld_library_paths(std::vector<std::string>&& library_paths) {
90     ld_library_paths_ = library_paths;
91   }
92 
get_default_library_pathsandroid_namespace_t93   const std::vector<std::string>& get_default_library_paths() const {
94     return default_library_paths_;
95   }
set_default_library_pathsandroid_namespace_t96   void set_default_library_paths(std::vector<std::string>&& library_paths) {
97     default_library_paths_ = library_paths;
98   }
99 
get_permitted_pathsandroid_namespace_t100   const std::vector<std::string>& get_permitted_paths() const {
101     return permitted_paths_;
102   }
set_permitted_pathsandroid_namespace_t103   void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
104     permitted_paths_ = permitted_paths;
105   }
106 
add_soinfoandroid_namespace_t107   void add_soinfo(soinfo* si) {
108     soinfo_list_.push_back(si);
109   }
110 
add_soinfosandroid_namespace_t111   void add_soinfos(const soinfo::soinfo_list_t& soinfos) {
112     for (auto si : soinfos) {
113       add_soinfo(si);
114       si->add_secondary_namespace(this);
115     }
116   }
117 
remove_soinfoandroid_namespace_t118   void remove_soinfo(soinfo* si) {
119     soinfo_list_.remove_if([&](soinfo* candidate) {
120       return si == candidate;
121     });
122   }
123 
soinfo_listandroid_namespace_t124   const soinfo::soinfo_list_t& soinfo_list() const { return soinfo_list_; }
125 
126   // For isolated namespaces - checks if the file is on the search path;
127   // always returns true for not isolated namespace.
128   bool is_accessible(const std::string& path);
129 
130  private:
131   const char* name_;
132   bool is_isolated_;
133   std::vector<std::string> ld_library_paths_;
134   std::vector<std::string> default_library_paths_;
135   std::vector<std::string> permitted_paths_;
136   soinfo::soinfo_list_t soinfo_list_;
137 
138   DISALLOW_COPY_AND_ASSIGN(android_namespace_t);
139 };
140 
141 android_namespace_t g_default_namespace;
142 
143 static std::unordered_map<uintptr_t, soinfo*> g_soinfo_handles_map;
144 static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
145 
146 static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);
147 
148 static LinkerTypeAllocator<soinfo> g_soinfo_allocator;
149 static LinkerTypeAllocator<LinkedListEntry<soinfo>> g_soinfo_links_allocator;
150 
151 static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
152 static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
153 
154 static soinfo* solist;
155 static soinfo* sonext;
156 static soinfo* somain; // main process, always the one after libdl_info
157 
158 #if defined(__LP64__)
159 static const char* const kSystemLibDir     = "/system/lib64";
160 static const char* const kVendorLibDir     = "/vendor/lib64";
161 static const char* const kAsanSystemLibDir = "/data/lib64";
162 static const char* const kAsanVendorLibDir = "/data/vendor/lib64";
163 #else
164 static const char* const kSystemLibDir     = "/system/lib";
165 static const char* const kVendorLibDir     = "/vendor/lib";
166 static const char* const kAsanSystemLibDir = "/data/lib";
167 static const char* const kAsanVendorLibDir = "/data/vendor/lib";
168 #endif
169 
170 static const char* const kDefaultLdPaths[] = {
171   kSystemLibDir,
172   kVendorLibDir,
173   nullptr
174 };
175 
176 static const char* const kAsanDefaultLdPaths[] = {
177   kAsanSystemLibDir,
178   kSystemLibDir,
179   kAsanVendorLibDir,
180   kVendorLibDir,
181   nullptr
182 };
183 
184 // Is ASAN enabled?
185 static bool g_is_asan = false;
186 
is_system_library(const std::string & realpath)187 static bool is_system_library(const std::string& realpath) {
188   for (const auto& dir : g_default_namespace.get_default_library_paths()) {
189     if (file_is_in_dir(realpath, dir)) {
190       return true;
191     }
192   }
193   return false;
194 }
195 
196 // Checks if the file exists and not a directory.
file_exists(const char * path)197 static bool file_exists(const char* path) {
198   int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC));
199   if (fd == -1) {
200     return false;
201   } else {
202     close(fd);
203     return true;
204   }
205 }
206 static std::string dirname(const char *path);
207 
208 // TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
209 // gradually remove libraries from this list until it is gone.
is_greylisted(const char * name,const soinfo * needed_by)210 static bool is_greylisted(const char* name, const soinfo* needed_by) {
211   static const char* const kLibraryGreyList[] = {
212     "libandroid_runtime.so",
213     "libbinder.so",
214     "libcrypto.so",
215     "libcutils.so",
216     "libexpat.so",
217     "libgui.so",
218     "libmedia.so",
219     "libnativehelper.so",
220     "libskia.so",
221     "libssl.so",
222     "libstagefright.so",
223     "libsqlite.so",
224     "libui.so",
225     "libutils.so",
226     "libvorbisidec.so",
227     nullptr
228   };
229 
230   // limit greylisting to apps targeting sdk version 23 and below
231   if (get_application_target_sdk_version() > 23) {
232     return false;
233   }
234 
235   // if the library needed by a system library - implicitly assume it
236   // is greylisted
237 
238   if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) {
239     return true;
240   }
241 
242   // if this is an absolute path - make sure it points to /system/lib(64)
243   if (name[0] == '/' && dirname(name) == kSystemLibDir) {
244     // and reduce the path to basename
245     name = basename(name);
246   }
247 
248   for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) {
249     if (strcmp(name, kLibraryGreyList[i]) == 0) {
250       return true;
251     }
252   }
253 
254   return false;
255 }
256 // END OF WORKAROUND
257 
258 static const ElfW(Versym) kVersymNotNeeded = 0;
259 static const ElfW(Versym) kVersymGlobal = 1;
260 
261 static const char* const* g_default_ld_paths;
262 static std::vector<std::string> g_ld_preload_names;
263 
264 static std::vector<soinfo*> g_ld_preloads;
265 
266 static bool g_public_namespace_initialized;
267 static soinfo::soinfo_list_t g_public_namespace;
268 
269 __LIBC_HIDDEN__ int g_ld_debug_verbosity;
270 
271 __LIBC_HIDDEN__ abort_msg_t* g_abort_message = nullptr; // For debuggerd.
272 
dirname(const char * path)273 static std::string dirname(const char *path) {
274   const char* last_slash = strrchr(path, '/');
275   if (last_slash == path) return "/";
276   else if (last_slash == nullptr) return ".";
277   else
278     return std::string(path, last_slash - path);
279 }
280 
281 #if STATS
282 struct linker_stats_t {
283   int count[kRelocMax];
284 };
285 
286 static linker_stats_t linker_stats;
287 
count_relocation(RelocationKind kind)288 void count_relocation(RelocationKind kind) {
289   ++linker_stats.count[kind];
290 }
291 #else
count_relocation(RelocationKind)292 void count_relocation(RelocationKind) {
293 }
294 #endif
295 
296 #if COUNT_PAGES
297 uint32_t bitmask[4096];
298 #endif
299 
300 static char __linker_dl_err_buf[768];
301 
linker_get_error_buffer()302 char* linker_get_error_buffer() {
303   return &__linker_dl_err_buf[0];
304 }
305 
linker_get_error_buffer_size()306 size_t linker_get_error_buffer_size() {
307   return sizeof(__linker_dl_err_buf);
308 }
309 
notify_gdb_of_load(soinfo * info)310 static void notify_gdb_of_load(soinfo* info) {
311   if (info->is_linker() || info->is_main_executable()) {
312     // gdb already knows about the linker and the main executable.
313     return;
314   }
315 
316   link_map* map = &(info->link_map_head);
317 
318   map->l_addr = info->load_bias;
319   // link_map l_name field is not const.
320   map->l_name = const_cast<char*>(info->get_realpath());
321   map->l_ld = info->dynamic;
322 
323   CHECK(map->l_name != nullptr);
324   CHECK(map->l_name[0] != '\0');
325 
326   notify_gdb_of_load(map);
327 }
328 
notify_gdb_of_unload(soinfo * info)329 static void notify_gdb_of_unload(soinfo* info) {
330   notify_gdb_of_unload(&(info->link_map_head));
331 }
332 
is_accessible(const std::string & file)333 bool android_namespace_t::is_accessible(const std::string& file) {
334   if (!is_isolated_) {
335     return true;
336   }
337 
338   for (const auto& dir : ld_library_paths_) {
339     if (file_is_in_dir(file, dir)) {
340       return true;
341     }
342   }
343 
344   for (const auto& dir : default_library_paths_) {
345     if (file_is_in_dir(file, dir)) {
346       return true;
347     }
348   }
349 
350   for (const auto& dir : permitted_paths_) {
351     if (file_is_under_dir(file, dir)) {
352       return true;
353     }
354   }
355 
356   return false;
357 }
358 
alloc()359 LinkedListEntry<soinfo>* SoinfoListAllocator::alloc() {
360   return g_soinfo_links_allocator.alloc();
361 }
362 
free(LinkedListEntry<soinfo> * entry)363 void SoinfoListAllocator::free(LinkedListEntry<soinfo>* entry) {
364   g_soinfo_links_allocator.free(entry);
365 }
366 
alloc()367 LinkedListEntry<android_namespace_t>* NamespaceListAllocator::alloc() {
368   return g_namespace_list_allocator.alloc();
369 }
370 
free(LinkedListEntry<android_namespace_t> * entry)371 void NamespaceListAllocator::free(LinkedListEntry<android_namespace_t>* entry) {
372   g_namespace_list_allocator.free(entry);
373 }
374 
soinfo_alloc(android_namespace_t * ns,const char * name,struct stat * file_stat,off64_t file_offset,uint32_t rtld_flags)375 static soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
376                             struct stat* file_stat, off64_t file_offset,
377                             uint32_t rtld_flags) {
378   if (strlen(name) >= PATH_MAX) {
379     DL_ERR("library name \"%s\" too long", name);
380     return nullptr;
381   }
382 
383   soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(ns, name, file_stat,
384                                                        file_offset, rtld_flags);
385 
386   sonext->next = si;
387   sonext = si;
388 
389   si->generate_handle();
390   ns->add_soinfo(si);
391 
392   TRACE("name %s: allocated soinfo @ %p", name, si);
393   return si;
394 }
395 
soinfo_free(soinfo * si)396 static void soinfo_free(soinfo* si) {
397   if (si == nullptr) {
398     return;
399   }
400 
401   if (si->base != 0 && si->size != 0) {
402     if (!si->is_mapped_by_caller()) {
403       munmap(reinterpret_cast<void*>(si->base), si->size);
404     } else {
405       // remap the region as PROT_NONE, MAP_ANONYMOUS | MAP_NORESERVE
406       mmap(reinterpret_cast<void*>(si->base), si->size, PROT_NONE,
407            MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
408     }
409   }
410 
411   soinfo *prev = nullptr, *trav;
412 
413   TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
414 
415   for (trav = solist; trav != nullptr; trav = trav->next) {
416     if (trav == si) {
417       break;
418     }
419     prev = trav;
420   }
421 
422   if (trav == nullptr) {
423     // si was not in solist
424     DL_ERR("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
425     return;
426   }
427 
428   // clear links to/from si
429   si->remove_all_links();
430 
431   // prev will never be null, because the first entry in solist is
432   // always the static libdl_info.
433   prev->next = si->next;
434   if (si == sonext) {
435     sonext = prev;
436   }
437 
438   si->~soinfo();
439   g_soinfo_allocator.free(si);
440 }
441 
442 // For every path element this function checks of it exists, and is a directory,
443 // and normalizes it:
444 // 1. For regular path it converts it to realpath()
445 // 2. For path in a zip file it uses realpath on the zipfile
446 //    normalizes entry name by calling normalize_path function.
resolve_paths(std::vector<std::string> & paths,std::vector<std::string> * resolved_paths)447 static void resolve_paths(std::vector<std::string>& paths,
448                           std::vector<std::string>* resolved_paths) {
449   resolved_paths->clear();
450   for (const auto& path : paths) {
451     char resolved_path[PATH_MAX];
452     const char* original_path = path.c_str();
453     if (realpath(original_path, resolved_path) != nullptr) {
454       struct stat s;
455       if (stat(resolved_path, &s) == 0) {
456         if (S_ISDIR(s.st_mode)) {
457           resolved_paths->push_back(resolved_path);
458         } else {
459           DL_WARN("Warning: \"%s\" is not a directory (excluding from path)", resolved_path);
460           continue;
461         }
462       } else {
463         DL_WARN("Warning: cannot stat file \"%s\": %s", resolved_path, strerror(errno));
464         continue;
465       }
466     } else {
467       std::string zip_path;
468       std::string entry_path;
469 
470       std::string normalized_path;
471 
472       if (!normalize_path(original_path, &normalized_path)) {
473         DL_WARN("Warning: unable to normalize \"%s\"", original_path);
474         continue;
475       }
476 
477       if (parse_zip_path(normalized_path.c_str(), &zip_path, &entry_path)) {
478         if (realpath(zip_path.c_str(), resolved_path) == nullptr) {
479           DL_WARN("Warning: unable to resolve \"%s\": %s", zip_path.c_str(), strerror(errno));
480           continue;
481         }
482 
483         resolved_paths->push_back(std::string(resolved_path) + kZipFileSeparator + entry_path);
484       }
485     }
486   }
487 }
488 
split_path(const char * path,const char * delimiters,std::vector<std::string> * paths)489 static void split_path(const char* path, const char* delimiters,
490                        std::vector<std::string>* paths) {
491   if (path != nullptr && path[0] != 0) {
492     *paths = android::base::Split(path, delimiters);
493   }
494 }
495 
parse_path(const char * path,const char * delimiters,std::vector<std::string> * resolved_paths)496 static void parse_path(const char* path, const char* delimiters,
497                        std::vector<std::string>* resolved_paths) {
498   std::vector<std::string> paths;
499   split_path(path, delimiters, &paths);
500   resolve_paths(paths, resolved_paths);
501 }
502 
parse_LD_LIBRARY_PATH(const char * path)503 static void parse_LD_LIBRARY_PATH(const char* path) {
504   std::vector<std::string> ld_libary_paths;
505   parse_path(path, ":", &ld_libary_paths);
506   g_default_namespace.set_ld_library_paths(std::move(ld_libary_paths));
507 }
508 
set_dt_runpath(const char * path)509 void soinfo::set_dt_runpath(const char* path) {
510   if (!has_min_version(3)) {
511     return;
512   }
513 
514   std::vector<std::string> runpaths;
515 
516   split_path(path, ":", &runpaths);
517 
518   std::string origin = dirname(get_realpath());
519   // FIXME: add $LIB and $PLATFORM.
520   std::pair<std::string, std::string> substs[] = {{"ORIGIN", origin}};
521   for (auto&& s : runpaths) {
522     size_t pos = 0;
523     while (pos < s.size()) {
524       pos = s.find("$", pos);
525       if (pos == std::string::npos) break;
526       for (const auto& subst : substs) {
527         const std::string& token = subst.first;
528         const std::string& replacement = subst.second;
529         if (s.substr(pos + 1, token.size()) == token) {
530           s.replace(pos, token.size() + 1, replacement);
531           // -1 to compensate for the ++pos below.
532           pos += replacement.size() - 1;
533           break;
534         } else if (s.substr(pos + 1, token.size() + 2) == "{" + token + "}") {
535           s.replace(pos, token.size() + 3, replacement);
536           pos += replacement.size() - 1;
537           break;
538         }
539       }
540       // Skip $ in case it did not match any of the known substitutions.
541       ++pos;
542     }
543   }
544 
545   resolve_paths(runpaths, &dt_runpath_);
546 }
547 
parse_LD_PRELOAD(const char * path)548 static void parse_LD_PRELOAD(const char* path) {
549   g_ld_preload_names.clear();
550   if (path != nullptr) {
551     // We have historically supported ':' as well as ' ' in LD_PRELOAD.
552     g_ld_preload_names = android::base::Split(path, " :");
553     std::remove_if(g_ld_preload_names.begin(),
554                    g_ld_preload_names.end(),
555                    [] (const std::string& s) { return s.empty(); });
556   }
557 }
558 
realpath_fd(int fd,std::string * realpath)559 static bool realpath_fd(int fd, std::string* realpath) {
560   std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
561   __libc_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
562   if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
563     PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
564     return false;
565   }
566 
567   *realpath = &buf[0];
568   return true;
569 }
570 
571 #if defined(__arm__)
572 
573 // For a given PC, find the .so that it belongs to.
574 // Returns the base address of the .ARM.exidx section
575 // for that .so, and the number of 8-byte entries
576 // in that section (via *pcount).
577 //
578 // Intended to be called by libc's __gnu_Unwind_Find_exidx().
579 //
580 // This function is exposed via dlfcn.cpp and libdl.so.
dl_unwind_find_exidx(_Unwind_Ptr pc,int * pcount)581 _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
582   uintptr_t addr = reinterpret_cast<uintptr_t>(pc);
583 
584   for (soinfo* si = solist; si != 0; si = si->next) {
585     if ((addr >= si->base) && (addr < (si->base + si->size))) {
586         *pcount = si->ARM_exidx_count;
587         return reinterpret_cast<_Unwind_Ptr>(si->ARM_exidx);
588     }
589   }
590   *pcount = 0;
591   return nullptr;
592 }
593 
594 #endif
595 
596 // Here, we only have to provide a callback to iterate across all the
597 // loaded libraries. gcc_eh does the rest.
do_dl_iterate_phdr(int (* cb)(dl_phdr_info * info,size_t size,void * data),void * data)598 int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
599   int rv = 0;
600   for (soinfo* si = solist; si != nullptr; si = si->next) {
601     dl_phdr_info dl_info;
602     dl_info.dlpi_addr = si->link_map_head.l_addr;
603     dl_info.dlpi_name = si->link_map_head.l_name;
604     dl_info.dlpi_phdr = si->phdr;
605     dl_info.dlpi_phnum = si->phnum;
606     rv = cb(&dl_info, sizeof(dl_phdr_info), data);
607     if (rv != 0) {
608       break;
609     }
610   }
611   return rv;
612 }
613 
ElfW(Versym)614 const ElfW(Versym)* soinfo::get_versym(size_t n) const {
615   if (has_min_version(2) && versym_ != nullptr) {
616     return versym_ + n;
617   }
618 
619   return nullptr;
620 }
621 
ElfW(Addr)622 ElfW(Addr) soinfo::get_verneed_ptr() const {
623   if (has_min_version(2)) {
624     return verneed_ptr_;
625   }
626 
627   return 0;
628 }
629 
get_verneed_cnt() const630 size_t soinfo::get_verneed_cnt() const {
631   if (has_min_version(2)) {
632     return verneed_cnt_;
633   }
634 
635   return 0;
636 }
637 
ElfW(Addr)638 ElfW(Addr) soinfo::get_verdef_ptr() const {
639   if (has_min_version(2)) {
640     return verdef_ptr_;
641   }
642 
643   return 0;
644 }
645 
get_verdef_cnt() const646 size_t soinfo::get_verdef_cnt() const {
647   if (has_min_version(2)) {
648     return verdef_cnt_;
649   }
650 
651   return 0;
652 }
653 
654 template<typename F>
for_each_verdef(const soinfo * si,F functor)655 static bool for_each_verdef(const soinfo* si, F functor) {
656   if (!si->has_min_version(2)) {
657     return true;
658   }
659 
660   uintptr_t verdef_ptr = si->get_verdef_ptr();
661   if (verdef_ptr == 0) {
662     return true;
663   }
664 
665   size_t offset = 0;
666 
667   size_t verdef_cnt = si->get_verdef_cnt();
668   for (size_t i = 0; i<verdef_cnt; ++i) {
669     const ElfW(Verdef)* verdef = reinterpret_cast<ElfW(Verdef)*>(verdef_ptr + offset);
670     size_t verdaux_offset = offset + verdef->vd_aux;
671     offset += verdef->vd_next;
672 
673     if (verdef->vd_version != 1) {
674       DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
675           i, verdef->vd_version, si->get_realpath());
676       return false;
677     }
678 
679     if ((verdef->vd_flags & VER_FLG_BASE) != 0) {
680       // "this is the version of the file itself.  It must not be used for
681       //  matching a symbol. It can be used to match references."
682       //
683       // http://www.akkadia.org/drepper/symbol-versioning
684       continue;
685     }
686 
687     if (verdef->vd_cnt == 0) {
688       DL_ERR("invalid verdef[%zd] vd_cnt == 0 (version without a name)", i);
689       return false;
690     }
691 
692     const ElfW(Verdaux)* verdaux = reinterpret_cast<ElfW(Verdaux)*>(verdef_ptr + verdaux_offset);
693 
694     if (functor(i, verdef, verdaux) == true) {
695       break;
696     }
697   }
698 
699   return true;
700 }
701 
find_verdef_version_index(const version_info * vi,ElfW (Versym)* versym) const702 bool soinfo::find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const {
703   if (vi == nullptr) {
704     *versym = kVersymNotNeeded;
705     return true;
706   }
707 
708   *versym = kVersymGlobal;
709 
710   return for_each_verdef(this,
711     [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
712       if (verdef->vd_hash == vi->elf_hash &&
713           strcmp(vi->name, get_string(verdaux->vda_name)) == 0) {
714         *versym = verdef->vd_ndx;
715         return true;
716       }
717 
718       return false;
719     }
720   );
721 }
722 
find_symbol_by_name(SymbolName & symbol_name,const version_info * vi,const ElfW (Sym)** symbol) const723 bool soinfo::find_symbol_by_name(SymbolName& symbol_name,
724                                  const version_info* vi,
725                                  const ElfW(Sym)** symbol) const {
726   uint32_t symbol_index;
727   bool success =
728       is_gnu_hash() ?
729       gnu_lookup(symbol_name, vi, &symbol_index) :
730       elf_lookup(symbol_name, vi, &symbol_index);
731 
732   if (success) {
733     *symbol = symbol_index == 0 ? nullptr : symtab_ + symbol_index;
734   }
735 
736   return success;
737 }
738 
is_symbol_global_and_defined(const soinfo * si,const ElfW (Sym)* s)739 static bool is_symbol_global_and_defined(const soinfo* si, const ElfW(Sym)* s) {
740   if (ELF_ST_BIND(s->st_info) == STB_GLOBAL ||
741       ELF_ST_BIND(s->st_info) == STB_WEAK) {
742     return s->st_shndx != SHN_UNDEF;
743   } else if (ELF_ST_BIND(s->st_info) != STB_LOCAL) {
744     DL_WARN("unexpected ST_BIND value: %d for \"%s\" in \"%s\"",
745             ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
746   }
747 
748   return false;
749 }
750 
751 static const ElfW(Versym) kVersymHiddenBit = 0x8000;
752 
is_versym_hidden(const ElfW (Versym)* versym)753 static inline bool is_versym_hidden(const ElfW(Versym)* versym) {
754   // the symbol is hidden if bit 15 of versym is set.
755   return versym != nullptr && (*versym & kVersymHiddenBit) != 0;
756 }
757 
check_symbol_version(const ElfW (Versym)verneed,const ElfW (Versym)* verdef)758 static inline bool check_symbol_version(const ElfW(Versym) verneed,
759                                         const ElfW(Versym)* verdef) {
760   return verneed == kVersymNotNeeded ||
761       verdef == nullptr ||
762       verneed == (*verdef & ~kVersymHiddenBit);
763 }
764 
gnu_lookup(SymbolName & symbol_name,const version_info * vi,uint32_t * symbol_index) const765 bool soinfo::gnu_lookup(SymbolName& symbol_name,
766                         const version_info* vi,
767                         uint32_t* symbol_index) const {
768   uint32_t hash = symbol_name.gnu_hash();
769   uint32_t h2 = hash >> gnu_shift2_;
770 
771   uint32_t bloom_mask_bits = sizeof(ElfW(Addr))*8;
772   uint32_t word_num = (hash / bloom_mask_bits) & gnu_maskwords_;
773   ElfW(Addr) bloom_word = gnu_bloom_filter_[word_num];
774 
775   *symbol_index = 0;
776 
777   TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
778       symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
779 
780   // test against bloom filter
781   if ((1 & (bloom_word >> (hash % bloom_mask_bits)) & (bloom_word >> (h2 % bloom_mask_bits))) == 0) {
782     TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
783         symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
784 
785     return true;
786   }
787 
788   // bloom test says "probably yes"...
789   uint32_t n = gnu_bucket_[hash % gnu_nbucket_];
790 
791   if (n == 0) {
792     TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
793         symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
794 
795     return true;
796   }
797 
798   // lookup versym for the version definition in this library
799   // note the difference between "version is not requested" (vi == nullptr)
800   // and "version not found". In the first case verneed is kVersymNotNeeded
801   // which implies that the default version can be accepted; the second case results in
802   // verneed = 1 (kVersymGlobal) and implies that we should ignore versioned symbols
803   // for this library and consider only *global* ones.
804   ElfW(Versym) verneed = 0;
805   if (!find_verdef_version_index(vi, &verneed)) {
806     return false;
807   }
808 
809   do {
810     ElfW(Sym)* s = symtab_ + n;
811     const ElfW(Versym)* verdef = get_versym(n);
812     // skip hidden versions when verneed == kVersymNotNeeded (0)
813     if (verneed == kVersymNotNeeded && is_versym_hidden(verdef)) {
814         continue;
815     }
816     if (((gnu_chain_[n] ^ hash) >> 1) == 0 &&
817         check_symbol_version(verneed, verdef) &&
818         strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
819         is_symbol_global_and_defined(this, s)) {
820       TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
821           symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(s->st_value),
822           static_cast<size_t>(s->st_size));
823       *symbol_index = n;
824       return true;
825     }
826   } while ((gnu_chain_[n++] & 1) == 0);
827 
828   TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
829              symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
830 
831   return true;
832 }
833 
elf_lookup(SymbolName & symbol_name,const version_info * vi,uint32_t * symbol_index) const834 bool soinfo::elf_lookup(SymbolName& symbol_name,
835                         const version_info* vi,
836                         uint32_t* symbol_index) const {
837   uint32_t hash = symbol_name.elf_hash();
838 
839   TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p h=%x(elf) %zd",
840              symbol_name.get_name(), get_realpath(),
841              reinterpret_cast<void*>(base), hash, hash % nbucket_);
842 
843   ElfW(Versym) verneed = 0;
844   if (!find_verdef_version_index(vi, &verneed)) {
845     return false;
846   }
847 
848   for (uint32_t n = bucket_[hash % nbucket_]; n != 0; n = chain_[n]) {
849     ElfW(Sym)* s = symtab_ + n;
850     const ElfW(Versym)* verdef = get_versym(n);
851 
852     // skip hidden versions when verneed == 0
853     if (verneed == kVersymNotNeeded && is_versym_hidden(verdef)) {
854         continue;
855     }
856 
857     if (check_symbol_version(verneed, verdef) &&
858         strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
859         is_symbol_global_and_defined(this, s)) {
860       TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
861                  symbol_name.get_name(), get_realpath(),
862                  reinterpret_cast<void*>(s->st_value),
863                  static_cast<size_t>(s->st_size));
864       *symbol_index = n;
865       return true;
866     }
867   }
868 
869   TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p %x %zd",
870              symbol_name.get_name(), get_realpath(),
871              reinterpret_cast<void*>(base), hash, hash % nbucket_);
872 
873   *symbol_index = 0;
874   return true;
875 }
876 
soinfo(android_namespace_t * ns,const char * realpath,const struct stat * file_stat,off64_t file_offset,int rtld_flags)877 soinfo::soinfo(android_namespace_t* ns, const char* realpath,
878                const struct stat* file_stat, off64_t file_offset,
879                int rtld_flags) {
880   memset(this, 0, sizeof(*this));
881 
882   if (realpath != nullptr) {
883     realpath_ = realpath;
884   }
885 
886   flags_ = FLAG_NEW_SOINFO;
887   version_ = SOINFO_VERSION;
888 
889   if (file_stat != nullptr) {
890     this->st_dev_ = file_stat->st_dev;
891     this->st_ino_ = file_stat->st_ino;
892     this->file_offset_ = file_offset;
893   }
894 
895   this->rtld_flags_ = rtld_flags;
896   this->primary_namespace_ = ns;
897 }
898 
~soinfo()899 soinfo::~soinfo() {
900   g_soinfo_handles_map.erase(handle_);
901 }
902 
calculate_elf_hash(const char * name)903 static uint32_t calculate_elf_hash(const char* name) {
904   const uint8_t* name_bytes = reinterpret_cast<const uint8_t*>(name);
905   uint32_t h = 0, g;
906 
907   while (*name_bytes) {
908     h = (h << 4) + *name_bytes++;
909     g = h & 0xf0000000;
910     h ^= g;
911     h ^= g >> 24;
912   }
913 
914   return h;
915 }
916 
elf_hash()917 uint32_t SymbolName::elf_hash() {
918   if (!has_elf_hash_) {
919     elf_hash_ = calculate_elf_hash(name_);
920     has_elf_hash_ = true;
921   }
922 
923   return elf_hash_;
924 }
925 
gnu_hash()926 uint32_t SymbolName::gnu_hash() {
927   if (!has_gnu_hash_) {
928     uint32_t h = 5381;
929     const uint8_t* name = reinterpret_cast<const uint8_t*>(name_);
930     while (*name != 0) {
931       h += (h << 5) + *name++; // h*33 + c = h + h * 32 + c = h + h << 5 + c
932     }
933 
934     gnu_hash_ =  h;
935     has_gnu_hash_ = true;
936   }
937 
938   return gnu_hash_;
939 }
940 
soinfo_do_lookup(soinfo * si_from,const char * name,const version_info * vi,soinfo ** si_found_in,const soinfo::soinfo_list_t & global_group,const soinfo::soinfo_list_t & local_group,const ElfW (Sym)** symbol)941 bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
942                       soinfo** si_found_in, const soinfo::soinfo_list_t& global_group,
943                       const soinfo::soinfo_list_t& local_group, const ElfW(Sym)** symbol) {
944   SymbolName symbol_name(name);
945   const ElfW(Sym)* s = nullptr;
946 
947   /* "This element's presence in a shared object library alters the dynamic linker's
948    * symbol resolution algorithm for references within the library. Instead of starting
949    * a symbol search with the executable file, the dynamic linker starts from the shared
950    * object itself. If the shared object fails to supply the referenced symbol, the
951    * dynamic linker then searches the executable file and other shared objects as usual."
952    *
953    * http://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html
954    *
955    * Note that this is unlikely since static linker avoids generating
956    * relocations for -Bsymbolic linked dynamic executables.
957    */
958   if (si_from->has_DT_SYMBOLIC) {
959     DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
960     if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
961       return false;
962     }
963 
964     if (s != nullptr) {
965       *si_found_in = si_from;
966     }
967   }
968 
969   // 1. Look for it in global_group
970   if (s == nullptr) {
971     bool error = false;
972     global_group.visit([&](soinfo* global_si) {
973       DEBUG("%s: looking up %s in %s (from global group)",
974           si_from->get_realpath(), name, global_si->get_realpath());
975       if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
976         error = true;
977         return false;
978       }
979 
980       if (s != nullptr) {
981         *si_found_in = global_si;
982         return false;
983       }
984 
985       return true;
986     });
987 
988     if (error) {
989       return false;
990     }
991   }
992 
993   // 2. Look for it in the local group
994   if (s == nullptr) {
995     bool error = false;
996     local_group.visit([&](soinfo* local_si) {
997       if (local_si == si_from && si_from->has_DT_SYMBOLIC) {
998         // we already did this - skip
999         return true;
1000       }
1001 
1002       DEBUG("%s: looking up %s in %s (from local group)",
1003           si_from->get_realpath(), name, local_si->get_realpath());
1004       if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
1005         error = true;
1006         return false;
1007       }
1008 
1009       if (s != nullptr) {
1010         *si_found_in = local_si;
1011         return false;
1012       }
1013 
1014       return true;
1015     });
1016 
1017     if (error) {
1018       return false;
1019     }
1020   }
1021 
1022   if (s != nullptr) {
1023     TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
1024                "found in %s, base = %p, load bias = %p",
1025                si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
1026                (*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
1027                reinterpret_cast<void*>((*si_found_in)->load_bias));
1028   }
1029 
1030   *symbol = s;
1031   return true;
1032 }
1033 
1034 class ProtectedDataGuard {
1035  public:
ProtectedDataGuard()1036   ProtectedDataGuard() {
1037     if (ref_count_++ == 0) {
1038       protect_data(PROT_READ | PROT_WRITE);
1039     }
1040   }
1041 
~ProtectedDataGuard()1042   ~ProtectedDataGuard() {
1043     if (ref_count_ == 0) { // overflow
1044       __libc_fatal("Too many nested calls to dlopen()");
1045     }
1046 
1047     if (--ref_count_ == 0) {
1048       protect_data(PROT_READ);
1049     }
1050   }
1051  private:
protect_data(int protection)1052   void protect_data(int protection) {
1053     g_soinfo_allocator.protect_all(protection);
1054     g_soinfo_links_allocator.protect_all(protection);
1055     g_namespace_allocator.protect_all(protection);
1056     g_namespace_list_allocator.protect_all(protection);
1057   }
1058 
1059   static size_t ref_count_;
1060 };
1061 
1062 size_t ProtectedDataGuard::ref_count_ = 0;
1063 
1064 // Each size has it's own allocator.
1065 template<size_t size>
1066 class SizeBasedAllocator {
1067  public:
alloc()1068   static void* alloc() {
1069     return allocator_.alloc();
1070   }
1071 
free(void * ptr)1072   static void free(void* ptr) {
1073     allocator_.free(ptr);
1074   }
1075 
1076  private:
1077   static LinkerBlockAllocator allocator_;
1078 };
1079 
1080 template<size_t size>
1081 LinkerBlockAllocator SizeBasedAllocator<size>::allocator_(size);
1082 
1083 template<typename T>
1084 class TypeBasedAllocator {
1085  public:
alloc()1086   static T* alloc() {
1087     return reinterpret_cast<T*>(SizeBasedAllocator<sizeof(T)>::alloc());
1088   }
1089 
free(T * ptr)1090   static void free(T* ptr) {
1091     SizeBasedAllocator<sizeof(T)>::free(ptr);
1092   }
1093 };
1094 
1095 class LoadTask {
1096  public:
1097   struct deleter_t {
operator ()LoadTask::deleter_t1098     void operator()(LoadTask* t) {
1099       t->~LoadTask();
1100       TypeBasedAllocator<LoadTask>::free(t);
1101     }
1102   };
1103 
1104   static deleter_t deleter;
1105 
create(const char * name,soinfo * needed_by,std::unordered_map<const soinfo *,ElfReader> * readers_map)1106   static LoadTask* create(const char* name, soinfo* needed_by,
1107                           std::unordered_map<const soinfo*, ElfReader>* readers_map) {
1108     LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
1109     return new (ptr) LoadTask(name, needed_by, readers_map);
1110   }
1111 
get_name() const1112   const char* get_name() const {
1113     return name_;
1114   }
1115 
get_needed_by() const1116   soinfo* get_needed_by() const {
1117     return needed_by_;
1118   }
1119 
get_soinfo() const1120   soinfo* get_soinfo() const {
1121     return si_;
1122   }
1123 
set_soinfo(soinfo * si)1124   void set_soinfo(soinfo* si) {
1125     si_ = si;
1126   }
1127 
get_file_offset() const1128   off64_t get_file_offset() const {
1129     return file_offset_;
1130   }
1131 
set_file_offset(off64_t offset)1132   void set_file_offset(off64_t offset) {
1133     file_offset_ = offset;
1134   }
1135 
get_fd() const1136   int get_fd() const {
1137     return fd_;
1138   }
1139 
set_fd(int fd,bool assume_ownership)1140   void set_fd(int fd, bool assume_ownership) {
1141     fd_ = fd;
1142     close_fd_ = assume_ownership;
1143   }
1144 
get_extinfo() const1145   const android_dlextinfo* get_extinfo() const {
1146     return extinfo_;
1147   }
1148 
set_extinfo(const android_dlextinfo * extinfo)1149   void set_extinfo(const android_dlextinfo* extinfo) {
1150     extinfo_ = extinfo;
1151   }
1152 
is_dt_needed() const1153   bool is_dt_needed() const {
1154     return is_dt_needed_;
1155   }
1156 
set_dt_needed(bool is_dt_needed)1157   void set_dt_needed(bool is_dt_needed) {
1158     is_dt_needed_ = is_dt_needed;
1159   }
1160 
get_elf_reader() const1161   const ElfReader& get_elf_reader() const {
1162     CHECK(si_ != nullptr);
1163     return (*elf_readers_map_)[si_];
1164   }
1165 
get_elf_reader()1166   ElfReader& get_elf_reader() {
1167     CHECK(si_ != nullptr);
1168     return (*elf_readers_map_)[si_];
1169   }
1170 
get_readers_map()1171   std::unordered_map<const soinfo*, ElfReader>* get_readers_map() {
1172     return elf_readers_map_;
1173   }
1174 
read(const char * realpath,off64_t file_size)1175   bool read(const char* realpath, off64_t file_size) {
1176     ElfReader& elf_reader = get_elf_reader();
1177     return elf_reader.Read(realpath, fd_, file_offset_, file_size);
1178   }
1179 
load()1180   bool load() {
1181     ElfReader& elf_reader = get_elf_reader();
1182     if (!elf_reader.Load(extinfo_)) {
1183       return false;
1184     }
1185 
1186     si_->base = elf_reader.load_start();
1187     si_->size = elf_reader.load_size();
1188     si_->set_mapped_by_caller(elf_reader.is_mapped_by_caller());
1189     si_->load_bias = elf_reader.load_bias();
1190     si_->phnum = elf_reader.phdr_count();
1191     si_->phdr = elf_reader.loaded_phdr();
1192 
1193     return true;
1194   }
1195 
1196  private:
LoadTask(const char * name,soinfo * needed_by,std::unordered_map<const soinfo *,ElfReader> * readers_map)1197   LoadTask(const char* name, soinfo* needed_by,
1198            std::unordered_map<const soinfo*, ElfReader>* readers_map)
1199     : name_(name), needed_by_(needed_by), si_(nullptr),
1200       fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
1201       is_dt_needed_(false) {}
1202 
~LoadTask()1203   ~LoadTask() {
1204     if (fd_ != -1 && close_fd_) {
1205       close(fd_);
1206     }
1207   }
1208 
1209   const char* name_;
1210   soinfo* needed_by_;
1211   soinfo* si_;
1212   const android_dlextinfo* extinfo_;
1213   int fd_;
1214   bool close_fd_;
1215   off64_t file_offset_;
1216   std::unordered_map<const soinfo*, ElfReader>* elf_readers_map_;
1217   // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
1218   bool is_dt_needed_;
1219   // END OF WORKAROUND
1220 
1221   DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
1222 };
1223 
1224 LoadTask::deleter_t LoadTask::deleter;
1225 
1226 template <typename T>
1227 using linked_list_t = LinkedList<T, TypeBasedAllocator<LinkedListEntry<T>>>;
1228 
1229 typedef linked_list_t<soinfo> SoinfoLinkedList;
1230 typedef linked_list_t<const char> StringLinkedList;
1231 typedef std::vector<LoadTask*> LoadTaskList;
1232 
1233 
1234 // This function walks down the tree of soinfo dependencies
1235 // in breadth-first order and
1236 //   * calls action(soinfo* si) for each node, and
1237 //   * terminates walk if action returns false.
1238 //
1239 // walk_dependencies_tree returns false if walk was terminated
1240 // by the action and true otherwise.
1241 template<typename F>
walk_dependencies_tree(soinfo * root_soinfos[],size_t root_soinfos_size,F action)1242 static bool walk_dependencies_tree(soinfo* root_soinfos[], size_t root_soinfos_size, F action) {
1243   SoinfoLinkedList visit_list;
1244   SoinfoLinkedList visited;
1245 
1246   for (size_t i = 0; i < root_soinfos_size; ++i) {
1247     visit_list.push_back(root_soinfos[i]);
1248   }
1249 
1250   soinfo* si;
1251   while ((si = visit_list.pop_front()) != nullptr) {
1252     if (visited.contains(si)) {
1253       continue;
1254     }
1255 
1256     if (!action(si)) {
1257       return false;
1258     }
1259 
1260     visited.push_back(si);
1261 
1262     si->get_children().for_each([&](soinfo* child) {
1263       visit_list.push_back(child);
1264     });
1265   }
1266 
1267   return true;
1268 }
1269 
1270 
ElfW(Sym)1271 static const ElfW(Sym)* dlsym_handle_lookup(soinfo* root, soinfo* skip_until,
1272                                             soinfo** found, SymbolName& symbol_name,
1273                                             const version_info* vi) {
1274   const ElfW(Sym)* result = nullptr;
1275   bool skip_lookup = skip_until != nullptr;
1276 
1277   walk_dependencies_tree(&root, 1, [&](soinfo* current_soinfo) {
1278     if (skip_lookup) {
1279       skip_lookup = current_soinfo != skip_until;
1280       return true;
1281     }
1282 
1283     if (!current_soinfo->find_symbol_by_name(symbol_name, vi, &result)) {
1284       result = nullptr;
1285       return false;
1286     }
1287 
1288     if (result != nullptr) {
1289       *found = current_soinfo;
1290       return false;
1291     }
1292 
1293     return true;
1294   });
1295 
1296   return result;
1297 }
1298 
1299 static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
1300                                             const char* name,
1301                                             const version_info* vi,
1302                                             soinfo** found,
1303                                             soinfo* caller,
1304                                             void* handle);
1305 
1306 // This is used by dlsym(3).  It performs symbol lookup only within the
1307 // specified soinfo object and its dependencies in breadth first order.
ElfW(Sym)1308 static const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found,
1309                                             const char* name, const version_info* vi) {
1310   // According to man dlopen(3) and posix docs in the case when si is handle
1311   // of the main executable we need to search not only in the executable and its
1312   // dependencies but also in all libraries loaded with RTLD_GLOBAL.
1313   //
1314   // Since RTLD_GLOBAL is always set for the main executable and all dt_needed shared
1315   // libraries and they are loaded in breath-first (correct) order we can just execute
1316   // dlsym(RTLD_DEFAULT, ...); instead of doing two stage lookup.
1317   if (si == somain) {
1318     return dlsym_linear_lookup(&g_default_namespace, name, vi, found, nullptr, RTLD_DEFAULT);
1319   }
1320 
1321   SymbolName symbol_name(name);
1322   return dlsym_handle_lookup(si, nullptr, found, symbol_name, vi);
1323 }
1324 
1325 /* This is used by dlsym(3) to performs a global symbol lookup. If the
1326    start value is null (for RTLD_DEFAULT), the search starts at the
1327    beginning of the global solist. Otherwise the search starts at the
1328    specified soinfo (for RTLD_NEXT).
1329  */
ElfW(Sym)1330 static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
1331                                             const char* name,
1332                                             const version_info* vi,
1333                                             soinfo** found,
1334                                             soinfo* caller,
1335                                             void* handle) {
1336   SymbolName symbol_name(name);
1337 
1338   auto& soinfo_list = ns->soinfo_list();
1339   auto start = soinfo_list.begin();
1340 
1341   if (handle == RTLD_NEXT) {
1342     if (caller == nullptr) {
1343       return nullptr;
1344     } else {
1345       auto it = soinfo_list.find(caller);
1346       CHECK (it != soinfo_list.end());
1347       start = ++it;
1348     }
1349   }
1350 
1351   const ElfW(Sym)* s = nullptr;
1352   for (auto it = start, end = soinfo_list.end(); it != end; ++it) {
1353     soinfo* si = *it;
1354     // Do not skip RTLD_LOCAL libraries in dlsym(RTLD_DEFAULT, ...)
1355     // if the library is opened by application with target api level <= 22
1356     // See http://b/21565766
1357     if ((si->get_rtld_flags() & RTLD_GLOBAL) == 0 && si->get_target_sdk_version() > 22) {
1358       continue;
1359     }
1360 
1361     if (!si->find_symbol_by_name(symbol_name, vi, &s)) {
1362       return nullptr;
1363     }
1364 
1365     if (s != nullptr) {
1366       *found = si;
1367       break;
1368     }
1369   }
1370 
1371   // If not found - use dlsym_handle_lookup for caller's
1372   // local_group unless it is part of the global group in which
1373   // case we already did it.
1374   if (s == nullptr && caller != nullptr &&
1375       (caller->get_rtld_flags() & RTLD_GLOBAL) == 0) {
1376     return dlsym_handle_lookup(caller->get_local_group_root(),
1377         (handle == RTLD_NEXT) ? caller : nullptr, found, symbol_name, vi);
1378   }
1379 
1380   if (s != nullptr) {
1381     TRACE_TYPE(LOOKUP, "%s s->st_value = %p, found->base = %p",
1382                name, reinterpret_cast<void*>(s->st_value), reinterpret_cast<void*>((*found)->base));
1383   }
1384 
1385   return s;
1386 }
1387 
find_containing_library(const void * p)1388 soinfo* find_containing_library(const void* p) {
1389   ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p);
1390   for (soinfo* si = solist; si != nullptr; si = si->next) {
1391     if (address >= si->base && address - si->base < si->size) {
1392       return si;
1393     }
1394   }
1395   return nullptr;
1396 }
1397 
ElfW(Sym)1398 ElfW(Sym)* soinfo::find_symbol_by_address(const void* addr) {
1399   return is_gnu_hash() ? gnu_addr_lookup(addr) : elf_addr_lookup(addr);
1400 }
1401 
symbol_matches_soaddr(const ElfW (Sym)* sym,ElfW (Addr)soaddr)1402 static bool symbol_matches_soaddr(const ElfW(Sym)* sym, ElfW(Addr) soaddr) {
1403   return sym->st_shndx != SHN_UNDEF &&
1404       soaddr >= sym->st_value &&
1405       soaddr < sym->st_value + sym->st_size;
1406 }
1407 
ElfW(Sym)1408 ElfW(Sym)* soinfo::gnu_addr_lookup(const void* addr) {
1409   ElfW(Addr) soaddr = reinterpret_cast<ElfW(Addr)>(addr) - load_bias;
1410 
1411   for (size_t i = 0; i < gnu_nbucket_; ++i) {
1412     uint32_t n = gnu_bucket_[i];
1413 
1414     if (n == 0) {
1415       continue;
1416     }
1417 
1418     do {
1419       ElfW(Sym)* sym = symtab_ + n;
1420       if (symbol_matches_soaddr(sym, soaddr)) {
1421         return sym;
1422       }
1423     } while ((gnu_chain_[n++] & 1) == 0);
1424   }
1425 
1426   return nullptr;
1427 }
1428 
ElfW(Sym)1429 ElfW(Sym)* soinfo::elf_addr_lookup(const void* addr) {
1430   ElfW(Addr) soaddr = reinterpret_cast<ElfW(Addr)>(addr) - load_bias;
1431 
1432   // Search the library's symbol table for any defined symbol which
1433   // contains this address.
1434   for (size_t i = 0; i < nchain_; ++i) {
1435     ElfW(Sym)* sym = symtab_ + i;
1436     if (symbol_matches_soaddr(sym, soaddr)) {
1437       return sym;
1438     }
1439   }
1440 
1441   return nullptr;
1442 }
1443 
1444 class ZipArchiveCache {
1445  public:
ZipArchiveCache()1446   ZipArchiveCache() {}
1447   ~ZipArchiveCache();
1448 
1449   bool get_or_open(const char* zip_path, ZipArchiveHandle* handle);
1450  private:
1451   DISALLOW_COPY_AND_ASSIGN(ZipArchiveCache);
1452 
1453   std::unordered_map<std::string, ZipArchiveHandle> cache_;
1454 };
1455 
get_or_open(const char * zip_path,ZipArchiveHandle * handle)1456 bool ZipArchiveCache::get_or_open(const char* zip_path, ZipArchiveHandle* handle) {
1457   std::string key(zip_path);
1458 
1459   auto it = cache_.find(key);
1460   if (it != cache_.end()) {
1461     *handle = it->second;
1462     return true;
1463   }
1464 
1465   int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
1466   if (fd == -1) {
1467     return false;
1468   }
1469 
1470   if (OpenArchiveFd(fd, "", handle) != 0) {
1471     // invalid zip-file (?)
1472     CloseArchive(handle);
1473     close(fd);
1474     return false;
1475   }
1476 
1477   cache_[key] = *handle;
1478   return true;
1479 }
1480 
~ZipArchiveCache()1481 ZipArchiveCache::~ZipArchiveCache() {
1482   for (const auto& it : cache_) {
1483     CloseArchive(it.second);
1484   }
1485 }
1486 
open_library_in_zipfile(ZipArchiveCache * zip_archive_cache,const char * const input_path,off64_t * file_offset,std::string * realpath)1487 static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache,
1488                                    const char* const input_path,
1489                                    off64_t* file_offset, std::string* realpath) {
1490   std::string normalized_path;
1491   if (!normalize_path(input_path, &normalized_path)) {
1492     return -1;
1493   }
1494 
1495   const char* const path = normalized_path.c_str();
1496   TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
1497 
1498   // Treat an '!/' separator inside a path as the separator between the name
1499   // of the zip file on disk and the subdirectory to search within it.
1500   // For example, if path is "foo.zip!/bar/bas/x.so", then we search for
1501   // "bar/bas/x.so" within "foo.zip".
1502   const char* const separator = strstr(path, kZipFileSeparator);
1503   if (separator == nullptr) {
1504     return -1;
1505   }
1506 
1507   char buf[512];
1508   if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
1509     PRINT("Warning: ignoring very long library path: %s", path);
1510     return -1;
1511   }
1512 
1513   buf[separator - path] = '\0';
1514 
1515   const char* zip_path = buf;
1516   const char* file_path = &buf[separator - path + 2];
1517   int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
1518   if (fd == -1) {
1519     return -1;
1520   }
1521 
1522   ZipArchiveHandle handle;
1523   if (!zip_archive_cache->get_or_open(zip_path, &handle)) {
1524     // invalid zip-file (?)
1525     close(fd);
1526     return -1;
1527   }
1528 
1529   ZipEntry entry;
1530 
1531   if (FindEntry(handle, ZipString(file_path), &entry) != 0) {
1532     // Entry was not found.
1533     close(fd);
1534     return -1;
1535   }
1536 
1537   // Check if it is properly stored
1538   if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
1539     close(fd);
1540     return -1;
1541   }
1542 
1543   *file_offset = entry.offset;
1544 
1545   if (realpath_fd(fd, realpath)) {
1546     *realpath += separator;
1547   } else {
1548     PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
1549           normalized_path.c_str());
1550     *realpath = normalized_path;
1551   }
1552 
1553   return fd;
1554 }
1555 
format_path(char * buf,size_t buf_size,const char * path,const char * name)1556 static bool format_path(char* buf, size_t buf_size, const char* path, const char* name) {
1557   int n = __libc_format_buffer(buf, buf_size, "%s/%s", path, name);
1558   if (n < 0 || n >= static_cast<int>(buf_size)) {
1559     PRINT("Warning: ignoring very long library path: %s/%s", path, name);
1560     return false;
1561   }
1562 
1563   return true;
1564 }
1565 
open_library_on_paths(ZipArchiveCache * zip_archive_cache,const char * name,off64_t * file_offset,const std::vector<std::string> & paths,std::string * realpath)1566 static int open_library_on_paths(ZipArchiveCache* zip_archive_cache,
1567                                  const char* name, off64_t* file_offset,
1568                                  const std::vector<std::string>& paths,
1569                                  std::string* realpath) {
1570   for (const auto& path : paths) {
1571     char buf[512];
1572     if (!format_path(buf, sizeof(buf), path.c_str(), name)) {
1573       continue;
1574     }
1575 
1576     int fd = -1;
1577     if (strstr(buf, kZipFileSeparator) != nullptr) {
1578       fd = open_library_in_zipfile(zip_archive_cache, buf, file_offset, realpath);
1579     }
1580 
1581     if (fd == -1) {
1582       fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC));
1583       if (fd != -1) {
1584         *file_offset = 0;
1585         if (!realpath_fd(fd, realpath)) {
1586           PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", buf);
1587           *realpath = buf;
1588         }
1589       }
1590     }
1591 
1592     if (fd != -1) {
1593       return fd;
1594     }
1595   }
1596 
1597   return -1;
1598 }
1599 
open_library(android_namespace_t * ns,ZipArchiveCache * zip_archive_cache,const char * name,soinfo * needed_by,off64_t * file_offset,std::string * realpath)1600 static int open_library(android_namespace_t* ns,
1601                         ZipArchiveCache* zip_archive_cache,
1602                         const char* name, soinfo *needed_by,
1603                         off64_t* file_offset, std::string* realpath) {
1604   TRACE("[ opening %s ]", name);
1605 
1606   // If the name contains a slash, we should attempt to open it directly and not search the paths.
1607   if (strchr(name, '/') != nullptr) {
1608     int fd = -1;
1609 
1610     if (strstr(name, kZipFileSeparator) != nullptr) {
1611       fd = open_library_in_zipfile(zip_archive_cache, name, file_offset, realpath);
1612     }
1613 
1614     if (fd == -1) {
1615       fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
1616       if (fd != -1) {
1617         *file_offset = 0;
1618         if (!realpath_fd(fd, realpath)) {
1619           PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", name);
1620           *realpath = name;
1621         }
1622       }
1623     }
1624 
1625     return fd;
1626   }
1627 
1628   // Otherwise we try LD_LIBRARY_PATH first, and fall back to the default library path
1629   int fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_ld_library_paths(), realpath);
1630   if (fd == -1 && needed_by != nullptr) {
1631     fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath);
1632     // Check if the library is accessible
1633     if (fd != -1 && !ns->is_accessible(*realpath)) {
1634       fd = -1;
1635     }
1636   }
1637 
1638   if (fd == -1) {
1639     fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
1640   }
1641 
1642   // TODO(dimitry): workaround for http://b/26394120 (the grey-list)
1643   if (fd == -1 && ns != &g_default_namespace && is_greylisted(name, needed_by)) {
1644     // try searching for it on default_namespace default_library_path
1645     fd = open_library_on_paths(zip_archive_cache, name, file_offset,
1646                                g_default_namespace.get_default_library_paths(), realpath);
1647   }
1648   // END OF WORKAROUND
1649 
1650   return fd;
1651 }
1652 
fix_dt_needed(const char * dt_needed,const char * sopath __unused)1653 static const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
1654 #if !defined(__LP64__)
1655   // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
1656   if (get_application_target_sdk_version() <= 22) {
1657     const char* bname = basename(dt_needed);
1658     if (bname != dt_needed) {
1659       DL_WARN("library \"%s\" has invalid DT_NEEDED entry \"%s\"", sopath, dt_needed);
1660       add_dlwarning(sopath, "invalid DT_NEEDED entry",  dt_needed);
1661     }
1662 
1663     return bname;
1664   }
1665 #endif
1666   return dt_needed;
1667 }
1668 
1669 template<typename F>
for_each_dt_needed(const soinfo * si,F action)1670 static void for_each_dt_needed(const soinfo* si, F action) {
1671   for (const ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) {
1672     if (d->d_tag == DT_NEEDED) {
1673       action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath()));
1674     }
1675   }
1676 }
1677 
1678 template<typename F>
for_each_dt_needed(const ElfReader & elf_reader,F action)1679 static void for_each_dt_needed(const ElfReader& elf_reader, F action) {
1680   for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
1681     if (d->d_tag == DT_NEEDED) {
1682       action(fix_dt_needed(elf_reader.get_string(d->d_un.d_val), elf_reader.name()));
1683     }
1684   }
1685 }
1686 
load_library(android_namespace_t * ns,LoadTask * task,LoadTaskList * load_tasks,int rtld_flags,const std::string & realpath)1687 static bool load_library(android_namespace_t* ns,
1688                          LoadTask* task,
1689                          LoadTaskList* load_tasks,
1690                          int rtld_flags,
1691                          const std::string& realpath) {
1692   off64_t file_offset = task->get_file_offset();
1693   const char* name = task->get_name();
1694   const android_dlextinfo* extinfo = task->get_extinfo();
1695 
1696   if ((file_offset % PAGE_SIZE) != 0) {
1697     DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
1698     return false;
1699   }
1700   if (file_offset < 0) {
1701     DL_ERR("file offset for the library \"%s\" is negative: %" PRId64, name, file_offset);
1702     return false;
1703   }
1704 
1705   struct stat file_stat;
1706   if (TEMP_FAILURE_RETRY(fstat(task->get_fd(), &file_stat)) != 0) {
1707     DL_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
1708     return false;
1709   }
1710   if (file_offset >= file_stat.st_size) {
1711     DL_ERR("file offset for the library \"%s\" >= file size: %" PRId64 " >= %" PRId64,
1712         name, file_offset, file_stat.st_size);
1713     return false;
1714   }
1715 
1716   // Check for symlink and other situations where
1717   // file can have different names, unless ANDROID_DLEXT_FORCE_LOAD is set
1718   if (extinfo == nullptr || (extinfo->flags & ANDROID_DLEXT_FORCE_LOAD) == 0) {
1719     auto predicate = [&](soinfo* si) {
1720       return si->get_st_dev() != 0 &&
1721              si->get_st_ino() != 0 &&
1722              si->get_st_dev() == file_stat.st_dev &&
1723              si->get_st_ino() == file_stat.st_ino &&
1724              si->get_file_offset() == file_offset;
1725     };
1726 
1727     soinfo* si = ns->soinfo_list().find_if(predicate);
1728 
1729     // check public namespace
1730     if (si == nullptr) {
1731       si = g_public_namespace.find_if(predicate);
1732       if (si != nullptr) {
1733         ns->add_soinfo(si);
1734       }
1735     }
1736 
1737     if (si != nullptr) {
1738       TRACE("library \"%s\" is already loaded under different name/path \"%s\" - "
1739             "will return existing soinfo", name, si->get_realpath());
1740       task->set_soinfo(si);
1741       return true;
1742     }
1743   }
1744 
1745   if ((rtld_flags & RTLD_NOLOAD) != 0) {
1746     DL_ERR("library \"%s\" wasn't loaded and RTLD_NOLOAD prevented it", name);
1747     return false;
1748   }
1749 
1750   if (!ns->is_accessible(realpath)) {
1751     // TODO(dimitry): workaround for http://b/26394120 - the grey-list
1752     const soinfo* needed_by = task->is_dt_needed() ? task->get_needed_by() : nullptr;
1753     if (is_greylisted(name, needed_by)) {
1754       // print warning only if needed by non-system library
1755       if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) {
1756         const soinfo* needed_or_dlopened_by = task->get_needed_by();
1757         const char* sopath = needed_or_dlopened_by == nullptr ? "(unknown)" :
1758                                                       needed_or_dlopened_by->get_realpath();
1759         DL_WARN("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the namespace \"%s\""
1760                 " - the access is temporarily granted as a workaround for http://b/26394120, note that the access"
1761                 " will be removed in future releases of Android.",
1762                 name, realpath.c_str(), sopath, ns->get_name());
1763         add_dlwarning(sopath, "unauthorized access to",  name);
1764       }
1765     } else {
1766       // do not load libraries if they are not accessible for the specified namespace.
1767       const char* needed_or_dlopened_by = task->get_needed_by() == nullptr ?
1768                                           "(unknown)" :
1769                                           task->get_needed_by()->get_realpath();
1770 
1771       DL_ERR("library \"%s\" needed or dlopened by \"%s\" is not accessible for the namespace \"%s\"",
1772              name, needed_or_dlopened_by, ns->get_name());
1773 
1774       PRINT("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the"
1775             " namespace: [name=\"%s\", ld_library_paths=\"%s\", default_library_paths=\"%s\","
1776             " permitted_paths=\"%s\"]",
1777             name, realpath.c_str(),
1778             needed_or_dlopened_by,
1779             ns->get_name(),
1780             android::base::Join(ns->get_ld_library_paths(), ':').c_str(),
1781             android::base::Join(ns->get_default_library_paths(), ':').c_str(),
1782             android::base::Join(ns->get_permitted_paths(), ':').c_str());
1783       return false;
1784     }
1785   }
1786 
1787   soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);
1788   if (si == nullptr) {
1789     return false;
1790   }
1791 
1792   task->set_soinfo(si);
1793 
1794   // Read the ELF header and some of the segments.
1795   if (!task->read(realpath.c_str(), file_stat.st_size)) {
1796     soinfo_free(si);
1797     task->set_soinfo(nullptr);
1798     return false;
1799   }
1800 
1801   // find and set DT_RUNPATH and dt_soname
1802   // Note that these field values are temporary and are
1803   // going to be overwritten on soinfo::prelink_image
1804   // with values from PT_LOAD segments.
1805   const ElfReader& elf_reader = task->get_elf_reader();
1806   for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
1807     if (d->d_tag == DT_RUNPATH) {
1808       si->set_dt_runpath(elf_reader.get_string(d->d_un.d_val));
1809     }
1810     if (d->d_tag == DT_SONAME) {
1811       si->set_soname(elf_reader.get_string(d->d_un.d_val));
1812     }
1813   }
1814 
1815   for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
1816     load_tasks->push_back(LoadTask::create(name, si, task->get_readers_map()));
1817   });
1818 
1819   return true;
1820 }
1821 
load_library(android_namespace_t * ns,LoadTask * task,ZipArchiveCache * zip_archive_cache,LoadTaskList * load_tasks,int rtld_flags)1822 static bool load_library(android_namespace_t* ns,
1823                          LoadTask* task,
1824                          ZipArchiveCache* zip_archive_cache,
1825                          LoadTaskList* load_tasks,
1826                          int rtld_flags) {
1827   const char* name = task->get_name();
1828   soinfo* needed_by = task->get_needed_by();
1829   const android_dlextinfo* extinfo = task->get_extinfo();
1830 
1831   off64_t file_offset;
1832   std::string realpath;
1833   if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
1834     file_offset = 0;
1835     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
1836       file_offset = extinfo->library_fd_offset;
1837     }
1838 
1839     if (!realpath_fd(extinfo->library_fd, &realpath)) {
1840       PRINT("warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
1841             "Will use given name.", name);
1842       realpath = name;
1843     }
1844 
1845     task->set_fd(extinfo->library_fd, false);
1846     task->set_file_offset(file_offset);
1847     return load_library(ns, task, load_tasks, rtld_flags, realpath);
1848   }
1849 
1850   // Open the file.
1851   int fd = open_library(ns, zip_archive_cache, name, needed_by, &file_offset, &realpath);
1852   if (fd == -1) {
1853     DL_ERR("library \"%s\" not found", name);
1854     return false;
1855   }
1856 
1857   task->set_fd(fd, true);
1858   task->set_file_offset(file_offset);
1859 
1860   return load_library(ns, task, load_tasks, rtld_flags, realpath);
1861 }
1862 
1863 // Returns true if library was found and false in 2 cases
1864 // 1. (for default namespace only) The library was found but loaded under different
1865 //    target_sdk_version (*candidate != nullptr)
1866 // 2. The library was not found by soname (*candidate is nullptr)
find_loaded_library_by_soname(android_namespace_t * ns,const char * name,soinfo ** candidate)1867 static bool find_loaded_library_by_soname(android_namespace_t* ns,
1868                                           const char* name, soinfo** candidate) {
1869   *candidate = nullptr;
1870 
1871   // Ignore filename with path.
1872   if (strchr(name, '/') != nullptr) {
1873     return false;
1874   }
1875 
1876   uint32_t target_sdk_version = get_application_target_sdk_version();
1877 
1878   return !ns->soinfo_list().visit([&](soinfo* si) {
1879     const char* soname = si->get_soname();
1880     if (soname != nullptr && (strcmp(name, soname) == 0)) {
1881       // If the library was opened under different target sdk version
1882       // skip this step and try to reopen it. The exceptions are
1883       // "libdl.so" and global group. There is no point in skipping
1884       // them because relocation process is going to use them
1885       // in any case.
1886       bool is_libdl = si == solist;
1887       if (is_libdl || (si->get_dt_flags_1() & DF_1_GLOBAL) != 0 ||
1888           !si->is_linked() || si->get_target_sdk_version() == target_sdk_version ||
1889           ns != &g_default_namespace) {
1890         *candidate = si;
1891         return false;
1892       } else if (*candidate == nullptr) {
1893         // for the different sdk version in the default namespace
1894         // remember the first library.
1895         *candidate = si;
1896       }
1897     }
1898 
1899     return true;
1900   });
1901 }
1902 
find_library_internal(android_namespace_t * ns,LoadTask * task,ZipArchiveCache * zip_archive_cache,LoadTaskList * load_tasks,int rtld_flags)1903 static bool find_library_internal(android_namespace_t* ns,
1904                                   LoadTask* task,
1905                                   ZipArchiveCache* zip_archive_cache,
1906                                   LoadTaskList* load_tasks,
1907                                   int rtld_flags) {
1908   soinfo* candidate;
1909 
1910   if (find_loaded_library_by_soname(ns, task->get_name(), &candidate)) {
1911     task->set_soinfo(candidate);
1912     return true;
1913   }
1914 
1915   if (ns != &g_default_namespace) {
1916     // check public namespace
1917     candidate = g_public_namespace.find_if([&](soinfo* si) {
1918       return strcmp(task->get_name(), si->get_soname()) == 0;
1919     });
1920 
1921     if (candidate != nullptr) {
1922       ns->add_soinfo(candidate);
1923       task->set_soinfo(candidate);
1924       return true;
1925     }
1926   }
1927 
1928   // Library might still be loaded, the accurate detection
1929   // of this fact is done by load_library.
1930   TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]",
1931       task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
1932 
1933   if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags)) {
1934     return true;
1935   } else {
1936     // In case we were unable to load the library but there
1937     // is a candidate loaded under the same soname but different
1938     // sdk level - return it anyways.
1939     if (candidate != nullptr) {
1940       task->set_soinfo(candidate);
1941       return true;
1942     }
1943   }
1944 
1945   return false;
1946 }
1947 
1948 static void soinfo_unload(soinfo* si);
1949 static void soinfo_unload(soinfo* soinfos[], size_t count);
1950 
1951 // TODO: this is slightly unusual way to construct
1952 // the global group for relocation. Not every RTLD_GLOBAL
1953 // library is included in this group for backwards-compatibility
1954 // reasons.
1955 //
1956 // This group consists of the main executable, LD_PRELOADs
1957 // and libraries with the DF_1_GLOBAL flag set.
make_global_group(android_namespace_t * ns)1958 static soinfo::soinfo_list_t make_global_group(android_namespace_t* ns) {
1959   soinfo::soinfo_list_t global_group;
1960   ns->soinfo_list().for_each([&](soinfo* si) {
1961     if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
1962       global_group.push_back(si);
1963     }
1964   });
1965 
1966   return global_group;
1967 }
1968 
1969 // This function provides a list of libraries to be shared
1970 // by the namespace. For the default namespace this is the global
1971 // group (see make_global_group). For all others this is a group
1972 // of RTLD_GLOBAL libraries (which includes the global group from
1973 // the default namespace).
get_shared_group(android_namespace_t * ns)1974 static soinfo::soinfo_list_t get_shared_group(android_namespace_t* ns) {
1975   if (ns == &g_default_namespace) {
1976     return make_global_group(ns);
1977   }
1978 
1979   soinfo::soinfo_list_t shared_group;
1980   ns->soinfo_list().for_each([&](soinfo* si) {
1981     if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
1982       shared_group.push_back(si);
1983     }
1984   });
1985 
1986   return shared_group;
1987 }
1988 
shuffle(std::vector<LoadTask * > * v)1989 static void shuffle(std::vector<LoadTask*>* v) {
1990   for (size_t i = 0, size = v->size(); i < size; ++i) {
1991     size_t n = size - i;
1992     size_t r = arc4random_uniform(n);
1993     std::swap((*v)[n-1], (*v)[r]);
1994   }
1995 }
1996 
1997 // add_as_children - add first-level loaded libraries (i.e. library_names[], but
1998 // not their transitive dependencies) as children of the start_with library.
1999 // This is false when find_libraries is called for dlopen(), when newly loaded
2000 // 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)2001 static bool find_libraries(android_namespace_t* ns,
2002                            soinfo* start_with,
2003                            const char* const library_names[],
2004                            size_t library_names_count, soinfo* soinfos[],
2005                            std::vector<soinfo*>* ld_preloads,
2006                            size_t ld_preloads_count, int rtld_flags,
2007                            const android_dlextinfo* extinfo,
2008                            bool add_as_children) {
2009   // Step 0: prepare.
2010   LoadTaskList load_tasks;
2011   std::unordered_map<const soinfo*, ElfReader> readers_map;
2012 
2013   for (size_t i = 0; i < library_names_count; ++i) {
2014     const char* name = library_names[i];
2015     load_tasks.push_back(LoadTask::create(name, start_with, &readers_map));
2016   }
2017 
2018   // Construct global_group.
2019   soinfo::soinfo_list_t global_group = make_global_group(ns);
2020 
2021   // If soinfos array is null allocate one on stack.
2022   // The array is needed in case of failure; for example
2023   // when library_names[] = {libone.so, libtwo.so} and libone.so
2024   // is loaded correctly but libtwo.so failed for some reason.
2025   // In this case libone.so should be unloaded on return.
2026   // See also implementation of failure_guard below.
2027 
2028   if (soinfos == nullptr) {
2029     size_t soinfos_size = sizeof(soinfo*)*library_names_count;
2030     soinfos = reinterpret_cast<soinfo**>(alloca(soinfos_size));
2031     memset(soinfos, 0, soinfos_size);
2032   }
2033 
2034   // list of libraries to link - see step 2.
2035   size_t soinfos_count = 0;
2036 
2037   auto scope_guard = make_scope_guard([&]() {
2038     for (LoadTask* t : load_tasks) {
2039       LoadTask::deleter(t);
2040     }
2041   });
2042 
2043   auto failure_guard = make_scope_guard([&]() {
2044     // Housekeeping
2045     soinfo_unload(soinfos, soinfos_count);
2046   });
2047 
2048   ZipArchiveCache zip_archive_cache;
2049 
2050   // Step 1: expand the list of load_tasks to include
2051   // all DT_NEEDED libraries (do not load them just yet)
2052   for (size_t i = 0; i<load_tasks.size(); ++i) {
2053     LoadTask* task = load_tasks[i];
2054     soinfo* needed_by = task->get_needed_by();
2055 
2056     bool is_dt_needed = needed_by != nullptr && (needed_by != start_with || add_as_children);
2057     task->set_extinfo(is_dt_needed ? nullptr : extinfo);
2058     task->set_dt_needed(is_dt_needed);
2059 
2060     if(!find_library_internal(ns, task, &zip_archive_cache, &load_tasks, rtld_flags)) {
2061       return false;
2062     }
2063 
2064     soinfo* si = task->get_soinfo();
2065 
2066     if (is_dt_needed) {
2067       needed_by->add_child(si);
2068     }
2069 
2070     if (si->is_linked()) {
2071       si->increment_ref_count();
2072     }
2073 
2074     // When ld_preloads is not null, the first
2075     // ld_preloads_count libs are in fact ld_preloads.
2076     if (ld_preloads != nullptr && soinfos_count < ld_preloads_count) {
2077       ld_preloads->push_back(si);
2078     }
2079 
2080     if (soinfos_count < library_names_count) {
2081       soinfos[soinfos_count++] = si;
2082     }
2083   }
2084 
2085   // Step 2: Load libraries in random order (see b/24047022)
2086   LoadTaskList load_list;
2087   for (auto&& task : load_tasks) {
2088     soinfo* si = task->get_soinfo();
2089     auto pred = [&](const LoadTask* t) {
2090       return t->get_soinfo() == si;
2091     };
2092 
2093     if (!si->is_linked() &&
2094         std::find_if(load_list.begin(), load_list.end(), pred) == load_list.end() ) {
2095       load_list.push_back(task);
2096     }
2097   }
2098   shuffle(&load_list);
2099 
2100   for (auto&& task : load_list) {
2101     if (!task->load()) {
2102       return false;
2103     }
2104   }
2105 
2106   // Step 3: pre-link all DT_NEEDED libraries in breadth first order.
2107   for (auto&& task : load_tasks) {
2108     soinfo* si = task->get_soinfo();
2109     if (!si->is_linked() && !si->prelink_image()) {
2110       return false;
2111     }
2112   }
2113 
2114   // Step 4: Add LD_PRELOADed libraries to the global group for
2115   // future runs. There is no need to explicitly add them to
2116   // the global group for this run because they are going to
2117   // appear in the local group in the correct order.
2118   if (ld_preloads != nullptr) {
2119     for (auto&& si : *ld_preloads) {
2120       si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
2121     }
2122   }
2123 
2124 
2125   // Step 5: link libraries.
2126   soinfo::soinfo_list_t local_group;
2127   walk_dependencies_tree(
2128       (start_with != nullptr && add_as_children) ? &start_with : soinfos,
2129       (start_with != nullptr && add_as_children) ? 1 : soinfos_count,
2130       [&] (soinfo* si) {
2131     local_group.push_back(si);
2132     return true;
2133   });
2134 
2135   // We need to increment ref_count in case
2136   // the root of the local group was not linked.
2137   bool was_local_group_root_linked = local_group.front()->is_linked();
2138 
2139   bool linked = local_group.visit([&](soinfo* si) {
2140     if (!si->is_linked()) {
2141       if (!si->link_image(global_group, local_group, extinfo)) {
2142         return false;
2143       }
2144     }
2145 
2146     return true;
2147   });
2148 
2149   if (linked) {
2150     local_group.for_each([](soinfo* si) {
2151       if (!si->is_linked()) {
2152         si->set_linked();
2153       }
2154     });
2155 
2156     failure_guard.disable();
2157   }
2158 
2159   if (!was_local_group_root_linked) {
2160     local_group.front()->increment_ref_count();
2161   }
2162 
2163   return linked;
2164 }
2165 
find_library(android_namespace_t * ns,const char * name,int rtld_flags,const android_dlextinfo * extinfo,soinfo * needed_by)2166 static soinfo* find_library(android_namespace_t* ns,
2167                             const char* name, int rtld_flags,
2168                             const android_dlextinfo* extinfo,
2169                             soinfo* needed_by) {
2170   soinfo* si;
2171 
2172   if (name == nullptr) {
2173     si = somain;
2174   } else if (!find_libraries(ns, needed_by, &name, 1, &si, nullptr, 0, rtld_flags,
2175                              extinfo, /* add_as_children */ false)) {
2176     return nullptr;
2177   }
2178 
2179   return si;
2180 }
2181 
soinfo_unload(soinfo * root)2182 static void soinfo_unload(soinfo* root) {
2183   if (root->is_linked()) {
2184     root = root->get_local_group_root();
2185   }
2186 
2187   if (!root->can_unload()) {
2188     TRACE("not unloading \"%s\" - the binary is flagged with NODELETE", root->get_realpath());
2189     return;
2190   }
2191 
2192   soinfo_unload(&root, 1);
2193 }
2194 
soinfo_unload(soinfo * soinfos[],size_t count)2195 static void soinfo_unload(soinfo* soinfos[], size_t count) {
2196   // Note that the library can be loaded but not linked;
2197   // in which case there is no root but we still need
2198   // to walk the tree and unload soinfos involved.
2199   //
2200   // This happens on unsuccessful dlopen, when one of
2201   // the DT_NEEDED libraries could not be linked/found.
2202   if (count == 0) {
2203     return;
2204   }
2205 
2206   soinfo::soinfo_list_t unload_list;
2207   for (size_t i = 0; i < count; ++i) {
2208     soinfo* si = soinfos[i];
2209 
2210     if (si->can_unload()) {
2211       size_t ref_count = si->is_linked() ? si->decrement_ref_count() : 0;
2212       if (ref_count == 0) {
2213         unload_list.push_back(si);
2214       } else {
2215         TRACE("not unloading '%s' group, decrementing ref_count to %zd",
2216             si->get_realpath(), ref_count);
2217       }
2218     } else {
2219       TRACE("not unloading '%s' - the binary is flagged with NODELETE", si->get_realpath());
2220       return;
2221     }
2222   }
2223 
2224   // This is used to identify soinfos outside of the load-group
2225   // note that we cannot have > 1 in the array and have any of them
2226   // linked. This is why we can safely use the first one.
2227   soinfo* root = soinfos[0];
2228 
2229   soinfo::soinfo_list_t local_unload_list;
2230   soinfo::soinfo_list_t external_unload_list;
2231   soinfo* si = nullptr;
2232 
2233   while ((si = unload_list.pop_front()) != nullptr) {
2234     if (local_unload_list.contains(si)) {
2235       continue;
2236     }
2237 
2238     local_unload_list.push_back(si);
2239 
2240     if (si->has_min_version(0)) {
2241       soinfo* child = nullptr;
2242       while ((child = si->get_children().pop_front()) != nullptr) {
2243         TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
2244             child->get_realpath(), child);
2245 
2246         if (local_unload_list.contains(child)) {
2247           continue;
2248         } else if (child->is_linked() && child->get_local_group_root() != root) {
2249           child->get_parents().remove_if([&] (const soinfo* parent) {
2250             return parent == si;
2251           });
2252           external_unload_list.push_back(child);
2253         } else {
2254           unload_list.push_front(child);
2255         }
2256       }
2257     } else {
2258 #if !defined(__work_around_b_24465209__)
2259       __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
2260 #else
2261       PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
2262       for_each_dt_needed(si, [&] (const char* library_name) {
2263         TRACE("deprecated (old format of soinfo): %s needs to unload %s",
2264             si->get_realpath(), library_name);
2265 
2266         soinfo* needed = find_library(si->get_primary_namespace(),
2267                                       library_name, RTLD_NOLOAD, nullptr, nullptr);
2268 
2269         if (needed != nullptr) {
2270           // Not found: for example if symlink was deleted between dlopen and dlclose
2271           // Since we cannot really handle errors at this point - print and continue.
2272           PRINT("warning: couldn't find %s needed by %s on unload.",
2273               library_name, si->get_realpath());
2274           return;
2275         } else if (local_unload_list.contains(needed)) {
2276           // already visited
2277           return;
2278         } else if (needed->is_linked() && needed->get_local_group_root() != root) {
2279           // external group
2280           external_unload_list.push_back(needed);
2281         } else {
2282           // local group
2283           unload_list.push_front(needed);
2284         }
2285       });
2286 #endif
2287     }
2288   }
2289 
2290   local_unload_list.for_each([](soinfo* si) {
2291     si->call_destructors();
2292   });
2293 
2294   while ((si = local_unload_list.pop_front()) != nullptr) {
2295     notify_gdb_of_unload(si);
2296     soinfo_free(si);
2297   }
2298 
2299   while ((si = external_unload_list.pop_front()) != nullptr) {
2300     soinfo_unload(si);
2301   }
2302 }
2303 
symbol_display_name(const char * sym_name,const char * sym_ver)2304 static std::string symbol_display_name(const char* sym_name, const char* sym_ver) {
2305   if (sym_ver == nullptr) {
2306     return sym_name;
2307   }
2308 
2309   return std::string(sym_name) + ", version " + sym_ver;
2310 }
2311 
get_caller_namespace(soinfo * caller)2312 static android_namespace_t* get_caller_namespace(soinfo* caller) {
2313   return caller != nullptr ? caller->get_primary_namespace() : g_anonymous_namespace;
2314 }
2315 
do_android_get_LD_LIBRARY_PATH(char * buffer,size_t buffer_size)2316 void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
2317   // Use basic string manipulation calls to avoid snprintf.
2318   // snprintf indirectly calls pthread_getspecific to get the size of a buffer.
2319   // When debug malloc is enabled, this call returns 0. This in turn causes
2320   // snprintf to do nothing, which causes libraries to fail to load.
2321   // See b/17302493 for further details.
2322   // Once the above bug is fixed, this code can be modified to use
2323   // snprintf again.
2324   size_t required_len = 0;
2325   for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
2326     required_len += strlen(g_default_ld_paths[i]) + 1;
2327   }
2328   if (buffer_size < required_len) {
2329     __libc_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: "
2330                  "buffer len %zu, required len %zu", buffer_size, required_len);
2331   }
2332   char* end = buffer;
2333   for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
2334     if (i > 0) *end++ = ':';
2335     end = stpcpy(end, g_default_ld_paths[i]);
2336   }
2337 }
2338 
do_android_update_LD_LIBRARY_PATH(const char * ld_library_path)2339 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
2340   parse_LD_LIBRARY_PATH(ld_library_path);
2341 }
2342 
do_dlopen(const char * name,int flags,const android_dlextinfo * extinfo,void * caller_addr)2343 void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo,
2344                   void* caller_addr) {
2345   soinfo* const caller = find_containing_library(caller_addr);
2346 
2347   if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {
2348     DL_ERR("invalid flags to dlopen: %x", flags);
2349     return nullptr;
2350   }
2351 
2352   android_namespace_t* ns = get_caller_namespace(caller);
2353 
2354   if (extinfo != nullptr) {
2355     if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {
2356       DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags);
2357       return nullptr;
2358     }
2359 
2360     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 &&
2361         (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
2362       DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without "
2363           "ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);
2364       return nullptr;
2365     }
2366 
2367     if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 &&
2368         (extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) {
2369       DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not "
2370              "compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT");
2371       return nullptr;
2372     }
2373 
2374     if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) {
2375       if (extinfo->library_namespace == nullptr) {
2376         DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null");
2377         return nullptr;
2378       }
2379       ns = extinfo->library_namespace;
2380     }
2381   }
2382 
2383   std::string asan_name_holder;
2384 
2385   const char* translated_name = name;
2386   if (g_is_asan) {
2387     if (file_is_in_dir(name, kSystemLibDir)) {
2388       asan_name_holder = std::string(kAsanSystemLibDir) + "/" + basename(name);
2389       if (file_exists(asan_name_holder.c_str())) {
2390         translated_name = asan_name_holder.c_str();
2391         PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
2392       }
2393     } else if (file_is_in_dir(name, kVendorLibDir)) {
2394       asan_name_holder = std::string(kAsanVendorLibDir) + "/" + basename(name);
2395       if (file_exists(asan_name_holder.c_str())) {
2396         translated_name = asan_name_holder.c_str();
2397         PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
2398       }
2399     }
2400   }
2401 
2402   ProtectedDataGuard guard;
2403   soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
2404   if (si != nullptr) {
2405     si->call_constructors();
2406     return si->to_handle();
2407   }
2408 
2409   return nullptr;
2410 }
2411 
do_dladdr(const void * addr,Dl_info * info)2412 int do_dladdr(const void* addr, Dl_info* info) {
2413   // Determine if this address can be found in any library currently mapped.
2414   soinfo* si = find_containing_library(addr);
2415   if (si == nullptr) {
2416     return 0;
2417   }
2418 
2419   memset(info, 0, sizeof(Dl_info));
2420 
2421   info->dli_fname = si->get_realpath();
2422   // Address at which the shared object is loaded.
2423   info->dli_fbase = reinterpret_cast<void*>(si->base);
2424 
2425   // Determine if any symbol in the library contains the specified address.
2426   ElfW(Sym)* sym = si->find_symbol_by_address(addr);
2427   if (sym != nullptr) {
2428     info->dli_sname = si->get_string(sym->st_name);
2429     info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
2430   }
2431 
2432   return 1;
2433 }
2434 
soinfo_from_handle(void * handle)2435 static soinfo* soinfo_from_handle(void* handle) {
2436   if ((reinterpret_cast<uintptr_t>(handle) & 1) != 0) {
2437     auto it = g_soinfo_handles_map.find(reinterpret_cast<uintptr_t>(handle));
2438     if (it == g_soinfo_handles_map.end()) {
2439       return nullptr;
2440     } else {
2441       return it->second;
2442     }
2443   }
2444 
2445   return static_cast<soinfo*>(handle);
2446 }
2447 
do_dlsym(void * handle,const char * sym_name,const char * sym_ver,void * caller_addr,void ** symbol)2448 bool do_dlsym(void* handle, const char* sym_name, const char* sym_ver,
2449               void* caller_addr, void** symbol) {
2450 #if !defined(__LP64__)
2451   if (handle == nullptr) {
2452     DL_ERR("dlsym failed: library handle is null");
2453     return false;
2454   }
2455 #endif
2456 
2457   if (sym_name == nullptr) {
2458     DL_ERR("dlsym failed: symbol name is null");
2459     return false;
2460   }
2461 
2462   soinfo* found = nullptr;
2463   const ElfW(Sym)* sym = nullptr;
2464   soinfo* caller = find_containing_library(caller_addr);
2465   android_namespace_t* ns = get_caller_namespace(caller);
2466 
2467   version_info vi_instance;
2468   version_info* vi = nullptr;
2469 
2470   if (sym_ver != nullptr) {
2471     vi_instance.name = sym_ver;
2472     vi_instance.elf_hash = calculate_elf_hash(sym_ver);
2473     vi = &vi_instance;
2474   }
2475 
2476   if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
2477     sym = dlsym_linear_lookup(ns, sym_name, vi, &found, caller, handle);
2478   } else {
2479     soinfo* si = soinfo_from_handle(handle);
2480     if (si == nullptr) {
2481       DL_ERR("dlsym failed: invalid handle: %p", handle);
2482       return false;
2483     }
2484     sym = dlsym_handle_lookup(si, &found, sym_name, vi);
2485   }
2486 
2487   if (sym != nullptr) {
2488     uint32_t bind = ELF_ST_BIND(sym->st_info);
2489 
2490     if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
2491       *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
2492       return true;
2493     }
2494 
2495     DL_ERR("symbol \"%s\" found but not global", symbol_display_name(sym_name, sym_ver).c_str());
2496     return false;
2497   }
2498 
2499   DL_ERR("undefined symbol: %s", symbol_display_name(sym_name, sym_ver).c_str());
2500   return false;
2501 }
2502 
do_dlclose(void * handle)2503 int do_dlclose(void* handle) {
2504   ProtectedDataGuard guard;
2505   soinfo* si = soinfo_from_handle(handle);
2506   if (si == nullptr) {
2507     DL_ERR("invalid handle: %p", handle);
2508     return -1;
2509   }
2510 
2511   soinfo_unload(si);
2512   return 0;
2513 }
2514 
init_namespaces(const char * public_ns_sonames,const char * anon_ns_library_path)2515 bool init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path) {
2516   CHECK(public_ns_sonames != nullptr);
2517   if (g_public_namespace_initialized) {
2518     DL_ERR("public namespace has already been initialized.");
2519     return false;
2520   }
2521 
2522   std::vector<std::string> sonames = android::base::Split(public_ns_sonames, ":");
2523 
2524   ProtectedDataGuard guard;
2525 
2526   auto failure_guard = make_scope_guard([&]() {
2527     g_public_namespace.clear();
2528   });
2529 
2530   for (const auto& soname : sonames) {
2531     soinfo* candidate = nullptr;
2532 
2533     find_loaded_library_by_soname(&g_default_namespace, soname.c_str(), &candidate);
2534 
2535     if (candidate == nullptr) {
2536       DL_ERR("error initializing public namespace: a library with soname \"%s\""
2537              " was not found in the default namespace", soname.c_str());
2538       return false;
2539     }
2540 
2541     candidate->set_nodelete();
2542     g_public_namespace.push_back(candidate);
2543   }
2544 
2545   g_public_namespace_initialized = true;
2546 
2547   // create anonymous namespace
2548   // When the caller is nullptr - create_namespace will take global group
2549   // from the anonymous namespace, which is fine because anonymous namespace
2550   // is still pointing to the default one.
2551   android_namespace_t* anon_ns =
2552       create_namespace(nullptr, "(anonymous)", nullptr, anon_ns_library_path,
2553                        ANDROID_NAMESPACE_TYPE_REGULAR, nullptr, &g_default_namespace);
2554 
2555   if (anon_ns == nullptr) {
2556     g_public_namespace_initialized = false;
2557     return false;
2558   }
2559   g_anonymous_namespace = anon_ns;
2560   failure_guard.disable();
2561   return true;
2562 }
2563 
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)2564 android_namespace_t* create_namespace(const void* caller_addr,
2565                                       const char* name,
2566                                       const char* ld_library_path,
2567                                       const char* default_library_path,
2568                                       uint64_t type,
2569                                       const char* permitted_when_isolated_path,
2570                                       android_namespace_t* parent_namespace) {
2571   if (!g_public_namespace_initialized) {
2572     DL_ERR("cannot create namespace: public namespace is not initialized.");
2573     return nullptr;
2574   }
2575 
2576   if (parent_namespace == nullptr) {
2577     // if parent_namespace is nullptr -> set it to the caller namespace
2578     soinfo* caller_soinfo = find_containing_library(caller_addr);
2579 
2580     parent_namespace = caller_soinfo != nullptr ?
2581                        caller_soinfo->get_primary_namespace() :
2582                        g_anonymous_namespace;
2583   }
2584 
2585   ProtectedDataGuard guard;
2586   std::vector<std::string> ld_library_paths;
2587   std::vector<std::string> default_library_paths;
2588   std::vector<std::string> permitted_paths;
2589 
2590   parse_path(ld_library_path, ":", &ld_library_paths);
2591   parse_path(default_library_path, ":", &default_library_paths);
2592   parse_path(permitted_when_isolated_path, ":", &permitted_paths);
2593 
2594   android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
2595   ns->set_name(name);
2596   ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
2597   ns->set_ld_library_paths(std::move(ld_library_paths));
2598   ns->set_default_library_paths(std::move(default_library_paths));
2599   ns->set_permitted_paths(std::move(permitted_paths));
2600 
2601   if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
2602     // If shared - clone the parent namespace
2603     ns->add_soinfos(parent_namespace->soinfo_list());
2604   } else {
2605     // If not shared - copy only the shared group
2606     ns->add_soinfos(get_shared_group(parent_namespace));
2607   }
2608 
2609   return ns;
2610 }
2611 
call_ifunc_resolver(ElfW (Addr)resolver_addr)2612 static ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr) {
2613   typedef ElfW(Addr) (*ifunc_resolver_t)(void);
2614   ifunc_resolver_t ifunc_resolver = reinterpret_cast<ifunc_resolver_t>(resolver_addr);
2615   ElfW(Addr) ifunc_addr = ifunc_resolver();
2616   TRACE_TYPE(RELO, "Called ifunc_resolver@%p. The result is %p",
2617       ifunc_resolver, reinterpret_cast<void*>(ifunc_addr));
2618 
2619   return ifunc_addr;
2620 }
2621 
get_version_info(ElfW (Versym)source_symver) const2622 const version_info* VersionTracker::get_version_info(ElfW(Versym) source_symver) const {
2623   if (source_symver < 2 ||
2624       source_symver >= version_infos.size() ||
2625       version_infos[source_symver].name == nullptr) {
2626     return nullptr;
2627   }
2628 
2629   return &version_infos[source_symver];
2630 }
2631 
add_version_info(size_t source_index,ElfW (Word)elf_hash,const char * ver_name,const soinfo * target_si)2632 void VersionTracker::add_version_info(size_t source_index,
2633                                       ElfW(Word) elf_hash,
2634                                       const char* ver_name,
2635                                       const soinfo* target_si) {
2636   if (source_index >= version_infos.size()) {
2637     version_infos.resize(source_index+1);
2638   }
2639 
2640   version_infos[source_index].elf_hash = elf_hash;
2641   version_infos[source_index].name = ver_name;
2642   version_infos[source_index].target_si = target_si;
2643 }
2644 
init_verneed(const soinfo * si_from)2645 bool VersionTracker::init_verneed(const soinfo* si_from) {
2646   uintptr_t verneed_ptr = si_from->get_verneed_ptr();
2647 
2648   if (verneed_ptr == 0) {
2649     return true;
2650   }
2651 
2652   size_t verneed_cnt = si_from->get_verneed_cnt();
2653 
2654   for (size_t i = 0, offset = 0; i<verneed_cnt; ++i) {
2655     const ElfW(Verneed)* verneed = reinterpret_cast<ElfW(Verneed)*>(verneed_ptr + offset);
2656     size_t vernaux_offset = offset + verneed->vn_aux;
2657     offset += verneed->vn_next;
2658 
2659     if (verneed->vn_version != 1) {
2660       DL_ERR("unsupported verneed[%zd] vn_version: %d (expected 1)", i, verneed->vn_version);
2661       return false;
2662     }
2663 
2664     const char* target_soname = si_from->get_string(verneed->vn_file);
2665     // find it in dependencies
2666     soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) {
2667       return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0;
2668     });
2669 
2670     if (target_si == nullptr) {
2671       DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
2672           target_soname, i, si_from->get_realpath());
2673       return false;
2674     }
2675 
2676     for (size_t j = 0; j<verneed->vn_cnt; ++j) {
2677       const ElfW(Vernaux)* vernaux = reinterpret_cast<ElfW(Vernaux)*>(verneed_ptr + vernaux_offset);
2678       vernaux_offset += vernaux->vna_next;
2679 
2680       const ElfW(Word) elf_hash = vernaux->vna_hash;
2681       const char* ver_name = si_from->get_string(vernaux->vna_name);
2682       ElfW(Half) source_index = vernaux->vna_other;
2683 
2684       add_version_info(source_index, elf_hash, ver_name, target_si);
2685     }
2686   }
2687 
2688   return true;
2689 }
2690 
init_verdef(const soinfo * si_from)2691 bool VersionTracker::init_verdef(const soinfo* si_from) {
2692   return for_each_verdef(si_from,
2693     [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
2694       add_version_info(verdef->vd_ndx, verdef->vd_hash,
2695           si_from->get_string(verdaux->vda_name), si_from);
2696       return false;
2697     }
2698   );
2699 }
2700 
init(const soinfo * si_from)2701 bool VersionTracker::init(const soinfo* si_from) {
2702   if (!si_from->has_min_version(2)) {
2703     return true;
2704   }
2705 
2706   return init_verneed(si_from) && init_verdef(si_from);
2707 }
2708 
lookup_version_info(const VersionTracker & version_tracker,ElfW (Word)sym,const char * sym_name,const version_info ** vi)2709 bool soinfo::lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
2710                                  const char* sym_name, const version_info** vi) {
2711   const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
2712   ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
2713 
2714   if (sym_ver != VER_NDX_LOCAL && sym_ver != VER_NDX_GLOBAL) {
2715     *vi = version_tracker.get_version_info(sym_ver);
2716 
2717     if (*vi == nullptr) {
2718       DL_ERR("cannot find verneed/verdef for version index=%d "
2719           "referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_realpath());
2720       return false;
2721     }
2722   } else {
2723     // there is no version info
2724     *vi = nullptr;
2725   }
2726 
2727   return true;
2728 }
2729 
2730 #if !defined(__mips__)
2731 #if defined(USE_RELA)
get_addend(ElfW (Rela)* rela,ElfW (Addr)reloc_addr __unused)2732 static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr __unused) {
2733   return rela->r_addend;
2734 }
2735 #else
get_addend(ElfW (Rel)* rel,ElfW (Addr)reloc_addr)2736 static ElfW(Addr) get_addend(ElfW(Rel)* rel, ElfW(Addr) reloc_addr) {
2737   if (ELFW(R_TYPE)(rel->r_info) == R_GENERIC_RELATIVE ||
2738       ELFW(R_TYPE)(rel->r_info) == R_GENERIC_IRELATIVE) {
2739     return *reinterpret_cast<ElfW(Addr)*>(reloc_addr);
2740   }
2741   return 0;
2742 }
2743 #endif
2744 
2745 template<typename ElfRelIteratorT>
relocate(const VersionTracker & version_tracker,ElfRelIteratorT && rel_iterator,const soinfo_list_t & global_group,const soinfo_list_t & local_group)2746 bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
2747                       const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
2748   for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
2749     const auto rel = rel_iterator.next();
2750     if (rel == nullptr) {
2751       return false;
2752     }
2753 
2754     ElfW(Word) type = ELFW(R_TYPE)(rel->r_info);
2755     ElfW(Word) sym = ELFW(R_SYM)(rel->r_info);
2756 
2757     ElfW(Addr) reloc = static_cast<ElfW(Addr)>(rel->r_offset + load_bias);
2758     ElfW(Addr) sym_addr = 0;
2759     const char* sym_name = nullptr;
2760     ElfW(Addr) addend = get_addend(rel, reloc);
2761 
2762     DEBUG("Processing \"%s\" relocation at index %zd", get_realpath(), idx);
2763     if (type == R_GENERIC_NONE) {
2764       continue;
2765     }
2766 
2767     const ElfW(Sym)* s = nullptr;
2768     soinfo* lsi = nullptr;
2769 
2770     if (sym != 0) {
2771       sym_name = get_string(symtab_[sym].st_name);
2772       const version_info* vi = nullptr;
2773 
2774       if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
2775         return false;
2776       }
2777 
2778       if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
2779         return false;
2780       }
2781 
2782       if (s == nullptr) {
2783         // We only allow an undefined symbol if this is a weak reference...
2784         s = &symtab_[sym];
2785         if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
2786           DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
2787           return false;
2788         }
2789 
2790         /* IHI0044C AAELF 4.5.1.1:
2791 
2792            Libraries are not searched to resolve weak references.
2793            It is not an error for a weak reference to remain unsatisfied.
2794 
2795            During linking, the value of an undefined weak reference is:
2796            - Zero if the relocation type is absolute
2797            - The address of the place if the relocation is pc-relative
2798            - The address of nominal base address if the relocation
2799              type is base-relative.
2800          */
2801 
2802         switch (type) {
2803           case R_GENERIC_JUMP_SLOT:
2804           case R_GENERIC_GLOB_DAT:
2805           case R_GENERIC_RELATIVE:
2806           case R_GENERIC_IRELATIVE:
2807 #if defined(__aarch64__)
2808           case R_AARCH64_ABS64:
2809           case R_AARCH64_ABS32:
2810           case R_AARCH64_ABS16:
2811 #elif defined(__x86_64__)
2812           case R_X86_64_32:
2813           case R_X86_64_64:
2814 #elif defined(__arm__)
2815           case R_ARM_ABS32:
2816 #elif defined(__i386__)
2817           case R_386_32:
2818 #endif
2819             /*
2820              * The sym_addr was initialized to be zero above, or the relocation
2821              * code below does not care about value of sym_addr.
2822              * No need to do anything.
2823              */
2824             break;
2825 #if defined(__x86_64__)
2826           case R_X86_64_PC32:
2827             sym_addr = reloc;
2828             break;
2829 #elif defined(__i386__)
2830           case R_386_PC32:
2831             sym_addr = reloc;
2832             break;
2833 #endif
2834           default:
2835             DL_ERR("unknown weak reloc type %d @ %p (%zu)", type, rel, idx);
2836             return false;
2837         }
2838       } else { // We got a definition.
2839 #if !defined(__LP64__)
2840         // When relocating dso with text_relocation .text segment is
2841         // not executable. We need to restore elf flags before resolving
2842         // STT_GNU_IFUNC symbol.
2843         bool protect_segments = has_text_relocations &&
2844                                 lsi == this &&
2845                                 ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC;
2846         if (protect_segments) {
2847           if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
2848             DL_ERR("can't protect segments for \"%s\": %s",
2849                    get_realpath(), strerror(errno));
2850             return false;
2851           }
2852         }
2853 #endif
2854         sym_addr = lsi->resolve_symbol_address(s);
2855 #if !defined(__LP64__)
2856         if (protect_segments) {
2857           if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
2858             DL_ERR("can't unprotect loadable segments for \"%s\": %s",
2859                    get_realpath(), strerror(errno));
2860             return false;
2861           }
2862         }
2863 #endif
2864       }
2865       count_relocation(kRelocSymbol);
2866     }
2867 
2868     switch (type) {
2869       case R_GENERIC_JUMP_SLOT:
2870         count_relocation(kRelocAbsolute);
2871         MARK(rel->r_offset);
2872         TRACE_TYPE(RELO, "RELO JMP_SLOT %16p <- %16p %s\n",
2873                    reinterpret_cast<void*>(reloc),
2874                    reinterpret_cast<void*>(sym_addr + addend), sym_name);
2875 
2876         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
2877         break;
2878       case R_GENERIC_GLOB_DAT:
2879         count_relocation(kRelocAbsolute);
2880         MARK(rel->r_offset);
2881         TRACE_TYPE(RELO, "RELO GLOB_DAT %16p <- %16p %s\n",
2882                    reinterpret_cast<void*>(reloc),
2883                    reinterpret_cast<void*>(sym_addr + addend), sym_name);
2884         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
2885         break;
2886       case R_GENERIC_RELATIVE:
2887         count_relocation(kRelocRelative);
2888         MARK(rel->r_offset);
2889         TRACE_TYPE(RELO, "RELO RELATIVE %16p <- %16p\n",
2890                    reinterpret_cast<void*>(reloc),
2891                    reinterpret_cast<void*>(load_bias + addend));
2892         *reinterpret_cast<ElfW(Addr)*>(reloc) = (load_bias + addend);
2893         break;
2894       case R_GENERIC_IRELATIVE:
2895         count_relocation(kRelocRelative);
2896         MARK(rel->r_offset);
2897         TRACE_TYPE(RELO, "RELO IRELATIVE %16p <- %16p\n",
2898                     reinterpret_cast<void*>(reloc),
2899                     reinterpret_cast<void*>(load_bias + addend));
2900         {
2901 #if !defined(__LP64__)
2902           // When relocating dso with text_relocation .text segment is
2903           // not executable. We need to restore elf flags for this
2904           // particular call.
2905           if (has_text_relocations) {
2906             if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
2907               DL_ERR("can't protect segments for \"%s\": %s",
2908                      get_realpath(), strerror(errno));
2909               return false;
2910             }
2911           }
2912 #endif
2913           ElfW(Addr) ifunc_addr = call_ifunc_resolver(load_bias + addend);
2914 #if !defined(__LP64__)
2915           // Unprotect it afterwards...
2916           if (has_text_relocations) {
2917             if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
2918               DL_ERR("can't unprotect loadable segments for \"%s\": %s",
2919                      get_realpath(), strerror(errno));
2920               return false;
2921             }
2922           }
2923 #endif
2924           *reinterpret_cast<ElfW(Addr)*>(reloc) = ifunc_addr;
2925         }
2926         break;
2927 
2928 #if defined(__aarch64__)
2929       case R_AARCH64_ABS64:
2930         count_relocation(kRelocAbsolute);
2931         MARK(rel->r_offset);
2932         TRACE_TYPE(RELO, "RELO ABS64 %16llx <- %16llx %s\n",
2933                    reloc, sym_addr + addend, sym_name);
2934         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
2935         break;
2936       case R_AARCH64_ABS32:
2937         count_relocation(kRelocAbsolute);
2938         MARK(rel->r_offset);
2939         TRACE_TYPE(RELO, "RELO ABS32 %16llx <- %16llx %s\n",
2940                    reloc, sym_addr + addend, sym_name);
2941         {
2942           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
2943           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
2944           if ((min_value <= (sym_addr + addend)) &&
2945               ((sym_addr + addend) <= max_value)) {
2946             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
2947           } else {
2948             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
2949                    sym_addr + addend, min_value, max_value);
2950             return false;
2951           }
2952         }
2953         break;
2954       case R_AARCH64_ABS16:
2955         count_relocation(kRelocAbsolute);
2956         MARK(rel->r_offset);
2957         TRACE_TYPE(RELO, "RELO ABS16 %16llx <- %16llx %s\n",
2958                    reloc, sym_addr + addend, sym_name);
2959         {
2960           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
2961           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
2962           if ((min_value <= (sym_addr + addend)) &&
2963               ((sym_addr + addend) <= max_value)) {
2964             *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
2965           } else {
2966             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
2967                    sym_addr + addend, min_value, max_value);
2968             return false;
2969           }
2970         }
2971         break;
2972       case R_AARCH64_PREL64:
2973         count_relocation(kRelocRelative);
2974         MARK(rel->r_offset);
2975         TRACE_TYPE(RELO, "RELO REL64 %16llx <- %16llx - %16llx %s\n",
2976                    reloc, sym_addr + addend, rel->r_offset, sym_name);
2977         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
2978         break;
2979       case R_AARCH64_PREL32:
2980         count_relocation(kRelocRelative);
2981         MARK(rel->r_offset);
2982         TRACE_TYPE(RELO, "RELO REL32 %16llx <- %16llx - %16llx %s\n",
2983                    reloc, sym_addr + addend, rel->r_offset, sym_name);
2984         {
2985           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
2986           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
2987           if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
2988               ((sym_addr + addend - rel->r_offset) <= max_value)) {
2989             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
2990           } else {
2991             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
2992                    sym_addr + addend - rel->r_offset, min_value, max_value);
2993             return false;
2994           }
2995         }
2996         break;
2997       case R_AARCH64_PREL16:
2998         count_relocation(kRelocRelative);
2999         MARK(rel->r_offset);
3000         TRACE_TYPE(RELO, "RELO REL16 %16llx <- %16llx - %16llx %s\n",
3001                    reloc, sym_addr + addend, rel->r_offset, sym_name);
3002         {
3003           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
3004           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
3005           if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
3006               ((sym_addr + addend - rel->r_offset) <= max_value)) {
3007             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
3008           } else {
3009             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
3010                    sym_addr + addend - rel->r_offset, min_value, max_value);
3011             return false;
3012           }
3013         }
3014         break;
3015 
3016       case R_AARCH64_COPY:
3017         /*
3018          * ET_EXEC is not supported so this should not happen.
3019          *
3020          * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
3021          *
3022          * Section 4.6.11 "Dynamic relocations"
3023          * R_AARCH64_COPY may only appear in executable objects where e_type is
3024          * set to ET_EXEC.
3025          */
3026         DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
3027         return false;
3028       case R_AARCH64_TLS_TPREL64:
3029         TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
3030                    reloc, (sym_addr + addend), rel->r_offset);
3031         break;
3032       case R_AARCH64_TLS_DTPREL32:
3033         TRACE_TYPE(RELO, "RELO TLS_DTPREL32 *** %16llx <- %16llx - %16llx\n",
3034                    reloc, (sym_addr + addend), rel->r_offset);
3035         break;
3036 #elif defined(__x86_64__)
3037       case R_X86_64_32:
3038         count_relocation(kRelocRelative);
3039         MARK(rel->r_offset);
3040         TRACE_TYPE(RELO, "RELO R_X86_64_32 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
3041                    static_cast<size_t>(sym_addr), sym_name);
3042         *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend;
3043         break;
3044       case R_X86_64_64:
3045         count_relocation(kRelocRelative);
3046         MARK(rel->r_offset);
3047         TRACE_TYPE(RELO, "RELO R_X86_64_64 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
3048                    static_cast<size_t>(sym_addr), sym_name);
3049         *reinterpret_cast<Elf64_Addr*>(reloc) = sym_addr + addend;
3050         break;
3051       case R_X86_64_PC32:
3052         count_relocation(kRelocRelative);
3053         MARK(rel->r_offset);
3054         TRACE_TYPE(RELO, "RELO R_X86_64_PC32 %08zx <- +%08zx (%08zx - %08zx) %s",
3055                    static_cast<size_t>(reloc), static_cast<size_t>(sym_addr - reloc),
3056                    static_cast<size_t>(sym_addr), static_cast<size_t>(reloc), sym_name);
3057         *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend - reloc;
3058         break;
3059 #elif defined(__arm__)
3060       case R_ARM_ABS32:
3061         count_relocation(kRelocAbsolute);
3062         MARK(rel->r_offset);
3063         TRACE_TYPE(RELO, "RELO ABS %08x <- %08x %s", reloc, sym_addr, sym_name);
3064         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
3065         break;
3066       case R_ARM_REL32:
3067         count_relocation(kRelocRelative);
3068         MARK(rel->r_offset);
3069         TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x - %08x %s",
3070                    reloc, sym_addr, rel->r_offset, sym_name);
3071         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr - rel->r_offset;
3072         break;
3073       case R_ARM_COPY:
3074         /*
3075          * ET_EXEC is not supported so this should not happen.
3076          *
3077          * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
3078          *
3079          * Section 4.6.1.10 "Dynamic relocations"
3080          * R_ARM_COPY may only appear in executable objects where e_type is
3081          * set to ET_EXEC.
3082          */
3083         DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
3084         return false;
3085 #elif defined(__i386__)
3086       case R_386_32:
3087         count_relocation(kRelocRelative);
3088         MARK(rel->r_offset);
3089         TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s", reloc, sym_addr, sym_name);
3090         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
3091         break;
3092       case R_386_PC32:
3093         count_relocation(kRelocRelative);
3094         MARK(rel->r_offset);
3095         TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s",
3096                    reloc, (sym_addr - reloc), sym_addr, reloc, sym_name);
3097         *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr - reloc);
3098         break;
3099 #endif
3100       default:
3101         DL_ERR("unknown reloc type %d @ %p (%zu)", type, rel, idx);
3102         return false;
3103     }
3104   }
3105   return true;
3106 }
3107 #endif  // !defined(__mips__)
3108 
call_array(const char * array_name __unused,linker_function_t * functions,size_t count,bool reverse)3109 void soinfo::call_array(const char* array_name __unused, linker_function_t* functions,
3110                         size_t count, bool reverse) {
3111   if (functions == nullptr) {
3112     return;
3113   }
3114 
3115   TRACE("[ Calling %s (size %zd) @ %p for \"%s\" ]", array_name, count, functions, get_realpath());
3116 
3117   int begin = reverse ? (count - 1) : 0;
3118   int end = reverse ? -1 : count;
3119   int step = reverse ? -1 : 1;
3120 
3121   for (int i = begin; i != end; i += step) {
3122     TRACE("[ %s[%d] == %p ]", array_name, i, functions[i]);
3123     call_function("function", functions[i]);
3124   }
3125 
3126   TRACE("[ Done calling %s for \"%s\" ]", array_name, get_realpath());
3127 }
3128 
call_function(const char * function_name __unused,linker_function_t function)3129 void soinfo::call_function(const char* function_name __unused, linker_function_t function) {
3130   if (function == nullptr || reinterpret_cast<uintptr_t>(function) == static_cast<uintptr_t>(-1)) {
3131     return;
3132   }
3133 
3134   TRACE("[ Calling %s @ %p for \"%s\" ]", function_name, function, get_realpath());
3135   function();
3136   TRACE("[ Done calling %s @ %p for \"%s\" ]", function_name, function, get_realpath());
3137 }
3138 
call_pre_init_constructors()3139 void soinfo::call_pre_init_constructors() {
3140   // DT_PREINIT_ARRAY functions are called before any other constructors for executables,
3141   // but ignored in a shared library.
3142   call_array("DT_PREINIT_ARRAY", preinit_array_, preinit_array_count_, false);
3143 }
3144 
call_constructors()3145 void soinfo::call_constructors() {
3146   if (constructors_called) {
3147     return;
3148   }
3149 
3150   // We set constructors_called before actually calling the constructors, otherwise it doesn't
3151   // protect against recursive constructor calls. One simple example of constructor recursion
3152   // is the libc debug malloc, which is implemented in libc_malloc_debug_leak.so:
3153   // 1. The program depends on libc, so libc's constructor is called here.
3154   // 2. The libc constructor calls dlopen() to load libc_malloc_debug_leak.so.
3155   // 3. dlopen() calls the constructors on the newly created
3156   //    soinfo for libc_malloc_debug_leak.so.
3157   // 4. The debug .so depends on libc, so CallConstructors is
3158   //    called again with the libc soinfo. If it doesn't trigger the early-
3159   //    out above, the libc constructor will be called again (recursively!).
3160   constructors_called = true;
3161 
3162   if (!is_main_executable() && preinit_array_ != nullptr) {
3163     // The GNU dynamic linker silently ignores these, but we warn the developer.
3164     PRINT("\"%s\": ignoring DT_PREINIT_ARRAY in shared library!", get_realpath());
3165   }
3166 
3167   get_children().for_each([] (soinfo* si) {
3168     si->call_constructors();
3169   });
3170 
3171   TRACE("\"%s\": calling constructors", get_realpath());
3172 
3173   // DT_INIT should be called before DT_INIT_ARRAY if both are present.
3174   call_function("DT_INIT", init_func_);
3175   call_array("DT_INIT_ARRAY", init_array_, init_array_count_, false);
3176 }
3177 
call_destructors()3178 void soinfo::call_destructors() {
3179   if (!constructors_called) {
3180     return;
3181   }
3182   TRACE("\"%s\": calling destructors", get_realpath());
3183 
3184   // DT_FINI_ARRAY must be parsed in reverse order.
3185   call_array("DT_FINI_ARRAY", fini_array_, fini_array_count_, true);
3186 
3187   // DT_FINI should be called after DT_FINI_ARRAY if both are present.
3188   call_function("DT_FINI", fini_func_);
3189 
3190   // This is needed on second call to dlopen
3191   // after library has been unloaded with RTLD_NODELETE
3192   constructors_called = false;
3193 }
3194 
add_child(soinfo * child)3195 void soinfo::add_child(soinfo* child) {
3196   if (has_min_version(0)) {
3197     child->parents_.push_back(this);
3198     this->children_.push_back(child);
3199   }
3200 }
3201 
remove_all_links()3202 void soinfo::remove_all_links() {
3203   if (!has_min_version(0)) {
3204     return;
3205   }
3206 
3207   // 1. Untie connected soinfos from 'this'.
3208   children_.for_each([&] (soinfo* child) {
3209     child->parents_.remove_if([&] (const soinfo* parent) {
3210       return parent == this;
3211     });
3212   });
3213 
3214   parents_.for_each([&] (soinfo* parent) {
3215     parent->children_.remove_if([&] (const soinfo* child) {
3216       return child == this;
3217     });
3218   });
3219 
3220   // 2. Remove from the primary namespace
3221   primary_namespace_->remove_soinfo(this);
3222   primary_namespace_ = nullptr;
3223 
3224   // 3. Remove from secondary namespaces
3225   secondary_namespaces_.for_each([&](android_namespace_t* ns) {
3226     ns->remove_soinfo(this);
3227   });
3228 
3229 
3230   // 4. Once everything untied - clear local lists.
3231   parents_.clear();
3232   children_.clear();
3233   secondary_namespaces_.clear();
3234 }
3235 
get_st_dev() const3236 dev_t soinfo::get_st_dev() const {
3237   if (has_min_version(0)) {
3238     return st_dev_;
3239   }
3240 
3241   return 0;
3242 };
3243 
get_st_ino() const3244 ino_t soinfo::get_st_ino() const {
3245   if (has_min_version(0)) {
3246     return st_ino_;
3247   }
3248 
3249   return 0;
3250 }
3251 
get_file_offset() const3252 off64_t soinfo::get_file_offset() const {
3253   if (has_min_version(1)) {
3254     return file_offset_;
3255   }
3256 
3257   return 0;
3258 }
3259 
get_rtld_flags() const3260 uint32_t soinfo::get_rtld_flags() const {
3261   if (has_min_version(1)) {
3262     return rtld_flags_;
3263   }
3264 
3265   return 0;
3266 }
3267 
get_dt_flags_1() const3268 uint32_t soinfo::get_dt_flags_1() const {
3269   if (has_min_version(1)) {
3270     return dt_flags_1_;
3271   }
3272 
3273   return 0;
3274 }
3275 
set_dt_flags_1(uint32_t dt_flags_1)3276 void soinfo::set_dt_flags_1(uint32_t dt_flags_1) {
3277   if (has_min_version(1)) {
3278     if ((dt_flags_1 & DF_1_GLOBAL) != 0) {
3279       rtld_flags_ |= RTLD_GLOBAL;
3280     }
3281 
3282     if ((dt_flags_1 & DF_1_NODELETE) != 0) {
3283       rtld_flags_ |= RTLD_NODELETE;
3284     }
3285 
3286     dt_flags_1_ = dt_flags_1;
3287   }
3288 }
3289 
set_nodelete()3290 void soinfo::set_nodelete() {
3291   rtld_flags_ |= RTLD_NODELETE;
3292 }
3293 
get_realpath() const3294 const char* soinfo::get_realpath() const {
3295 #if defined(__work_around_b_24465209__)
3296   if (has_min_version(2)) {
3297     return realpath_.c_str();
3298   } else {
3299     return old_name_;
3300   }
3301 #else
3302   return realpath_.c_str();
3303 #endif
3304 }
3305 
set_soname(const char * soname)3306 void soinfo::set_soname(const char* soname) {
3307 #if defined(__work_around_b_24465209__)
3308   if (has_min_version(2)) {
3309     soname_ = soname;
3310   }
3311   strlcpy(old_name_, soname_, sizeof(old_name_));
3312 #else
3313   soname_ = soname;
3314 #endif
3315 }
3316 
get_soname() const3317 const char* soinfo::get_soname() const {
3318 #if defined(__work_around_b_24465209__)
3319   if (has_min_version(2)) {
3320     return soname_;
3321   } else {
3322     return old_name_;
3323   }
3324 #else
3325   return soname_;
3326 #endif
3327 }
3328 
3329 // This is a return on get_children()/get_parents() if
3330 // 'this->flags' does not have FLAG_NEW_SOINFO set.
3331 static soinfo::soinfo_list_t g_empty_list;
3332 
get_children()3333 soinfo::soinfo_list_t& soinfo::get_children() {
3334   if (has_min_version(0)) {
3335     return children_;
3336   }
3337 
3338   return g_empty_list;
3339 }
3340 
get_children() const3341 const soinfo::soinfo_list_t& soinfo::get_children() const {
3342   if (has_min_version(0)) {
3343     return children_;
3344   }
3345 
3346   return g_empty_list;
3347 }
3348 
get_parents()3349 soinfo::soinfo_list_t& soinfo::get_parents() {
3350   if (has_min_version(0)) {
3351     return parents_;
3352   }
3353 
3354   return g_empty_list;
3355 }
3356 
3357 static std::vector<std::string> g_empty_runpath;
3358 
get_dt_runpath() const3359 const std::vector<std::string>& soinfo::get_dt_runpath() const {
3360   if (has_min_version(3)) {
3361     return dt_runpath_;
3362   }
3363 
3364   return g_empty_runpath;
3365 }
3366 
get_primary_namespace()3367 android_namespace_t* soinfo::get_primary_namespace() {
3368   if (has_min_version(3)) {
3369     return primary_namespace_;
3370   }
3371 
3372   return &g_default_namespace;
3373 }
3374 
add_secondary_namespace(android_namespace_t * secondary_ns)3375 void soinfo::add_secondary_namespace(android_namespace_t* secondary_ns) {
3376   CHECK(has_min_version(3));
3377   secondary_namespaces_.push_back(secondary_ns);
3378 }
3379 
ElfW(Addr)3380 ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
3381   if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) {
3382     return call_ifunc_resolver(s->st_value + load_bias);
3383   }
3384 
3385   return static_cast<ElfW(Addr)>(s->st_value + load_bias);
3386 }
3387 
get_string(ElfW (Word)index) const3388 const char* soinfo::get_string(ElfW(Word) index) const {
3389   if (has_min_version(1) && (index >= strtab_size_)) {
3390     __libc_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d",
3391         get_realpath(), strtab_size_, index);
3392   }
3393 
3394   return strtab_ + index;
3395 }
3396 
is_gnu_hash() const3397 bool soinfo::is_gnu_hash() const {
3398   return (flags_ & FLAG_GNU_HASH) != 0;
3399 }
3400 
can_unload() const3401 bool soinfo::can_unload() const {
3402   return !is_linked() || ((get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0);
3403 }
3404 
is_linked() const3405 bool soinfo::is_linked() const {
3406   return (flags_ & FLAG_LINKED) != 0;
3407 }
3408 
is_main_executable() const3409 bool soinfo::is_main_executable() const {
3410   return (flags_ & FLAG_EXE) != 0;
3411 }
3412 
is_linker() const3413 bool soinfo::is_linker() const {
3414   return (flags_ & FLAG_LINKER) != 0;
3415 }
3416 
set_linked()3417 void soinfo::set_linked() {
3418   flags_ |= FLAG_LINKED;
3419 }
3420 
set_linker_flag()3421 void soinfo::set_linker_flag() {
3422   flags_ |= FLAG_LINKER;
3423 }
3424 
set_main_executable()3425 void soinfo::set_main_executable() {
3426   flags_ |= FLAG_EXE;
3427 }
3428 
increment_ref_count()3429 void soinfo::increment_ref_count() {
3430   local_group_root_->ref_count_++;
3431 }
3432 
decrement_ref_count()3433 size_t soinfo::decrement_ref_count() {
3434   return --local_group_root_->ref_count_;
3435 }
3436 
get_local_group_root() const3437 soinfo* soinfo::get_local_group_root() const {
3438   return local_group_root_;
3439 }
3440 
3441 
set_mapped_by_caller(bool mapped_by_caller)3442 void soinfo::set_mapped_by_caller(bool mapped_by_caller) {
3443   if (mapped_by_caller) {
3444     flags_ |= FLAG_MAPPED_BY_CALLER;
3445   } else {
3446     flags_ &= ~FLAG_MAPPED_BY_CALLER;
3447   }
3448 }
3449 
is_mapped_by_caller() const3450 bool soinfo::is_mapped_by_caller() const {
3451   return (flags_ & FLAG_MAPPED_BY_CALLER) != 0;
3452 }
3453 
3454 // This function returns api-level at the time of
3455 // dlopen/load. Note that libraries opened by system
3456 // will always have 'current' api level.
get_target_sdk_version() const3457 uint32_t soinfo::get_target_sdk_version() const {
3458   if (!has_min_version(2)) {
3459     return __ANDROID_API__;
3460   }
3461 
3462   return local_group_root_->target_sdk_version_;
3463 }
3464 
get_handle() const3465 uintptr_t soinfo::get_handle() const {
3466   CHECK(has_min_version(3));
3467   CHECK(handle_ != 0);
3468   return handle_;
3469 }
3470 
to_handle()3471 void* soinfo::to_handle() {
3472   if (get_application_target_sdk_version() <= 23 || !has_min_version(3)) {
3473     return this;
3474   }
3475 
3476   return reinterpret_cast<void*>(get_handle());
3477 }
3478 
generate_handle()3479 void soinfo::generate_handle() {
3480   CHECK(has_min_version(3));
3481   CHECK(handle_ == 0); // Make sure this is the first call
3482 
3483   // Make sure the handle is unique and does not collide
3484   // with special values which are RTLD_DEFAULT and RTLD_NEXT.
3485   do {
3486     arc4random_buf(&handle_, sizeof(handle_));
3487     // the least significant bit for the handle is always 1
3488     // making it easy to test the type of handle passed to
3489     // dl* functions.
3490     handle_ = handle_ | 1;
3491   } while (handle_ == reinterpret_cast<uintptr_t>(RTLD_DEFAULT) ||
3492            handle_ == reinterpret_cast<uintptr_t>(RTLD_NEXT) ||
3493            g_soinfo_handles_map.find(handle_) != g_soinfo_handles_map.end());
3494 
3495   g_soinfo_handles_map[handle_] = this;
3496 }
3497 
prelink_image()3498 bool soinfo::prelink_image() {
3499   /* Extract dynamic section */
3500   ElfW(Word) dynamic_flags = 0;
3501   phdr_table_get_dynamic_section(phdr, phnum, load_bias, &dynamic, &dynamic_flags);
3502 
3503   /* We can't log anything until the linker is relocated */
3504   bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
3505   if (!relocating_linker) {
3506     INFO("[ Linking \"%s\" ]", get_realpath());
3507     DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
3508   }
3509 
3510   if (dynamic == nullptr) {
3511     if (!relocating_linker) {
3512       DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
3513     }
3514     return false;
3515   } else {
3516     if (!relocating_linker) {
3517       DEBUG("dynamic = %p", dynamic);
3518     }
3519   }
3520 
3521 #if defined(__arm__)
3522   (void) phdr_table_get_arm_exidx(phdr, phnum, load_bias,
3523                                   &ARM_exidx, &ARM_exidx_count);
3524 #endif
3525 
3526   // Extract useful information from dynamic section.
3527   // Note that: "Except for the DT_NULL element at the end of the array,
3528   // and the relative order of DT_NEEDED elements, entries may appear in any order."
3529   //
3530   // source: http://www.sco.com/developers/gabi/1998-04-29/ch5.dynamic.html
3531   uint32_t needed_count = 0;
3532   for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
3533     DEBUG("d = %p, d[0](tag) = %p d[1](val) = %p",
3534           d, reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
3535     switch (d->d_tag) {
3536       case DT_SONAME:
3537         // this is parsed after we have strtab initialized (see below).
3538         break;
3539 
3540       case DT_HASH:
3541         nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
3542         nchain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
3543         bucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8);
3544         chain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8 + nbucket_ * 4);
3545         break;
3546 
3547       case DT_GNU_HASH:
3548         gnu_nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
3549         // skip symndx
3550         gnu_maskwords_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[2];
3551         gnu_shift2_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[3];
3552 
3553         gnu_bloom_filter_ = reinterpret_cast<ElfW(Addr)*>(load_bias + d->d_un.d_ptr + 16);
3554         gnu_bucket_ = reinterpret_cast<uint32_t*>(gnu_bloom_filter_ + gnu_maskwords_);
3555         // amend chain for symndx = header[1]
3556         gnu_chain_ = gnu_bucket_ + gnu_nbucket_ -
3557             reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
3558 
3559         if (!powerof2(gnu_maskwords_)) {
3560           DL_ERR("invalid maskwords for gnu_hash = 0x%x, in \"%s\" expecting power to two",
3561               gnu_maskwords_, get_realpath());
3562           return false;
3563         }
3564         --gnu_maskwords_;
3565 
3566         flags_ |= FLAG_GNU_HASH;
3567         break;
3568 
3569       case DT_STRTAB:
3570         strtab_ = reinterpret_cast<const char*>(load_bias + d->d_un.d_ptr);
3571         break;
3572 
3573       case DT_STRSZ:
3574         strtab_size_ = d->d_un.d_val;
3575         break;
3576 
3577       case DT_SYMTAB:
3578         symtab_ = reinterpret_cast<ElfW(Sym)*>(load_bias + d->d_un.d_ptr);
3579         break;
3580 
3581       case DT_SYMENT:
3582         if (d->d_un.d_val != sizeof(ElfW(Sym))) {
3583           DL_ERR("invalid DT_SYMENT: %zd in \"%s\"",
3584               static_cast<size_t>(d->d_un.d_val), get_realpath());
3585           return false;
3586         }
3587         break;
3588 
3589       case DT_PLTREL:
3590 #if defined(USE_RELA)
3591         if (d->d_un.d_val != DT_RELA) {
3592           DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_RELA", get_realpath());
3593           return false;
3594         }
3595 #else
3596         if (d->d_un.d_val != DT_REL) {
3597           DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_REL", get_realpath());
3598           return false;
3599         }
3600 #endif
3601         break;
3602 
3603       case DT_JMPREL:
3604 #if defined(USE_RELA)
3605         plt_rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
3606 #else
3607         plt_rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
3608 #endif
3609         break;
3610 
3611       case DT_PLTRELSZ:
3612 #if defined(USE_RELA)
3613         plt_rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
3614 #else
3615         plt_rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
3616 #endif
3617         break;
3618 
3619       case DT_PLTGOT:
3620 #if defined(__mips__)
3621         // Used by mips and mips64.
3622         plt_got_ = reinterpret_cast<ElfW(Addr)**>(load_bias + d->d_un.d_ptr);
3623 #endif
3624         // Ignore for other platforms... (because RTLD_LAZY is not supported)
3625         break;
3626 
3627       case DT_DEBUG:
3628         // Set the DT_DEBUG entry to the address of _r_debug for GDB
3629         // if the dynamic table is writable
3630 // FIXME: not working currently for N64
3631 // The flags for the LOAD and DYNAMIC program headers do not agree.
3632 // The LOAD section containing the dynamic table has been mapped as
3633 // read-only, but the DYNAMIC header claims it is writable.
3634 #if !(defined(__mips__) && defined(__LP64__))
3635         if ((dynamic_flags & PF_W) != 0) {
3636           d->d_un.d_val = reinterpret_cast<uintptr_t>(&_r_debug);
3637         }
3638 #endif
3639         break;
3640 #if defined(USE_RELA)
3641       case DT_RELA:
3642         rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
3643         break;
3644 
3645       case DT_RELASZ:
3646         rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
3647         break;
3648 
3649       case DT_ANDROID_RELA:
3650         android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
3651         break;
3652 
3653       case DT_ANDROID_RELASZ:
3654         android_relocs_size_ = d->d_un.d_val;
3655         break;
3656 
3657       case DT_ANDROID_REL:
3658         DL_ERR("unsupported DT_ANDROID_REL in \"%s\"", get_realpath());
3659         return false;
3660 
3661       case DT_ANDROID_RELSZ:
3662         DL_ERR("unsupported DT_ANDROID_RELSZ in \"%s\"", get_realpath());
3663         return false;
3664 
3665       case DT_RELAENT:
3666         if (d->d_un.d_val != sizeof(ElfW(Rela))) {
3667           DL_ERR("invalid DT_RELAENT: %zd", static_cast<size_t>(d->d_un.d_val));
3668           return false;
3669         }
3670         break;
3671 
3672       // ignored (see DT_RELCOUNT comments for details)
3673       case DT_RELACOUNT:
3674         break;
3675 
3676       case DT_REL:
3677         DL_ERR("unsupported DT_REL in \"%s\"", get_realpath());
3678         return false;
3679 
3680       case DT_RELSZ:
3681         DL_ERR("unsupported DT_RELSZ in \"%s\"", get_realpath());
3682         return false;
3683 
3684 #else
3685       case DT_REL:
3686         rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
3687         break;
3688 
3689       case DT_RELSZ:
3690         rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
3691         break;
3692 
3693       case DT_RELENT:
3694         if (d->d_un.d_val != sizeof(ElfW(Rel))) {
3695           DL_ERR("invalid DT_RELENT: %zd", static_cast<size_t>(d->d_un.d_val));
3696           return false;
3697         }
3698         break;
3699 
3700       case DT_ANDROID_REL:
3701         android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
3702         break;
3703 
3704       case DT_ANDROID_RELSZ:
3705         android_relocs_size_ = d->d_un.d_val;
3706         break;
3707 
3708       case DT_ANDROID_RELA:
3709         DL_ERR("unsupported DT_ANDROID_RELA in \"%s\"", get_realpath());
3710         return false;
3711 
3712       case DT_ANDROID_RELASZ:
3713         DL_ERR("unsupported DT_ANDROID_RELASZ in \"%s\"", get_realpath());
3714         return false;
3715 
3716       // "Indicates that all RELATIVE relocations have been concatenated together,
3717       // and specifies the RELATIVE relocation count."
3718       //
3719       // TODO: Spec also mentions that this can be used to optimize relocation process;
3720       // Not currently used by bionic linker - ignored.
3721       case DT_RELCOUNT:
3722         break;
3723 
3724       case DT_RELA:
3725         DL_ERR("unsupported DT_RELA in \"%s\"", get_realpath());
3726         return false;
3727 
3728       case DT_RELASZ:
3729         DL_ERR("unsupported DT_RELASZ in \"%s\"", get_realpath());
3730         return false;
3731 
3732 #endif
3733       case DT_INIT:
3734         init_func_ = reinterpret_cast<linker_function_t>(load_bias + d->d_un.d_ptr);
3735         DEBUG("%s constructors (DT_INIT) found at %p", get_realpath(), init_func_);
3736         break;
3737 
3738       case DT_FINI:
3739         fini_func_ = reinterpret_cast<linker_function_t>(load_bias + d->d_un.d_ptr);
3740         DEBUG("%s destructors (DT_FINI) found at %p", get_realpath(), fini_func_);
3741         break;
3742 
3743       case DT_INIT_ARRAY:
3744         init_array_ = reinterpret_cast<linker_function_t*>(load_bias + d->d_un.d_ptr);
3745         DEBUG("%s constructors (DT_INIT_ARRAY) found at %p", get_realpath(), init_array_);
3746         break;
3747 
3748       case DT_INIT_ARRAYSZ:
3749         init_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
3750         break;
3751 
3752       case DT_FINI_ARRAY:
3753         fini_array_ = reinterpret_cast<linker_function_t*>(load_bias + d->d_un.d_ptr);
3754         DEBUG("%s destructors (DT_FINI_ARRAY) found at %p", get_realpath(), fini_array_);
3755         break;
3756 
3757       case DT_FINI_ARRAYSZ:
3758         fini_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
3759         break;
3760 
3761       case DT_PREINIT_ARRAY:
3762         preinit_array_ = reinterpret_cast<linker_function_t*>(load_bias + d->d_un.d_ptr);
3763         DEBUG("%s constructors (DT_PREINIT_ARRAY) found at %p", get_realpath(), preinit_array_);
3764         break;
3765 
3766       case DT_PREINIT_ARRAYSZ:
3767         preinit_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
3768         break;
3769 
3770       case DT_TEXTREL:
3771 #if defined(__LP64__)
3772         DL_ERR("text relocations (DT_TEXTREL) found in 64-bit ELF file \"%s\"", get_realpath());
3773         return false;
3774 #else
3775         has_text_relocations = true;
3776         break;
3777 #endif
3778 
3779       case DT_SYMBOLIC:
3780         has_DT_SYMBOLIC = true;
3781         break;
3782 
3783       case DT_NEEDED:
3784         ++needed_count;
3785         break;
3786 
3787       case DT_FLAGS:
3788         if (d->d_un.d_val & DF_TEXTREL) {
3789 #if defined(__LP64__)
3790           DL_ERR("text relocations (DF_TEXTREL) found in 64-bit ELF file \"%s\"", get_realpath());
3791           return false;
3792 #else
3793           has_text_relocations = true;
3794 #endif
3795         }
3796         if (d->d_un.d_val & DF_SYMBOLIC) {
3797           has_DT_SYMBOLIC = true;
3798         }
3799         break;
3800 
3801       case DT_FLAGS_1:
3802         set_dt_flags_1(d->d_un.d_val);
3803 
3804         if ((d->d_un.d_val & ~SUPPORTED_DT_FLAGS_1) != 0) {
3805           DL_WARN("%s: unsupported flags DT_FLAGS_1=%p", get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
3806         }
3807         break;
3808 #if defined(__mips__)
3809       case DT_MIPS_RLD_MAP:
3810         // Set the DT_MIPS_RLD_MAP entry to the address of _r_debug for GDB.
3811         {
3812           r_debug** dp = reinterpret_cast<r_debug**>(load_bias + d->d_un.d_ptr);
3813           *dp = &_r_debug;
3814         }
3815         break;
3816       case DT_MIPS_RLD_MAP2:
3817         // Set the DT_MIPS_RLD_MAP2 entry to the address of _r_debug for GDB.
3818         {
3819           r_debug** dp = reinterpret_cast<r_debug**>(
3820               reinterpret_cast<ElfW(Addr)>(d) + d->d_un.d_val);
3821           *dp = &_r_debug;
3822         }
3823         break;
3824 
3825       case DT_MIPS_RLD_VERSION:
3826       case DT_MIPS_FLAGS:
3827       case DT_MIPS_BASE_ADDRESS:
3828       case DT_MIPS_UNREFEXTNO:
3829         break;
3830 
3831       case DT_MIPS_SYMTABNO:
3832         mips_symtabno_ = d->d_un.d_val;
3833         break;
3834 
3835       case DT_MIPS_LOCAL_GOTNO:
3836         mips_local_gotno_ = d->d_un.d_val;
3837         break;
3838 
3839       case DT_MIPS_GOTSYM:
3840         mips_gotsym_ = d->d_un.d_val;
3841         break;
3842 #endif
3843       // Ignored: "Its use has been superseded by the DF_BIND_NOW flag"
3844       case DT_BIND_NOW:
3845         break;
3846 
3847       case DT_VERSYM:
3848         versym_ = reinterpret_cast<ElfW(Versym)*>(load_bias + d->d_un.d_ptr);
3849         break;
3850 
3851       case DT_VERDEF:
3852         verdef_ptr_ = load_bias + d->d_un.d_ptr;
3853         break;
3854       case DT_VERDEFNUM:
3855         verdef_cnt_ = d->d_un.d_val;
3856         break;
3857 
3858       case DT_VERNEED:
3859         verneed_ptr_ = load_bias + d->d_un.d_ptr;
3860         break;
3861 
3862       case DT_VERNEEDNUM:
3863         verneed_cnt_ = d->d_un.d_val;
3864         break;
3865 
3866       case DT_RUNPATH:
3867         // this is parsed after we have strtab initialized (see below).
3868         break;
3869 
3870       default:
3871         if (!relocating_linker) {
3872           DL_WARN("%s: unused DT entry: type %p arg %p", get_realpath(),
3873               reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
3874         }
3875         break;
3876     }
3877   }
3878 
3879 #if defined(__mips__) && !defined(__LP64__)
3880   if (!mips_check_and_adjust_fp_modes()) {
3881     return false;
3882   }
3883 #endif
3884 
3885   DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p",
3886         reinterpret_cast<void*>(base), strtab_, symtab_);
3887 
3888   // Sanity checks.
3889   if (relocating_linker && needed_count != 0) {
3890     DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries");
3891     return false;
3892   }
3893   if (nbucket_ == 0 && gnu_nbucket_ == 0) {
3894     DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
3895         "(new hash type from the future?)", get_realpath());
3896     return false;
3897   }
3898   if (strtab_ == 0) {
3899     DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
3900     return false;
3901   }
3902   if (symtab_ == 0) {
3903     DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
3904     return false;
3905   }
3906 
3907   // second pass - parse entries relying on strtab
3908   for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
3909     switch (d->d_tag) {
3910       case DT_SONAME:
3911         set_soname(get_string(d->d_un.d_val));
3912         break;
3913       case DT_RUNPATH:
3914         set_dt_runpath(get_string(d->d_un.d_val));
3915         break;
3916     }
3917   }
3918 
3919   // Before M release linker was using basename in place of soname.
3920   // In the case when dt_soname is absent some apps stop working
3921   // because they can't find dt_needed library by soname.
3922   // This workaround should keep them working. (applies only
3923   // for apps targeting sdk version <=22). Make an exception for
3924   // the main executable and linker; they do not need to have dt_soname
3925   if (soname_ == nullptr && this != somain && (flags_ & FLAG_LINKER) == 0 &&
3926       get_application_target_sdk_version() <= 22) {
3927     soname_ = basename(realpath_.c_str());
3928     DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
3929         get_realpath(), soname_);
3930     // Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
3931   }
3932   return true;
3933 }
3934 
link_image(const soinfo_list_t & global_group,const soinfo_list_t & local_group,const android_dlextinfo * extinfo)3935 bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
3936                         const android_dlextinfo* extinfo) {
3937 
3938   local_group_root_ = local_group.front();
3939   if (local_group_root_ == nullptr) {
3940     local_group_root_ = this;
3941   }
3942 
3943   if ((flags_ & FLAG_LINKER) == 0 && local_group_root_ == this) {
3944     target_sdk_version_ = get_application_target_sdk_version();
3945   }
3946 
3947   VersionTracker version_tracker;
3948 
3949   if (!version_tracker.init(this)) {
3950     return false;
3951   }
3952 
3953 #if !defined(__LP64__)
3954   if (has_text_relocations) {
3955     // Fail if app is targeting sdk version > 22
3956     if (get_application_target_sdk_version() > 22) {
3957       PRINT("%s: has text relocations", get_realpath());
3958       DL_ERR("%s: has text relocations", get_realpath());
3959       return false;
3960     }
3961     // Make segments writable to allow text relocations to work properly. We will later call
3962     // phdr_table_protect_segments() after all of them are applied.
3963     DL_WARN("%s has text relocations. This is wasting memory and prevents "
3964             "security hardening. Please fix.", get_realpath());
3965     add_dlwarning(get_realpath(), "text relocations");
3966     if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
3967       DL_ERR("can't unprotect loadable segments for \"%s\": %s",
3968              get_realpath(), strerror(errno));
3969       return false;
3970     }
3971   }
3972 #endif
3973 
3974   if (android_relocs_ != nullptr) {
3975     // check signature
3976     if (android_relocs_size_ > 3 &&
3977         android_relocs_[0] == 'A' &&
3978         android_relocs_[1] == 'P' &&
3979         android_relocs_[2] == 'S' &&
3980         android_relocs_[3] == '2') {
3981       DEBUG("[ android relocating %s ]", get_realpath());
3982 
3983       bool relocated = false;
3984       const uint8_t* packed_relocs = android_relocs_ + 4;
3985       const size_t packed_relocs_size = android_relocs_size_ - 4;
3986 
3987       relocated = relocate(
3988           version_tracker,
3989           packed_reloc_iterator<sleb128_decoder>(
3990             sleb128_decoder(packed_relocs, packed_relocs_size)),
3991           global_group, local_group);
3992 
3993       if (!relocated) {
3994         return false;
3995       }
3996     } else {
3997       DL_ERR("bad android relocation header.");
3998       return false;
3999     }
4000   }
4001 
4002 #if defined(USE_RELA)
4003   if (rela_ != nullptr) {
4004     DEBUG("[ relocating %s ]", get_realpath());
4005     if (!relocate(version_tracker,
4006             plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
4007       return false;
4008     }
4009   }
4010   if (plt_rela_ != nullptr) {
4011     DEBUG("[ relocating %s plt ]", get_realpath());
4012     if (!relocate(version_tracker,
4013             plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
4014       return false;
4015     }
4016   }
4017 #else
4018   if (rel_ != nullptr) {
4019     DEBUG("[ relocating %s ]", get_realpath());
4020     if (!relocate(version_tracker,
4021             plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
4022       return false;
4023     }
4024   }
4025   if (plt_rel_ != nullptr) {
4026     DEBUG("[ relocating %s plt ]", get_realpath());
4027     if (!relocate(version_tracker,
4028             plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
4029       return false;
4030     }
4031   }
4032 #endif
4033 
4034 #if defined(__mips__)
4035   if (!mips_relocate_got(version_tracker, global_group, local_group)) {
4036     return false;
4037   }
4038 #endif
4039 
4040   DEBUG("[ finished linking %s ]", get_realpath());
4041 
4042 #if !defined(__LP64__)
4043   if (has_text_relocations) {
4044     // All relocations are done, we can protect our segments back to read-only.
4045     if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
4046       DL_ERR("can't protect segments for \"%s\": %s",
4047              get_realpath(), strerror(errno));
4048       return false;
4049     }
4050   }
4051 #endif
4052 
4053   // We can also turn on GNU RELRO protection if we're not linking the dynamic linker
4054   // itself --- it can't make system calls yet, and will have to call protect_relro later.
4055   if (!is_linker() && !protect_relro()) {
4056     return false;
4057   }
4058 
4059   /* Handle serializing/sharing the RELRO segment */
4060   if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
4061     if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
4062                                        extinfo->relro_fd) < 0) {
4063       DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
4064              get_realpath(), strerror(errno));
4065       return false;
4066     }
4067   } else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
4068     if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
4069                                  extinfo->relro_fd) < 0) {
4070       DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
4071              get_realpath(), strerror(errno));
4072       return false;
4073     }
4074   }
4075 
4076   notify_gdb_of_load(this);
4077   return true;
4078 }
4079 
protect_relro()4080 bool soinfo::protect_relro() {
4081   if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
4082     DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
4083            get_realpath(), strerror(errno));
4084     return false;
4085   }
4086   return true;
4087 }
4088 
4089 /*
4090  * This function add vdso to internal dso list.
4091  * It helps to stack unwinding through signal handlers.
4092  * Also, it makes bionic more like glibc.
4093  */
add_vdso(KernelArgumentBlock & args __unused)4094 static void add_vdso(KernelArgumentBlock& args __unused) {
4095 #if defined(AT_SYSINFO_EHDR)
4096   ElfW(Ehdr)* ehdr_vdso = reinterpret_cast<ElfW(Ehdr)*>(args.getauxval(AT_SYSINFO_EHDR));
4097   if (ehdr_vdso == nullptr) {
4098     return;
4099   }
4100 
4101   soinfo* si = soinfo_alloc(&g_default_namespace, "[vdso]", nullptr, 0, 0);
4102 
4103   si->phdr = reinterpret_cast<ElfW(Phdr)*>(reinterpret_cast<char*>(ehdr_vdso) + ehdr_vdso->e_phoff);
4104   si->phnum = ehdr_vdso->e_phnum;
4105   si->base = reinterpret_cast<ElfW(Addr)>(ehdr_vdso);
4106   si->size = phdr_table_get_load_size(si->phdr, si->phnum);
4107   si->load_bias = get_elf_exec_load_bias(ehdr_vdso);
4108 
4109   si->prelink_image();
4110   si->link_image(g_empty_list, soinfo::soinfo_list_t::make_list(si), nullptr);
4111 #endif
4112 }
4113 
4114 /* gdb expects the linker to be in the debug shared object list.
4115  * Without this, gdb has trouble locating the linker's ".text"
4116  * and ".plt" sections. Gdb could also potentially use this to
4117  * relocate the offset of our exported 'rtld_db_dlactivity' symbol.
4118  * Note that the linker shouldn't be on the soinfo list.
4119  */
init_linker_info_for_gdb(ElfW (Addr)linker_base)4120 static void init_linker_info_for_gdb(ElfW(Addr) linker_base) {
4121   static link_map linker_link_map_for_gdb;
4122 #if defined(__LP64__)
4123   static char kLinkerPath[] = "/system/bin/linker64";
4124 #else
4125   static char kLinkerPath[] = "/system/bin/linker";
4126 #endif
4127 
4128   linker_link_map_for_gdb.l_addr = linker_base;
4129   linker_link_map_for_gdb.l_name = kLinkerPath;
4130 
4131   /*
4132    * Set the dynamic field in the link map otherwise gdb will complain with
4133    * the following:
4134    *   warning: .dynamic section for "/system/bin/linker" is not at the
4135    *   expected address (wrong library or version mismatch?)
4136    */
4137   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_base);
4138   ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_base + elf_hdr->e_phoff);
4139   phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base,
4140                                  &linker_link_map_for_gdb.l_ld, nullptr);
4141 
4142   insert_link_map_into_debug_map(&linker_link_map_for_gdb);
4143 }
4144 
init_default_namespace()4145 static void init_default_namespace() {
4146   g_default_namespace.set_name("(default)");
4147   g_default_namespace.set_isolated(false);
4148 
4149   const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
4150                                                        somain->load_bias);
4151   const char* bname = basename(interp);
4152   if (bname && (strcmp(bname, "linker_asan") == 0 || strcmp(bname, "linker_asan64") == 0)) {
4153     g_default_ld_paths = kAsanDefaultLdPaths;
4154     g_is_asan = true;
4155   } else {
4156     g_default_ld_paths = kDefaultLdPaths;
4157   }
4158 
4159   char real_path[PATH_MAX];
4160   std::vector<std::string> ld_default_paths;
4161   for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
4162     if (realpath(g_default_ld_paths[i], real_path) != nullptr) {
4163       ld_default_paths.push_back(real_path);
4164     } else {
4165       ld_default_paths.push_back(g_default_ld_paths[i]);
4166     }
4167   }
4168 
4169   g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
4170 };
4171 
4172 extern "C" int __system_properties_init(void);
4173 
get_executable_path()4174 static const char* get_executable_path() {
4175   static std::string executable_path;
4176   if (executable_path.empty()) {
4177     char path[PATH_MAX];
4178     ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
4179     if (path_len == -1 || path_len >= static_cast<ssize_t>(sizeof(path))) {
4180       __libc_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno));
4181     }
4182     executable_path = std::string(path, path_len);
4183   }
4184 
4185   return executable_path.c_str();
4186 }
4187 
4188 /*
4189  * This code is called after the linker has linked itself and
4190  * fixed it's own GOT. It is safe to make references to externs
4191  * and other non-local data at this point.
4192  */
__linker_init_post_relocation(KernelArgumentBlock & args,ElfW (Addr)linker_base)4193 static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(Addr) linker_base) {
4194 #if TIMING
4195   struct timeval t0, t1;
4196   gettimeofday(&t0, 0);
4197 #endif
4198 
4199   // Sanitize the environment.
4200   __libc_init_AT_SECURE(args);
4201 
4202   // Initialize system properties
4203   __system_properties_init(); // may use 'environ'
4204 
4205   debuggerd_init();
4206 
4207   // Get a few environment variables.
4208   const char* LD_DEBUG = getenv("LD_DEBUG");
4209   if (LD_DEBUG != nullptr) {
4210     g_ld_debug_verbosity = atoi(LD_DEBUG);
4211   }
4212 
4213 #if defined(__LP64__)
4214   INFO("[ Android dynamic linker (64-bit) ]");
4215 #else
4216   INFO("[ Android dynamic linker (32-bit) ]");
4217 #endif
4218 
4219   // These should have been sanitized by __libc_init_AT_SECURE, but the test
4220   // doesn't cost us anything.
4221   const char* ldpath_env = nullptr;
4222   const char* ldpreload_env = nullptr;
4223   if (!getauxval(AT_SECURE)) {
4224     ldpath_env = getenv("LD_LIBRARY_PATH");
4225     if (ldpath_env != nullptr) {
4226       INFO("[ LD_LIBRARY_PATH set to \"%s\" ]", ldpath_env);
4227     }
4228     ldpreload_env = getenv("LD_PRELOAD");
4229     if (ldpreload_env != nullptr) {
4230       INFO("[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
4231     }
4232   }
4233 
4234   struct stat file_stat;
4235   // Stat "/proc/self/exe" instead of executable_path because
4236   // the executable could be unlinked by this point and it should
4237   // not cause a crash (see http://b/31084669)
4238   if (TEMP_FAILURE_RETRY(stat("/proc/self/exe", &file_stat)) != 0) {
4239     __libc_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno));
4240   }
4241 
4242   const char* executable_path = get_executable_path();
4243   soinfo* si = soinfo_alloc(&g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL);
4244   if (si == nullptr) {
4245     __libc_fatal("Couldn't allocate soinfo: out of memory?");
4246   }
4247 
4248   /* bootstrap the link map, the main exe always needs to be first */
4249   si->set_main_executable();
4250   link_map* map = &(si->link_map_head);
4251 
4252   // Register the main executable and the linker upfront to have
4253   // gdb aware of them before loading the rest of the dependency
4254   // tree.
4255   map->l_addr = 0;
4256   map->l_name = const_cast<char*>(executable_path);
4257   insert_link_map_into_debug_map(map);
4258   init_linker_info_for_gdb(linker_base);
4259 
4260   // Extract information passed from the kernel.
4261   si->phdr = reinterpret_cast<ElfW(Phdr)*>(args.getauxval(AT_PHDR));
4262   si->phnum = args.getauxval(AT_PHNUM);
4263   si->entry = args.getauxval(AT_ENTRY);
4264 
4265   /* Compute the value of si->base. We can't rely on the fact that
4266    * the first entry is the PHDR because this will not be true
4267    * for certain executables (e.g. some in the NDK unit test suite)
4268    */
4269   si->base = 0;
4270   si->size = phdr_table_get_load_size(si->phdr, si->phnum);
4271   si->load_bias = 0;
4272   for (size_t i = 0; i < si->phnum; ++i) {
4273     if (si->phdr[i].p_type == PT_PHDR) {
4274       si->load_bias = reinterpret_cast<ElfW(Addr)>(si->phdr) - si->phdr[i].p_vaddr;
4275       si->base = reinterpret_cast<ElfW(Addr)>(si->phdr) - si->phdr[i].p_offset;
4276       break;
4277     }
4278   }
4279   si->dynamic = nullptr;
4280 
4281   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
4282   if (elf_hdr->e_type != ET_DYN) {
4283     __libc_fatal("\"%s\": error: only position independent executables (PIE) are supported.",
4284                  args.argv[0]);
4285   }
4286 
4287   // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
4288   parse_LD_LIBRARY_PATH(ldpath_env);
4289   parse_LD_PRELOAD(ldpreload_env);
4290 
4291   somain = si;
4292 
4293   init_default_namespace();
4294 
4295   if (!si->prelink_image()) {
4296     __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
4297   }
4298 
4299   // add somain to global group
4300   si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
4301 
4302   // Load ld_preloads and dependencies.
4303   StringLinkedList needed_library_name_list;
4304   size_t needed_libraries_count = 0;
4305   size_t ld_preloads_count = 0;
4306 
4307   for (const auto& ld_preload_name : g_ld_preload_names) {
4308     needed_library_name_list.push_back(ld_preload_name.c_str());
4309     ++needed_libraries_count;
4310     ++ld_preloads_count;
4311   }
4312 
4313   for_each_dt_needed(si, [&](const char* name) {
4314     needed_library_name_list.push_back(name);
4315     ++needed_libraries_count;
4316   });
4317 
4318   const char* needed_library_names[needed_libraries_count];
4319 
4320   memset(needed_library_names, 0, sizeof(needed_library_names));
4321   needed_library_name_list.copy_to_array(needed_library_names, needed_libraries_count);
4322 
4323   if (needed_libraries_count > 0 &&
4324       !find_libraries(&g_default_namespace, si, needed_library_names, needed_libraries_count,
4325                       nullptr, &g_ld_preloads, ld_preloads_count, RTLD_GLOBAL, nullptr,
4326                       /* add_as_children */ true)) {
4327     __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
4328   } else if (needed_libraries_count == 0) {
4329     if (!si->link_image(g_empty_list, soinfo::soinfo_list_t::make_list(si), nullptr)) {
4330       __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
4331     }
4332     si->increment_ref_count();
4333   }
4334 
4335   add_vdso(args);
4336 
4337   {
4338     ProtectedDataGuard guard;
4339 
4340     si->call_pre_init_constructors();
4341 
4342     /* After the prelink_image, the si->load_bias is initialized.
4343      * For so lib, the map->l_addr will be updated in notify_gdb_of_load.
4344      * We need to update this value for so exe here. So Unwind_Backtrace
4345      * for some arch like x86 could work correctly within so exe.
4346      */
4347     map->l_addr = si->load_bias;
4348     si->call_constructors();
4349   }
4350 
4351 #if TIMING
4352   gettimeofday(&t1, nullptr);
4353   PRINT("LINKER TIME: %s: %d microseconds", args.argv[0], (int) (
4354            (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
4355            (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec)));
4356 #endif
4357 #if STATS
4358   PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol", args.argv[0],
4359          linker_stats.count[kRelocAbsolute],
4360          linker_stats.count[kRelocRelative],
4361          linker_stats.count[kRelocCopy],
4362          linker_stats.count[kRelocSymbol]);
4363 #endif
4364 #if COUNT_PAGES
4365   {
4366     unsigned n;
4367     unsigned i;
4368     unsigned count = 0;
4369     for (n = 0; n < 4096; n++) {
4370       if (bitmask[n]) {
4371         unsigned x = bitmask[n];
4372 #if defined(__LP64__)
4373         for (i = 0; i < 32; i++) {
4374 #else
4375         for (i = 0; i < 8; i++) {
4376 #endif
4377           if (x & 1) {
4378             count++;
4379           }
4380           x >>= 1;
4381         }
4382       }
4383     }
4384     PRINT("PAGES MODIFIED: %s: %d (%dKB)", args.argv[0], count, count * 4);
4385   }
4386 #endif
4387 
4388 #if TIMING || STATS || COUNT_PAGES
4389   fflush(stdout);
4390 #endif
4391 
4392   TRACE("[ Ready to execute \"%s\" @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
4393   return si->entry;
4394 }
4395 
4396 /* Compute the load-bias of an existing executable. This shall only
4397  * be used to compute the load bias of an executable or shared library
4398  * that was loaded by the kernel itself.
4399  *
4400  * Input:
4401  *    elf    -> address of ELF header, assumed to be at the start of the file.
4402  * Return:
4403  *    load bias, i.e. add the value of any p_vaddr in the file to get
4404  *    the corresponding address in memory.
4405  */
4406 static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf) {
4407   ElfW(Addr) offset = elf->e_phoff;
4408   const ElfW(Phdr)* phdr_table =
4409       reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
4410   const ElfW(Phdr)* phdr_end = phdr_table + elf->e_phnum;
4411 
4412   for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_end; phdr++) {
4413     if (phdr->p_type == PT_LOAD) {
4414       return reinterpret_cast<ElfW(Addr)>(elf) + phdr->p_offset - phdr->p_vaddr;
4415     }
4416   }
4417   return 0;
4418 }
4419 
4420 static void __linker_cannot_link(KernelArgumentBlock& args) {
4421   __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", args.argv[0], linker_get_error_buffer());
4422 }
4423 
4424 /*
4425  * This is the entry point for the linker, called from begin.S. This
4426  * method is responsible for fixing the linker's own relocations, and
4427  * then calling __linker_init_post_relocation().
4428  *
4429  * Because this method is called before the linker has fixed it's own
4430  * relocations, any attempt to reference an extern variable, extern
4431  * function, or other GOT reference will generate a segfault.
4432  */
4433 extern "C" ElfW(Addr) __linker_init(void* raw_args) {
4434   KernelArgumentBlock args(raw_args);
4435 
4436   ElfW(Addr) linker_addr = args.getauxval(AT_BASE);
4437   ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
4438   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
4439   ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
4440 
4441   soinfo linker_so(nullptr, nullptr, nullptr, 0, 0);
4442 
4443   // If the linker is not acting as PT_INTERP entry_point is equal to
4444   // _start. Which means that the linker is running as an executable and
4445   // already linked by PT_INTERP.
4446   //
4447   // This happens when user tries to run 'adb shell /system/bin/linker'
4448   // see also https://code.google.com/p/android/issues/detail?id=63174
4449   if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
4450     __libc_format_fd(STDOUT_FILENO,
4451                      "This is %s, the helper program for shared library executables.\n",
4452                      args.argv[0]);
4453     exit(0);
4454   }
4455 
4456   linker_so.base = linker_addr;
4457   linker_so.size = phdr_table_get_load_size(phdr, elf_hdr->e_phnum);
4458   linker_so.load_bias = get_elf_exec_load_bias(elf_hdr);
4459   linker_so.dynamic = nullptr;
4460   linker_so.phdr = phdr;
4461   linker_so.phnum = elf_hdr->e_phnum;
4462   linker_so.set_linker_flag();
4463 
4464   // Prelink the linker so we can access linker globals.
4465   if (!linker_so.prelink_image()) __linker_cannot_link(args);
4466 
4467   // This might not be obvious... The reasons why we pass g_empty_list
4468   // in place of local_group here are (1) we do not really need it, because
4469   // linker is built with DT_SYMBOLIC and therefore relocates its symbols against
4470   // itself without having to look into local_group and (2) allocators
4471   // are not yet initialized, and therefore we cannot use linked_list.push_*
4472   // functions at this point.
4473   if (!linker_so.link_image(g_empty_list, g_empty_list, nullptr)) __linker_cannot_link(args);
4474 
4475 #if defined(__i386__)
4476   // On x86, we can't make system calls before this point.
4477   // We can't move this up because this needs to assign to a global.
4478   // Note that until we call __libc_init_main_thread below we have
4479   // no TLS, so you shouldn't make a system call that can fail, because
4480   // it will SEGV when it tries to set errno.
4481   __libc_init_sysinfo(args);
4482 #endif
4483 
4484   // Initialize the main thread (including TLS, so system calls really work).
4485   __libc_init_main_thread(args);
4486 
4487   // We didn't protect the linker's RELRO pages in link_image because we
4488   // couldn't make system calls on x86 at that point, but we can now...
4489   if (!linker_so.protect_relro()) __linker_cannot_link(args);
4490 
4491   // Initialize the linker's static libc's globals
4492   __libc_init_globals(args);
4493 
4494   // Initialize the linker's own global variables
4495   linker_so.call_constructors();
4496 
4497   // Initialize static variables. Note that in order to
4498   // get correct libdl_info we need to call constructors
4499   // before get_libdl_info().
4500   solist = get_libdl_info();
4501   sonext = get_libdl_info();
4502   g_default_namespace.add_soinfo(get_libdl_info());
4503 
4504   // We have successfully fixed our own relocations. It's safe to run
4505   // the main part of the linker now.
4506   args.abort_message_ptr = &g_abort_message;
4507   ElfW(Addr) start_address = __linker_init_post_relocation(args, linker_addr);
4508 
4509   INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));
4510 
4511   // Return the address that the calling assembly stub should jump to.
4512   return start_address;
4513 }
4514