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