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