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