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