1 #define _GNU_SOURCE
2 #define SYSCALL_NO_TLS 1
3
4 #include "dynlink.h"
5
6 #include <stdbool.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <stdint.h>
14 #include <elf.h>
15 #include <sys/mman.h>
16 #include <limits.h>
17 #include <fcntl.h>
18 #include <sys/stat.h>
19 #include <errno.h>
20 #include <link.h>
21 #include <setjmp.h>
22 #include <pthread.h>
23 #include <ctype.h>
24 #include <dlfcn.h>
25 #include <semaphore.h>
26 #include <sys/membarrier.h>
27 #include <sys/time.h>
28 #include <time.h>
29
30 #include "dlfcn_ext.h"
31 #include "dynlink_rand.h"
32 #include "ld_log.h"
33 #include "libc.h"
34 #include "malloc_impl.h"
35 #include "namespace.h"
36 #include "ns_config.h"
37 #include "pthread_impl.h"
38 #include "strops.h"
39 #ifdef OHOS_ENABLE_PARAMETER
40 #include "sys_param.h"
41 #endif
42 #ifdef LOAD_ORDER_RANDOMIZATION
43 #include "zip_archive.h"
44 #endif
45
46 static void error(const char *, ...);
47
48 #define MAXP2(a,b) (-(-(a)&-(b)))
49 #define ALIGN(x,y) ((x)+(y)-1 & -(y))
50 #define GNU_HASH_FILTER(ght, ghm, gho) \
51 const size_t *bloomwords = (const void *)(ght+4); \
52 size_t f = bloomwords[gho & (ght[2]-1)]; \
53 if (!(f & ghm)) continue; \
54 f >>= (gh >> ght[3]) % (8 * sizeof f); \
55 if (!(f & 1)) continue;
56
57 #define container_of(p,t,m) ((t*)((char *)(p)-offsetof(t,m)))
58 #define countof(a) ((sizeof (a))/(sizeof (a)[0]))
59 #define DSO_FLAGS_NODELETE 0x1
60
61 #ifdef HANDLE_RANDOMIZATION
62 #define NEXT_DYNAMIC_INDEX 2
63 #define MIN_DEPS_COUNT 2
64 #define NAME_INDEX_ZERO 0
65 #define NAME_INDEX_ONE 1
66 #define NAME_INDEX_TWO 2
67 #define NAME_INDEX_THREE 3
68 #define TLS_CNT_INCREASE 3
69 #define INVALID_FD_INHIBIT_FURTHER_SEARCH (-2)
70 #endif
71
72 #define PARENTS_BASE_CAPACITY 8
73 #define RELOC_CAN_SEARCH_DSO_BASE_CAPACITY 32
74
75 struct debug {
76 int ver;
77 void *head;
78 void (*bp)(void);
79 int state;
80 void *base;
81 };
82
83 struct reserved_address_params {
84 void* start_addr;
85 size_t reserved_size;
86 bool must_use_reserved;
87 bool reserved_address_recursive;
88 #ifdef LOAD_ORDER_RANDOMIZATION
89 struct dso *target;
90 #endif
91 };
92
93 struct td_index {
94 size_t args[2];
95 struct td_index *next;
96 };
97
98 struct verinfo {
99 const char *s;
100 const char *v;
101 bool use_vna_hash;
102 uint32_t vna_hash;
103 };
104
105 struct sym_info_pair {
106 uint_fast32_t sym_h;
107 uint32_t sym_l;
108 };
109
110 struct dso {
111 #if DL_FDPIC
112 struct fdpic_loadmap *loadmap;
113 #else
114 unsigned char *base;
115 #endif
116 char *name;
117 size_t *dynv;
118 struct dso *next, *prev;
119 /* add namespace */
120 ns_t *namespace;
121 /* mark the dso status */
122 unsigned int flags;
123
124 int cache_sym_index;
125 struct dso *cache_dso;
126 Sym *cache_sym;
127
128 Phdr *phdr;
129 int phnum;
130 size_t phentsize;
131 Sym *syms;
132 Elf_Symndx *hashtab;
133 uint32_t *ghashtab;
134 int16_t *versym;
135 Verdef *verdef;
136 Verneed *verneed;
137 char *strings;
138 struct dso *syms_next, *lazy_next;
139 size_t *lazy, lazy_cnt;
140 unsigned char *map;
141 size_t map_len;
142 dev_t dev;
143 ino_t ino;
144 uint64_t file_offset;
145 char relocated;
146 char constructed;
147 char kernel_mapped;
148 char mark;
149 char bfs_built;
150 char runtime_loaded;
151 char by_dlopen;
152 struct dso **deps, *needed_by;
153 size_t ndeps_direct;
154 size_t next_dep;
155 int ctor_visitor;
156 int nr_dlopen;
157 char *rpath_orig, *rpath;
158 struct tls_module tls;
159 size_t tls_id;
160 size_t relro_start, relro_end;
161 uintptr_t *new_dtv;
162 unsigned char *new_tls;
163 struct td_index *td_index;
164 struct dso *fini_next;
165 char *shortname;
166 #if DL_FDPIC
167 unsigned char *base;
168 #else
169 struct fdpic_loadmap *loadmap;
170 #endif
171 struct funcdesc {
172 void *addr;
173 size_t *got;
174 } *funcdescs;
175 size_t *got;
176 struct dso **parents;
177 size_t parents_count;
178 size_t parents_capacity;
179 bool is_global;
180 bool is_reloc_head_so_dep;
181 struct dso **reloc_can_search_dso_list;
182 size_t reloc_can_search_dso_count;
183 size_t reloc_can_search_dso_capacity;
184 char buf[];
185 };
186
187 struct symdef {
188 Sym *sym;
189 struct dso *dso;
190 };
191
192 typedef void (*stage3_func)(size_t *, size_t *);
193
194 static struct builtin_tls {
195 char c[8];
196 struct pthread pt;
197 void *space[16];
198 } builtin_tls[1];
199 #define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
200
201 #define ADDEND_LIMIT 4096
202 static size_t *saved_addends, *apply_addends_to;
203 static bool g_is_asan;
204 static struct dso ldso;
205 static struct dso *head, *tail, *fini_head, *syms_tail, *lazy_head;
206 static char *env_path, *sys_path;
207 static unsigned long long gencnt;
208 static int runtime;
209 static int ldd_mode;
210 static int ldso_fail;
211 static int noload;
212 static int shutting_down;
213 static jmp_buf *rtld_fail;
214 static pthread_rwlock_t lock;
215 static struct debug debug;
216 static struct tls_module *tls_tail;
217 static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
218 static size_t static_tls_cnt;
219 static pthread_mutex_t init_fini_lock;
220 static pthread_cond_t ctor_cond;
221 static struct dso *builtin_deps[2];
222 static struct dso *const no_deps[1];
223 static struct dso *builtin_ctor_queue[4];
224 static struct dso **main_ctor_queue;
225 static struct fdpic_loadmap *app_loadmap;
226 static struct fdpic_dummy_loadmap app_dummy_loadmap;
227
228 struct debug *_dl_debug_addr = &debug;
229
230 extern hidden int __malloc_replaced;
231
232 hidden void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
233
234 extern hidden void (*const __init_array_end)(void), (*const __fini_array_end)(void);
235
236 weak_alias(__init_array_start, __init_array_end);
237 weak_alias(__fini_array_start, __fini_array_end);
238 #ifdef DFX_SIGNAL_LIBC
__InstallSignalHandler()239 static void __InstallSignalHandler()
240 {
241 }
242 weak_alias(__InstallSignalHandler, DFX_InstallSignalHandler);
243 #endif
244
245 #ifdef HANDLE_RANDOMIZATION
246 static int do_dlclose(struct dso *p);
247 #endif
248
249 #ifdef LOAD_ORDER_RANDOMIZATION
250 static bool map_library_header(struct loadtask *task);
251 static bool task_map_library(struct loadtask *task, struct reserved_address_params *reserved_params);
252 static bool load_library_header(struct loadtask *task);
253 static void task_load_library(struct loadtask *task, struct reserved_address_params *reserved_params);
254 static void preload_direct_deps(struct dso *p, ns_t *namespace, struct loadtasks *tasks);
255 static void unmap_preloaded_sections(struct loadtasks *tasks);
256 static void preload_deps(struct dso *p, struct loadtasks *tasks);
257 static void run_loadtasks(struct loadtasks *tasks, struct reserved_address_params *reserved_params);
258 static void assign_tls(struct dso *p);
259 static void load_preload(char *s, ns_t *ns, struct loadtasks *tasks);
260 static void open_library_by_path(const char *name, const char *s, struct loadtask *task, struct zip_info *z_info);
261 static void handle_asan_path_open_by_task(int fd, const char *name, ns_t *namespace, struct loadtask *task, struct zip_info *z_info);
262 #endif
263
264 /* Sharing relro */
265 static void handle_relro_sharing(struct dso *p, const dl_extinfo *extinfo, ssize_t *relro_fd_offset);
266
267 /* asan path open */
268 int handle_asan_path_open(int fd, const char *name, ns_t *namespace, char *buf, size_t buf_size);
269
270 /* add namespace function */
271 static void *addr2dso(size_t a);
272 static void get_sys_path(ns_configor *conf);
273 static void dlclose_ns(struct dso *p);
get_app_path(char * path,size_t size)274 static bool get_app_path(char *path, size_t size)
275 {
276 int l = 0;
277 l = readlink("/proc/self/exe", path, size);
278 if (l < 0 || l >= size) {
279 LD_LOGD("get_app_path readlink failed!");
280 return false;
281 }
282 path[l] = 0;
283 LD_LOGD("get_app_path path:%{public}s.", path);
284 return true;
285 }
286
init_default_namespace(struct dso * app)287 static void init_default_namespace(struct dso *app)
288 {
289 ns_t *default_ns = get_default_ns();
290 memset(default_ns, 0, sizeof *default_ns);
291 ns_set_name(default_ns, NS_DEFAULT_NAME);
292 if (env_path) ns_set_env_paths(default_ns, env_path);
293 ns_set_lib_paths(default_ns, sys_path);
294 ns_set_separated(default_ns, false);
295 app->namespace = default_ns;
296 ns_add_dso(default_ns, app);
297 LD_LOGD("init_default_namespace default_namespace:"
298 "nsname: default ,"
299 "lib_paths:%{public}s ,"
300 "env_path:%{public}s ,"
301 "separated: false.",
302 sys_path, env_path);
303 return;
304 }
305
set_ns_attrs(ns_t * ns,ns_configor * conf)306 static void set_ns_attrs(ns_t *ns, ns_configor *conf)
307 {
308 if(!ns || !conf) {
309 return;
310 }
311
312 char *lib_paths, *asan_lib_paths, *permitted_paths, *asan_permitted_paths, *allowed_libs;
313
314 ns_set_separated(ns, conf->get_separated(ns->ns_name));
315
316 lib_paths = conf->get_lib_paths(ns->ns_name);
317 if (lib_paths) ns_set_lib_paths(ns, lib_paths);
318
319 asan_lib_paths = conf->get_asan_lib_paths(ns->ns_name);
320 if (asan_lib_paths) ns_set_asan_lib_paths(ns, asan_lib_paths);
321
322 permitted_paths = conf->get_permitted_paths(ns->ns_name);
323 if (permitted_paths) ns_set_permitted_paths(ns, permitted_paths);
324
325 asan_permitted_paths = conf->get_asan_permitted_paths(ns->ns_name);
326 if (asan_permitted_paths) ns_set_asan_permitted_paths(ns, asan_permitted_paths);
327
328 allowed_libs = conf->get_allowed_libs(ns->ns_name);
329 if (allowed_libs) ns_set_allowed_libs(ns, allowed_libs);
330
331 LD_LOGD("set_ns_attrs :"
332 "ns_name: %{public}s ,"
333 "separated:%{public}d ,"
334 "lib_paths:%{public}s ,"
335 "asan_lib_paths:%{public}s ,"
336 "permitted_paths:%{public}s ,"
337 "asan_permitted_paths:%{public}s ,"
338 "allowed_libs: %{public}s .",
339 ns->ns_name, ns->separated, ns->lib_paths, ns->asan_lib_paths, permitted_paths,
340 asan_permitted_paths, allowed_libs);
341 }
342
set_ns_inherits(ns_t * ns,ns_configor * conf)343 static void set_ns_inherits(ns_t *ns, ns_configor *conf)
344 {
345 if(!ns || !conf) {
346 return;
347 }
348
349 strlist *inherits = conf->get_inherits(ns->ns_name);
350 if (inherits) {
351 for (size_t i=0; i<inherits->num; i++) {
352 ns_t *inherited_ns = find_ns_by_name(inherits->strs[i]);
353 if (inherited_ns) {
354 char *shared_libs = conf->get_inherit_shared_libs(ns->ns_name, inherited_ns->ns_name);
355 ns_add_inherit(ns, inherited_ns, shared_libs);
356 LD_LOGD("set_ns_inherits :"
357 "ns_name: %{public}s ,"
358 "separated:%{public}d ,"
359 "lib_paths:%{public}s ,"
360 "asan_lib_paths:%{public}s ,",
361 inherited_ns->ns_name, inherited_ns->separated, inherited_ns->lib_paths,
362 inherited_ns->asan_lib_paths);
363 }
364 }
365 strlist_free(inherits);
366 } else {
367 LD_LOGD("set_ns_inherits inherits is NULL!");
368 }
369 }
370
init_namespace(struct dso * app)371 static void init_namespace(struct dso *app)
372 {
373 char app_path[PATH_MAX+1];
374 if (!get_app_path(app_path, sizeof app_path)) {
375 strcpy(app_path, app->name);
376 }
377 char *t = strrchr(app_path, '/');
378 if (t) {
379 *t = 0;
380 } else {
381 app_path[0] = '.';
382 app_path[1] = 0;
383 }
384
385 nslist *nsl = nslist_init();
386 ns_configor *conf = configor_init();
387 char file_path[sizeof "/etc/ld-musl-namespace-" + sizeof (LDSO_ARCH) + sizeof ".ini" + 1] = {0};
388 (void)snprintf(file_path, sizeof file_path, "/etc/ld-musl-namespace-%s.ini", LDSO_ARCH);
389 LD_LOGI("init_namespace file_path:%{public}s", file_path);
390 int ret = conf->parse(file_path, app_path);
391 if (ret < 0) {
392 LD_LOGE("init_namespace ini file parse failed!");
393 /* Init_default_namespace is required even if the ini file parsing fails */
394 if (!sys_path) get_sys_path(conf);
395 init_default_namespace(app);
396 configor_free();
397 return;
398 }
399
400 /* sys_path needs to be parsed through ini file */
401 if (!sys_path) get_sys_path(conf);
402 init_default_namespace(app);
403
404 /* Init default namespace */
405 ns_t *d_ns = get_default_ns();
406 set_ns_attrs(d_ns, conf);
407
408 /* Init other namespace */
409 if (!nsl) {
410 LD_LOGE("init nslist fail!");
411 configor_free();
412 return;
413 }
414 strlist *s_ns = conf->get_namespaces();
415 if (s_ns) {
416 for (size_t i=0; i<s_ns->num; i++) {
417 ns_t *ns = ns_alloc();
418 ns_set_name(ns, s_ns->strs[i]);
419 set_ns_attrs(ns, conf);
420 ns_add_dso(ns, app);
421 nslist_add_ns(ns);
422 }
423 strlist_free(s_ns);
424 }
425 /* Set inherited namespace */
426 set_ns_inherits(d_ns, conf);
427 for (size_t i = 0; i < nsl->num; i++) {
428 set_ns_inherits(nsl->nss[i], conf);
429 }
430 configor_free();
431 return;
432 }
433
dl_strcmp(const char * l,const char * r)434 static int dl_strcmp(const char *l, const char *r)
435 {
436 for (; *l==*r && *l; l++, r++);
437 return *(unsigned char *)l - *(unsigned char *)r;
438 }
439 #define strcmp(l,r) dl_strcmp(l,r)
440
441 /* Compute load address for a virtual address in a given dso. */
442 #if DL_FDPIC
laddr(const struct dso * p,size_t v)443 static void *laddr(const struct dso *p, size_t v)
444 {
445 size_t j=0;
446 if (!p->loadmap) return p->base + v;
447 for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++);
448 return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);
449 }
laddr_pg(const struct dso * p,size_t v)450 static void *laddr_pg(const struct dso *p, size_t v)
451 {
452 size_t j=0;
453 size_t pgsz = PAGE_SIZE;
454 if (!p->loadmap) return p->base + v;
455 for (j=0; ; j++) {
456 size_t a = p->loadmap->segs[j].p_vaddr;
457 size_t b = a + p->loadmap->segs[j].p_memsz;
458 a &= -pgsz;
459 b += pgsz-1;
460 b &= -pgsz;
461 if (v-a<b-a) break;
462 }
463 return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);
464 }
fdbarrier(void * p)465 static void (*fdbarrier(void *p))()
466 {
467 void (*fd)();
468 __asm__("" : "=r"(fd) : "0"(p));
469 return fd;
470 }
471 #define fpaddr(p, v) fdbarrier((&(struct funcdesc){ \
472 laddr(p, v), (p)->got }))
473 #else
474 #define laddr(p, v) (void *)((p)->base + (v))
475 #define laddr_pg(p, v) laddr(p, v)
476 #define fpaddr(p, v) ((void (*)())laddr(p, v))
477 #endif
478
decode_vec(size_t * v,size_t * a,size_t cnt)479 static void decode_vec(size_t *v, size_t *a, size_t cnt)
480 {
481 size_t i;
482 for (i=0; i<cnt; i++) a[i] = 0;
483 for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
484 if (v[0] < 8*sizeof(long)) {
485 a[0] |= 1UL<<v[0];
486 }
487 a[v[0]] = v[1];
488 }
489 }
490
search_vec(size_t * v,size_t * r,size_t key)491 static int search_vec(size_t *v, size_t *r, size_t key)
492 {
493 for (; v[0]!=key; v+=2)
494 if (!v[0]) return 0;
495 *r = v[1];
496 return 1;
497 }
498
check_vna_hash(Verdef * def,int16_t vsym,uint32_t vna_hash)499 static int check_vna_hash(Verdef *def, int16_t vsym, uint32_t vna_hash)
500 {
501 int matched = 0;
502
503 vsym &= 0x7fff;
504 Verdef *verdef = def;
505 for(;;) {
506 if ((verdef->vd_ndx & 0x7fff) == vsym) {
507 if (vna_hash == verdef->vd_hash) {
508 matched = 1;
509 }
510 break;
511 }
512 if (matched) {
513 break;
514 }
515 if (verdef->vd_next == 0) {
516 break;
517 }
518 verdef = (Verdef *)((char *)verdef + verdef->vd_next);
519 }
520 #if (LD_LOG_LEVEL & LD_LOG_DEBUG)
521 if (!matched) {
522 LD_LOGD("check_vna_hash no matched found. vsym=%{public}d vna_hash=%{public}x", vsym, vna_hash);
523 }
524 #endif
525 return matched;
526 }
527
check_verinfo(Verdef * def,int16_t * versym,uint32_t index,struct verinfo * verinfo,char * strings)528 static int check_verinfo(Verdef *def, int16_t *versym, uint32_t index, struct verinfo *verinfo, char *strings)
529 {
530 /* if the versym and verinfo is null , then not need version. */
531 if (!versym || !def) {
532 if (strlen(verinfo->v) == 0) {
533 return 1;
534 } else {
535 LD_LOGD("check_verinfo versym or def is null and verinfo->v exist, s:%{public}s v:%{public}s.",
536 verinfo->s, verinfo->v);
537 return 0;
538 }
539 }
540
541 int16_t vsym = versym[index];
542
543 /* find the verneed symbol. */
544 if (verinfo->use_vna_hash) {
545 if (vsym != VER_NDX_LOCAL && versym != VER_NDX_GLOBAL) {
546 return check_vna_hash(def, vsym, verinfo->vna_hash);
547 }
548 }
549
550 /* if the version length is zero and vsym not less than zero, then library hava default version symbol. */
551 if (strlen(verinfo->v) == 0) {
552 if (vsym >= 0) {
553 return 1;
554 } else {
555 LD_LOGD("check_verinfo not default version. vsym:%{public}d s:%{public}s", vsym, verinfo->s);
556 return 0;
557 }
558 }
559
560 /* find the version of symbol. */
561 vsym &= 0x7fff;
562 for (;;) {
563 if (!(def->vd_flags & VER_FLG_BASE) && (def->vd_ndx & 0x7fff) == vsym) {
564 break;
565 }
566 if (def->vd_next == 0) {
567 return 0;
568 }
569 def = (Verdef *)((char *)def + def->vd_next);
570 }
571
572 Verdaux *aux = (Verdaux *)((char *)def + def->vd_aux);
573
574 int ret = !strcmp(verinfo->v, strings + aux->vda_name);
575 #if (LD_LOG_LEVEL & LD_LOG_DEBUG)
576 if (!ret) {
577 LD_LOGD("check_verinfo version not match. s=%{public}s v=%{public}s vsym=%{public}d vda_name=%{public}s",
578 verinfo->s, verinfo->v, vsym, strings + aux->vda_name);
579 }
580 #endif
581 return ret;
582 }
583
sysv_hash(const char * s0)584 static struct sym_info_pair sysv_hash(const char *s0)
585 {
586 struct sym_info_pair s_info_p;
587 const unsigned char *s = (void *)s0;
588 uint_fast32_t h = 0;
589 while (*s) {
590 h = 16*h + *s++;
591 h ^= h>>24 & 0xf0;
592 }
593 s_info_p.sym_h = h & 0xfffffff;
594 s_info_p.sym_l = (char *)s - s0;
595 return s_info_p;
596 }
597
gnu_hash(const char * s0)598 static struct sym_info_pair gnu_hash(const char *s0)
599 {
600 struct sym_info_pair s_info_p;
601 const unsigned char *s = (void *)s0;
602 uint_fast32_t h = 5381;
603 for (; *s; s++)
604 h += h*32 + *s;
605 s_info_p.sym_h = h;
606 s_info_p.sym_l = (char *)s - s0;
607 return s_info_p;
608 }
609
sysv_lookup(struct verinfo * verinfo,struct sym_info_pair s_info_p,struct dso * dso)610 static Sym *sysv_lookup(struct verinfo *verinfo, struct sym_info_pair s_info_p, struct dso *dso)
611 {
612 size_t i;
613 uint32_t h = s_info_p.sym_h;
614 Sym *syms = dso->syms;
615 Elf_Symndx *hashtab = dso->hashtab;
616 char *strings = dso->strings;
617 for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
618 if ((!dso->versym || (dso->versym[i] & 0x7fff) >= 0)
619 && (!memcmp(verinfo->s, strings+syms[i].st_name, s_info_p.sym_l))) {
620 if (!check_verinfo(dso->verdef, dso->versym, i, verinfo, dso->strings)) {
621 continue;
622 }
623
624 return syms+i;
625 }
626
627 }
628 LD_LOGD("sysv_lookup not find the symbol, "
629 "so:%{public}s s:%{public}s v:%{public}s use_vna_hash:%{public}d vna_hash:%{public}x",
630 dso->name, verinfo->s, verinfo->v, verinfo->use_vna_hash, verinfo->vna_hash);
631 return 0;
632 }
633
gnu_lookup(struct sym_info_pair s_info_p,uint32_t * hashtab,struct dso * dso,struct verinfo * verinfo)634 static Sym *gnu_lookup(struct sym_info_pair s_info_p, uint32_t *hashtab, struct dso *dso, struct verinfo *verinfo)
635 {
636 uint32_t h1 = s_info_p.sym_h;
637 uint32_t nbuckets = hashtab[0];
638 uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
639 uint32_t i = buckets[h1 % nbuckets];
640
641 if (!i) {
642 LD_LOGD("gnu_lookup symbol not found (bloom filter), so:%{public}s s:%{public}s", dso->name, verinfo->s);
643 return 0;
644 }
645
646 uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
647
648 for (h1 |= 1; ; i++) {
649 uint32_t h2 = *hashval++;
650 if ((h1 == (h2|1)) && (!dso->versym || (dso->versym[i] & 0x7fff) >= 0)
651 && !memcmp(verinfo->s, dso->strings + dso->syms[i].st_name, s_info_p.sym_l)) {
652 if (!check_verinfo(dso->verdef, dso->versym, i, verinfo, dso->strings)) {
653 continue;
654 }
655
656 return dso->syms+i;
657 }
658
659 if (h2 & 1) break;
660 }
661
662 LD_LOGD("gnu_lookup symbol not found, "
663 "so:%{public}s s:%{public}s v:%{public}s use_vna_hash:%{public}d vna_hash:%{public}x",
664 dso->name, verinfo->s, verinfo->v, verinfo->use_vna_hash, verinfo->vna_hash);
665 return 0;
666 }
667
check_sym_accessible(struct dso * dso,ns_t * ns)668 static bool check_sym_accessible(struct dso *dso, ns_t *ns)
669 {
670 if (!dso || !dso->namespace || !ns) {
671 LD_LOGD("check_sym_accessible invalid parameter!");
672 return false;
673 }
674 if (dso->namespace == ns) {
675 return true;
676 }
677 for (int i = 0; i < dso->parents_count; i++) {
678 if (dso->parents[i]->namespace == ns) {
679 return true;
680 }
681 }
682 LD_LOGD(
683 "check_sym_accessible dso name [%{public}s] ns_name [%{public}s] not accessible!", dso->name, ns->ns_name);
684 return false;
685 }
686
find_dso_parent(struct dso * p,struct dso * target)687 static int find_dso_parent(struct dso *p, struct dso *target)
688 {
689 int index = -1;
690 for (int i = 0; i < p->parents_count; i++) {
691 if (p->parents[i] == target) {
692 index = i;
693 break;
694 }
695 }
696 return index;
697 }
698
add_dso_parent(struct dso * p,struct dso * parent)699 static void add_dso_parent(struct dso *p, struct dso *parent)
700 {
701 int index = find_dso_parent(p, parent);
702 if (index != -1) {
703 return;
704 }
705 if (p->parents_count + 1 > p->parents_capacity) {
706 if (p->parents_capacity == 0) {
707 p->parents = (struct dso **)internal_malloc(sizeof(struct dso *) * PARENTS_BASE_CAPACITY);
708 if (!p->parents) {
709 return;
710 }
711 p->parents_capacity = PARENTS_BASE_CAPACITY;
712 } else {
713 struct dso ** realloced = (struct dso **)internal_realloc(
714 p->parents, sizeof(struct dso *) * (p->parents_capacity + PARENTS_BASE_CAPACITY));
715 if (!realloced) {
716 return;
717 }
718 p->parents = realloced;
719 p->parents_capacity += PARENTS_BASE_CAPACITY;
720 }
721 }
722 p->parents[p->parents_count] = parent;
723 p->parents_count++;
724 }
725
remove_dso_parent(struct dso * p,struct dso * parent)726 static void remove_dso_parent(struct dso *p, struct dso *parent)
727 {
728 int index = find_dso_parent(p, parent);
729 if (index == -1) {
730 return;
731 }
732 int i;
733 for (i = 0; i < index; i++) {
734 p->parents[i] = p->parents[i];
735 }
736 for (i = index; i < p->parents_count - 1; i++) {
737 p->parents[i] = p->parents[i + 1];
738 }
739 p->parents_count--;
740 }
741
add_reloc_can_search_dso(struct dso * p,struct dso * can_search_so)742 static void add_reloc_can_search_dso(struct dso *p, struct dso *can_search_so)
743 {
744 if (p->reloc_can_search_dso_count + 1 > p->reloc_can_search_dso_capacity) {
745 if (p->reloc_can_search_dso_capacity == 0) {
746 p->reloc_can_search_dso_list =
747 (struct dso **)internal_malloc(sizeof(struct dso *) * RELOC_CAN_SEARCH_DSO_BASE_CAPACITY);
748 if (!p->reloc_can_search_dso_list) {
749 return;
750 }
751 p->reloc_can_search_dso_capacity = RELOC_CAN_SEARCH_DSO_BASE_CAPACITY;
752 } else {
753 struct dso ** realloced = (struct dso **)internal_realloc(
754 p->reloc_can_search_dso_list,
755 sizeof(struct dso *) * (p->reloc_can_search_dso_capacity + RELOC_CAN_SEARCH_DSO_BASE_CAPACITY));
756 if (!realloced) {
757 return;
758 }
759 p->reloc_can_search_dso_list = realloced;
760 p->reloc_can_search_dso_capacity += RELOC_CAN_SEARCH_DSO_BASE_CAPACITY;
761 }
762 }
763 p->reloc_can_search_dso_list[p->reloc_can_search_dso_count] = can_search_so;
764 p->reloc_can_search_dso_count++;
765 }
766
free_reloc_can_search_dso(struct dso * p)767 static void free_reloc_can_search_dso(struct dso *p)
768 {
769 if (p->reloc_can_search_dso_list) {
770 internal_free(p->reloc_can_search_dso_list);
771 p->reloc_can_search_dso_list = NULL;
772 p->reloc_can_search_dso_count = 0;
773 p->reloc_can_search_dso_capacity = 0;
774 }
775 }
776
777 static char* reloc_white_list[] = {
778 "/usr/lib/libace_lite.so",
779 "/usr/lib/libsec_shared.so",
780 "/usr/lib/libisp.so",
781 "/usr/lib/lib_hiae.so",
782 "/usr/lib/lib_hiawb.so",
783 "/usr/lib/libmedia_hal_common.so",
784 "/usr/lib/libhi_osal.so",
785 "/usr/lib/libmpi.so"
786 };
787
788 /* The list of so that can be accessed during relocation include:
789 * - The is_global flag of the so is true which means accessible by default.
790 * Global so includes exe, ld preload so and ldso.
791 * - We only check whether ns is accessible for the so if is_reloc_head_so_dep is true.
792 *
793 * How to set is_reloc_head_so_dep:
794 * When dlopen A, we set is_reloc_head_so_dep to true for
795 * all direct and indirect dependent sos of A, including A itself. */
add_can_search_so_list_in_dso(struct dso * dso_relocating,struct dso * start_check_dso)796 static void add_can_search_so_list_in_dso(struct dso *dso_relocating, struct dso *start_check_dso) {
797 struct dso *p = start_check_dso;
798 for (; p; p = p->syms_next) {
799 if (p->is_global) {
800 add_reloc_can_search_dso(dso_relocating, p);
801 continue;
802 }
803
804 if (p->is_reloc_head_so_dep) {
805 if (dso_relocating->namespace && check_sym_accessible(p, dso_relocating->namespace)) {
806 add_reloc_can_search_dso(dso_relocating, p);
807 continue;
808 }
809 }
810
811 for (size_t i = 0; i < sizeof(reloc_white_list) / sizeof(char*); i++) {
812 if (strcmp(reloc_white_list[i], p->name) == 0) {
813 add_reloc_can_search_dso(dso_relocating, p);
814 break;
815 }
816 }
817 }
818
819 return;
820 }
821
822 #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
823 #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
824
825 #ifndef ARCH_SYM_REJECT_UND
826 #define ARCH_SYM_REJECT_UND(s) 0
827 #endif
828
829 #if defined(__GNUC__)
830 __attribute__((always_inline))
831 #endif
find_sym2(struct dso * dso,struct verinfo * verinfo,int need_def,int use_deps,ns_t * ns)832 static inline struct symdef find_sym2(struct dso *dso, struct verinfo *verinfo, int need_def, int use_deps, ns_t *ns)
833 {
834 struct sym_info_pair s_info_p = gnu_hash(verinfo->s);
835 uint32_t h = 0, gh = s_info_p.sym_h, gho = gh / (8*sizeof(size_t)), *ght;
836 size_t ghm = 1ul << gh % (8*sizeof(size_t));
837 struct symdef def = {0};
838 struct dso **deps = use_deps ? dso->deps : 0;
839 for (; dso; dso=use_deps ? *deps++ : dso->syms_next) {
840 Sym *sym;
841 if (ns && !check_sym_accessible(dso, ns)) {
842 continue;
843 }
844 if ((ght = dso->ghashtab)) {
845 GNU_HASH_FILTER(ght, ghm, gho)
846 sym = gnu_lookup(s_info_p, ght, dso, verinfo);
847 } else {
848 if (!h) s_info_p = sysv_hash(verinfo->s);
849 sym = sysv_lookup(verinfo, s_info_p, dso);
850 }
851
852 if (!sym) continue;
853 if (!sym->st_shndx)
854 if (need_def || (sym->st_info&0xf) == STT_TLS
855 || ARCH_SYM_REJECT_UND(sym))
856 continue;
857 if (!sym->st_value)
858 if ((sym->st_info&0xf) != STT_TLS)
859 continue;
860 if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
861 if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
862 def.sym = sym;
863 def.dso = dso;
864 break;
865 }
866 return def;
867 }
868
find_sym_by_saved_so_list(int sym_type,struct dso * dso,struct verinfo * verinfo,int need_def,struct dso * dso_relocating)869 static inline struct symdef find_sym_by_saved_so_list(
870 int sym_type, struct dso *dso, struct verinfo *verinfo, int need_def, struct dso *dso_relocating)
871 {
872 struct sym_info_pair s_info_p = gnu_hash(verinfo->s);
873 uint32_t h = 0, gh = s_info_p.sym_h, gho = gh / (8 * sizeof(size_t)), *ght;
874 size_t ghm = 1ul << gh % (8 * sizeof(size_t));
875 struct symdef def = {0};
876 // skip head dso.
877 int start_search_index = sym_type==REL_COPY ? 1 : 0;
878 struct dso *dso_searching = 0;
879 for (int i = start_search_index; i < dso_relocating->reloc_can_search_dso_count; i++) {
880 dso_searching = dso_relocating->reloc_can_search_dso_list[i];
881 Sym *sym;
882 if ((ght = dso_searching->ghashtab)) {
883 GNU_HASH_FILTER(ght, ghm, gho)
884 sym = gnu_lookup(s_info_p, ght, dso_searching, verinfo);
885 } else {
886 if (!h) s_info_p = sysv_hash(verinfo->s);
887 sym = sysv_lookup(verinfo, s_info_p, dso_searching);
888 }
889 if (!sym) continue;
890 if (!sym->st_shndx)
891 if (need_def || (sym->st_info&0xf) == STT_TLS
892 || ARCH_SYM_REJECT_UND(sym))
893 continue;
894 if (!sym->st_value)
895 if ((sym->st_info&0xf) != STT_TLS)
896 continue;
897 if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
898 if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
899 def.sym = sym;
900 def.dso = dso_searching;
901 break;
902 }
903 return def;
904 }
905
find_sym(struct dso * dso,const char * s,int need_def)906 static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
907 {
908 struct verinfo verinfo = { .s = s, .v = "", .use_vna_hash = false };
909 return find_sym2(dso, &verinfo, need_def, 0, NULL);
910 }
911
get_vna_hash(struct dso * dso,int sym_index,uint32_t * vna_hash)912 static bool get_vna_hash(struct dso *dso, int sym_index, uint32_t *vna_hash)
913 {
914 if (!dso->versym || !dso->verneed) {
915 return false;
916 }
917
918 uint16_t vsym = dso->versym[sym_index];
919 if (vsym == VER_NDX_LOCAL || vsym == VER_NDX_GLOBAL) {
920 return false;
921 }
922
923 bool result = false;
924 Verneed *verneed = dso->verneed;
925 Vernaux *vernaux;
926 vsym &= 0x7fff;
927
928 for(;;) {
929 vernaux = (Vernaux *)((char *)verneed + verneed->vn_aux);
930
931 for (size_t cnt = 0; cnt < verneed->vn_cnt; cnt++) {
932 if ((vernaux->vna_other & 0x7fff) == vsym) {
933 result = true;
934 *vna_hash = vernaux->vna_hash;
935 break;
936 }
937
938 vernaux = (Vernaux *)((char *)vernaux + vernaux->vna_next);
939 }
940
941 if (result) {
942 break;
943 }
944
945 if (verneed->vn_next == 0) {
946 break;
947 }
948
949 verneed = (Verneed *)((char *)verneed + verneed->vn_next);
950 }
951 return result;
952 }
953
do_relocs(struct dso * dso,size_t * rel,size_t rel_size,size_t stride)954 static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
955 {
956 unsigned char *base = dso->base;
957 Sym *syms = dso->syms;
958 char *strings = dso->strings;
959 Sym *sym;
960 const char *name;
961 void *ctx;
962 int type;
963 int sym_index;
964 struct symdef def;
965 size_t *reloc_addr;
966 size_t sym_val;
967 size_t tls_val;
968 size_t addend;
969 int skip_relative = 0, reuse_addends = 0, save_slot = 0;
970
971 if (dso == &ldso) {
972 /* Only ldso's REL table needs addend saving/reuse. */
973 if (rel == apply_addends_to)
974 reuse_addends = 1;
975 skip_relative = 1;
976 }
977
978 for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
979 if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;
980 type = R_TYPE(rel[1]);
981 if (type == REL_NONE) continue;
982 reloc_addr = laddr(dso, rel[0]);
983
984 if (stride > 2) {
985 addend = rel[2];
986 } else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
987 addend = 0;
988 } else if (reuse_addends) {
989 /* Save original addend in stage 2 where the dso
990 * chain consists of just ldso; otherwise read back
991 * saved addend since the inline one was clobbered. */
992 if (head==&ldso)
993 saved_addends[save_slot] = *reloc_addr;
994 addend = saved_addends[save_slot++];
995 } else {
996 addend = *reloc_addr;
997 }
998
999 sym_index = R_SYM(rel[1]);
1000 if (sym_index) {
1001 sym = syms + sym_index;
1002 name = strings + sym->st_name;
1003 ctx = type==REL_COPY ? head->syms_next : head;
1004 struct verinfo vinfo = { .s = name, .v = "" };
1005 vinfo.use_vna_hash = get_vna_hash(dso, sym_index, &vinfo.vna_hash);
1006 if (dso->cache_sym_index == sym_index) {
1007 def = (struct symdef){ .dso = dso->cache_dso, .sym = dso->cache_sym };
1008 } else {
1009 def = (sym->st_info>>4) == STB_LOCAL
1010 ? (struct symdef){ .dso = dso, .sym = sym }
1011 : dso != &ldso ? find_sym_by_saved_so_list(type, ctx, &vinfo, type==REL_PLT, dso)
1012 : find_sym2(ctx, &vinfo, type==REL_PLT, 0, dso->namespace);
1013 dso->cache_sym_index = sym_index;
1014 dso->cache_dso = def.dso;
1015 dso->cache_sym = def.sym;
1016 }
1017
1018 if (!def.sym && (sym->st_shndx != SHN_UNDEF
1019 || sym->st_info>>4 != STB_WEAK)) {
1020 if (dso->lazy && (type==REL_PLT || type==REL_GOT)) {
1021 dso->lazy[3*dso->lazy_cnt+0] = rel[0];
1022 dso->lazy[3*dso->lazy_cnt+1] = rel[1];
1023 dso->lazy[3*dso->lazy_cnt+2] = addend;
1024 dso->lazy_cnt++;
1025 continue;
1026 }
1027 LD_LOGE("relocating failed: symbol not found. "
1028 "dso=%{public}s s=%{public}s use_vna_hash=%{public}d van_hash=%{public}x",
1029 dso->name, name, vinfo.use_vna_hash, vinfo.vna_hash);
1030 error("Error relocating %s: %s: symbol not found",
1031 dso->name, name);
1032 if (runtime) longjmp(*rtld_fail, 1);
1033 continue;
1034 }
1035 } else {
1036 sym = 0;
1037 def.sym = 0;
1038 def.dso = dso;
1039 }
1040
1041 sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;
1042 tls_val = def.sym ? def.sym->st_value : 0;
1043
1044 if ((type == REL_TPOFF || type == REL_TPOFF_NEG)
1045 && def.dso->tls_id > static_tls_cnt) {
1046 error("Error relocating %s: %s: initial-exec TLS "
1047 "resolves to dynamic definition in %s",
1048 dso->name, name, def.dso->name);
1049 longjmp(*rtld_fail, 1);
1050 }
1051
1052 switch(type) {
1053 case REL_NONE:
1054 break;
1055 case REL_OFFSET:
1056 addend -= (size_t)reloc_addr;
1057 case REL_SYMBOLIC:
1058 case REL_GOT:
1059 case REL_PLT:
1060 *reloc_addr = sym_val + addend;
1061 break;
1062 case REL_USYMBOLIC:
1063 memcpy(reloc_addr, &(size_t){sym_val + addend}, sizeof(size_t));
1064 break;
1065 case REL_RELATIVE:
1066 *reloc_addr = (size_t)base + addend;
1067 break;
1068 case REL_SYM_OR_REL:
1069 if (sym) *reloc_addr = sym_val + addend;
1070 else *reloc_addr = (size_t)base + addend;
1071 break;
1072 case REL_COPY:
1073 memcpy(reloc_addr, (void *)sym_val, sym->st_size);
1074 break;
1075 case REL_OFFSET32:
1076 *(uint32_t *)reloc_addr = sym_val + addend
1077 - (size_t)reloc_addr;
1078 break;
1079 case REL_FUNCDESC:
1080 *reloc_addr = def.sym ? (size_t)(def.dso->funcdescs
1081 + (def.sym - def.dso->syms)) : 0;
1082 break;
1083 case REL_FUNCDESC_VAL:
1084 if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val;
1085 else *reloc_addr = sym_val;
1086 reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0;
1087 break;
1088 case REL_DTPMOD:
1089 *reloc_addr = def.dso->tls_id;
1090 break;
1091 case REL_DTPOFF:
1092 *reloc_addr = tls_val + addend - DTP_OFFSET;
1093 break;
1094 #ifdef TLS_ABOVE_TP
1095 case REL_TPOFF:
1096 *reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;
1097 break;
1098 #else
1099 case REL_TPOFF:
1100 *reloc_addr = tls_val - def.dso->tls.offset + addend;
1101 break;
1102 case REL_TPOFF_NEG:
1103 *reloc_addr = def.dso->tls.offset - tls_val + addend;
1104 break;
1105 #endif
1106 case REL_TLSDESC:
1107 if (stride<3) addend = reloc_addr[1];
1108 if (def.dso->tls_id > static_tls_cnt) {
1109 struct td_index *new = internal_malloc(sizeof *new);
1110 if (!new) {
1111 error(
1112 "Error relocating %s: cannot allocate TLSDESC for %s",
1113 dso->name, sym ? name : "(local)" );
1114 longjmp(*rtld_fail, 1);
1115 }
1116 new->next = dso->td_index;
1117 dso->td_index = new;
1118 new->args[0] = def.dso->tls_id;
1119 new->args[1] = tls_val + addend - DTP_OFFSET;
1120 reloc_addr[0] = (size_t)__tlsdesc_dynamic;
1121 reloc_addr[1] = (size_t)new;
1122 } else {
1123 reloc_addr[0] = (size_t)__tlsdesc_static;
1124 #ifdef TLS_ABOVE_TP
1125 reloc_addr[1] = tls_val + def.dso->tls.offset
1126 + TPOFF_K + addend;
1127 #else
1128 reloc_addr[1] = tls_val - def.dso->tls.offset
1129 + addend;
1130 #endif
1131 }
1132 #ifdef TLSDESC_BACKWARDS
1133 /* Some archs (32-bit ARM at least) invert the order of
1134 * the descriptor members. Fix them up here. */
1135 size_t tmp = reloc_addr[0];
1136 reloc_addr[0] = reloc_addr[1];
1137 reloc_addr[1] = tmp;
1138 #endif
1139 break;
1140 default:
1141 error("Error relocating %s: unsupported relocation type %d",
1142 dso->name, type);
1143 if (runtime) longjmp(*rtld_fail, 1);
1144 continue;
1145 }
1146 }
1147 }
1148
redo_lazy_relocs()1149 static void redo_lazy_relocs()
1150 {
1151 struct dso *p = lazy_head, *next;
1152 lazy_head = 0;
1153 for (; p; p=next) {
1154 next = p->lazy_next;
1155 size_t size = p->lazy_cnt*3*sizeof(size_t);
1156 p->lazy_cnt = 0;
1157 do_relocs(p, p->lazy, size, 3);
1158 if (p->lazy_cnt) {
1159 p->lazy_next = lazy_head;
1160 lazy_head = p;
1161 } else {
1162 internal_free(p->lazy);
1163 p->lazy = 0;
1164 p->lazy_next = 0;
1165 }
1166 }
1167 }
1168
1169 /* A huge hack: to make up for the wastefulness of shared libraries
1170 * needing at least a page of dirty memory even if they have no global
1171 * data, we reclaim the gaps at the beginning and end of writable maps
1172 * and "donate" them to the heap. */
1173
reclaim(struct dso * dso,size_t start,size_t end)1174 static void reclaim(struct dso *dso, size_t start, size_t end)
1175 {
1176 if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end;
1177 if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start;
1178 if (start >= end) return;
1179 char *base = laddr_pg(dso, start);
1180 __malloc_donate(base, base+(end-start));
1181 }
1182
reclaim_gaps(struct dso * dso)1183 static void reclaim_gaps(struct dso *dso)
1184 {
1185 Phdr *ph = dso->phdr;
1186 size_t phcnt = dso->phnum;
1187
1188 for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {
1189 if (ph->p_type!=PT_LOAD) continue;
1190 if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
1191 reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
1192 reclaim(dso, ph->p_vaddr+ph->p_memsz,
1193 ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
1194 }
1195 }
1196
mmap_fixed(void * p,size_t n,int prot,int flags,int fd,off_t off)1197 static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
1198 {
1199 static int no_map_fixed;
1200 char *q;
1201 if (!no_map_fixed) {
1202 q = mmap(p, n, prot, flags|MAP_FIXED, fd, off);
1203 if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)
1204 return q;
1205 no_map_fixed = 1;
1206 }
1207 /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
1208 if (flags & MAP_ANONYMOUS) {
1209 memset(p, 0, n);
1210 return p;
1211 }
1212 ssize_t r;
1213 if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
1214 for (q=p; n; q+=r, off+=r, n-=r) {
1215 r = read(fd, q, n);
1216 if (r < 0 && errno != EINTR) return MAP_FAILED;
1217 if (!r) {
1218 memset(q, 0, n);
1219 break;
1220 }
1221 }
1222 return p;
1223 }
1224
unmap_library(struct dso * dso)1225 static void unmap_library(struct dso *dso)
1226 {
1227 if (dso->loadmap) {
1228 size_t i;
1229 for (i=0; i<dso->loadmap->nsegs; i++) {
1230 if (!dso->loadmap->segs[i].p_memsz)
1231 continue;
1232 munmap((void *)dso->loadmap->segs[i].addr,
1233 dso->loadmap->segs[i].p_memsz);
1234 }
1235 internal_free(dso->loadmap);
1236 } else if (dso->map && dso->map_len) {
1237 munmap(dso->map, dso->map_len);
1238 }
1239 }
1240
get_random(void * buf,size_t buflen)1241 static bool get_random(void *buf, size_t buflen)
1242 {
1243 int ret;
1244 int fd = open("/dev/urandom", O_RDONLY);
1245 if (fd < 0) {
1246 return false;
1247 }
1248
1249 ret = read(fd, buf, buflen);
1250 if (ret < 0) {
1251 close(fd);
1252 return false;
1253 }
1254
1255 close(fd);
1256 return true;
1257 }
1258
fill_random_data(void * buf,size_t buflen)1259 static void fill_random_data(void *buf, size_t buflen)
1260 {
1261 uint64_t x;
1262 int i;
1263 int pos = 0;
1264 struct timespec ts;
1265 /* Try to use urandom to get the random number first */
1266 if (!get_random(buf, buflen)) {
1267 /* Can't get random number from /dev/urandom, generate from addr based on ASLR and time */
1268 for (i = 1; i <= (buflen / sizeof(x)); i++) {
1269 (void)clock_gettime(CLOCK_REALTIME, &ts);
1270 x = (((uint64_t)get_random) << 32) ^ (uint64_t)fill_random_data ^ ts.tv_nsec;
1271 memcpy((char *)buf + pos, &x, sizeof(x));
1272 pos += sizeof(x);
1273 }
1274 }
1275 return;
1276 }
1277
map_library(int fd,struct dso * dso,struct reserved_address_params * reserved_params)1278 static void *map_library(int fd, struct dso *dso, struct reserved_address_params *reserved_params)
1279 {
1280 Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
1281 void *allocated_buf=0;
1282 size_t phsize;
1283 size_t addr_min=SIZE_MAX, addr_max=0, map_len;
1284 size_t this_min, this_max;
1285 size_t nsegs = 0;
1286 off_t off_start;
1287 Ehdr *eh;
1288 Phdr *ph, *ph0;
1289 unsigned prot;
1290 unsigned char *map=MAP_FAILED, *base;
1291 size_t dyn=0;
1292 size_t tls_image=0;
1293 size_t i;
1294 int map_flags = MAP_PRIVATE;
1295 size_t start_addr;
1296
1297 ssize_t l = read(fd, buf, sizeof buf);
1298 eh = buf;
1299 if (l<0) return 0;
1300 if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
1301 goto noexec;
1302 phsize = eh->e_phentsize * eh->e_phnum;
1303 if (phsize > sizeof buf - sizeof *eh) {
1304 allocated_buf = internal_malloc(phsize);
1305 if (!allocated_buf) return 0;
1306 l = pread(fd, allocated_buf, phsize, eh->e_phoff);
1307 if (l < 0) goto error;
1308 if (l != phsize) goto noexec;
1309 ph = ph0 = allocated_buf;
1310 } else if (eh->e_phoff + phsize > l) {
1311 l = pread(fd, buf+1, phsize, eh->e_phoff);
1312 if (l < 0) goto error;
1313 if (l != phsize) goto noexec;
1314 ph = ph0 = (void *)(buf + 1);
1315 } else {
1316 ph = ph0 = (void *)((char *)buf + eh->e_phoff);
1317 }
1318 for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
1319 if (ph->p_type == PT_DYNAMIC) {
1320 dyn = ph->p_vaddr;
1321 } else if (ph->p_type == PT_TLS) {
1322 tls_image = ph->p_vaddr;
1323 dso->tls.align = ph->p_align;
1324 dso->tls.len = ph->p_filesz;
1325 dso->tls.size = ph->p_memsz;
1326 } else if (ph->p_type == PT_GNU_RELRO) {
1327 dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
1328 dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
1329 } else if (ph->p_type == PT_GNU_STACK) {
1330 if (!runtime && ph->p_memsz > __default_stacksize) {
1331 __default_stacksize =
1332 ph->p_memsz < DEFAULT_STACK_MAX ?
1333 ph->p_memsz : DEFAULT_STACK_MAX;
1334 }
1335 }
1336 if (ph->p_type != PT_LOAD) continue;
1337 nsegs++;
1338 if (ph->p_vaddr < addr_min) {
1339 addr_min = ph->p_vaddr;
1340 off_start = ph->p_offset;
1341 prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1342 ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1343 ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1344 }
1345 if (ph->p_vaddr+ph->p_memsz > addr_max) {
1346 addr_max = ph->p_vaddr+ph->p_memsz;
1347 }
1348 }
1349 if (!dyn) goto noexec;
1350 if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
1351 dso->loadmap = internal_calloc(1, sizeof *dso->loadmap
1352 + nsegs * sizeof *dso->loadmap->segs);
1353 if (!dso->loadmap) goto error;
1354 dso->loadmap->nsegs = nsegs;
1355 for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {
1356 if (ph->p_type != PT_LOAD) continue;
1357 prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1358 ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1359 ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1360 map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
1361 prot, MAP_PRIVATE,
1362 fd, ph->p_offset & -PAGE_SIZE);
1363 if (map == MAP_FAILED) {
1364 unmap_library(dso);
1365 goto error;
1366 }
1367 dso->loadmap->segs[i].addr = (size_t)map +
1368 (ph->p_vaddr & PAGE_SIZE-1);
1369 dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
1370 dso->loadmap->segs[i].p_memsz = ph->p_memsz;
1371 i++;
1372 if (prot & PROT_WRITE) {
1373 size_t brk = (ph->p_vaddr & PAGE_SIZE-1)
1374 + ph->p_filesz;
1375 size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;
1376 size_t pgend = brk + ph->p_memsz - ph->p_filesz
1377 + PAGE_SIZE-1 & -PAGE_SIZE;
1378 if (pgend > pgbrk && mmap_fixed(map+pgbrk,
1379 pgend-pgbrk, prot,
1380 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
1381 -1, off_start) == MAP_FAILED)
1382 goto error;
1383 memset(map + brk, 0, pgbrk-brk);
1384 }
1385 }
1386 map = (void *)dso->loadmap->segs[0].addr;
1387 map_len = 0;
1388 goto done_mapping;
1389 }
1390 addr_max += PAGE_SIZE-1;
1391 addr_max &= -PAGE_SIZE;
1392 addr_min &= -PAGE_SIZE;
1393 off_start &= -PAGE_SIZE;
1394 map_len = addr_max - addr_min + off_start;
1395 start_addr = addr_min;
1396 if (reserved_params) {
1397 if (map_len > reserved_params->reserved_size) {
1398 if (reserved_params->must_use_reserved) {
1399 goto error;
1400 }
1401 } else {
1402 start_addr = ((size_t)reserved_params->start_addr - 1 + PAGE_SIZE) & -PAGE_SIZE;
1403 map_flags |= MAP_FIXED;
1404 }
1405 }
1406 /* The first time, we map too much, possibly even more than
1407 * the length of the file. This is okay because we will not
1408 * use the invalid part; we just need to reserve the right
1409 * amount of virtual address space to map over later. */
1410 map = DL_NOMMU_SUPPORT
1411 ? mmap((void *)start_addr, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,
1412 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
1413 : mmap((void *)start_addr, map_len, prot,
1414 map_flags, fd, off_start);
1415 if (map==MAP_FAILED) goto error;
1416 if (reserved_params && map_len < reserved_params->reserved_size) {
1417 reserved_params->reserved_size -= (map_len + (start_addr - (size_t)reserved_params->start_addr));
1418 reserved_params->start_addr = (void *)((uint8_t *)map + map_len);
1419 }
1420 dso->map = map;
1421 dso->map_len = map_len;
1422 /* If the loaded file is not relocatable and the requested address is
1423 * not available, then the load operation must fail. */
1424 if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {
1425 errno = EBUSY;
1426 goto error;
1427 }
1428 base = map - addr_min;
1429 dso->phdr = 0;
1430 dso->phnum = 0;
1431 for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
1432 if (ph->p_type == PT_OHOS_RANDOMDATA) {
1433 fill_random_data((void *)(ph->p_vaddr + base), ph->p_memsz);
1434 continue;
1435 }
1436 if (ph->p_type != PT_LOAD) continue;
1437 /* Check if the programs headers are in this load segment, and
1438 * if so, record the address for use by dl_iterate_phdr. */
1439 if (!dso->phdr && eh->e_phoff >= ph->p_offset
1440 && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {
1441 dso->phdr = (void *)(base + ph->p_vaddr
1442 + (eh->e_phoff-ph->p_offset));
1443 dso->phnum = eh->e_phnum;
1444 dso->phentsize = eh->e_phentsize;
1445 }
1446 this_min = ph->p_vaddr & -PAGE_SIZE;
1447 this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
1448 off_start = ph->p_offset & -PAGE_SIZE;
1449 prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1450 ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1451 ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1452 /* Reuse the existing mapping for the lowest-address LOAD */
1453 if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT)
1454 if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
1455 goto error;
1456 if (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) {
1457 size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
1458 size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
1459 memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
1460 if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
1461 goto error;
1462 }
1463 }
1464 for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
1465 if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
1466 if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
1467 && errno != ENOSYS)
1468 goto error;
1469 break;
1470 }
1471 done_mapping:
1472 dso->base = base;
1473 dso->dynv = laddr(dso, dyn);
1474 if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);
1475 internal_free(allocated_buf);
1476 return map;
1477 noexec:
1478 errno = ENOEXEC;
1479 error:
1480 if (map!=MAP_FAILED) unmap_library(dso);
1481 internal_free(allocated_buf);
1482 return 0;
1483 }
1484
path_open(const char * name,const char * s,char * buf,size_t buf_size)1485 static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
1486 {
1487 size_t l;
1488 int fd;
1489 for (;;) {
1490 s += strspn(s, ":\n");
1491 l = strcspn(s, ":\n");
1492 if (l-1 >= INT_MAX) return -1;
1493 if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
1494 if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
1495 switch (errno) {
1496 case ENOENT:
1497 case ENOTDIR:
1498 case EACCES:
1499 case ENAMETOOLONG:
1500 break;
1501 default:
1502 /* Any negative value but -1 will inhibit
1503 * futher path search. */
1504 return -2;
1505 }
1506 }
1507 s += l;
1508 }
1509 }
1510
fixup_rpath(struct dso * p,char * buf,size_t buf_size)1511 static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
1512 {
1513 size_t n, l;
1514 const char *s, *t, *origin;
1515 char *d;
1516 if (p->rpath || !p->rpath_orig) return 0;
1517 if (!strchr(p->rpath_orig, '$')) {
1518 p->rpath = p->rpath_orig;
1519 return 0;
1520 }
1521 n = 0;
1522 s = p->rpath_orig;
1523 while ((t=strchr(s, '$'))) {
1524 if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
1525 return 0;
1526 s = t+1;
1527 n++;
1528 }
1529 if (n > SSIZE_MAX/PATH_MAX) return 0;
1530
1531 if (p->kernel_mapped) {
1532 /* $ORIGIN searches cannot be performed for the main program
1533 * when it is suid/sgid/AT_SECURE. This is because the
1534 * pathname is under the control of the caller of execve.
1535 * For libraries, however, $ORIGIN can be processed safely
1536 * since the library's pathname came from a trusted source
1537 * (either system paths or a call to dlopen). */
1538 if (libc.secure)
1539 return 0;
1540 l = readlink("/proc/self/exe", buf, buf_size);
1541 if (l == -1) switch (errno) {
1542 case ENOENT:
1543 case ENOTDIR:
1544 case EACCES:
1545 break;
1546 default:
1547 return -1;
1548 }
1549 if (l >= buf_size)
1550 return 0;
1551 buf[l] = 0;
1552 origin = buf;
1553 } else {
1554 origin = p->name;
1555 }
1556 t = strrchr(origin, '/');
1557 if (t) {
1558 l = t-origin;
1559 } else {
1560 /* Normally p->name will always be an absolute or relative
1561 * pathname containing at least one '/' character, but in the
1562 * case where ldso was invoked as a command to execute a
1563 * program in the working directory, app.name may not. Fix. */
1564 origin = ".";
1565 l = 1;
1566 }
1567 /* Disallow non-absolute origins for suid/sgid/AT_SECURE. */
1568 if (libc.secure && *origin != '/')
1569 return 0;
1570 p->rpath = internal_malloc(strlen(p->rpath_orig) + n*l + 1);
1571 if (!p->rpath) return -1;
1572
1573 d = p->rpath;
1574 s = p->rpath_orig;
1575 while ((t=strchr(s, '$'))) {
1576 memcpy(d, s, t-s);
1577 d += t-s;
1578 memcpy(d, origin, l);
1579 d += l;
1580 /* It was determined previously that the '$' is followed
1581 * either by "ORIGIN" or "{ORIGIN}". */
1582 s = t + 7 + 2*(t[1]=='{');
1583 }
1584 strcpy(d, s);
1585 return 0;
1586 }
1587
decode_dyn(struct dso * p)1588 static void decode_dyn(struct dso *p)
1589 {
1590 size_t dyn[DYN_CNT];
1591 decode_vec(p->dynv, dyn, DYN_CNT);
1592 p->syms = laddr(p, dyn[DT_SYMTAB]);
1593 p->strings = laddr(p, dyn[DT_STRTAB]);
1594 if (dyn[0]&(1<<DT_HASH))
1595 p->hashtab = laddr(p, dyn[DT_HASH]);
1596 if (dyn[0]&(1<<DT_RPATH))
1597 p->rpath_orig = p->strings + dyn[DT_RPATH];
1598 if (dyn[0]&(1<<DT_RUNPATH))
1599 p->rpath_orig = p->strings + dyn[DT_RUNPATH];
1600 if (dyn[0]&(1<<DT_PLTGOT))
1601 p->got = laddr(p, dyn[DT_PLTGOT]);
1602 if (search_vec(p->dynv, dyn, DT_GNU_HASH))
1603 p->ghashtab = laddr(p, *dyn);
1604 if (search_vec(p->dynv, dyn, DT_VERSYM))
1605 p->versym = laddr(p, *dyn);
1606 if (search_vec(p->dynv, dyn, DT_VERDEF))
1607 p->verdef = laddr(p, *dyn);
1608 if (search_vec(p->dynv, dyn, DT_VERNEED))
1609 p->verneed = laddr(p, *dyn);
1610 }
1611
count_syms(struct dso * p)1612 static size_t count_syms(struct dso *p)
1613 {
1614 if (p->hashtab) return p->hashtab[1];
1615
1616 size_t nsym, i;
1617 uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
1618 uint32_t *hashval;
1619 for (i = nsym = 0; i < p->ghashtab[0]; i++) {
1620 if (buckets[i] > nsym)
1621 nsym = buckets[i];
1622 }
1623 if (nsym) {
1624 hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);
1625 do nsym++;
1626 while (!(*hashval++ & 1));
1627 }
1628 return nsym;
1629 }
1630
dl_mmap(size_t n)1631 static void *dl_mmap(size_t n)
1632 {
1633 void *p;
1634 int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;
1635 #ifdef SYS_mmap2
1636 p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);
1637 #else
1638 p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);
1639 #endif
1640 return (unsigned long)p > -4096UL ? 0 : p;
1641 }
1642
makefuncdescs(struct dso * p)1643 static void makefuncdescs(struct dso *p)
1644 {
1645 static int self_done;
1646 size_t nsym = count_syms(p);
1647 size_t i, size = nsym * sizeof(*p->funcdescs);
1648
1649 if (!self_done) {
1650 p->funcdescs = dl_mmap(size);
1651 self_done = 1;
1652 } else {
1653 p->funcdescs = internal_malloc(size);
1654 }
1655 if (!p->funcdescs) {
1656 if (!runtime) a_crash();
1657 error("Error allocating function descriptors for %s", p->name);
1658 longjmp(*rtld_fail, 1);
1659 }
1660 for (i=0; i<nsym; i++) {
1661 if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {
1662 p->funcdescs[i].addr = laddr(p, p->syms[i].st_value);
1663 p->funcdescs[i].got = p->got;
1664 } else {
1665 p->funcdescs[i].addr = 0;
1666 p->funcdescs[i].got = 0;
1667 }
1668 }
1669 }
1670
get_sys_path(ns_configor * conf)1671 static void get_sys_path(ns_configor *conf)
1672 {
1673 LD_LOGD("get_sys_path g_is_asan:%{public}d", g_is_asan);
1674 /* Use ini file's system paths when Asan is not enabled */
1675 if (!g_is_asan) {
1676 sys_path = conf->get_sys_paths();
1677 } else {
1678 /* Use ini file's asan system paths when the Asan is enabled
1679 * Merge two strings when both sys_paths and asan_sys_paths are valid */
1680 sys_path = conf->get_asan_sys_paths();
1681 char *sys_path_default = conf->get_sys_paths();
1682 if (!sys_path) {
1683 sys_path = sys_path_default;
1684 } else if (sys_path_default) {
1685 size_t newlen = strlen(sys_path) + strlen(sys_path_default) + 2;
1686 char *new_syspath = internal_malloc(newlen);
1687 memset(new_syspath, 0, newlen);
1688 strcpy(new_syspath, sys_path);
1689 strcat(new_syspath, ":");
1690 strcat(new_syspath, sys_path_default);
1691 sys_path = new_syspath;
1692 }
1693 }
1694 if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib:/lib64";
1695 LD_LOGD("get_sys_path sys_path:%{public}s", sys_path);
1696 }
1697
search_dso_by_name(const char * name,const ns_t * ns)1698 static struct dso *search_dso_by_name(const char *name, const ns_t *ns) {
1699 LD_LOGD("search_dso_by_name name:%{public}s, ns_name:%{public}s", name, ns ? ns->ns_name: "NULL");
1700 for (size_t i = 0; i < ns->ns_dsos->num; i++){
1701 struct dso *p = ns->ns_dsos->dsos[i];
1702 if (p->shortname && !strcmp(p->shortname, name)) {
1703 LD_LOGD("search_dso_by_name found name:%{public}s, ns_name:%{public}s", name, ns ? ns->ns_name: "NULL");
1704 return p;
1705 }
1706 }
1707 return NULL;
1708 }
1709
search_dso_by_fstat(const struct stat * st,const ns_t * ns,uint64_t file_offset)1710 static struct dso *search_dso_by_fstat(const struct stat *st, const ns_t *ns, uint64_t file_offset) {
1711 LD_LOGD("search_dso_by_fstat ns_name:%{public}s", ns ? ns->ns_name : "NULL");
1712 for (size_t i = 0; i < ns->ns_dsos->num; i++){
1713 struct dso *p = ns->ns_dsos->dsos[i];
1714 if (p->dev == st->st_dev && p->ino == st->st_ino && p->file_offset == file_offset) {
1715 LD_LOGD("search_dso_by_fstat found dev:%{public}lu, ino:%{public}lu, ns_name:%{public}s",
1716 st->st_dev, st->st_ino, ns ? ns->ns_name : "NULL");
1717 return p;
1718 }
1719 }
1720 return NULL;
1721 }
1722 /* Find loaded so by name */
find_library_by_name(const char * name,const ns_t * ns,bool check_inherited)1723 static struct dso *find_library_by_name(const char *name, const ns_t *ns, bool check_inherited)
1724 {
1725 LD_LOGD("find_library_by_name name:%{public}s, ns_name:%{public}s, check_inherited:%{public}d",
1726 name,
1727 ns ? ns->ns_name : "NULL",
1728 !!check_inherited);
1729 struct dso *p = search_dso_by_name(name, ns);
1730 if (p) return p;
1731 if (check_inherited && ns->ns_inherits) {
1732 for (size_t i = 0; i < ns->ns_inherits->num; i++){
1733 ns_inherit * inherit = ns->ns_inherits->inherits[i];
1734 p = search_dso_by_name(name, inherit->inherited_ns);
1735 if (p && is_sharable(inherit, name)) return p;
1736 }
1737 }
1738 return NULL;
1739 }
1740 /* Find loaded so by file stat */
find_library_by_fstat(const struct stat * st,const ns_t * ns,bool check_inherited,uint64_t file_offset)1741 static struct dso *find_library_by_fstat(const struct stat *st, const ns_t *ns, bool check_inherited, uint64_t file_offset) {
1742 LD_LOGD("find_library_by_fstat ns_name:%{public}s, check_inherited :%{public}d",
1743 ns ? ns->ns_name : "NULL",
1744 !!check_inherited);
1745 struct dso *p = search_dso_by_fstat(st, ns, file_offset);
1746 if (p) return p;
1747 if (check_inherited && ns->ns_inherits) {
1748 for (size_t i = 0; i < ns->ns_inherits->num; i++){
1749 ns_inherit *inherit = ns->ns_inherits->inherits[i];
1750 p = search_dso_by_fstat(st, inherit->inherited_ns, file_offset);
1751 if (p && is_sharable(inherit, p->shortname)) return p;
1752 }
1753 }
1754 return NULL;
1755 }
1756
1757 #ifndef LOAD_ORDER_RANDOMIZATION
1758 /* add namespace function */
load_library(const char * name,struct dso * needed_by,ns_t * namespace,bool check_inherited,struct reserved_address_params * reserved_params)1759 struct dso *load_library(
1760 const char *name, struct dso *needed_by, ns_t *namespace, bool check_inherited, struct reserved_address_params *reserved_params)
1761 {
1762 char buf[PATH_MAX+1];
1763 const char *pathname;
1764 unsigned char *map;
1765 struct dso *p, temp_dso = {0};
1766 int fd;
1767 struct stat st;
1768 size_t alloc_size;
1769 int n_th = 0;
1770 int is_self = 0;
1771
1772 if (!*name) {
1773 errno = EINVAL;
1774 return 0;
1775 }
1776
1777 /* Catch and block attempts to reload the implementation itself */
1778 if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
1779 static const char reserved[] =
1780 "c.pthread.rt.m.dl.util.xnet.";
1781 const char *rp, *next;
1782 for (rp=reserved; *rp; rp=next) {
1783 next = strchr(rp, '.') + 1;
1784 if (strncmp(name+3, rp, next-rp) == 0)
1785 break;
1786 }
1787 if (*rp) {
1788 if (ldd_mode) {
1789 /* Track which names have been resolved
1790 * and only report each one once. */
1791 static unsigned reported;
1792 unsigned mask = 1U<<(rp-reserved);
1793 if (!(reported & mask)) {
1794 reported |= mask;
1795 dprintf(1, "\t%s => %s (%p)\n",
1796 name, ldso.name,
1797 ldso.base);
1798 }
1799 }
1800 is_self = 1;
1801 }
1802 }
1803 if (!strcmp(name, ldso.name)) is_self = 1;
1804 if (is_self) {
1805 if (!ldso.prev) {
1806 tail->next = &ldso;
1807 ldso.prev = tail;
1808 tail = &ldso;
1809 ldso.namespace = namespace;
1810 ns_add_dso(namespace, &ldso);
1811 }
1812 return &ldso;
1813 }
1814 if (strchr(name, '/')) {
1815 pathname = name;
1816
1817 if (!is_accessible(namespace, pathname, g_is_asan, check_inherited)) {
1818 fd = -1;
1819 LD_LOGD("load_library is_accessible return false,fd = -1");
1820 } else {
1821 fd = open(name, O_RDONLY|O_CLOEXEC);
1822 LD_LOGD("load_library is_accessible return true, open file fd:%{public}d .", fd);
1823 }
1824 } else {
1825 /* Search for the name to see if it's already loaded */
1826 /* Search in namespace */
1827 p = find_library_by_name(name, namespace, check_inherited);
1828 if (p) {
1829 LD_LOGD("load_library find_library_by_name found p, return it!");
1830 return p;
1831 }
1832 if (strlen(name) > NAME_MAX) {
1833 LD_LOGE("load_library name exceeding the maximum length, return 0!");
1834 return 0;
1835 }
1836 fd = -1;
1837 if (namespace->env_paths) fd = path_open(name, namespace->env_paths, buf, sizeof buf);
1838 for (p = needed_by; fd == -1 && p; p = p->needed_by) {
1839 if (fixup_rpath(p, buf, sizeof buf) < 0) {
1840 LD_LOGD("load_library Inhibit further search,fd = -2.");
1841 fd = -2; /* Inhibit further search. */
1842 }
1843 if (p->rpath) {
1844 fd = path_open(name, p->rpath, buf, sizeof buf);
1845 LD_LOGD("load_library p->rpath path_open fd:%{public}d.", fd);
1846 }
1847
1848 }
1849 if (g_is_asan) {
1850 fd = handle_asan_path_open(fd, name, namespace, buf, sizeof buf);
1851 LD_LOGD("load_library handle_asan_path_open fd:%{public}d.", fd);
1852 } else {
1853 if (fd == -1 && namespace->lib_paths) {
1854 fd = path_open(name, namespace->lib_paths, buf, sizeof buf);
1855 LD_LOGD("load_library no asan lib_paths path_open fd:%{public}d.", fd);
1856 }
1857 }
1858 pathname = buf;
1859 LD_LOGD("load_library lib_paths pathname:%{public}s.", pathname);
1860 }
1861 if (fd < 0) {
1862 if (!check_inherited || !namespace->ns_inherits) return 0;
1863 /* Load lib in inherited namespace. Do not check inherited again.*/
1864 for (size_t i = 0; i < namespace->ns_inherits->num; i++) {
1865 ns_inherit *inherit = namespace->ns_inherits->inherits[i];
1866 if (strchr(name, '/')==0 && !is_sharable(inherit, name)) continue;
1867 p = load_library(name, needed_by, inherit->inherited_ns, false, reserved_params);
1868 if (p) {
1869 LD_LOGD("load_library search in inherited, found p ,inherited_ns name:%{public}s",
1870 inherit->inherited_ns->ns_name);
1871 return p;
1872 }
1873 }
1874 return 0;
1875 }
1876 if (fstat(fd, &st) < 0) {
1877 close(fd);
1878 LD_LOGE("load_library fstat < 0,return 0!");
1879 return 0;
1880 }
1881 /* Search in namespace */
1882 p = find_library_by_fstat(&st, namespace, check_inherited, 0);
1883 if (p) {
1884 /* If this library was previously loaded with a
1885 * pathname but a search found the same inode,
1886 * setup its shortname so it can be found by name. */
1887 if (!p->shortname && pathname != name)
1888 p->shortname = strrchr(p->name, '/')+1;
1889 close(fd);
1890 LD_LOGD("load_library find_library_by_fstat, found p and return it!");
1891 return p;
1892 }
1893 map = noload ? 0 : map_library(fd, &temp_dso, reserved_params);
1894 close(fd);
1895 if (!map) return 0;
1896
1897 /* Avoid the danger of getting two versions of libc mapped into the
1898 * same process when an absolute pathname was used. The symbols
1899 * checked are chosen to catch both musl and glibc, and to avoid
1900 * false positives from interposition-hack libraries. */
1901 decode_dyn(&temp_dso);
1902 if (find_sym(&temp_dso, "__libc_start_main", 1).sym &&
1903 find_sym(&temp_dso, "stdin", 1).sym) {
1904 unmap_library(&temp_dso);
1905 return load_library("libc.so", needed_by, namespace, true, reserved_params);
1906 }
1907 /* Past this point, if we haven't reached runtime yet, ldso has
1908 * committed either to use the mapped library or to abort execution.
1909 * Unmapping is not possible, so we can safely reclaim gaps. */
1910 if (!runtime) reclaim_gaps(&temp_dso);
1911
1912 /* Allocate storage for the new DSO. When there is TLS, this
1913 * storage must include a reservation for all pre-existing
1914 * threads to obtain copies of both the new TLS, and an
1915 * extended DTV capable of storing an additional slot for
1916 * the newly-loaded DSO. */
1917 alloc_size = sizeof *p + strlen(pathname) + 1;
1918 if (runtime && temp_dso.tls.image) {
1919 size_t per_th = temp_dso.tls.size + temp_dso.tls.align
1920 + sizeof(void *) * (tls_cnt+3);
1921 n_th = libc.threads_minus_1 + 1;
1922 if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
1923 else alloc_size += n_th * per_th;
1924 }
1925 p = internal_calloc(1, alloc_size);
1926 if (!p) {
1927 unmap_library(&temp_dso);
1928 return 0;
1929 }
1930 memcpy(p, &temp_dso, sizeof temp_dso);
1931 p->dev = st.st_dev;
1932 p->ino = st.st_ino;
1933 p->needed_by = needed_by;
1934 p->name = p->buf;
1935 p->runtime_loaded = runtime;
1936 strcpy(p->name, pathname);
1937 /* Add a shortname only if name arg was not an explicit pathname. */
1938 if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
1939 if (p->tls.image) {
1940 p->tls_id = ++tls_cnt;
1941 tls_align = MAXP2(tls_align, p->tls.align);
1942 #ifdef TLS_ABOVE_TP
1943 p->tls.offset = tls_offset + ( (p->tls.align-1) &
1944 (-tls_offset + (uintptr_t)p->tls.image) );
1945 tls_offset = p->tls.offset + p->tls.size;
1946 #else
1947 tls_offset += p->tls.size + p->tls.align - 1;
1948 tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
1949 & (p->tls.align-1);
1950 p->tls.offset = tls_offset;
1951 #endif
1952 p->new_dtv = (void *)(-sizeof(size_t) &
1953 (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
1954 p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
1955 if (tls_tail) tls_tail->next = &p->tls;
1956 else libc.tls_head = &p->tls;
1957 tls_tail = &p->tls;
1958 }
1959
1960 tail->next = p;
1961 p->prev = tail;
1962 tail = p;
1963
1964 /* Add dso to namespace */
1965 p->namespace = namespace;
1966 ns_add_dso(namespace, p);
1967 if (runtime)
1968 p->by_dlopen = 1;
1969
1970 if (DL_FDPIC) makefuncdescs(p);
1971
1972 if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
1973
1974 return p;
1975 }
1976
load_direct_deps(struct dso * p,ns_t * namespace,struct reserved_address_params * reserved_params)1977 static void load_direct_deps(struct dso *p, ns_t *namespace, struct reserved_address_params *reserved_params)
1978 {
1979 size_t i, cnt=0;
1980
1981 if (p->deps) return;
1982 /* For head, all preloads are direct pseudo-dependencies.
1983 * Count and include them now to avoid realloc later. */
1984 if (p==head) for (struct dso *q=p->next; q; q=q->next)
1985 cnt++;
1986 for (i=0; p->dynv[i]; i+=2)
1987 if (p->dynv[i] == DT_NEEDED) cnt++;
1988 /* Use builtin buffer for apps with no external deps, to
1989 * preserve property of no runtime failure paths. */
1990 p->deps = (p==head && cnt<2) ? builtin_deps :
1991 internal_calloc(cnt+1, sizeof *p->deps);
1992 if (!p->deps) {
1993 error("Error loading dependencies for %s", p->name);
1994 if (runtime) longjmp(*rtld_fail, 1);
1995 }
1996 cnt=0;
1997 if (p==head) for (struct dso *q=p->next; q; q=q->next)
1998 p->deps[cnt++] = q;
1999 for (i=0; p->dynv[i]; i+=2) {
2000 if (p->dynv[i] != DT_NEEDED) continue;
2001 struct dso *dep = load_library(p->strings + p->dynv[i+1], p, namespace, true, reserved_params);
2002 LD_LOGD("loading shared library %{public}s: (needed by %{public}s)", p->strings + p->dynv[i+1], p->name);
2003 if (!dep) {
2004 error("Error loading shared library %s: %m (needed by %s)",
2005 p->strings + p->dynv[i+1], p->name);
2006 if (runtime) longjmp(*rtld_fail, 1);
2007 continue;
2008 }
2009 p->deps[cnt++] = dep;
2010 }
2011 p->deps[cnt] = 0;
2012 p->ndeps_direct = cnt;
2013 for (i = 0; i < p->ndeps_direct; i++) {
2014 add_dso_parent(p->deps[i], p);
2015 }
2016 }
2017
load_deps(struct dso * p,struct reserved_address_params * reserved_params)2018 static void load_deps(struct dso *p, struct reserved_address_params *reserved_params)
2019 {
2020 if (p->deps) return;
2021 for (; p; p=p->next)
2022 load_direct_deps(p, p->namespace, reserved_params);
2023 }
2024 #endif
2025
extend_bfs_deps(struct dso * p)2026 static void extend_bfs_deps(struct dso *p)
2027 {
2028 size_t i, j, cnt, ndeps_all;
2029 struct dso **tmp;
2030
2031 /* Can't use realloc if the original p->deps was allocated at
2032 * program entry and malloc has been replaced, or if it's
2033 * the builtin non-allocated trivial main program deps array. */
2034 int no_realloc = (__malloc_replaced && !p->runtime_loaded)
2035 || p->deps == builtin_deps;
2036
2037 if (p->bfs_built) return;
2038 ndeps_all = p->ndeps_direct;
2039
2040 /* Mark existing (direct) deps so they won't be duplicated. */
2041 for (i=0; p->deps[i]; i++)
2042 p->deps[i]->mark = 1;
2043
2044 /* For each dependency already in the list, copy its list of direct
2045 * dependencies to the list, excluding any items already in the
2046 * list. Note that the list this loop iterates over will grow during
2047 * the loop, but since duplicates are excluded, growth is bounded. */
2048 for (i=0; p->deps[i]; i++) {
2049 struct dso *dep = p->deps[i];
2050 for (j=cnt=0; j<dep->ndeps_direct; j++)
2051 if (!dep->deps[j]->mark) cnt++;
2052 tmp = no_realloc ?
2053 internal_malloc(sizeof(*tmp) * (ndeps_all+cnt+1)) :
2054 internal_realloc(p->deps, sizeof(*tmp) * (ndeps_all+cnt+1));
2055 if (!tmp) {
2056 error("Error recording dependencies for %s", p->name);
2057 if (runtime) longjmp(*rtld_fail, 1);
2058 continue;
2059 }
2060 if (no_realloc) {
2061 memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1));
2062 no_realloc = 0;
2063 }
2064 p->deps = tmp;
2065 for (j=0; j<dep->ndeps_direct; j++) {
2066 if (dep->deps[j]->mark) continue;
2067 dep->deps[j]->mark = 1;
2068 p->deps[ndeps_all++] = dep->deps[j];
2069 }
2070 p->deps[ndeps_all] = 0;
2071 }
2072 p->bfs_built = 1;
2073 for (p=head; p; p=p->next)
2074 p->mark = 0;
2075 }
2076
2077 #ifndef LOAD_ORDER_RANDOMIZATION
load_preload(char * s,ns_t * ns)2078 static void load_preload(char *s, ns_t *ns)
2079 {
2080 int tmp;
2081 char *z;
2082 for (z=s; *z; s=z) {
2083 for ( ; *s && (isspace(*s) || *s==':'); s++);
2084 for (z=s; *z && !isspace(*z) && *z!=':'; z++);
2085 tmp = *z;
2086 *z = 0;
2087 load_library(s, 0, ns, true, NULL);
2088 *z = tmp;
2089 }
2090 }
2091 #endif
2092
add_syms(struct dso * p)2093 static void add_syms(struct dso *p)
2094 {
2095 if (!p->syms_next && syms_tail != p) {
2096 syms_tail->syms_next = p;
2097 syms_tail = p;
2098 }
2099 }
2100
revert_syms(struct dso * old_tail)2101 static void revert_syms(struct dso *old_tail)
2102 {
2103 struct dso *p, *next;
2104 /* Chop off the tail of the list of dsos that participate in
2105 * the global symbol table, reverting them to RTLD_LOCAL. */
2106 for (p=old_tail; p; p=next) {
2107 next = p->syms_next;
2108 p->syms_next = 0;
2109 }
2110 syms_tail = old_tail;
2111 }
2112
do_mips_relocs(struct dso * p,size_t * got)2113 static void do_mips_relocs(struct dso *p, size_t *got)
2114 {
2115 size_t i, j, rel[2];
2116 unsigned char *base = p->base;
2117 i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
2118 if (p==&ldso) {
2119 got += i;
2120 } else {
2121 while (i--) *got++ += (size_t)base;
2122 }
2123 j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
2124 i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
2125 Sym *sym = p->syms + j;
2126 rel[0] = (unsigned char *)got - base;
2127 for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
2128 rel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT);
2129 do_relocs(p, rel, sizeof rel, 2);
2130 }
2131 }
2132
sleb128_decoder(uint8_t * current,uint8_t * end,size_t * value)2133 static uint8_t* sleb128_decoder(uint8_t* current, uint8_t* end, size_t* value)
2134 {
2135 size_t result = 0;
2136 static const size_t size = CHAR_BIT * sizeof(result);
2137
2138 size_t shift = 0;
2139 uint8_t byte;
2140
2141 do {
2142 if (current >= end) {
2143 a_crash();
2144 }
2145
2146 byte = *current++;
2147 result |= ((size_t)(byte & 127) << shift);
2148 shift += 7;
2149 } while (byte & 128);
2150
2151 if (shift < size && (byte & 64)) {
2152 result |= -((size_t)(1) << shift);
2153 }
2154
2155 *value = result;
2156
2157 return current;
2158 }
2159
do_android_relocs(struct dso * p,size_t dt_name,size_t dt_size)2160 static void do_android_relocs(struct dso *p, size_t dt_name, size_t dt_size)
2161 {
2162 size_t android_rel_addr = 0, android_rel_size = 0;
2163 uint8_t *android_rel_curr, *android_rel_end;
2164
2165 search_vec(p->dynv, &android_rel_addr, dt_name);
2166 search_vec(p->dynv, &android_rel_size, dt_size);
2167
2168 if (!android_rel_addr || (android_rel_size < 4)) {
2169 return;
2170 }
2171
2172 android_rel_curr = laddr(p, android_rel_addr);
2173 if (memcmp(android_rel_curr, "APS2", ANDROID_REL_SIGN_SIZE)) {
2174 return;
2175 }
2176
2177 android_rel_curr += ANDROID_REL_SIGN_SIZE;
2178 android_rel_size -= ANDROID_REL_SIGN_SIZE;
2179
2180 android_rel_end = android_rel_curr + android_rel_size;
2181
2182 size_t relocs_num;
2183 size_t rel[3] = {0};
2184
2185 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &relocs_num);
2186 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[0]);
2187
2188 for (size_t i = 0; i < relocs_num;) {
2189
2190 size_t group_size, group_flags;
2191
2192 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_size);
2193 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_flags);
2194
2195 size_t group_r_offset_delta = 0;
2196
2197 if (group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) {
2198 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_r_offset_delta);
2199 }
2200
2201 if (group_flags & RELOCATION_GROUPED_BY_INFO_FLAG) {
2202 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[1]);
2203 }
2204
2205 const size_t addend_flags = group_flags & (RELOCATION_GROUP_HAS_ADDEND_FLAG | RELOCATION_GROUPED_BY_ADDEND_FLAG);
2206
2207 if (addend_flags == RELOCATION_GROUP_HAS_ADDEND_FLAG) {
2208 } else if (addend_flags == (RELOCATION_GROUP_HAS_ADDEND_FLAG | RELOCATION_GROUPED_BY_ADDEND_FLAG)) {
2209 size_t addend;
2210 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &addend);
2211 rel[2] += addend;
2212 } else {
2213 rel[2] = 0;
2214 }
2215
2216 for (size_t j = 0; j < group_size; j++) {
2217 if (group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) {
2218 rel[0] += group_r_offset_delta;
2219 } else {
2220 size_t offset_detla;
2221 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &offset_detla);
2222
2223 rel[0] += offset_detla;
2224 }
2225
2226 if ((group_flags & RELOCATION_GROUPED_BY_INFO_FLAG) == 0) {
2227 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[1]);
2228 }
2229
2230 if (addend_flags == RELOCATION_GROUP_HAS_ADDEND_FLAG) {
2231 size_t addend;
2232 android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &addend);
2233 rel[2] += addend;
2234 }
2235
2236 if (dt_name == DT_ANDROID_REL) {
2237 LD_LOGI("do_android_relocs REL %{public}x %{public}x", rel[0], rel[1]);
2238 do_relocs(p, rel, sizeof(size_t)*2, 2);
2239 } else {
2240 LD_LOGI("do_android_relocs RELA %{public}x %{public}x %{public}x", rel[0], rel[1], rel[2]);
2241 do_relocs(p, rel, sizeof(size_t)*3, 3);
2242 }
2243 }
2244
2245 i += group_size;
2246 }
2247 }
2248
do_relr_relocs(struct dso * dso,size_t * relr,size_t relr_size)2249 static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)
2250 {
2251 unsigned char *base = dso->base;
2252 size_t *reloc_addr;
2253 for (; relr_size; relr++, relr_size-=sizeof(size_t))
2254 if ((relr[0]&1) == 0) {
2255 reloc_addr = laddr(dso, relr[0]);
2256 *reloc_addr++ += (size_t)base;
2257 } else {
2258 int i = 0;
2259 for (size_t bitmap=relr[0]; (bitmap>>=1); i++)
2260 if (bitmap&1)
2261 reloc_addr[i] += (size_t)base;
2262 reloc_addr += 8*sizeof(size_t)-1;
2263 }
2264 }
2265
reloc_all(struct dso * p,const dl_extinfo * extinfo)2266 static void reloc_all(struct dso *p, const dl_extinfo *extinfo)
2267 {
2268 ssize_t relro_fd_offset = 0;
2269 size_t dyn[DYN_CNT];
2270 for (; p; p=p->next) {
2271 if (p->relocated) continue;
2272 if (p != &ldso) {
2273 add_can_search_so_list_in_dso(p, head);
2274 }
2275 decode_vec(p->dynv, dyn, DYN_CNT);
2276 if (NEED_MIPS_GOT_RELOCS)
2277 do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
2278 do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
2279 2+(dyn[DT_PLTREL]==DT_RELA));
2280 do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
2281 do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
2282 if (!DL_FDPIC)
2283 do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
2284
2285 do_android_relocs(p, DT_ANDROID_REL, DT_ANDROID_RELSZ);
2286 do_android_relocs(p, DT_ANDROID_RELA, DT_ANDROID_RELASZ);
2287
2288 if (head != &ldso && p->relro_start != p->relro_end &&
2289 mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)
2290 && errno != ENOSYS) {
2291 error("Error relocating %s: RELRO protection failed: %m",
2292 p->name);
2293 if (runtime) longjmp(*rtld_fail, 1);
2294 }
2295 /* Handle serializing/mapping the RELRO segment */
2296 handle_relro_sharing(p, extinfo, &relro_fd_offset);
2297
2298 p->relocated = 1;
2299 free_reloc_can_search_dso(p);
2300 }
2301 }
2302
kernel_mapped_dso(struct dso * p)2303 static void kernel_mapped_dso(struct dso *p)
2304 {
2305 size_t min_addr = -1, max_addr = 0, cnt;
2306 Phdr *ph = p->phdr;
2307 for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
2308 if (ph->p_type == PT_DYNAMIC) {
2309 p->dynv = laddr(p, ph->p_vaddr);
2310 } else if (ph->p_type == PT_GNU_RELRO) {
2311 p->relro_start = ph->p_vaddr & -PAGE_SIZE;
2312 p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
2313 } else if (ph->p_type == PT_GNU_STACK) {
2314 if (!runtime && ph->p_memsz > __default_stacksize) {
2315 __default_stacksize =
2316 ph->p_memsz < DEFAULT_STACK_MAX ?
2317 ph->p_memsz : DEFAULT_STACK_MAX;
2318 }
2319 }
2320 if (ph->p_type != PT_LOAD) continue;
2321 if (ph->p_vaddr < min_addr)
2322 min_addr = ph->p_vaddr;
2323 if (ph->p_vaddr+ph->p_memsz > max_addr)
2324 max_addr = ph->p_vaddr+ph->p_memsz;
2325 }
2326 min_addr &= -PAGE_SIZE;
2327 max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
2328 p->map = p->base + min_addr;
2329 p->map_len = max_addr - min_addr;
2330 p->kernel_mapped = 1;
2331 }
2332
__libc_exit_fini()2333 void __libc_exit_fini()
2334 {
2335 struct dso *p;
2336 size_t dyn[DYN_CNT];
2337 int self = __pthread_self()->tid;
2338
2339 /* Take both locks before setting shutting_down, so that
2340 * either lock is sufficient to read its value. The lock
2341 * order matches that in dlopen to avoid deadlock. */
2342 pthread_rwlock_wrlock(&lock);
2343 pthread_mutex_lock(&init_fini_lock);
2344 shutting_down = 1;
2345 pthread_rwlock_unlock(&lock);
2346 for (p=fini_head; p; p=p->fini_next) {
2347 while (p->ctor_visitor && p->ctor_visitor!=self)
2348 pthread_cond_wait(&ctor_cond, &init_fini_lock);
2349 if (!p->constructed) continue;
2350 decode_vec(p->dynv, dyn, DYN_CNT);
2351 if (dyn[0] & (1<<DT_FINI_ARRAY)) {
2352 size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
2353 size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;
2354 while (n--) ((void (*)(void))*--fn)();
2355 }
2356 #ifndef NO_LEGACY_INITFINI
2357 if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
2358 fpaddr(p, dyn[DT_FINI])();
2359 #endif
2360 }
2361 }
2362
queue_ctors(struct dso * dso)2363 static struct dso **queue_ctors(struct dso *dso)
2364 {
2365 size_t cnt, qpos, spos, i;
2366 struct dso *p, **queue, **stack;
2367
2368 if (ldd_mode) return 0;
2369
2370 /* Bound on queue size is the total number of indirect deps.
2371 * If a bfs deps list was built, we can use it. Otherwise,
2372 * bound by the total number of DSOs, which is always safe and
2373 * is reasonable we use it (for main app at startup). */
2374 if (dso->bfs_built) {
2375 for (cnt=0; dso->deps[cnt]; cnt++)
2376 dso->deps[cnt]->mark = 0;
2377 cnt++; /* self, not included in deps */
2378 } else {
2379 for (cnt=0, p=head; p; cnt++, p=p->next)
2380 p->mark = 0;
2381 }
2382 cnt++; /* termination slot */
2383 if (dso==head && cnt <= countof(builtin_ctor_queue))
2384 queue = builtin_ctor_queue;
2385 else
2386 queue = internal_calloc(cnt, sizeof *queue);
2387
2388 if (!queue) {
2389 error("Error allocating constructor queue: %m\n");
2390 if (runtime) longjmp(*rtld_fail, 1);
2391 return 0;
2392 }
2393
2394 /* Opposite ends of the allocated buffer serve as an output queue
2395 * and a working stack. Setup initial stack with just the argument
2396 * dso and initial queue empty... */
2397 stack = queue;
2398 qpos = 0;
2399 spos = cnt;
2400 stack[--spos] = dso;
2401 dso->next_dep = 0;
2402 dso->mark = 1;
2403
2404 /* Then perform pseudo-DFS sort, but ignoring circular deps. */
2405 while (spos<cnt) {
2406 p = stack[spos++];
2407 while (p->next_dep < p->ndeps_direct) {
2408 if (p->deps[p->next_dep]->mark) {
2409 p->next_dep++;
2410 } else {
2411 stack[--spos] = p;
2412 p = p->deps[p->next_dep];
2413 p->next_dep = 0;
2414 p->mark = 1;
2415 }
2416 }
2417 queue[qpos++] = p;
2418 }
2419 queue[qpos] = 0;
2420 for (i=0; i<qpos; i++) queue[i]->mark = 0;
2421
2422 return queue;
2423 }
2424
do_init_fini(struct dso ** queue)2425 static void do_init_fini(struct dso **queue)
2426 {
2427 struct dso *p;
2428 size_t dyn[DYN_CNT], i;
2429 int self = __pthread_self()->tid;
2430
2431 pthread_mutex_lock(&init_fini_lock);
2432 for (i=0; (p=queue[i]); i++) {
2433 while ((p->ctor_visitor && p->ctor_visitor!=self) || shutting_down)
2434 pthread_cond_wait(&ctor_cond, &init_fini_lock);
2435 if (p->ctor_visitor || p->constructed)
2436 continue;
2437 p->ctor_visitor = self;
2438
2439 decode_vec(p->dynv, dyn, DYN_CNT);
2440 if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
2441 p->fini_next = fini_head;
2442 fini_head = p;
2443 }
2444
2445 pthread_mutex_unlock(&init_fini_lock);
2446
2447 #ifndef NO_LEGACY_INITFINI
2448 if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
2449 fpaddr(p, dyn[DT_INIT])();
2450 #endif
2451 if (dyn[0] & (1<<DT_INIT_ARRAY)) {
2452 size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
2453 size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);
2454 while (n--) ((void (*)(void))*fn++)();
2455 }
2456
2457 pthread_mutex_lock(&init_fini_lock);
2458 p->ctor_visitor = 0;
2459 p->constructed = 1;
2460 pthread_cond_broadcast(&ctor_cond);
2461 }
2462 pthread_mutex_unlock(&init_fini_lock);
2463 }
2464
__libc_start_init(void)2465 void __libc_start_init(void)
2466 {
2467 do_init_fini(main_ctor_queue);
2468 if (!__malloc_replaced && main_ctor_queue != builtin_ctor_queue)
2469 internal_free(main_ctor_queue);
2470 main_ctor_queue = 0;
2471 }
2472
dl_debug_state(void)2473 static void dl_debug_state(void)
2474 {
2475 }
2476
2477 weak_alias(dl_debug_state, _dl_debug_state);
2478
__init_tls(size_t * auxv)2479 void __init_tls(size_t *auxv)
2480 {
2481 }
2482
update_tls_size()2483 static void update_tls_size()
2484 {
2485 libc.tls_cnt = tls_cnt;
2486 libc.tls_align = tls_align;
2487 libc.tls_size = ALIGN(
2488 (1+tls_cnt) * sizeof(void *) +
2489 tls_offset +
2490 sizeof(struct pthread) +
2491 tls_align * 2,
2492 tls_align);
2493 }
2494
install_new_tls(void)2495 static void install_new_tls(void)
2496 {
2497 sigset_t set;
2498 pthread_t self = __pthread_self(), td;
2499 struct dso *dtv_provider = container_of(tls_tail, struct dso, tls);
2500 uintptr_t (*newdtv)[tls_cnt+1] = (void *)dtv_provider->new_dtv;
2501 struct dso *p;
2502 size_t i, j;
2503 size_t old_cnt = self->dtv[0];
2504
2505 __block_app_sigs(&set);
2506 __tl_lock();
2507 /* Copy existing dtv contents from all existing threads. */
2508 for (i=0, td=self; !i || td!=self; i++, td=td->next) {
2509 memcpy(newdtv+i, td->dtv,
2510 (old_cnt+1)*sizeof(uintptr_t));
2511 newdtv[i][0] = tls_cnt;
2512 }
2513 /* Install new dtls into the enlarged, uninstalled dtv copies. */
2514 for (p=head; ; p=p->next) {
2515 if (p->tls_id <= old_cnt) continue;
2516 unsigned char *mem = p->new_tls;
2517 for (j=0; j<i; j++) {
2518 unsigned char *new = mem;
2519 new += ((uintptr_t)p->tls.image - (uintptr_t)mem)
2520 & (p->tls.align-1);
2521 memcpy(new, p->tls.image, p->tls.len);
2522 newdtv[j][p->tls_id] =
2523 (uintptr_t)new + DTP_OFFSET;
2524 mem += p->tls.size + p->tls.align;
2525 }
2526 if (p->tls_id == tls_cnt) break;
2527 }
2528
2529 /* Broadcast barrier to ensure contents of new dtv is visible
2530 * if the new dtv pointer is. The __membarrier function has a
2531 * fallback emulation using signals for kernels that lack the
2532 * feature at the syscall level. */
2533
2534 __membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0);
2535
2536 /* Install new dtv for each thread. */
2537 for (j=0, td=self; !j || td!=self; j++, td=td->next) {
2538 td->dtv = td->dtv_copy = newdtv[j];
2539 }
2540
2541 __tl_unlock();
2542 __restore_sigs(&set);
2543 }
2544
2545 /* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the
2546 * following stage 2 and stage 3 functions via primitive symbolic lookup
2547 * since it does not have access to their addresses to begin with. */
2548
2549 /* Stage 2 of the dynamic linker is called after relative relocations
2550 * have been processed. It can make function calls to static functions
2551 * and access string literals and static data, but cannot use extern
2552 * symbols. Its job is to perform symbolic relocations on the dynamic
2553 * linker itself, but some of the relocations performed may need to be
2554 * replaced later due to copy relocations in the main program. */
2555
__dls2(unsigned char * base,size_t * sp)2556 hidden void __dls2(unsigned char *base, size_t *sp)
2557 {
2558 size_t *auxv;
2559 for (auxv=sp+1+*sp+1; *auxv; auxv++);
2560 auxv++;
2561 if (DL_FDPIC) {
2562 void *p1 = (void *)sp[-2];
2563 void *p2 = (void *)sp[-1];
2564 if (!p1) {
2565 size_t aux[AUX_CNT];
2566 decode_vec(auxv, aux, AUX_CNT);
2567 if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
2568 else ldso.base = (void *)(aux[AT_PHDR] & -4096);
2569 }
2570 app_loadmap = p2 ? p1 : 0;
2571 ldso.loadmap = p2 ? p2 : p1;
2572 ldso.base = laddr(&ldso, 0);
2573 } else {
2574 ldso.base = base;
2575 }
2576 Ehdr *ehdr = (void *)ldso.base;
2577 ldso.name = ldso.shortname = "libc.so";
2578 ldso.phnum = ehdr->e_phnum;
2579 ldso.phdr = laddr(&ldso, ehdr->e_phoff);
2580 ldso.phentsize = ehdr->e_phentsize;
2581 ldso.is_global = true;
2582 kernel_mapped_dso(&ldso);
2583 decode_dyn(&ldso);
2584
2585 if (DL_FDPIC) makefuncdescs(&ldso);
2586
2587 /* Prepare storage for to save clobbered REL addends so they
2588 * can be reused in stage 3. There should be very few. If
2589 * something goes wrong and there are a huge number, abort
2590 * instead of risking stack overflow. */
2591 size_t dyn[DYN_CNT];
2592 decode_vec(ldso.dynv, dyn, DYN_CNT);
2593 size_t *rel = laddr(&ldso, dyn[DT_REL]);
2594 size_t rel_size = dyn[DT_RELSZ];
2595 size_t symbolic_rel_cnt = 0;
2596 apply_addends_to = rel;
2597 for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
2598 if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;
2599 if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
2600 size_t addends[symbolic_rel_cnt+1];
2601 saved_addends = addends;
2602
2603 head = &ldso;
2604 reloc_all(&ldso, NULL);
2605
2606 ldso.relocated = 0;
2607
2608 /* Call dynamic linker stage-2b, __dls2b, looking it up
2609 * symbolically as a barrier against moving the address
2610 * load across the above relocation processing. */
2611 struct symdef dls2b_def = find_sym(&ldso, "__dls2b", 0);
2612 if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp, auxv);
2613 else ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv);
2614 }
2615
2616 /* Stage 2b sets up a valid thread pointer, which requires relocations
2617 * completed in stage 2, and on which stage 3 is permitted to depend.
2618 * This is done as a separate stage, with symbolic lookup as a barrier,
2619 * so that loads of the thread pointer and &errno can be pure/const and
2620 * thereby hoistable. */
2621
__dls2b(size_t * sp,size_t * auxv)2622 void __dls2b(size_t *sp, size_t *auxv)
2623 {
2624 /* Setup early thread pointer in builtin_tls for ldso/libc itself to
2625 * use during dynamic linking. If possible it will also serve as the
2626 * thread pointer at runtime. */
2627 search_vec(auxv, &__hwcap, AT_HWCAP);
2628 libc.auxv = auxv;
2629 libc.tls_size = sizeof builtin_tls;
2630 libc.tls_align = tls_align;
2631 if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
2632 a_crash();
2633 }
2634
2635 struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
2636 if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp, auxv);
2637 else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv);
2638 }
2639
2640 /* Stage 3 of the dynamic linker is called with the dynamic linker/libc
2641 * fully functional. Its job is to load (if not already loaded) and
2642 * process dependencies and relocations for the main application and
2643 * transfer control to its entry point. */
2644
__dls3(size_t * sp,size_t * auxv)2645 void __dls3(size_t *sp, size_t *auxv)
2646 {
2647 static struct dso app, vdso;
2648 size_t aux[AUX_CNT];
2649 size_t i;
2650 char *env_preload=0;
2651 char *replace_argv0=0;
2652 size_t vdso_base;
2653 int argc = *sp;
2654 char **argv = (void *)(sp+1);
2655 char **argv_orig = argv;
2656 char **envp = argv+argc+1;
2657
2658 /* Find aux vector just past environ[] and use it to initialize
2659 * global data that may be needed before we can make syscalls. */
2660 __environ = envp;
2661 decode_vec(auxv, aux, AUX_CNT);
2662 search_vec(auxv, &__sysinfo, AT_SYSINFO);
2663 __pthread_self()->sysinfo = __sysinfo;
2664 libc.page_size = aux[AT_PAGESZ];
2665 libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
2666 || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
2667
2668 /* Only trust user/env if kernel says we're not suid/sgid */
2669 if (!libc.secure) {
2670 env_path = getenv("LD_LIBRARY_PATH");
2671 env_preload = getenv("LD_PRELOAD");
2672 }
2673 #ifdef OHOS_ENABLE_PARAMETER
2674 InitParameterClient();
2675 #endif
2676 ld_log_reset();
2677 /* If the main program was already loaded by the kernel,
2678 * AT_PHDR will point to some location other than the dynamic
2679 * linker's program headers. */
2680 if (aux[AT_PHDR] != (size_t)ldso.phdr) {
2681 size_t interp_off = 0;
2682 size_t tls_image = 0;
2683 /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
2684 Phdr *phdr = app.phdr = (void *)aux[AT_PHDR];
2685 app.phnum = aux[AT_PHNUM];
2686 app.phentsize = aux[AT_PHENT];
2687 for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
2688 if (phdr->p_type == PT_PHDR)
2689 app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
2690 else if (phdr->p_type == PT_INTERP)
2691 interp_off = (size_t)phdr->p_vaddr;
2692 else if (phdr->p_type == PT_TLS) {
2693 tls_image = phdr->p_vaddr;
2694 app.tls.len = phdr->p_filesz;
2695 app.tls.size = phdr->p_memsz;
2696 app.tls.align = phdr->p_align;
2697 }
2698 }
2699 if (DL_FDPIC) app.loadmap = app_loadmap;
2700 if (app.tls.size) app.tls.image = laddr(&app, tls_image);
2701 if (interp_off) ldso.name = laddr(&app, interp_off);
2702 if ((aux[0] & (1UL<<AT_EXECFN))
2703 && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
2704 app.name = (char *)aux[AT_EXECFN];
2705 else
2706 app.name = argv[0];
2707 kernel_mapped_dso(&app);
2708 } else {
2709 int fd;
2710 char *ldname = argv[0];
2711 size_t l = strlen(ldname);
2712 if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
2713 argv++;
2714 while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {
2715 char *opt = argv[0]+2;
2716 *argv++ = (void *)-1;
2717 if (!*opt) {
2718 break;
2719 } else if (!memcmp(opt, "list", 5)) {
2720 ldd_mode = 1;
2721 } else if (!memcmp(opt, "library-path", 12)) {
2722 if (opt[12]=='=') env_path = opt+13;
2723 else if (opt[12]) *argv = 0;
2724 else if (*argv) env_path = *argv++;
2725 } else if (!memcmp(opt, "preload", 7)) {
2726 if (opt[7]=='=') env_preload = opt+8;
2727 else if (opt[7]) *argv = 0;
2728 else if (*argv) env_preload = *argv++;
2729 } else if (!memcmp(opt, "argv0", 5)) {
2730 if (opt[5]=='=') replace_argv0 = opt+6;
2731 else if (opt[5]) *argv = 0;
2732 else if (*argv) replace_argv0 = *argv++;
2733 } else {
2734 argv[0] = 0;
2735 }
2736 }
2737 argv[-1] = (void *)(argc - (argv-argv_orig));
2738 if (!argv[0]) {
2739 dprintf(2, "musl libc (" LDSO_ARCH ")\n"
2740 "Version %s\n"
2741 "Dynamic Program Loader\n"
2742 "Usage: %s [options] [--] pathname%s\n",
2743 __libc_version, ldname,
2744 ldd_mode ? "" : " [args]");
2745 _exit(1);
2746 }
2747 fd = open(argv[0], O_RDONLY);
2748 if (fd < 0) {
2749 dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
2750 _exit(1);
2751 }
2752 Ehdr *ehdr = (void *)map_library(fd, &app, NULL);
2753 if (!ehdr) {
2754 dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
2755 _exit(1);
2756 }
2757 close(fd);
2758 ldso.name = ldname;
2759 app.name = argv[0];
2760 aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);
2761 /* Find the name that would have been used for the dynamic
2762 * linker had ldd not taken its place. */
2763 if (ldd_mode) {
2764 for (i=0; i<app.phnum; i++) {
2765 if (app.phdr[i].p_type == PT_INTERP)
2766 ldso.name = laddr(&app, app.phdr[i].p_vaddr);
2767 }
2768 dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
2769 }
2770 }
2771 if (app.tls.size) {
2772 libc.tls_head = tls_tail = &app.tls;
2773 app.tls_id = tls_cnt = 1;
2774 #ifdef TLS_ABOVE_TP
2775 app.tls.offset = GAP_ABOVE_TP;
2776 app.tls.offset += (-GAP_ABOVE_TP + (uintptr_t)app.tls.image)
2777 & (app.tls.align-1);
2778 tls_offset = app.tls.offset + app.tls.size;
2779 #else
2780 tls_offset = app.tls.offset = app.tls.size
2781 + ( -((uintptr_t)app.tls.image + app.tls.size)
2782 & (app.tls.align-1) );
2783 #endif
2784 tls_align = MAXP2(tls_align, app.tls.align);
2785 }
2786 decode_dyn(&app);
2787 if (DL_FDPIC) {
2788 makefuncdescs(&app);
2789 if (!app.loadmap) {
2790 app.loadmap = (void *)&app_dummy_loadmap;
2791 app.loadmap->nsegs = 1;
2792 app.loadmap->segs[0].addr = (size_t)app.map;
2793 app.loadmap->segs[0].p_vaddr = (size_t)app.map
2794 - (size_t)app.base;
2795 app.loadmap->segs[0].p_memsz = app.map_len;
2796 }
2797 argv[-3] = (void *)app.loadmap;
2798 }
2799 app.is_global = true;
2800
2801 /* Initial dso chain consists only of the app. */
2802 head = tail = syms_tail = &app;
2803
2804 /* Donate unused parts of app and library mapping to malloc */
2805 reclaim_gaps(&app);
2806 reclaim_gaps(&ldso);
2807
2808 /* Load preload/needed libraries, add symbols to global namespace. */
2809 ldso.deps = (struct dso **)no_deps;
2810 /* Init g_is_asan */
2811 g_is_asan = false;
2812 LD_LOGD("__dls3 ldso.name:%{public}s.", ldso.name);
2813 /* Through ldso Name to judge whether the Asan function is enabled */
2814 if (strstr(ldso.name, "-asan")) {
2815 g_is_asan = true;
2816 LD_LOGD("__dls3 g_is_asan is true.");
2817 }
2818 /* Init all namespaces by config file. there is a default namespace always*/
2819 init_namespace(&app);
2820
2821 #ifdef LOAD_ORDER_RANDOMIZATION
2822 struct loadtasks *tasks = create_loadtasks();
2823 if (!tasks) {
2824 _exit(1);
2825 }
2826 if (env_preload) {
2827 load_preload(env_preload, get_default_ns(), tasks);
2828 }
2829 for (struct dso *q=head; q; q=q->next) {
2830 q->is_global = true;
2831 }
2832 preload_deps(&app, tasks);
2833 unmap_preloaded_sections(tasks);
2834 shuffle_loadtasks(tasks);
2835 run_loadtasks(tasks, NULL);
2836 free_loadtasks(tasks);
2837 assign_tls(app.next);
2838 #else
2839 if (env_preload) load_preload(env_preload, get_default_ns());
2840 for (struct dso *q=head; q; q=q->next) {
2841 q->is_global = true;
2842 }
2843 load_deps(&app, NULL);
2844 #endif
2845
2846 /* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of app, including app self. */
2847 for (struct dso *p=head; p; p=p->next) {
2848 p->is_reloc_head_so_dep = true;
2849 add_syms(p);
2850 }
2851
2852 /* Attach to vdso, if provided by the kernel, last so that it does
2853 * not become part of the global namespace. */
2854 if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {
2855 Ehdr *ehdr = (void *)vdso_base;
2856 Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
2857 vdso.phnum = ehdr->e_phnum;
2858 vdso.phentsize = ehdr->e_phentsize;
2859 for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
2860 if (phdr->p_type == PT_DYNAMIC)
2861 vdso.dynv = (void *)(vdso_base + phdr->p_offset);
2862 if (phdr->p_type == PT_LOAD)
2863 vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
2864 }
2865 vdso.name = "";
2866 vdso.shortname = "linux-gate.so.1";
2867 vdso.relocated = 1;
2868 vdso.deps = (struct dso **)no_deps;
2869 decode_dyn(&vdso);
2870 vdso.prev = tail;
2871 tail->next = &vdso;
2872 tail = &vdso;
2873 vdso.namespace = get_default_ns();
2874 ns_add_dso(vdso.namespace, &vdso);
2875 }
2876
2877 for (i=0; app.dynv[i]; i+=2) {
2878 if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)
2879 app.dynv[i+1] = (size_t)&debug;
2880 if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {
2881 size_t *ptr = (size_t *) app.dynv[i+1];
2882 *ptr = (size_t)&debug;
2883 }
2884 }
2885
2886 /* This must be done before final relocations, since it calls
2887 * malloc, which may be provided by the application. Calling any
2888 * application code prior to the jump to its entry point is not
2889 * valid in our model and does not work with FDPIC, where there
2890 * are additional relocation-like fixups that only the entry point
2891 * code can see to perform. */
2892 main_ctor_queue = queue_ctors(&app);
2893
2894 /* Initial TLS must also be allocated before final relocations
2895 * might result in calloc being a call to application code. */
2896 update_tls_size();
2897 void *initial_tls = builtin_tls;
2898 if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {
2899 initial_tls = internal_calloc(libc.tls_size, 1);
2900 if (!initial_tls) {
2901 dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
2902 argv[0], libc.tls_size);
2903 _exit(127);
2904 }
2905 }
2906 static_tls_cnt = tls_cnt;
2907
2908 /* The main program must be relocated LAST since it may contain
2909 * copy relocations which depend on libraries' relocations. */
2910 reloc_all(app.next, NULL);
2911 reloc_all(&app, NULL);
2912 for (struct dso *q=head; q; q=q->next) {
2913 q->is_reloc_head_so_dep = false;
2914 }
2915
2916 /* Actual copying to new TLS needs to happen after relocations,
2917 * since the TLS images might have contained relocated addresses. */
2918 if (initial_tls != builtin_tls) {
2919 pthread_t self = __pthread_self();
2920 pthread_t td = __copy_tls(initial_tls);
2921 if (__init_tp(td) < 0) {
2922 a_crash();
2923 }
2924 td->tsd = self->tsd;
2925 } else {
2926 size_t tmp_tls_size = libc.tls_size;
2927 pthread_t self = __pthread_self();
2928 /* Temporarily set the tls size to the full size of
2929 * builtin_tls so that __copy_tls will use the same layout
2930 * as it did for before. Then check, just to be safe. */
2931 libc.tls_size = sizeof builtin_tls;
2932 if (__copy_tls((void*)builtin_tls) != self) a_crash();
2933 libc.tls_size = tmp_tls_size;
2934 }
2935
2936 if (ldso_fail) _exit(127);
2937 if (ldd_mode) _exit(0);
2938
2939 /* Determine if malloc was interposed by a replacement implementation
2940 * so that calloc and the memalign family can harden against the
2941 * possibility of incomplete replacement. */
2942 if (find_sym(head, "malloc", 1).dso != &ldso)
2943 __malloc_replaced = 1;
2944
2945 /* Switch to runtime mode: any further failures in the dynamic
2946 * linker are a reportable failure rather than a fatal startup
2947 * error. */
2948 runtime = 1;
2949
2950 debug.ver = 1;
2951 debug.bp = dl_debug_state;
2952 debug.head = head;
2953 debug.base = ldso.base;
2954 debug.state = RT_CONSISTENT;
2955 _dl_debug_state();
2956
2957 if (replace_argv0) argv[0] = replace_argv0;
2958
2959 #ifdef DFX_SIGNAL_LIBC
2960 DFX_InstallSignalHandler();
2961 #endif
2962 errno = 0;
2963
2964 CRTJMP((void *)aux[AT_ENTRY], argv-1);
2965 for(;;);
2966 }
2967
prepare_lazy(struct dso * p)2968 static void prepare_lazy(struct dso *p)
2969 {
2970 size_t dyn[DYN_CNT], n, flags1=0;
2971 decode_vec(p->dynv, dyn, DYN_CNT);
2972 search_vec(p->dynv, &flags1, DT_FLAGS_1);
2973 if (dyn[DT_BIND_NOW] || (dyn[DT_FLAGS] & DF_BIND_NOW) || (flags1 & DF_1_NOW))
2974 return;
2975 n = dyn[DT_RELSZ]/2 + dyn[DT_RELASZ]/3 + dyn[DT_PLTRELSZ]/2 + 1;
2976 if (NEED_MIPS_GOT_RELOCS) {
2977 size_t j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
2978 size_t i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
2979 n += i-j;
2980 }
2981 p->lazy = internal_calloc(n, 3*sizeof(size_t));
2982 if (!p->lazy) {
2983 error("Error preparing lazy relocation for %s: %m", p->name);
2984 longjmp(*rtld_fail, 1);
2985 }
2986 p->lazy_next = lazy_head;
2987 lazy_head = p;
2988 }
2989
dlopen_post(struct dso * p,int mode)2990 static void *dlopen_post(struct dso* p, int mode) {
2991 if (p == NULL) {
2992 return p;
2993 }
2994
2995 p->nr_dlopen++;
2996 if (p->bfs_built) {
2997 for (int i = 0; p->deps[i]; i++) {
2998 p->deps[i]->nr_dlopen++;
2999
3000 if (mode & RTLD_NODELETE) {
3001 p->deps[i]->flags |= DSO_FLAGS_NODELETE;
3002 }
3003 }
3004 }
3005
3006 #ifdef HANDLE_RANDOMIZATION
3007 void *handle = assign_valid_handle(p);
3008 if (handle == NULL) {
3009 LD_LOGE("dlopen_post: generate random handle failed");
3010 do_dlclose(p);
3011 }
3012
3013 return handle;
3014 #endif
3015
3016 return p;
3017 }
3018
3019 /* add namespace function */
dlopen_impl(const char * file,int mode,const char * namespace,const void * caller_addr,const dl_extinfo * extinfo)3020 static void *dlopen_impl(
3021 const char *file, int mode, const char *namespace, const void *caller_addr, const dl_extinfo *extinfo)
3022 {
3023 struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next;
3024 struct tls_module *orig_tls_tail;
3025 size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
3026 size_t i;
3027 int cs;
3028 jmp_buf jb;
3029 struct dso **volatile ctor_queue = 0;
3030 ns_t *ns;
3031 struct dso *caller;
3032 bool reserved_address = false;
3033 bool reserved_address_recursive = false;
3034 struct reserved_address_params reserved_params = {0};
3035 #ifdef LOAD_ORDER_RANDOMIZATION
3036 struct loadtasks *tasks = NULL;
3037 struct loadtask *task = NULL;
3038 bool is_task_appended = false;
3039 #endif
3040
3041 if (!file) {
3042 LD_LOGD("dlopen_impl file is null, return head.");
3043 return dlopen_post(head, mode);
3044 }
3045
3046 if (extinfo) {
3047 reserved_address_recursive = extinfo->flag & DL_EXT_RESERVED_ADDRESS_RECURSIVE;
3048 if (extinfo->flag & DL_EXT_RESERVED_ADDRESS) {
3049 reserved_address = true;
3050 reserved_params.start_addr = extinfo->reserved_addr;
3051 reserved_params.reserved_size = extinfo->reserved_size;
3052 reserved_params.must_use_reserved = true;
3053 reserved_params.reserved_address_recursive = reserved_address_recursive;
3054 } else if (extinfo->flag & DL_EXT_RESERVED_ADDRESS_HINT) {
3055 reserved_address = true;
3056 reserved_params.start_addr = extinfo->reserved_addr;
3057 reserved_params.reserved_size = extinfo->reserved_size;
3058 reserved_params.must_use_reserved = false;
3059 reserved_params.reserved_address_recursive = reserved_address_recursive;
3060 }
3061 }
3062
3063 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
3064 pthread_rwlock_wrlock(&lock);
3065 __inhibit_ptc();
3066
3067 debug.state = RT_ADD;
3068 _dl_debug_state();
3069 /* When namespace does not exist, use caller's namespce
3070 * and when caller does not exist, use default namespce. */
3071 caller = (struct dso *)addr2dso((size_t)caller_addr);
3072 ns = find_ns_by_name(namespace);
3073 if (!ns) ns = ((caller && caller->namespace) ? caller->namespace : get_default_ns());
3074
3075 p = 0;
3076 if (shutting_down) {
3077 error("Cannot dlopen while program is exiting.");
3078 goto end;
3079 }
3080 orig_tls_tail = tls_tail;
3081 orig_tls_cnt = tls_cnt;
3082 orig_tls_offset = tls_offset;
3083 orig_tls_align = tls_align;
3084 orig_lazy_head = lazy_head;
3085 orig_syms_tail = syms_tail;
3086 orig_tail = tail;
3087 noload = mode & RTLD_NOLOAD;
3088
3089 rtld_fail = &jb;
3090 if (setjmp(*rtld_fail)) {
3091 /* Clean up anything new that was (partially) loaded */
3092 revert_syms(orig_syms_tail);
3093 for (p=orig_tail->next; p; p=next) {
3094 next = p->next;
3095 while (p->td_index) {
3096 void *tmp = p->td_index->next;
3097 internal_free(p->td_index);
3098 p->td_index = tmp;
3099 }
3100 internal_free(p->funcdescs);
3101 if (p->rpath != p->rpath_orig)
3102 internal_free(p->rpath);
3103 if (p->deps) {
3104 for (int i = 0; i < p->ndeps_direct; i++) {
3105 remove_dso_parent(p->deps[i], p);
3106 }
3107 }
3108 internal_free(p->deps);
3109 dlclose_ns(p);
3110 unmap_library(p);
3111 if (p->parents) {
3112 internal_free(p->parents);
3113 }
3114 free_reloc_can_search_dso(p);
3115 internal_free(p);
3116 }
3117 internal_free(ctor_queue);
3118 ctor_queue = 0;
3119 if (!orig_tls_tail) libc.tls_head = 0;
3120 tls_tail = orig_tls_tail;
3121 if (tls_tail) tls_tail->next = 0;
3122 tls_cnt = orig_tls_cnt;
3123 tls_offset = orig_tls_offset;
3124 tls_align = orig_tls_align;
3125 lazy_head = orig_lazy_head;
3126 tail = orig_tail;
3127 tail->next = 0;
3128 p = 0;
3129 goto end;
3130 } else {
3131 #ifdef LOAD_ORDER_RANDOMIZATION
3132 tasks = create_loadtasks();
3133 if (!tasks) {
3134 LD_LOGE("dlopen_impl create loadtasks failed");
3135 goto end;
3136 }
3137 task = create_loadtask(file, head, ns, true);
3138 if (!task) {
3139 LD_LOGE("dlopen_impl create loadtask failed");
3140 goto end;
3141 }
3142 if (!load_library_header(task)) {
3143 LD_LOGE("dlopen_impl load library header failed for %{public}s", task->name);
3144 goto end;
3145 }
3146 if (reserved_address) {
3147 reserved_params.target = task->p;
3148 }
3149 }
3150 if (!task->p) {
3151 LD_LOGE("dlopen_impl load library failed for %{public}s", task->name);
3152 error(noload ?
3153 "Library %s is not already loaded" :
3154 "Error loading shared library %s: %m",
3155 file);
3156 goto end;
3157 }
3158 if (!task->isloaded) {
3159 is_task_appended = append_loadtasks(tasks, task);
3160 }
3161 preload_deps(task->p, tasks);
3162 unmap_preloaded_sections(tasks);
3163 if (!reserved_address_recursive) {
3164 shuffle_loadtasks(tasks);
3165 }
3166 run_loadtasks(tasks, reserved_address ? &reserved_params : NULL);
3167 p = task->p;
3168 if (!task->isloaded) {
3169 assign_tls(p);
3170 }
3171 if (!is_task_appended) {
3172 free_task(task);
3173 task = NULL;
3174 }
3175 free_loadtasks(tasks);
3176 tasks = NULL;
3177 #else
3178 p = load_library(file, head, ns, true, reserved_address ? &reserved_params : NULL);
3179 }
3180
3181 if (!p) {
3182 error(noload ?
3183 "Library %s is not already loaded" :
3184 "Error loading shared library %s: %m",
3185 file);
3186 goto end;
3187 }
3188 /* First load handling */
3189 load_deps(p, reserved_address && reserved_address_recursive ? &reserved_params : NULL);
3190 #endif
3191 extend_bfs_deps(p);
3192 pthread_mutex_lock(&init_fini_lock);
3193 if (!p->constructed) ctor_queue = queue_ctors(p);
3194 pthread_mutex_unlock(&init_fini_lock);
3195 if (!p->relocated && (mode & RTLD_LAZY)) {
3196 prepare_lazy(p);
3197 for (i=0; p->deps[i]; i++)
3198 if (!p->deps[i]->relocated)
3199 prepare_lazy(p->deps[i]);
3200 }
3201 if (!p->relocated || (mode & RTLD_GLOBAL)) {
3202 /* Make new symbols global, at least temporarily, so we can do
3203 * relocations. If not RTLD_GLOBAL, this is reverted below. */
3204 add_syms(p);
3205 /* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of p, including p self. */
3206 p->is_reloc_head_so_dep = true;
3207 for (i=0; p->deps[i]; i++) {
3208 p->deps[i]->is_reloc_head_so_dep = true;
3209 add_syms(p->deps[i]);
3210 }
3211 }
3212 struct dso *reloc_head_so = p;
3213 if (!p->relocated) {
3214 reloc_all(p, extinfo);
3215 }
3216 reloc_head_so->is_reloc_head_so_dep = false;
3217 for (size_t i=0; reloc_head_so->deps[i]; i++) {
3218 reloc_head_so->deps[i]->is_reloc_head_so_dep = false;
3219 }
3220
3221 /* If RTLD_GLOBAL was not specified, undo any new additions
3222 * to the global symbol table. This is a nop if the library was
3223 * previously loaded and already global. */
3224 if (!(mode & RTLD_GLOBAL))
3225 revert_syms(orig_syms_tail);
3226
3227 /* Processing of deferred lazy relocations must not happen until
3228 * the new libraries are committed; otherwise we could end up with
3229 * relocations resolved to symbol definitions that get removed. */
3230 redo_lazy_relocs();
3231
3232 if (mode & RTLD_NODELETE) {
3233 p->flags |= DSO_FLAGS_NODELETE;
3234 }
3235
3236 update_tls_size();
3237 if (tls_cnt != orig_tls_cnt)
3238 install_new_tls();
3239 orig_tail = tail;
3240
3241 p = dlopen_post(p, mode);
3242 end:
3243 debug.state = RT_CONSISTENT;
3244 _dl_debug_state();
3245 #ifdef LOAD_ORDER_RANDOMIZATION
3246 if (!is_task_appended) {
3247 free_task(task);
3248 }
3249 free_loadtasks(tasks);
3250 #endif
3251 __release_ptc();
3252 if (p) gencnt++;
3253 pthread_rwlock_unlock(&lock);
3254 if (ctor_queue) {
3255 do_init_fini(ctor_queue);
3256 internal_free(ctor_queue);
3257 }
3258 pthread_setcancelstate(cs, 0);
3259 return p;
3260 }
3261
dlopen(const char * file,int mode)3262 void *dlopen(const char *file, int mode)
3263 {
3264 const void *caller_addr = __builtin_return_address(0);
3265 musl_log_reset();
3266 ld_log_reset();
3267 LD_LOGI("dlopen file:%{public}s, mode:%{public}x ,caller_addr:%{public}p .", file, mode, caller_addr);
3268 return dlopen_impl(file, mode, NULL, caller_addr, NULL);
3269 }
3270
dlns_init(Dl_namespace * dlns,const char * name)3271 void dlns_init(Dl_namespace *dlns, const char *name)
3272 {
3273 if (!dlns) {
3274 LD_LOGE("dlns_init dlns is null.");
3275 return;
3276 }
3277 if (!name) {
3278 LD_LOGE("dlns_init name is null.");
3279 dlns->name[0] = 0;
3280 return;
3281 }
3282 snprintf(dlns->name, sizeof dlns->name, name);
3283 LD_LOGI("dlns_init dlns->name:%{public}s .", dlns->name);
3284 }
3285
dlns_get(const char * name,Dl_namespace * dlns)3286 int dlns_get(const char *name, Dl_namespace *dlns)
3287 {
3288 if (!dlns) {
3289 LD_LOGE("dlns_get dlns is null.");
3290 return EINVAL;
3291 }
3292 int ret = 0;
3293 ns_t *ns = NULL;
3294 pthread_rwlock_rdlock(&lock);
3295 if (!name) {
3296 struct dso *caller;
3297 const void *caller_addr = __builtin_return_address(0);
3298 caller = (struct dso *)addr2dso((size_t)caller_addr);
3299 ns = ((caller && caller->namespace) ? caller->namespace : get_default_ns());
3300 (void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
3301 LD_LOGI("dlns_get name is null, current dlns dlns->name:%{public}s.", dlns->name);
3302 } else {
3303 ns = find_ns_by_name(name);
3304 if (ns) {
3305 (void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
3306 LD_LOGI("dlns_get found ns, current dlns dlns->name:%{public}s.", dlns->name);
3307 } else {
3308 LD_LOGI("dlns_get not found ns! name:%{public}s.", name);
3309 ret = ENOKEY;
3310 }
3311 }
3312 pthread_rwlock_unlock(&lock);
3313 return ret;
3314 }
3315
dlopen_ns(Dl_namespace * dlns,const char * file,int mode)3316 void *dlopen_ns(Dl_namespace *dlns, const char *file, int mode)
3317 {
3318 const void *caller_addr = __builtin_return_address(0);
3319 musl_log_reset();
3320 ld_log_reset();
3321 LD_LOGI("dlopen_ns file:%{public}s, mode:%{public}x , caller_addr:%{public}p , dlns->name:%{public}s.",
3322 file,
3323 mode,
3324 caller_addr,
3325 dlns ? dlns->name : "NULL");
3326 return dlopen_impl(file, mode, dlns->name, caller_addr, NULL);
3327 }
3328
dlopen_ns_ext(Dl_namespace * dlns,const char * file,int mode,const dl_extinfo * extinfo)3329 void *dlopen_ns_ext(Dl_namespace *dlns, const char *file, int mode, const dl_extinfo *extinfo)
3330 {
3331 const void *caller_addr = __builtin_return_address(0);
3332 musl_log_reset();
3333 ld_log_reset();
3334 LD_LOGI("dlopen_ns_ext file:%{public}s, mode:%{public}x , caller_addr:%{public}p , "
3335 "dlns->name:%{public}s. , extinfo->flag:%{public}x",
3336 file,
3337 mode,
3338 caller_addr,
3339 dlns->name,
3340 extinfo ? extinfo->flag : 0);
3341 return dlopen_impl(file, mode, dlns->name, caller_addr, extinfo);
3342 }
3343
dlns_create2(Dl_namespace * dlns,const char * lib_path,int flags)3344 int dlns_create2(Dl_namespace *dlns, const char *lib_path, int flags)
3345 {
3346 if (!dlns) {
3347 LD_LOGE("dlns_create2 dlns is null.");
3348 return EINVAL;
3349 }
3350 ns_t *ns;
3351
3352 pthread_rwlock_wrlock(&lock);
3353 ns = find_ns_by_name(dlns->name);
3354 if (ns) {
3355 LD_LOGE("dlns_create2 ns is exist.");
3356 pthread_rwlock_unlock(&lock);
3357 return EEXIST;
3358 }
3359 ns = ns_alloc();
3360 if (!ns) {
3361 LD_LOGE("dlns_create2 no memery.");
3362 pthread_rwlock_unlock(&lock);
3363 return ENOMEM;
3364 }
3365 ns_set_name(ns, dlns->name);
3366 ns_add_dso(ns, get_default_ns()->ns_dsos->dsos[0]); /* add main app to this namespace*/
3367 nslist_add_ns(ns); /* add ns to list*/
3368 ns_set_lib_paths(ns, lib_path);
3369
3370 if ((flags & CREATE_INHERIT_DEFAULT) != 0) {
3371 ns_add_inherit(ns, get_default_ns(), NULL);
3372 }
3373
3374 if ((flags & CREATE_INHERIT_CURRENT) != 0) {
3375 struct dso *caller;
3376 const void *caller_addr = __builtin_return_address(0);
3377 caller = (struct dso *)addr2dso((size_t)caller_addr);
3378 if (caller && caller->namespace) {
3379 ns_add_inherit(ns, caller->namespace, NULL);
3380 }
3381 }
3382
3383 LD_LOGI("dlns_create2:"
3384 "ns_name: %{public}s ,"
3385 "separated:%{public}d ,"
3386 "lib_paths:%{public}s ",
3387 ns->ns_name, ns->separated, ns->lib_paths);
3388 pthread_rwlock_unlock(&lock);
3389
3390 return 0;
3391 }
3392
dlns_create(Dl_namespace * dlns,const char * lib_path)3393 int dlns_create(Dl_namespace *dlns, const char *lib_path)
3394 {
3395 LD_LOGI("dlns_create lib_paths:%{public}s", lib_path);
3396 return dlns_create2(dlns, lib_path, CREATE_INHERIT_DEFAULT);
3397 }
3398
dlns_inherit(Dl_namespace * dlns,Dl_namespace * inherited,const char * shared_libs)3399 int dlns_inherit(Dl_namespace *dlns, Dl_namespace *inherited, const char *shared_libs)
3400 {
3401 if (!dlns || !inherited) {
3402 LD_LOGE("dlns_inherit dlns or inherited is null.");
3403 return EINVAL;
3404 }
3405
3406 pthread_rwlock_wrlock(&lock);
3407 ns_t* ns = find_ns_by_name(dlns->name);
3408 ns_t* ns_inherited = find_ns_by_name(inherited->name);
3409 if (!ns || !ns_inherited) {
3410 LD_LOGE("dlns_inherit ns or ns_inherited is not found.");
3411 pthread_rwlock_unlock(&lock);
3412 return ENOKEY;
3413 }
3414 ns_add_inherit(ns, ns_inherited, shared_libs);
3415 pthread_rwlock_unlock(&lock);
3416
3417 return 0;
3418 }
3419
dlclose_ns(struct dso * p)3420 static void dlclose_ns(struct dso *p)
3421 {
3422 if (!p) return;
3423 ns_t * ns = p->namespace;
3424 if (!ns||!ns->ns_dsos) return;
3425 for (size_t i=0; i<ns->ns_dsos->num; i++) {
3426 if (p == ns->ns_dsos->dsos[i]) {
3427 for (size_t j=i+1; j<ns->ns_dsos->num; j++) {
3428 ns->ns_dsos->dsos[j-1] = ns->ns_dsos->dsos[j];
3429 }
3430 ns->ns_dsos->num--;
3431 return;
3432 }
3433 }
3434 }
3435
__dl_invalid_handle(void * h)3436 hidden int __dl_invalid_handle(void *h)
3437 {
3438 struct dso *p;
3439 for (p=head; p; p=p->next) if (h==p) return 0;
3440 error("Invalid library handle %p", (void *)h);
3441 return 1;
3442 }
3443
addr2dso(size_t a)3444 static void *addr2dso(size_t a)
3445 {
3446 struct dso *p;
3447 size_t i;
3448 if (DL_FDPIC) for (p=head; p; p=p->next) {
3449 i = count_syms(p);
3450 if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
3451 return p;
3452 }
3453 for (p=head; p; p=p->next) {
3454 if (DL_FDPIC && p->loadmap) {
3455 for (i=0; i<p->loadmap->nsegs; i++) {
3456 if (a-p->loadmap->segs[i].p_vaddr
3457 < p->loadmap->segs[i].p_memsz)
3458 return p;
3459 }
3460 } else {
3461 Phdr *ph = p->phdr;
3462 size_t phcnt = p->phnum;
3463 size_t entsz = p->phentsize;
3464 size_t base = (size_t)p->base;
3465 for (; phcnt--; ph=(void *)((char *)ph+entsz)) {
3466 if (ph->p_type != PT_LOAD) continue;
3467 if (a-base-ph->p_vaddr < ph->p_memsz)
3468 return p;
3469 }
3470 if (a-(size_t)p->map < p->map_len)
3471 return 0;
3472 }
3473 }
3474 return 0;
3475 }
3476
do_dlsym(struct dso * p,const char * s,const char * v,void * ra)3477 static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra)
3478 {
3479 int use_deps = 0;
3480 bool ra2dso = false;
3481 ns_t *ns = NULL;
3482 struct dso *caller = NULL;
3483 if (p == head || p == RTLD_DEFAULT) {
3484 p = head;
3485 ra2dso = true;
3486 } else if (p == RTLD_NEXT) {
3487 p = addr2dso((size_t)ra);
3488 if (!p) p=head;
3489 p = p->next;
3490 ra2dso = true;
3491 #ifndef HANDLE_RANDOMIZATION
3492 } else if (__dl_invalid_handle(p)) {
3493 return 0;
3494 #endif
3495 } else {
3496 use_deps = 1;
3497 ns = p->namespace;
3498 }
3499 if (ra2dso) {
3500 caller = (struct dso *)addr2dso((size_t)ra);
3501 if (caller && caller->namespace) {
3502 ns = caller->namespace;
3503 }
3504 }
3505 struct verinfo verinfo = { .s = s, .v = v, .use_vna_hash = false };
3506 struct symdef def = find_sym2(p, &verinfo, 0, use_deps, ns);
3507 if (!def.sym) {
3508 LD_LOGE("do_dlsym failed: symbol not found. so=%{public}s s=%{public}s v=%{public}s", p->name, s, v);
3509 error("Symbol not found: %s, version: %s", s, strlen(v) > 0 ? v : "null");
3510 return 0;
3511 }
3512 if ((def.sym->st_info&0xf) == STT_TLS)
3513 return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value-DTP_OFFSET});
3514 if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
3515 return def.dso->funcdescs + (def.sym - def.dso->syms);
3516 return laddr(def.dso, def.sym->st_value);
3517 }
3518
dlclose_impl(struct dso * p)3519 static int dlclose_impl(struct dso *p)
3520 {
3521 size_t n;
3522 struct dso *d;
3523
3524 if (__dl_invalid_handle(p))
3525 return -1;
3526
3527 if (!p->by_dlopen) {
3528 error("Library %s is not loaded by dlopen", p->name);
3529 return -1;
3530 }
3531
3532 /* dso is marked as RTLD_NODELETE library, do nothing here. */
3533 if ((p->flags & DSO_FLAGS_NODELETE) != 0) {
3534 return 0;
3535 }
3536
3537 if (--(p->nr_dlopen) > 0)
3538 return 0;
3539
3540 /* call destructors if needed */
3541 if (p->constructed) {
3542 size_t dyn[DYN_CNT];
3543 decode_vec(p->dynv, dyn, DYN_CNT);
3544 if (dyn[0] & (1<<DT_FINI_ARRAY)) {
3545 n = dyn[DT_FINI_ARRAYSZ] / sizeof(size_t);
3546 size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY]) + n;
3547 while (n--)
3548 ((void (*)(void))*--fn)();
3549 }
3550 p->constructed = 0;
3551 }
3552
3553 /* remove dso symbols from global list */
3554 if (p->syms_next) {
3555 for (d = head; d->syms_next != p; d = d->syms_next)
3556 ; /* NOP */
3557 d->syms_next = p->syms_next;
3558 } else if (p == syms_tail) {
3559 for (d = head; d->syms_next != p; d = d->syms_next)
3560 ; /* NOP */
3561 d->syms_next = NULL;
3562 syms_tail = d;
3563 }
3564
3565 /* remove dso from lazy list if needed */
3566 if (p == lazy_head) {
3567 lazy_head = p->lazy_next;
3568 } else if (p->lazy_next) {
3569 for (d = lazy_head; d->lazy_next != p; d = d->lazy_next)
3570 ; /* NOP */
3571 d->lazy_next = p->lazy_next;
3572 }
3573
3574 /* remove dso from fini list */
3575 if (p == fini_head) {
3576 fini_head = p->fini_next;
3577 } else if (p->fini_next) {
3578 for (d = fini_head; d->fini_next != p; d = d->fini_next)
3579 ; /* NOP */
3580 d->fini_next = p->fini_next;
3581 }
3582
3583 /* empty tls image */
3584 if (p->tls.size != 0) {
3585 p->tls.image = NULL;
3586 }
3587
3588 /* remove dso from global dso list */
3589 if (p == tail) {
3590 tail = p->prev;
3591 tail->next = NULL;
3592 } else {
3593 p->next->prev = p->prev;
3594 p->prev->next = p->next;
3595 }
3596
3597 /* remove dso from namespace */
3598 dlclose_ns(p);
3599
3600 if (p->lazy != NULL)
3601 internal_free(p->lazy);
3602 if (p->deps) {
3603 for (int i = 0; i < p->ndeps_direct; i++) {
3604 remove_dso_parent(p->deps[i], p);
3605 }
3606 }
3607 if (p->deps != no_deps)
3608 internal_free(p->deps);
3609 unmap_library(p);
3610
3611 if (p->parents) {
3612 internal_free(p->parents);
3613 }
3614
3615 free_reloc_can_search_dso(p);
3616 if (p->tls.size == 0) {
3617 internal_free(p);
3618 }
3619
3620 return 0;
3621 }
3622
3623 static char* dlclose_deps_black_list[] =
3624 {
3625 "/system/lib/libhidebug.so",
3626 "/system/lib64/libhidebug.so",
3627 "/system/lib64/libmsdp_neardetect_algorithm.z.so",
3628 "/vendor/lib64/libhril_hdf.z.so"
3629 };
3630
do_dlclose(struct dso * p)3631 static int do_dlclose(struct dso *p)
3632 {
3633 bool ldclose_deps = true;
3634
3635 for (int i = 0; i < sizeof(dlclose_deps_black_list)/sizeof(char*); i++) {
3636 if (!strcmp(dlclose_deps_black_list[i], p->name)) {
3637 ldclose_deps = false;
3638 break;
3639 }
3640 }
3641
3642 size_t deps_num;
3643
3644 for (deps_num = 0; p->deps[deps_num]; deps_num++);
3645
3646 struct dso **deps_bak = internal_malloc(deps_num*sizeof(struct dso*));
3647 if (deps_bak != NULL) {
3648 memcpy(deps_bak, p->deps, deps_num*sizeof(struct dso*));
3649 }
3650
3651 LD_LOGI("do_dlclose name=%{public}s count=%{public}d by_dlopen=%{public}d", p->name, p->nr_dlopen, p->by_dlopen);
3652 dlclose_impl(p);
3653
3654 if (ldclose_deps) {
3655 for (size_t i = 0; i < deps_num; i++) {
3656 LD_LOGI("do_dlclose name=%{public}s count=%{public}d by_dlopen=%{public}d", deps_bak[i]->name, deps_bak[i]->nr_dlopen, deps_bak[i]->by_dlopen);
3657 dlclose_impl(deps_bak[i]);
3658 }
3659 }
3660
3661 internal_free(deps_bak);
3662
3663 return 0;
3664 }
3665
__dlclose(void * p)3666 hidden int __dlclose(void *p)
3667 {
3668 int rc;
3669 pthread_rwlock_wrlock(&lock);
3670 __inhibit_ptc();
3671 #ifdef HANDLE_RANDOMIZATION
3672 struct dso *dso = find_dso_by_handle(p);
3673 if (dso == NULL) {
3674 errno = EINVAL;
3675 error("Handle is invalid.");
3676 LD_LOGE("Handle is not find.");
3677 __release_ptc();
3678 pthread_rwlock_unlock(&lock);
3679 return -1;
3680 }
3681 rc = do_dlclose(dso);
3682 if (!rc) {
3683 struct dso *t = head;
3684 for (; t && t != dso; t = t->next) {
3685 ;
3686 }
3687 if (t == NULL) {
3688 remove_handle_node(p);
3689 }
3690 }
3691 #else
3692 rc = do_dlclose(p);
3693 #endif
3694 __release_ptc();
3695 pthread_rwlock_unlock(&lock);
3696 return rc;
3697 }
3698
dladdr(const void * addr_arg,Dl_info * info)3699 int dladdr(const void *addr_arg, Dl_info *info)
3700 {
3701 size_t addr = (size_t)addr_arg;
3702 struct dso *p;
3703 Sym *sym, *bestsym;
3704 uint32_t nsym;
3705 char *strings;
3706 size_t best = 0;
3707 size_t besterr = -1;
3708
3709 pthread_rwlock_rdlock(&lock);
3710 p = addr2dso(addr);
3711 pthread_rwlock_unlock(&lock);
3712
3713 if (!p) return 0;
3714
3715 sym = p->syms;
3716 strings = p->strings;
3717 nsym = count_syms(p);
3718
3719 if (DL_FDPIC) {
3720 size_t idx = (addr-(size_t)p->funcdescs)
3721 / sizeof(*p->funcdescs);
3722 if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) {
3723 best = (size_t)(p->funcdescs + idx);
3724 bestsym = sym + idx;
3725 besterr = 0;
3726 }
3727 }
3728
3729 if (!best) for (; nsym; nsym--, sym++) {
3730 if (sym->st_value
3731 && (1<<(sym->st_info&0xf) & OK_TYPES)
3732 && (1<<(sym->st_info>>4) & OK_BINDS)) {
3733 size_t symaddr = (size_t)laddr(p, sym->st_value);
3734 if (symaddr > addr || symaddr <= best)
3735 continue;
3736 best = symaddr;
3737 bestsym = sym;
3738 besterr = addr - symaddr;
3739 if (addr == symaddr)
3740 break;
3741 }
3742 }
3743
3744 if (best && besterr > bestsym->st_size-1) {
3745 best = 0;
3746 bestsym = 0;
3747 }
3748
3749 info->dli_fname = p->name;
3750 info->dli_fbase = p->map;
3751
3752 if (!best) {
3753 info->dli_sname = 0;
3754 info->dli_saddr = 0;
3755 return 1;
3756 }
3757
3758 if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC)
3759 best = (size_t)(p->funcdescs + (bestsym - p->syms));
3760 info->dli_sname = strings + bestsym->st_name;
3761 info->dli_saddr = (void *)best;
3762
3763 return 1;
3764 }
3765
__dlsym(void * restrict p,const char * restrict s,void * restrict ra)3766 hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
3767 {
3768 void *res;
3769 ld_log_reset();
3770 pthread_rwlock_rdlock(&lock);
3771 #ifdef HANDLE_RANDOMIZATION
3772 if ((p != RTLD_DEFAULT) && (p != RTLD_NEXT)) {
3773 struct dso *dso = find_dso_by_handle(p);
3774 if (dso == NULL) {
3775 pthread_rwlock_unlock(&lock);
3776 return 0;
3777 }
3778 res = do_dlsym(dso, s, "", ra);
3779 } else {
3780 res = do_dlsym(p, s, "", ra);
3781 }
3782 #else
3783 res = do_dlsym(p, s, "", ra);
3784 #endif
3785 pthread_rwlock_unlock(&lock);
3786 return res;
3787 }
3788
__dlvsym(void * restrict p,const char * restrict s,const char * restrict v,void * restrict ra)3789 hidden void *__dlvsym(void *restrict p, const char *restrict s, const char *restrict v, void *restrict ra)
3790 {
3791 void *res;
3792 ld_log_reset();
3793 pthread_rwlock_rdlock(&lock);
3794 #ifdef HANDLE_RANDOMIZATION
3795 if ((p != RTLD_DEFAULT) && (p != RTLD_NEXT)) {
3796 struct dso *dso = find_dso_by_handle(p);
3797 if (dso == NULL) {
3798 pthread_rwlock_unlock(&lock);
3799 return 0;
3800 }
3801 res = do_dlsym(dso, s, v, ra);
3802 } else {
3803 res = do_dlsym(p, s, v, ra);
3804 }
3805 #else
3806 res = do_dlsym(p, s, v, ra);
3807 #endif
3808 pthread_rwlock_unlock(&lock);
3809 return res;
3810 }
3811
__dlsym_redir_time64(void * restrict p,const char * restrict s,void * restrict ra)3812 hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)
3813 {
3814 #if _REDIR_TIME64
3815 const char *suffix, *suffix2 = "";
3816 char redir[36];
3817
3818 /* Map the symbol name to a time64 version of itself according to the
3819 * pattern used for naming the redirected time64 symbols. */
3820 size_t l = strnlen(s, sizeof redir);
3821 if (l<4 || l==sizeof redir) goto no_redir;
3822 if (s[l-2]=='_' && s[l-1]=='r') {
3823 l -= 2;
3824 suffix2 = s+l;
3825 }
3826 if (l<4) goto no_redir;
3827 if (!strcmp(s+l-4, "time")) suffix = "64";
3828 else suffix = "_time64";
3829
3830 /* Use the presence of the remapped symbol name in libc to determine
3831 * whether it's one that requires time64 redirection; replace if so. */
3832 snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2);
3833 if (find_sym(&ldso, redir, 1).sym) s = redir;
3834 no_redir:
3835 #endif
3836 return __dlsym(p, s, ra);
3837 }
3838
dl_iterate_phdr(int (* callback)(struct dl_phdr_info * info,size_t size,void * data),void * data)3839 int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
3840 {
3841 struct dso *current;
3842 struct dl_phdr_info info;
3843 int ret = 0;
3844 for(current = head; current;) {
3845 info.dlpi_addr = (uintptr_t)current->base;
3846 info.dlpi_name = current->name;
3847 info.dlpi_phdr = current->phdr;
3848 info.dlpi_phnum = current->phnum;
3849 info.dlpi_adds = gencnt;
3850 info.dlpi_subs = 0;
3851 info.dlpi_tls_modid = current->tls_id;
3852 info.dlpi_tls_data = current->tls.image;
3853
3854 ret = (callback)(&info, sizeof (info), data);
3855
3856 if (ret != 0) break;
3857
3858 pthread_rwlock_rdlock(&lock);
3859 current = current->next;
3860 pthread_rwlock_unlock(&lock);
3861 }
3862 return ret;
3863 }
3864
error(const char * fmt,...)3865 static void error(const char *fmt, ...)
3866 {
3867 va_list ap;
3868 va_start(ap, fmt);
3869 if (!runtime) {
3870 vdprintf(2, fmt, ap);
3871 dprintf(2, "\n");
3872 ldso_fail = 1;
3873 va_end(ap);
3874 return;
3875 }
3876 __dl_vseterr(fmt, ap);
3877 va_end(ap);
3878 }
3879
dlns_set_namespace_lib_path(const char * name,const char * lib_path)3880 int dlns_set_namespace_lib_path(const char * name, const char * lib_path)
3881 {
3882 if (!name || !lib_path) {
3883 LD_LOGE("dlns_set_namespace_lib_path name or lib_path is null.");
3884 return EINVAL;
3885 }
3886
3887 pthread_rwlock_wrlock(&lock);
3888 ns_t* ns = find_ns_by_name(name);
3889 if (!ns) {
3890 pthread_rwlock_unlock(&lock);
3891 LD_LOGE("dlns_set_namespace_lib_path fail, input ns name : [%{public}s] is not found.", name);
3892 return ENOKEY;
3893 }
3894
3895 ns_set_lib_paths(ns, lib_path);
3896 pthread_rwlock_unlock(&lock);
3897 return 0;
3898 }
3899
dlns_set_namespace_separated(const char * name,const bool separated)3900 int dlns_set_namespace_separated(const char * name, const bool separated)
3901 {
3902 if (!name) {
3903 LD_LOGE("dlns_set_namespace_separated name is null.");
3904 return EINVAL;
3905 }
3906
3907 pthread_rwlock_wrlock(&lock);
3908 ns_t* ns = find_ns_by_name(name);
3909 if (!ns) {
3910 pthread_rwlock_unlock(&lock);
3911 LD_LOGE("dlns_set_namespace_separated fail, input ns name : [%{public}s] is not found.", name);
3912 return ENOKEY;
3913 }
3914
3915 ns_set_separated(ns, separated);
3916 pthread_rwlock_unlock(&lock);
3917 return 0;
3918 }
3919
dlns_set_namespace_permitted_paths(const char * name,const char * permitted_paths)3920 int dlns_set_namespace_permitted_paths(const char * name, const char * permitted_paths)
3921 {
3922 if (!name || !permitted_paths) {
3923 LD_LOGE("dlns_set_namespace_permitted_paths name or permitted_paths is null.");
3924 return EINVAL;
3925 }
3926
3927 pthread_rwlock_wrlock(&lock);
3928 ns_t* ns = find_ns_by_name(name);
3929 if (!ns) {
3930 pthread_rwlock_unlock(&lock);
3931 LD_LOGE("dlns_set_namespace_permitted_paths fail, input ns name : [%{public}s] is not found.", name);
3932 return ENOKEY;
3933 }
3934
3935 ns_set_permitted_paths(ns, permitted_paths);
3936 pthread_rwlock_unlock(&lock);
3937 return 0;
3938 }
3939
dlns_set_namespace_allowed_libs(const char * name,const char * allowed_libs)3940 int dlns_set_namespace_allowed_libs(const char * name, const char * allowed_libs)
3941 {
3942 if (!name || !allowed_libs) {
3943 LD_LOGE("dlns_set_namespace_allowed_libs name or allowed_libs is null.");
3944 return EINVAL;
3945 }
3946
3947 pthread_rwlock_wrlock(&lock);
3948 ns_t* ns = find_ns_by_name(name);
3949 if (!ns) {
3950 pthread_rwlock_unlock(&lock);
3951 LD_LOGE("dlns_set_namespace_allowed_libs fail, input ns name : [%{public}s] is not found.", name);
3952 return ENOKEY;
3953 }
3954
3955 ns_set_allowed_libs(ns, allowed_libs);
3956 pthread_rwlock_unlock(&lock);
3957 return 0;
3958 }
3959
handle_asan_path_open(int fd,const char * name,ns_t * namespace,char * buf,size_t buf_size)3960 int handle_asan_path_open(int fd, const char *name, ns_t *namespace, char *buf, size_t buf_size)
3961 {
3962 LD_LOGD("handle_asan_path_open fd:%{public}d, name:%{public}s , namespace:%{public}s .",
3963 fd,
3964 name,
3965 namespace ? namespace->ns_name : "NULL");
3966 int fd_tmp = fd;
3967 if (fd == -1 && (namespace->asan_lib_paths || namespace->lib_paths)) {
3968 if (namespace->lib_paths && namespace->asan_lib_paths) {
3969 size_t newlen = strlen(namespace->asan_lib_paths) + strlen(namespace->lib_paths) + 2;
3970 char *new_lib_paths = internal_malloc(newlen);
3971 memset(new_lib_paths, 0, newlen);
3972 strcpy(new_lib_paths, namespace->asan_lib_paths);
3973 strcat(new_lib_paths, ":");
3974 strcat(new_lib_paths, namespace->lib_paths);
3975 fd_tmp = path_open(name, new_lib_paths, buf, buf_size);
3976 LD_LOGD("handle_asan_path_open path_open new_lib_paths:%{public}s ,fd: %{public}d.", new_lib_paths, fd_tmp);
3977 internal_free(new_lib_paths);
3978 } else if (namespace->asan_lib_paths) {
3979 fd_tmp = path_open(name, namespace->asan_lib_paths, buf, buf_size);
3980 LD_LOGD("handle_asan_path_open path_open asan_lib_paths:%{public}s ,fd: %{public}d.",
3981 namespace->asan_lib_paths,
3982 fd_tmp);
3983 } else {
3984 fd_tmp = path_open(name, namespace->lib_paths, buf, buf_size);
3985 LD_LOGD(
3986 "handle_asan_path_open path_open lib_paths:%{public}s ,fd: %{public}d.", namespace->lib_paths, fd_tmp);
3987 }
3988 }
3989 return fd_tmp;
3990 }
3991
dlopen_ext(const char * file,int mode,const dl_extinfo * extinfo)3992 void* dlopen_ext(const char *file, int mode, const dl_extinfo *extinfo)
3993 {
3994 const void *caller_addr = __builtin_return_address(0);
3995 musl_log_reset();
3996 ld_log_reset();
3997 if (extinfo != NULL) {
3998 if ((extinfo->flag & ~(DL_EXT_VALID_FLAG_BITS)) != 0) {
3999 LD_LOGE("Error dlopen_ext %{public}s: invalid flag %{public}x", file, extinfo->flag);
4000 return NULL;
4001 }
4002 }
4003 LD_LOGI("dlopen_ext file:%{public}s, mode:%{public}x , caller_addr:%{public}p , extinfo->flag:%{public}x",
4004 file,
4005 mode,
4006 caller_addr,
4007 extinfo ? extinfo->flag : 0);
4008 return dlopen_impl(file, mode, NULL, caller_addr, extinfo);
4009 }
4010
4011 #ifdef LOAD_ORDER_RANDOMIZATION
open_library_by_path(const char * name,const char * s,struct loadtask * task,struct zip_info * z_info)4012 static void open_library_by_path(const char *name, const char *s, struct loadtask *task, struct zip_info *z_info)
4013 {
4014 char *buf = task->buf;
4015 size_t buf_size = sizeof task->buf;
4016 size_t l;
4017 for (;;) {
4018 s += strspn(s, ":\n");
4019 l = strcspn(s, ":\n");
4020 if (l-1 >= INT_MAX) return;
4021 if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
4022 char *separator = strstr(buf, ZIP_FILE_PATH_SEPARATOR);
4023 if (separator != NULL) {
4024 int res = open_uncompressed_library_in_zipfile(buf, z_info, separator);
4025 if (res == 0) {
4026 task->fd = z_info->fd;
4027 task->file_offset = z_info->file_offset;
4028 break;
4029 } else {
4030 memset(z_info->path_buf, 0, sizeof(z_info->path_buf));
4031 }
4032 } else {
4033 if ((task->fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) break;
4034 }
4035 }
4036 s += l;
4037 }
4038 return;
4039 }
4040
handle_asan_path_open_by_task(int fd,const char * name,ns_t * namespace,struct loadtask * task,struct zip_info * z_info)4041 static void handle_asan_path_open_by_task(int fd, const char *name, ns_t *namespace, struct loadtask *task,
4042 struct zip_info *z_info)
4043 {
4044 LD_LOGD("handle_asan_path_open_by_task fd:%{public}d, name:%{public}s , namespace:%{public}s .",
4045 fd,
4046 name,
4047 namespace ? namespace->ns_name : "NULL");
4048 if (fd == -1 && (namespace->asan_lib_paths || namespace->lib_paths)) {
4049 if (namespace->lib_paths && namespace->asan_lib_paths) {
4050 size_t newlen = strlen(namespace->asan_lib_paths) + strlen(namespace->lib_paths) + 2;
4051 char *new_lib_paths = internal_malloc(newlen);
4052 memset(new_lib_paths, 0, newlen);
4053 strcpy(new_lib_paths, namespace->asan_lib_paths);
4054 strcat(new_lib_paths, ":");
4055 strcat(new_lib_paths, namespace->lib_paths);
4056 open_library_by_path(name, new_lib_paths, task, z_info);
4057 LD_LOGD("handle_asan_path_open_by_task open_library_by_path new_lib_paths:%{public}s ,fd: %{public}d.",
4058 new_lib_paths,
4059 task->fd);
4060 internal_free(new_lib_paths);
4061 } else if (namespace->asan_lib_paths) {
4062 open_library_by_path(name, namespace->asan_lib_paths, task, z_info);
4063 LD_LOGD("handle_asan_path_open_by_task open_library_by_path asan_lib_paths:%{public}s ,fd: %{public}d.",
4064 namespace->asan_lib_paths,
4065 task->fd);
4066 } else {
4067 open_library_by_path(name, namespace->lib_paths, task, z_info);
4068 LD_LOGD("handle_asan_path_open_by_task open_library_by_path lib_paths:%{public}s ,fd: %{public}d.",
4069 namespace->lib_paths,
4070 task->fd);
4071 }
4072 }
4073 return;
4074 }
4075
4076 /* Used to get an uncompress library offset in zip file, then we can use the offset to mmap the library directly. */
open_uncompressed_library_in_zipfile(const char * path,struct zip_info * z_info,char * separator)4077 int open_uncompressed_library_in_zipfile(const char *path, struct zip_info *z_info, char *separator)
4078 {
4079 struct local_file_header zip_file_header;
4080 struct central_dir_entry c_dir_entry;
4081 struct zip_end_locator end_locator;
4082
4083 /* Use "'!/' to split the path into zipfile path and library path in zipfile.
4084 * For example:
4085 * - path: x/xx/xxx.zip!/x/xx/xxx.so
4086 * - zipfile path: x/xx/xxx.zip
4087 * - library path in zipfile: x/xx/xxx.so */
4088 if (strlcpy(z_info->path_buf, path, PATH_BUF_SIZE) >= PATH_BUF_SIZE) {
4089 LD_LOGE("Open uncompressed library: input path %{public}s is too long.", path);
4090 return -1;
4091 }
4092 z_info->path_buf[separator - path] = '\0';
4093 z_info->file_path_index = separator - path + 2;
4094 char *zip_file_path = z_info->path_buf;
4095 char *lib_path = &z_info->path_buf[z_info->file_path_index];
4096 if (zip_file_path == NULL || lib_path == NULL) {
4097 LD_LOGE("Open uncompressed library: get zip and lib path failed.");
4098 return -1;
4099 }
4100 LD_LOGD("Open uncompressed library: input path: %{public}s, zip file path: %{public}s, library path: %{public}s.",
4101 path, zip_file_path, lib_path);
4102
4103 // Get zip file length
4104 FILE *zip_file = fopen(zip_file_path, "re");
4105 if (zip_file == NULL) {
4106 LD_LOGE("Open uncompressed library: fopen %{public}s failed.", zip_file_path);
4107 return -1;
4108 }
4109 if (fseek(zip_file, 0, SEEK_END) != 0) {
4110 LD_LOGE("Open uncompressed library: fseek SEEK_END failed.");
4111 fclose(zip_file);
4112 return -1;
4113 }
4114 int64_t zip_file_len = ftell(zip_file);
4115 if (zip_file_len == -1) {
4116 LD_LOGE("Open uncompressed library: get zip file length failed.");
4117 fclose(zip_file);
4118 return -1;
4119 }
4120
4121 // Read end of central directory record.
4122 size_t end_locator_len = sizeof(end_locator);
4123 size_t end_locator_pos = zip_file_len - end_locator_len;
4124 if (fseek(zip_file, end_locator_pos, SEEK_SET) != 0) {
4125 LD_LOGE("Open uncompressed library: fseek end locator position failed.");
4126 fclose(zip_file);
4127 return -1;
4128 }
4129 if (fread(&end_locator, sizeof(end_locator), 1, zip_file) != 1 || end_locator.signature != EOCD_SIGNATURE) {
4130 LD_LOGE("Open uncompressed library: fread end locator failed.");
4131 fclose(zip_file);
4132 return -1;
4133 }
4134
4135 char file_name[PATH_BUF_SIZE];
4136 uint64_t current_dir_pos = end_locator.offset;
4137 for (uint16_t i = 0; i < end_locator.total_entries; i++) {
4138 // Read central dir entry.
4139 if (fseek(zip_file, current_dir_pos, SEEK_SET) != 0) {
4140 LD_LOGE("Open uncompressed library: fseek current centra dir entry position failed.");
4141 fclose(zip_file);
4142 return -1;
4143 }
4144 if (fread(&c_dir_entry, sizeof(c_dir_entry), 1, zip_file) != 1 || c_dir_entry.signature != CENTRAL_SIGNATURE) {
4145 LD_LOGE("Open uncompressed library: fread centra dir entry failed.");
4146 fclose(zip_file);
4147 return -1;
4148 }
4149
4150 if (fread(file_name, c_dir_entry.name_size, 1, zip_file) != 1) {
4151 LD_LOGE("Open uncompressed library: fread file name failed.");
4152 fclose(zip_file);
4153 return -1;
4154 }
4155 if (strcmp(file_name, lib_path) == 0) {
4156 // Read local file header.
4157 if (fseek(zip_file, c_dir_entry.local_header_offset, SEEK_SET) != 0) {
4158 LD_LOGE("Open uncompressed library: fseek local file header failed.");
4159 fclose(zip_file);
4160 return -1;
4161 }
4162 if (fread(&zip_file_header, sizeof(zip_file_header), 1, zip_file) != 1) {
4163 LD_LOGE("Open uncompressed library: fread local file header failed.");
4164 fclose(zip_file);
4165 return -1;
4166 }
4167 if (zip_file_header.signature != LOCAL_FILE_HEADER_SIGNATURE) {
4168 LD_LOGE("Open uncompressed library: read local file header signature error.");
4169 fclose(zip_file);
4170 return -1;
4171 }
4172
4173 z_info->file_offset = c_dir_entry.local_header_offset + sizeof(zip_file_header) +
4174 zip_file_header.name_size + zip_file_header.extra_size;
4175 if (zip_file_header.compression_method != COMPRESS_STORED || z_info->file_offset % PAGE_SIZE != 0) {
4176 LD_LOGE("Open uncompressed library: open %{public}s in %{public}s failed because of misalignment or saved with compression."
4177 "compress method %{public}d, file offset %{public}lu",
4178 lib_path, zip_file_path, zip_file_header.compression_method, z_info->file_offset);
4179 fclose(zip_file);
4180 return -2;
4181 }
4182 z_info->found = true;
4183 break;
4184 }
4185
4186 memset(file_name, 0, sizeof(file_name));
4187 current_dir_pos += sizeof(c_dir_entry);
4188 current_dir_pos += c_dir_entry.name_size + c_dir_entry.extra_size + c_dir_entry.comment_size;
4189 }
4190 if(!z_info->found) {
4191 LD_LOGE("Open uncompressed library: %{public}s was not found in %{public}s.", lib_path, zip_file_path);
4192 fclose(zip_file);
4193 return -3;
4194 }
4195 z_info->fd = fileno(zip_file);
4196
4197 return 0;
4198 }
4199
map_library_header(struct loadtask * task)4200 static bool map_library_header(struct loadtask *task)
4201 {
4202 off_t off_start;
4203 Phdr *ph;
4204 size_t i;
4205
4206 ssize_t l = pread(task->fd, task->ehdr_buf, sizeof task->ehdr_buf, task->file_offset);
4207 task->eh = task->ehdr_buf;
4208 if (l < 0) {
4209 LD_LOGE("Error mapping header %{public}s: failed to read fd", task->name);
4210 return false;
4211 }
4212 if (l < sizeof(Ehdr) || (task->eh->e_type != ET_DYN && task->eh->e_type != ET_EXEC)) {
4213 LD_LOGE("Error mapping header %{public}s: invaliled Ehdr", task->name);
4214 goto noexec;
4215 }
4216 task->phsize = task->eh->e_phentsize * task->eh->e_phnum;
4217 if (task->phsize > sizeof task->ehdr_buf - sizeof(Ehdr)) {
4218 task->allocated_buf = internal_malloc(task->phsize);
4219 if (!task->allocated_buf) {
4220 LD_LOGE("Error mapping header %{public}s: failed to alloc memory", task->name);
4221 return false;
4222 }
4223 l = pread(task->fd, task->allocated_buf, task->phsize, task->eh->e_phoff + task->file_offset);
4224 if (l < 0) {
4225 LD_LOGE("Error mapping header %{public}s: failed to pread", task->name);
4226 goto error;
4227 }
4228 if (l != task->phsize) {
4229 LD_LOGE("Error mapping header %{public}s: unmatched phsize", task->name);
4230 goto noexec;
4231 }
4232 ph = task->ph0 = task->allocated_buf;
4233 } else if (task->eh->e_phoff + task->phsize > l) {
4234 l = pread(task->fd, task->ehdr_buf + 1, task->phsize, task->eh->e_phoff + task->file_offset);
4235 if (l < 0) {
4236 LD_LOGE("Error mapping header %{public}s: failed to pread", task->name);
4237 goto error;
4238 }
4239 if (l != task->phsize) {
4240 LD_LOGE("Error mapping header %{public}s: unmatched phsize", task->name);
4241 goto noexec;
4242 }
4243 ph = task->ph0 = (void *)(task->ehdr_buf + 1);
4244 } else {
4245 ph = task->ph0 = (void *)((char *)task->ehdr_buf + task->eh->e_phoff);
4246 }
4247 for (i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4248 if (ph->p_type == PT_DYNAMIC) {
4249 task->dyn = ph->p_vaddr;
4250 } else if (ph->p_type == PT_TLS) {
4251 task->tls_image = ph->p_vaddr;
4252 task->tls.align = ph->p_align;
4253 task->tls.len = ph->p_filesz;
4254 task->tls.size = ph->p_memsz;
4255 }
4256
4257 if (ph->p_type != PT_DYNAMIC) {
4258 continue;
4259 }
4260 // map the dynamic segment and the string table of the library
4261 off_start = ph->p_offset;
4262 off_start &= -PAGE_SIZE;
4263 task->dyn_map_len = ph->p_memsz + (ph->p_offset - off_start);
4264 /* The default value of file_offset is 0.
4265 * The value of file_offset may be greater than 0 when opening library from zip file.
4266 * The value of file_offset ensures PAGE_SIZE aligned. */
4267 task->dyn_map = mmap(0, task->dyn_map_len, PROT_READ, MAP_PRIVATE, task->fd, off_start + task->file_offset);
4268 if (task->dyn_map == MAP_FAILED) {
4269 LD_LOGE("Error mapping header %{public}s: failed to map dynamic section", task->name);
4270 goto error;
4271 }
4272 task->dyn_addr = (size_t *)((unsigned char *)task->dyn_map + (ph->p_offset - off_start));
4273 size_t dyn_tmp;
4274 off_t str_table;
4275 size_t str_size;
4276 if (search_vec(task->dyn_addr, &dyn_tmp, DT_STRTAB)) {
4277 str_table = dyn_tmp;
4278 } else {
4279 LD_LOGE("Error mapping header %{public}s: DT_STRTAB not found", task->name);
4280 goto error;
4281 }
4282 if (search_vec(task->dyn_addr, &dyn_tmp, DT_STRSZ)) {
4283 str_size = dyn_tmp;
4284 } else {
4285 LD_LOGE("Error mapping header %{public}s: DT_STRSZ not found", task->name);
4286 goto error;
4287 }
4288 off_start = str_table;
4289 off_start &= -PAGE_SIZE;
4290 task->str_map_len = str_size + (str_table - off_start);
4291 task->str_map = mmap(0, task->str_map_len, PROT_READ, MAP_PRIVATE, task->fd, off_start + task->file_offset);
4292 if (task->str_map == MAP_FAILED) {
4293 LD_LOGE("Error mapping header %{public}s: failed to map string section", task->name);
4294 goto error;
4295 }
4296 task->str_addr = (char *)task->str_map + str_table - off_start;
4297 }
4298 if (!task->dyn) {
4299 LD_LOGE("Error mapping header %{public}s: dynamic section not found", task->name);
4300 goto noexec;
4301 }
4302 return true;
4303 noexec:
4304 errno = ENOEXEC;
4305 error:
4306 internal_free(task->allocated_buf);
4307 task->allocated_buf = NULL;
4308 return false;
4309 }
4310
task_map_library(struct loadtask * task,struct reserved_address_params * reserved_params)4311 static bool task_map_library(struct loadtask *task, struct reserved_address_params *reserved_params)
4312 {
4313 size_t addr_min = SIZE_MAX, addr_max = 0, map_len;
4314 size_t this_min, this_max;
4315 size_t nsegs = 0;
4316 off_t off_start;
4317 Phdr *ph = task->ph0;
4318 unsigned prot;
4319 unsigned char *map = MAP_FAILED, *base;
4320 size_t i;
4321 int map_flags = MAP_PRIVATE;
4322 size_t start_addr;
4323
4324 for (i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4325 if (ph->p_type == PT_GNU_RELRO) {
4326 task->p->relro_start = ph->p_vaddr & -PAGE_SIZE;
4327 task->p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
4328 } else if (ph->p_type == PT_GNU_STACK) {
4329 if (!runtime && ph->p_memsz > __default_stacksize) {
4330 __default_stacksize =
4331 ph->p_memsz < DEFAULT_STACK_MAX ?
4332 ph->p_memsz : DEFAULT_STACK_MAX;
4333 }
4334 }
4335 if (ph->p_type != PT_LOAD) {
4336 continue;
4337 }
4338 nsegs++;
4339 if (ph->p_vaddr < addr_min) {
4340 addr_min = ph->p_vaddr;
4341 off_start = ph->p_offset;
4342 prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4343 ((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4344 ((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4345 }
4346 if (ph->p_vaddr + ph->p_memsz > addr_max) {
4347 addr_max = ph->p_vaddr + ph->p_memsz;
4348 }
4349 }
4350 if (!task->dyn) {
4351 LD_LOGE("Error mapping library %{public}s: dynamic section not found", task->name);
4352 goto noexec;
4353 }
4354 if (DL_FDPIC && !(task->eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
4355 task->p->loadmap = internal_calloc(1, sizeof(struct fdpic_loadmap) + nsegs * sizeof(struct fdpic_loadseg));
4356 if (!task->p->loadmap) {
4357 goto error;
4358 }
4359 task->p->loadmap->nsegs = nsegs;
4360 for (ph = task->ph0, i = 0; i < nsegs; ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4361 if (ph->p_type != PT_LOAD) {
4362 continue;
4363 }
4364 prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4365 ((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4366 ((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4367 map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE - 1),
4368 prot, MAP_PRIVATE,
4369 task->fd, ph->p_offset & -PAGE_SIZE + task->file_offset);
4370 if (map == MAP_FAILED) {
4371 unmap_library(task->p);
4372 goto error;
4373 }
4374 task->p->loadmap->segs[i].addr = (size_t)map +
4375 (ph->p_vaddr & PAGE_SIZE - 1);
4376 task->p->loadmap->segs[i].p_vaddr = ph->p_vaddr;
4377 task->p->loadmap->segs[i].p_memsz = ph->p_memsz;
4378 i++;
4379 if (prot & PROT_WRITE) {
4380 size_t brk = (ph->p_vaddr & PAGE_SIZE - 1) + ph->p_filesz;
4381 size_t pgbrk = (brk + PAGE_SIZE - 1) & -PAGE_SIZE;
4382 size_t pgend = (brk + ph->p_memsz - ph->p_filesz + PAGE_SIZE - 1) & -PAGE_SIZE;
4383 if (pgend > pgbrk && mmap_fixed(map + pgbrk,
4384 pgend - pgbrk, prot,
4385 MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
4386 -1, off_start) == MAP_FAILED)
4387 goto error;
4388 memset(map + brk, 0, pgbrk - brk);
4389 }
4390 }
4391 map = (void *)task->p->loadmap->segs[0].addr;
4392 map_len = 0;
4393 goto done_mapping;
4394 }
4395 addr_max += PAGE_SIZE - 1;
4396 addr_max &= -PAGE_SIZE;
4397 addr_min &= -PAGE_SIZE;
4398 off_start &= -PAGE_SIZE;
4399 map_len = addr_max - addr_min + off_start;
4400 start_addr = addr_min;
4401 if (reserved_params) {
4402 if (map_len > reserved_params->reserved_size) {
4403 if (reserved_params->must_use_reserved) {
4404 LD_LOGE("Error mapping library %{public}s: map len is larger than reserved address", task->name);
4405 goto error;
4406 }
4407 } else {
4408 start_addr = ((size_t)reserved_params->start_addr - 1 + PAGE_SIZE) & -PAGE_SIZE;
4409 map_flags |= MAP_FIXED;
4410 }
4411 }
4412 /* The first time, we map too much, possibly even more than
4413 * the length of the file. This is okay because we will not
4414 * use the invalid part; we just need to reserve the right
4415 * amount of virtual address space to map over later. */
4416 map = DL_NOMMU_SUPPORT
4417 ? mmap((void *)start_addr, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
4418 : mmap((void *)start_addr, map_len, prot, map_flags, task->fd, off_start + task->file_offset);
4419 if (map == MAP_FAILED) {
4420 LD_LOGE("Error mapping library %{public}s: failed to map fd", task->name);
4421 goto error;
4422 }
4423 if (reserved_params && map_len < reserved_params->reserved_size) {
4424 reserved_params->reserved_size -= (map_len + (start_addr - (size_t)reserved_params->start_addr));
4425 reserved_params->start_addr = (void *)((uint8_t *)map + map_len);
4426 }
4427 task->p->map = map;
4428 task->p->map_len = map_len;
4429 /* If the loaded file is not relocatable and the requested address is
4430 * not available, then the load operation must fail. */
4431 if (task->eh->e_type != ET_DYN && addr_min && map != (void *)addr_min) {
4432 LD_LOGE("Error mapping library %{public}s: device or resource busy", task->name);
4433 errno = EBUSY;
4434 goto error;
4435 }
4436 base = map - addr_min;
4437 task->p->phdr = 0;
4438 task->p->phnum = 0;
4439 for (ph = task->ph0, i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4440 if (ph->p_type == PT_OHOS_RANDOMDATA) {
4441 fill_random_data((void *)(ph->p_vaddr + base), ph->p_memsz);
4442 continue;
4443 }
4444 if (ph->p_type != PT_LOAD) {
4445 continue;
4446 }
4447 /* Check if the programs headers are in this load segment, and
4448 * if so, record the address for use by dl_iterate_phdr. */
4449 if (!task->p->phdr && task->eh->e_phoff >= ph->p_offset
4450 && task->eh->e_phoff + task->phsize <= ph->p_offset + ph->p_filesz) {
4451 task->p->phdr = (void *)(base + ph->p_vaddr + (task->eh->e_phoff - ph->p_offset));
4452 task->p->phnum = task->eh->e_phnum;
4453 task->p->phentsize = task->eh->e_phentsize;
4454 }
4455 this_min = ph->p_vaddr & -PAGE_SIZE;
4456 this_max = ph->p_vaddr + ph->p_memsz + PAGE_SIZE - 1 & -PAGE_SIZE;
4457 off_start = ph->p_offset & -PAGE_SIZE;
4458 prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4459 ((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4460 ((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4461 /* Reuse the existing mapping for the lowest-address LOAD */
4462 if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT) {
4463 if (mmap_fixed(
4464 base + this_min,
4465 this_max - this_min,
4466 prot, MAP_PRIVATE | MAP_FIXED,
4467 task->fd,
4468 off_start + task->file_offset) == MAP_FAILED) {
4469 LD_LOGE("Error mapping library %{public}s: mmap fix failed, errno: %{public}d", task->name, errno);
4470 goto error;
4471 }
4472 }
4473 if (ph->p_memsz > ph->p_filesz && (ph->p_flags & PF_W)) {
4474 size_t brk = (size_t)base + ph->p_vaddr + ph->p_filesz;
4475 size_t pgbrk = brk + PAGE_SIZE - 1 & -PAGE_SIZE;
4476 memset((void *)brk, 0, pgbrk - brk & PAGE_SIZE - 1);
4477 if (pgbrk - (size_t)base < this_max && mmap_fixed(
4478 (void *)pgbrk,
4479 (size_t)base + this_max - pgbrk,
4480 prot,
4481 MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
4482 -1,
4483 0) == MAP_FAILED) {
4484 LD_LOGE("Error mapping library: mmap fix failed");
4485 goto error;
4486 }
4487 }
4488 }
4489 for (i = 0; ((size_t *)(base + task->dyn))[i]; i += NEXT_DYNAMIC_INDEX) {
4490 if (((size_t *)(base + task->dyn))[i] == DT_TEXTREL) {
4491 if (mprotect(map, map_len, PROT_READ | PROT_WRITE | PROT_EXEC) && errno != ENOSYS) {
4492 LD_LOGE("Error mapping library %{public}s: mprotect failed", task->name);
4493 goto error;
4494 }
4495 break;
4496 }
4497 }
4498 done_mapping:
4499 task->p->base = base;
4500 task->p->dynv = laddr(task->p, task->dyn);
4501 if (task->p->tls.size) {
4502 task->p->tls.image = laddr(task->p, task->tls_image);
4503 }
4504 internal_free(task->allocated_buf);
4505 task->allocated_buf = NULL;
4506 return true;
4507 noexec:
4508 errno = ENOEXEC;
4509 error:
4510 if (map != MAP_FAILED) {
4511 unmap_library(task->p);
4512 }
4513 internal_free(task->allocated_buf);
4514 task->allocated_buf = NULL;
4515 return false;
4516 }
4517
load_library_header(struct loadtask * task)4518 static bool load_library_header(struct loadtask *task)
4519 {
4520 const char *name = task->name;
4521 struct dso *needed_by = task->needed_by;
4522 ns_t *namespace = task->namespace;
4523 bool check_inherited = task->check_inherited;
4524 struct zip_info z_info;
4525
4526 bool map = false;
4527 struct stat st;
4528 size_t alloc_size;
4529 int n_th = 0;
4530 int is_self = 0;
4531
4532 if (!*name) {
4533 errno = EINVAL;
4534 return false;
4535 }
4536
4537 /* Catch and block attempts to reload the implementation itself */
4538 if (name[NAME_INDEX_ZERO] == 'l' && name[NAME_INDEX_ONE] == 'i' && name[NAME_INDEX_TWO] == 'b') {
4539 static const char reserved[] =
4540 "c.pthread.rt.m.dl.util.xnet.";
4541 const char *rp, *next;
4542 for (rp = reserved; *rp; rp = next) {
4543 next = strchr(rp, '.') + 1;
4544 if (strncmp(name + NAME_INDEX_THREE, rp, next - rp) == 0) {
4545 break;
4546 }
4547 }
4548 if (*rp) {
4549 if (ldd_mode) {
4550 /* Track which names have been resolved
4551 * and only report each one once. */
4552 static unsigned reported;
4553 unsigned mask = 1U << (rp - reserved);
4554 if (!(reported & mask)) {
4555 reported |= mask;
4556 dprintf(1, "\t%s => %s (%p)\n",
4557 name, ldso.name,
4558 ldso.base);
4559 }
4560 }
4561 is_self = 1;
4562 }
4563 }
4564 if (!strcmp(name, ldso.name)) {
4565 is_self = 1;
4566 }
4567 if (is_self) {
4568 if (!ldso.prev) {
4569 tail->next = &ldso;
4570 ldso.prev = tail;
4571 tail = &ldso;
4572 ldso.namespace = namespace;
4573 ns_add_dso(namespace, &ldso);
4574 }
4575 task->isloaded = true;
4576 task->p = &ldso;
4577 return true;
4578 }
4579 if (strchr(name, '/')) {
4580 char *separator = strstr(name, ZIP_FILE_PATH_SEPARATOR);
4581 if (separator != NULL) {
4582 int res = open_uncompressed_library_in_zipfile(name, &z_info, separator);
4583 if (!res) {
4584 task->pathname = name;
4585 if (!is_accessible(namespace, task->pathname, g_is_asan, check_inherited)) {
4586 LD_LOGE("Open uncompressed library: check ns accessible failed, pathname %{public}s namespace %{public}s.",
4587 task->pathname, namespace ? namespace->ns_name : "NULL");
4588 task->fd = -1;
4589 } else {
4590 task->fd = z_info.fd;
4591 task->file_offset = z_info.file_offset;
4592 }
4593 } else {
4594 LD_LOGE("Open uncompressed library in zip file failed, name:%{public}s res:%{public}d", name, res);
4595 return false;
4596 }
4597 } else {
4598 task->pathname = name;
4599 if (!is_accessible(namespace, task->pathname, g_is_asan, check_inherited)) {
4600 task->fd = -1;
4601 } else {
4602 task->fd = open(name, O_RDONLY | O_CLOEXEC);
4603 }
4604 }
4605 } else {
4606 /* Search for the name to see if it's already loaded */
4607 /* Search in namespace */
4608 task->p = find_library_by_name(name, namespace, check_inherited);
4609 if (task->p) {
4610 task->isloaded = true;
4611 return true;
4612 }
4613 if (strlen(name) > NAME_MAX) {
4614 LD_LOGE("load_library name length is larger than NAME_MAX:%{public}s.", name);
4615 return false;
4616 }
4617 task->fd = -1;
4618 if (namespace->env_paths) {
4619 open_library_by_path(name, namespace->env_paths, task, &z_info);
4620 }
4621 for (task->p = needed_by; task->fd == -1 && task->p; task->p = task->p->needed_by) {
4622 if (fixup_rpath(task->p, task->buf, sizeof task->buf) < 0) {
4623 task->fd = INVALID_FD_INHIBIT_FURTHER_SEARCH; /* Inhibit further search. */
4624 }
4625 if (task->p->rpath) {
4626 open_library_by_path(name, task->p->rpath, task, &z_info);
4627 }
4628 }
4629 if (g_is_asan) {
4630 handle_asan_path_open_by_task(task->fd, name, namespace, task, &z_info);
4631 LD_LOGD("load_library handle_asan_path_open_by_task fd:%{public}d.", task->fd);
4632 } else {
4633 if (task->fd == -1 && namespace->lib_paths) {
4634 open_library_by_path(name, namespace->lib_paths, task, &z_info);
4635 LD_LOGD("load_library no asan lib_paths path_open fd:%{public}d.", task->fd);
4636 }
4637 }
4638 task->pathname = task->buf;
4639 }
4640 if (task->fd < 0) {
4641 if (!check_inherited || !namespace->ns_inherits) {
4642 return false;
4643 }
4644 /* Load lib in inherited namespace. Do not check inherited again.*/
4645 for (size_t i = 0; i < namespace->ns_inherits->num; i++) {
4646 ns_inherit *inherit = namespace->ns_inherits->inherits[i];
4647 if (strchr(name, '/') == 0 && !is_sharable(inherit, name)) {
4648 continue;
4649 }
4650 task->namespace = inherit->inherited_ns;
4651 task->check_inherited = false;
4652 if (load_library_header(task)) {
4653 return true;
4654 }
4655 }
4656 return false;
4657 }
4658
4659 if (fstat(task->fd, &st) < 0) {
4660 LD_LOGE("Error loading header %{public}s: failed to get file state", task->name);
4661 close(task->fd);
4662 task->fd = -1;
4663 return false;
4664 }
4665 /* Search in namespace */
4666 task->p = find_library_by_fstat(&st, namespace, check_inherited, task->file_offset);
4667 if (task->p) {
4668 /* If this library was previously loaded with a
4669 * pathname but a search found the same inode,
4670 * setup its shortname so it can be found by name. */
4671 if (!task->p->shortname && task->pathname != name) {
4672 task->p->shortname = strrchr(task->p->name, '/') + 1;
4673 }
4674 close(task->fd);
4675 task->fd = -1;
4676 task->isloaded = true;
4677 return true;
4678 }
4679
4680 map = noload ? 0 : map_library_header(task);
4681 if (!map) {
4682 LD_LOGE("Error loading header %{public}s: failed to map header", task->name);
4683 close(task->fd);
4684 task->fd = -1;
4685 return false;
4686 }
4687
4688 /* Allocate storage for the new DSO. When there is TLS, this
4689 * storage must include a reservation for all pre-existing
4690 * threads to obtain copies of both the new TLS, and an
4691 * extended DTV capable of storing an additional slot for
4692 * the newly-loaded DSO. */
4693 alloc_size = sizeof(struct dso) + strlen(task->pathname) + 1;
4694 if (runtime && task->tls.size) {
4695 size_t per_th = task->tls.size + task->tls.align + sizeof(void *) * (tls_cnt + TLS_CNT_INCREASE);
4696 n_th = libc.threads_minus_1 + 1;
4697 if (n_th > SSIZE_MAX / per_th) {
4698 alloc_size = SIZE_MAX;
4699 } else {
4700 alloc_size += n_th * per_th;
4701 }
4702 }
4703 task->p = internal_calloc(1, alloc_size);
4704 if (!task->p) {
4705 LD_LOGE("Error loading header %{public}s: failed to allocate dso", task->name);
4706 close(task->fd);
4707 task->fd = -1;
4708 return false;
4709 }
4710 task->p->dev = st.st_dev;
4711 task->p->ino = st.st_ino;
4712 task->p->file_offset = task->file_offset;
4713 task->p->needed_by = needed_by;
4714 task->p->name = task->p->buf;
4715 strcpy(task->p->name, task->pathname);
4716 task->p->tls = task->tls;
4717 task->p->dynv = task->dyn_addr;
4718 task->p->strings = task->str_addr;
4719
4720 /* Add a shortname only if name arg was not an explicit pathname. */
4721 if (task->pathname != name) {
4722 task->p->shortname = strrchr(task->p->name, '/') + 1;
4723 }
4724
4725 if (task->p->tls.size) {
4726 task->p->tls_id = ++tls_cnt;
4727 task->p->new_dtv = (void *)(-sizeof(size_t) &
4728 (uintptr_t)(task->p->name + strlen(task->p->name) + sizeof(size_t)));
4729 task->p->new_tls = (void *)(task->p->new_dtv + n_th * (tls_cnt + 1));
4730 }
4731
4732 tail->next = task->p;
4733 task->p->prev = tail;
4734 tail = task->p;
4735
4736 /* Add dso to namespace */
4737 task->p->namespace = namespace;
4738 ns_add_dso(namespace, task->p);
4739 return true;
4740 }
4741
task_load_library(struct loadtask * task,struct reserved_address_params * reserved_params)4742 static void task_load_library(struct loadtask *task, struct reserved_address_params *reserved_params)
4743 {
4744 bool map = noload ? 0 : task_map_library(task, reserved_params);
4745 close(task->fd);
4746 task->fd = -1;
4747 if (!map) {
4748 LD_LOGE("Error loading library %{public}s: failed to map library", task->name);
4749 error("Error loading library %s: failed to map library", task->name);
4750 if (runtime) {
4751 longjmp(*rtld_fail, 1);
4752 }
4753 return;
4754 };
4755
4756 /* Avoid the danger of getting two versions of libc mapped into the
4757 * same process when an absolute pathname was used. The symbols
4758 * checked are chosen to catch both musl and glibc, and to avoid
4759 * false positives from interposition-hack libraries. */
4760 decode_dyn(task->p);
4761 if (find_sym(task->p, "__libc_start_main", 1).sym &&
4762 find_sym(task->p, "stdin", 1).sym) {
4763 do_dlclose(task->p);
4764 task->p = NULL;
4765 internal_free((void*)task->name);
4766 task->name = ld_strdup("libc.so");
4767 task->check_inherited = true;
4768 if (!load_library_header(task)) {
4769 LD_LOGE("Error loading library %{public}s: failed to load libc.so", task->name);
4770 error("Error loading library %s: failed to load libc.so", task->name);
4771 if (runtime) {
4772 longjmp(*rtld_fail, 1);
4773 }
4774 }
4775 return;
4776 }
4777 /* Past this point, if we haven't reached runtime yet, ldso has
4778 * committed either to use the mapped library or to abort execution.
4779 * Unmapping is not possible, so we can safely reclaim gaps. */
4780 if (!runtime) {
4781 reclaim_gaps(task->p);
4782 }
4783 task->p->runtime_loaded = runtime;
4784 if (runtime)
4785 task->p->by_dlopen = 1;
4786
4787 if (DL_FDPIC) {
4788 makefuncdescs(task->p);
4789 }
4790
4791 if (ldd_mode) {
4792 dprintf(1, "\t%s => %s (%p)\n", task->name, task->pathname, task->p->base);
4793 }
4794 }
4795
preload_direct_deps(struct dso * p,ns_t * namespace,struct loadtasks * tasks)4796 static void preload_direct_deps(struct dso *p, ns_t *namespace, struct loadtasks *tasks)
4797 {
4798 size_t i, cnt = 0;
4799 if (p->deps) {
4800 return;
4801 }
4802 /* For head, all preloads are direct pseudo-dependencies.
4803 * Count and include them now to avoid realloc later. */
4804 if (p == head) {
4805 for (struct dso *q = p->next; q; q = q->next) {
4806 cnt++;
4807 }
4808 }
4809 for (i = 0; p->dynv[i]; i += NEXT_DYNAMIC_INDEX) {
4810 if (p->dynv[i] == DT_NEEDED) {
4811 cnt++;
4812 }
4813 }
4814 /* Use builtin buffer for apps with no external deps, to
4815 * preserve property of no runtime failure paths. */
4816 p->deps = (p == head && cnt < MIN_DEPS_COUNT) ? builtin_deps :
4817 internal_calloc(cnt + 1, sizeof *p->deps);
4818 if (!p->deps) {
4819 LD_LOGE("Error loading dependencies for %{public}s", p->name);
4820 error("Error loading dependencies for %s", p->name);
4821 if (runtime) {
4822 longjmp(*rtld_fail, 1);
4823 }
4824 }
4825 cnt = 0;
4826 if (p == head) {
4827 for (struct dso *q = p->next; q; q = q->next) {
4828 p->deps[cnt++] = q;
4829 }
4830 }
4831 for (i = 0; p->dynv[i]; i += NEXT_DYNAMIC_INDEX) {
4832 if (p->dynv[i] != DT_NEEDED) {
4833 continue;
4834 }
4835 struct loadtask *task = create_loadtask(p->strings + p->dynv[i + 1], p, namespace, true);
4836 if (!task) {
4837 LD_LOGE("Error loading dependencies %{public}s : create load task failed", p->name);
4838 error("Error loading dependencies for %s : create load task failed", p->name);
4839 if (runtime) {
4840 longjmp(*rtld_fail, 1);
4841 }
4842 continue;
4843 }
4844 LD_LOGD("loading shared library %{public}s: (needed by %{public}s)", p->strings + p->dynv[i+1], p->name);
4845 if (!load_library_header(task)) {
4846 free_task(task);
4847 task = NULL;
4848 LD_LOGE("Error loading shared library %{public}s: (needed by %{public}s)",
4849 p->strings + p->dynv[i + 1],
4850 p->name);
4851 error("Error loading shared library %s: %m (needed by %s)",
4852 p->strings + p->dynv[i + 1], p->name);
4853 if (runtime) {
4854 longjmp(*rtld_fail, 1);
4855 }
4856 continue;
4857 }
4858 p->deps[cnt++] = task->p;
4859 if (task->isloaded) {
4860 free_task(task);
4861 task = NULL;
4862 } else {
4863 append_loadtasks(tasks, task);
4864 }
4865 }
4866 p->deps[cnt] = 0;
4867 p->ndeps_direct = cnt;
4868 for (i = 0; i < p->ndeps_direct; i++) {
4869 add_dso_parent(p->deps[i], p);
4870 }
4871 }
4872
unmap_preloaded_sections(struct loadtasks * tasks)4873 static void unmap_preloaded_sections(struct loadtasks *tasks)
4874 {
4875 struct loadtask *task = NULL;
4876 for (size_t i = 0; i < tasks->length; i++) {
4877 task = get_loadtask(tasks, i);
4878 if (!task) {
4879 continue;
4880 }
4881 if (task->dyn_map_len) {
4882 munmap(task->dyn_map, task->dyn_map_len);
4883 task->dyn_map = NULL;
4884 task->dyn_map_len = 0;
4885 if (task->p) {
4886 task->p->dynv = NULL;
4887 }
4888 }
4889 if (task->str_map_len) {
4890 munmap(task->str_map, task->str_map_len);
4891 task->str_map = NULL;
4892 task->str_map_len = 0;
4893 if (task->p) {
4894 task->p->strings = NULL;
4895 }
4896 }
4897 }
4898 }
4899
preload_deps(struct dso * p,struct loadtasks * tasks)4900 static void preload_deps(struct dso *p, struct loadtasks *tasks)
4901 {
4902 if (p->deps) {
4903 return;
4904 }
4905 for (; p; p = p->next) {
4906 preload_direct_deps(p, p->namespace, tasks);
4907 }
4908 }
4909
run_loadtasks(struct loadtasks * tasks,struct reserved_address_params * reserved_params)4910 static void run_loadtasks(struct loadtasks *tasks, struct reserved_address_params *reserved_params)
4911 {
4912 struct loadtask *task = NULL;
4913 bool reserved_address = false;
4914 for (size_t i = 0; i < tasks->length; i++) {
4915 task = get_loadtask(tasks, i);
4916 if (task) {
4917 if (reserved_params) {
4918 reserved_address = reserved_params->reserved_address_recursive || (reserved_params->target == task->p);
4919 }
4920 task_load_library(task, reserved_address ? reserved_params : NULL);
4921 }
4922 }
4923 }
4924
assign_tls(struct dso * p)4925 static void assign_tls(struct dso *p)
4926 {
4927 while (p) {
4928 if (p->tls.image) {
4929 tls_align = MAXP2(tls_align, p->tls.align);
4930 #ifdef TLS_ABOVE_TP
4931 p->tls.offset = tls_offset + ((p->tls.align - 1) &
4932 (-tls_offset + (uintptr_t)p->tls.image));
4933 tls_offset = p->tls.offset + p->tls.size;
4934 #else
4935 tls_offset += p->tls.size + p->tls.align - 1;
4936 tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
4937 & (p->tls.align - 1);
4938 p->tls.offset = tls_offset;
4939 #endif
4940 if (tls_tail) {
4941 tls_tail->next = &p->tls;
4942 } else {
4943 libc.tls_head = &p->tls;
4944 }
4945 tls_tail = &p->tls;
4946 }
4947
4948 p = p->next;
4949 }
4950 }
4951
load_preload(char * s,ns_t * ns,struct loadtasks * tasks)4952 static void load_preload(char *s, ns_t *ns, struct loadtasks *tasks)
4953 {
4954 int tmp;
4955 char *z;
4956
4957 struct loadtask *task = NULL;
4958 for (z = s; *z; s = z) {
4959 for (; *s && (isspace(*s) || *s == ':'); s++) {
4960 ;
4961 }
4962 for (z = s; *z && !isspace(*z) && *z != ':'; z++) {
4963 ;
4964 }
4965 tmp = *z;
4966 *z = 0;
4967 task = create_loadtask(s, NULL, ns, true);
4968 if (!task) {
4969 continue;
4970 }
4971 if (load_library_header(task)) {
4972 if (!task->isloaded) {
4973 append_loadtasks(tasks, task);
4974 task = NULL;
4975 }
4976 }
4977 if (task) {
4978 free_task(task);
4979 }
4980 *z = tmp;
4981 }
4982 }
4983 #endif
4984
serialize_gnu_relro(int fd,struct dso * dso,ssize_t * file_offset)4985 static int serialize_gnu_relro(int fd, struct dso *dso, ssize_t *file_offset)
4986 {
4987 ssize_t count = dso->relro_end - dso->relro_start;
4988 ssize_t offset = 0;
4989 while (count > 0) {
4990 ssize_t write_size = TEMP_FAILURE_RETRY(write(fd, laddr(dso, dso->relro_start + offset), count));
4991 if (-1 == write_size) {
4992 LD_LOGE("Error serializing relro %{public}s: failed to write GNU_RELRO", dso->name);
4993 return -1;
4994 }
4995 offset += write_size;
4996 count -= write_size;
4997 }
4998
4999 ssize_t size = dso->relro_end - dso->relro_start;
5000 void *map = mmap(
5001 laddr(dso, dso->relro_start),
5002 size,
5003 PROT_READ,
5004 MAP_PRIVATE | MAP_FIXED,
5005 fd,
5006 *file_offset);
5007 if (map == MAP_FAILED) {
5008 LD_LOGE("Error serializing relro %{public}s: failed to map GNU_RELRO", dso->name);
5009 return -1;
5010 }
5011 *file_offset += size;
5012 return 0;
5013 }
5014
map_gnu_relro(int fd,struct dso * dso,ssize_t * file_offset)5015 static int map_gnu_relro(int fd, struct dso *dso, ssize_t *file_offset)
5016 {
5017 ssize_t ext_fd_file_size = 0;
5018 struct stat ext_fd_file_stat;
5019 if (TEMP_FAILURE_RETRY(fstat(fd, &ext_fd_file_stat)) != 0) {
5020 LD_LOGE("Error mapping relro %{public}s: failed to get file state", dso->name);
5021 return -1;
5022 }
5023 ext_fd_file_size = ext_fd_file_stat.st_size;
5024
5025 void *ext_temp_map = MAP_FAILED;
5026 ext_temp_map = mmap(NULL, ext_fd_file_size, PROT_READ, MAP_PRIVATE, fd, 0);
5027 if (ext_temp_map == MAP_FAILED) {
5028 LD_LOGE("Error mapping relro %{public}s: failed to map fd", dso->name);
5029 return -1;
5030 }
5031
5032 char *file_base = (char *)(ext_temp_map) + *file_offset;
5033 char *mem_base = (char *)(laddr(dso, dso->relro_start));
5034 ssize_t start_offset = 0;
5035 ssize_t size = dso->relro_end - dso->relro_start;
5036
5037 if (size > ext_fd_file_size - *file_offset) {
5038 LD_LOGE("Error mapping relro %{public}s: invalid file size", dso->name);
5039 return -1;
5040 }
5041 while (start_offset < size) {
5042 // Find start location.
5043 while (start_offset < size) {
5044 if (memcmp(mem_base + start_offset, file_base + start_offset, PAGE_SIZE) == 0) {
5045 break;
5046 }
5047 start_offset += PAGE_SIZE;
5048 }
5049
5050 // Find end location.
5051 ssize_t end_offset = start_offset;
5052 while (end_offset < size) {
5053 if (memcmp(mem_base + end_offset, file_base + end_offset, PAGE_SIZE) != 0) {
5054 break;
5055 }
5056 end_offset += PAGE_SIZE;
5057 }
5058
5059 // Map pages.
5060 ssize_t map_length = end_offset - start_offset;
5061 ssize_t map_offset = *file_offset + start_offset;
5062 if (map_length > 0) {
5063 void *map = mmap(
5064 mem_base + start_offset, map_length, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, map_offset);
5065 if (map == MAP_FAILED) {
5066 LD_LOGE("Error mapping relro %{public}s: failed to map GNU_RELRO", dso->name);
5067 munmap(ext_temp_map, ext_fd_file_size);
5068 return -1;
5069 }
5070 }
5071
5072 start_offset = end_offset;
5073 }
5074 *file_offset += size;
5075 munmap(ext_temp_map, ext_fd_file_size);
5076 return 0;
5077 }
5078
handle_relro_sharing(struct dso * p,const dl_extinfo * extinfo,ssize_t * relro_fd_offset)5079 static void handle_relro_sharing(struct dso *p, const dl_extinfo *extinfo, ssize_t *relro_fd_offset)
5080 {
5081 if (extinfo == NULL) {
5082 return;
5083 }
5084 if (extinfo->flag & DL_EXT_WRITE_RELRO) {
5085 LD_LOGD("Serializing GNU_RELRO %{public}s", p->name);
5086 if (serialize_gnu_relro(extinfo->relro_fd, p, relro_fd_offset) < 0) {
5087 LD_LOGE("Error serializing GNU_RELRO %{public}s", p->name);
5088 error("Error serializing GNU_RELRO");
5089 if (runtime) longjmp(*rtld_fail, 1);
5090 }
5091 } else if (extinfo->flag & DL_EXT_USE_RELRO) {
5092 LD_LOGD("Mapping GNU_RELRO %{public}s", p->name);
5093 if (map_gnu_relro(extinfo->relro_fd, p, relro_fd_offset) < 0) {
5094 LD_LOGE("Error mapping GNU_RELRO %{public}s", p->name);
5095 error("Error mapping GNU_RELRO");
5096 if (runtime) longjmp(*rtld_fail, 1);
5097 }
5098 }
5099 }