• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 			if (!is_dlclose_debug_enable()) {
1233 				munmap((void *)dso->loadmap->segs[i].addr,
1234 					dso->loadmap->segs[i].p_memsz);
1235 			} else {
1236 				(void)mprotect((void *)dso->loadmap->segs[i].addr,
1237 					dso->loadmap->segs[i].p_memsz, PROT_NONE);
1238 			}
1239 		}
1240 		internal_free(dso->loadmap);
1241 	} else if (dso->map && dso->map_len) {
1242 		if (!is_dlclose_debug_enable()) {
1243 			munmap(dso->map, dso->map_len);
1244 		} else {
1245 			mprotect(dso->map, dso->map_len, PROT_NONE);
1246 		}
1247 	}
1248 }
1249 
get_random(void * buf,size_t buflen)1250 static bool get_random(void *buf, size_t buflen)
1251 {
1252 	int ret;
1253 	int fd = open("/dev/urandom", O_RDONLY);
1254 	if (fd < 0) {
1255 		return false;
1256 	}
1257 
1258 	ret = read(fd, buf, buflen);
1259 	if (ret < 0) {
1260 		close(fd);
1261 		return false;
1262 	}
1263 
1264 	close(fd);
1265 	return true;
1266 }
1267 
fill_random_data(void * buf,size_t buflen)1268 static void fill_random_data(void *buf, size_t buflen)
1269 {
1270 	uint64_t x;
1271 	int i;
1272 	int pos = 0;
1273 	struct timespec ts;
1274 	/* Try to use urandom to get the random number first */
1275 	if (!get_random(buf, buflen)) {
1276 		/* Can't get random number from /dev/urandom, generate from addr based on ASLR and time */
1277 		for (i = 1; i <= (buflen / sizeof(x)); i++) {
1278 			(void)clock_gettime(CLOCK_REALTIME, &ts);
1279 			x = (((uint64_t)get_random) << 32) ^ (uint64_t)fill_random_data ^ ts.tv_nsec;
1280 			memcpy((char *)buf + pos, &x, sizeof(x));
1281 			pos += sizeof(x);
1282 		}
1283 	}
1284 	return;
1285 }
1286 
map_library(int fd,struct dso * dso,struct reserved_address_params * reserved_params)1287 static void *map_library(int fd, struct dso *dso, struct reserved_address_params *reserved_params)
1288 {
1289 	Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
1290 	void *allocated_buf=0;
1291 	size_t phsize;
1292 	size_t addr_min=SIZE_MAX, addr_max=0, map_len;
1293 	size_t this_min, this_max;
1294 	size_t nsegs = 0;
1295 	off_t off_start;
1296 	Ehdr *eh;
1297 	Phdr *ph, *ph0;
1298 	unsigned prot;
1299 	unsigned char *map=MAP_FAILED, *base;
1300 	size_t dyn=0;
1301 	size_t tls_image=0;
1302 	size_t i;
1303 	int map_flags = MAP_PRIVATE;
1304 	size_t start_addr;
1305 
1306 	ssize_t l = read(fd, buf, sizeof buf);
1307 	eh = buf;
1308 	if (l<0) return 0;
1309 	if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
1310 		goto noexec;
1311 	phsize = eh->e_phentsize * eh->e_phnum;
1312 	if (phsize > sizeof buf - sizeof *eh) {
1313 		allocated_buf = internal_malloc(phsize);
1314 		if (!allocated_buf) return 0;
1315 		l = pread(fd, allocated_buf, phsize, eh->e_phoff);
1316 		if (l < 0) goto error;
1317 		if (l != phsize) goto noexec;
1318 		ph = ph0 = allocated_buf;
1319 	} else if (eh->e_phoff + phsize > l) {
1320 		l = pread(fd, buf+1, phsize, eh->e_phoff);
1321 		if (l < 0) goto error;
1322 		if (l != phsize) goto noexec;
1323 		ph = ph0 = (void *)(buf + 1);
1324 	} else {
1325 		ph = ph0 = (void *)((char *)buf + eh->e_phoff);
1326 	}
1327 	for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
1328 		if (ph->p_type == PT_DYNAMIC) {
1329 			dyn = ph->p_vaddr;
1330 		} else if (ph->p_type == PT_TLS) {
1331 			tls_image = ph->p_vaddr;
1332 			dso->tls.align = ph->p_align;
1333 			dso->tls.len = ph->p_filesz;
1334 			dso->tls.size = ph->p_memsz;
1335 		} else if (ph->p_type == PT_GNU_RELRO) {
1336 			dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
1337 			dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
1338 		} else if (ph->p_type == PT_GNU_STACK) {
1339 			if (!runtime && ph->p_memsz > __default_stacksize) {
1340 				__default_stacksize =
1341 					ph->p_memsz < DEFAULT_STACK_MAX ?
1342 					ph->p_memsz : DEFAULT_STACK_MAX;
1343 			}
1344 		}
1345 		if (ph->p_type != PT_LOAD) continue;
1346 		nsegs++;
1347 		if (ph->p_vaddr < addr_min) {
1348 			addr_min = ph->p_vaddr;
1349 			off_start = ph->p_offset;
1350 			prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1351 				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1352 				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1353 		}
1354 		if (ph->p_vaddr+ph->p_memsz > addr_max) {
1355 			addr_max = ph->p_vaddr+ph->p_memsz;
1356 		}
1357 	}
1358 	if (!dyn) goto noexec;
1359 	if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
1360 		dso->loadmap = internal_calloc(1, sizeof *dso->loadmap
1361 			+ nsegs * sizeof *dso->loadmap->segs);
1362 		if (!dso->loadmap) goto error;
1363 		dso->loadmap->nsegs = nsegs;
1364 		for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {
1365 			if (ph->p_type != PT_LOAD) continue;
1366 			prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1367 				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1368 				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1369 			map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
1370 				prot, MAP_PRIVATE,
1371 				fd, ph->p_offset & -PAGE_SIZE);
1372 			if (map == MAP_FAILED) {
1373 				unmap_library(dso);
1374 				goto error;
1375 			}
1376 			dso->loadmap->segs[i].addr = (size_t)map +
1377 				(ph->p_vaddr & PAGE_SIZE-1);
1378 			dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
1379 			dso->loadmap->segs[i].p_memsz = ph->p_memsz;
1380 			i++;
1381 			if (prot & PROT_WRITE) {
1382 				size_t brk = (ph->p_vaddr & PAGE_SIZE-1)
1383 					+ ph->p_filesz;
1384 				size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;
1385 				size_t pgend = brk + ph->p_memsz - ph->p_filesz
1386 					+ PAGE_SIZE-1 & -PAGE_SIZE;
1387 				if (pgend > pgbrk && mmap_fixed(map+pgbrk,
1388 					pgend-pgbrk, prot,
1389 					MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
1390 					-1, off_start) == MAP_FAILED)
1391 					goto error;
1392 				memset(map + brk, 0, pgbrk-brk);
1393 			}
1394 		}
1395 		map = (void *)dso->loadmap->segs[0].addr;
1396 		map_len = 0;
1397 		goto done_mapping;
1398 	}
1399 	addr_max += PAGE_SIZE-1;
1400 	addr_max &= -PAGE_SIZE;
1401 	addr_min &= -PAGE_SIZE;
1402 	off_start &= -PAGE_SIZE;
1403 	map_len = addr_max - addr_min + off_start;
1404 	start_addr = addr_min;
1405 	if (reserved_params) {
1406 		if (map_len > reserved_params->reserved_size) {
1407 			if (reserved_params->must_use_reserved) {
1408 				goto error;
1409 			}
1410 		} else {
1411 			start_addr = ((size_t)reserved_params->start_addr - 1 + PAGE_SIZE) & -PAGE_SIZE;
1412 			map_flags |= MAP_FIXED;
1413 		}
1414 	}
1415 	/* The first time, we map too much, possibly even more than
1416 	 * the length of the file. This is okay because we will not
1417 	 * use the invalid part; we just need to reserve the right
1418 	 * amount of virtual address space to map over later. */
1419 	map = DL_NOMMU_SUPPORT
1420 		? mmap((void *)start_addr, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,
1421 			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
1422 		: mmap((void *)start_addr, map_len, prot,
1423 			map_flags, fd, off_start);
1424 	if (map==MAP_FAILED) goto error;
1425 	if (reserved_params && map_len < reserved_params->reserved_size) {
1426 		reserved_params->reserved_size -= (map_len + (start_addr - (size_t)reserved_params->start_addr));
1427 		reserved_params->start_addr = (void *)((uint8_t *)map + map_len);
1428 	}
1429 	dso->map = map;
1430 	dso->map_len = map_len;
1431 	/* If the loaded file is not relocatable and the requested address is
1432 	 * not available, then the load operation must fail. */
1433 	if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {
1434 		errno = EBUSY;
1435 		goto error;
1436 	}
1437 	base = map - addr_min;
1438 	dso->phdr = 0;
1439 	dso->phnum = 0;
1440 	for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
1441 		if (ph->p_type == PT_OHOS_RANDOMDATA) {
1442 			fill_random_data((void *)(ph->p_vaddr + base), ph->p_memsz);
1443 			continue;
1444 		}
1445 		if (ph->p_type != PT_LOAD) continue;
1446 		/* Check if the programs headers are in this load segment, and
1447 		 * if so, record the address for use by dl_iterate_phdr. */
1448 		if (!dso->phdr && eh->e_phoff >= ph->p_offset
1449 			&& eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {
1450 			dso->phdr = (void *)(base + ph->p_vaddr
1451 				+ (eh->e_phoff-ph->p_offset));
1452 			dso->phnum = eh->e_phnum;
1453 			dso->phentsize = eh->e_phentsize;
1454 		}
1455 		this_min = ph->p_vaddr & -PAGE_SIZE;
1456 		this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
1457 		off_start = ph->p_offset & -PAGE_SIZE;
1458 		prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
1459 			((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
1460 			((ph->p_flags&PF_X) ? PROT_EXEC : 0));
1461 		/* Reuse the existing mapping for the lowest-address LOAD */
1462 		if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT)
1463 			if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
1464 				goto error;
1465 		if (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) {
1466 			size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
1467 			size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
1468 			memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
1469 			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)
1470 				goto error;
1471 		}
1472 	}
1473 	for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
1474 		if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
1475 			if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
1476 				&& errno != ENOSYS)
1477 				goto error;
1478 			break;
1479 		}
1480 done_mapping:
1481 	dso->base = base;
1482 	dso->dynv = laddr(dso, dyn);
1483 	if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);
1484 	internal_free(allocated_buf);
1485 	return map;
1486 noexec:
1487 	errno = ENOEXEC;
1488 error:
1489 	if (map!=MAP_FAILED) unmap_library(dso);
1490 	internal_free(allocated_buf);
1491 	return 0;
1492 }
1493 
path_open(const char * name,const char * s,char * buf,size_t buf_size)1494 static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
1495 {
1496 	size_t l;
1497 	int fd;
1498 	for (;;) {
1499 		s += strspn(s, ":\n");
1500 		l = strcspn(s, ":\n");
1501 		if (l-1 >= INT_MAX) return -1;
1502 		if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
1503 			if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
1504 			switch (errno) {
1505 			case ENOENT:
1506 			case ENOTDIR:
1507 			case EACCES:
1508 			case ENAMETOOLONG:
1509 				break;
1510 			default:
1511 				/* Any negative value but -1 will inhibit
1512 				 * futher path search. */
1513 				return -2;
1514 			}
1515 		}
1516 		s += l;
1517 	}
1518 }
1519 
fixup_rpath(struct dso * p,char * buf,size_t buf_size)1520 static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
1521 {
1522 	size_t n, l;
1523 	const char *s, *t, *origin;
1524 	char *d;
1525 	if (p->rpath || !p->rpath_orig) return 0;
1526 	if (!strchr(p->rpath_orig, '$')) {
1527 		p->rpath = p->rpath_orig;
1528 		return 0;
1529 	}
1530 	n = 0;
1531 	s = p->rpath_orig;
1532 	while ((t=strchr(s, '$'))) {
1533 		if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
1534 			return 0;
1535 		s = t+1;
1536 		n++;
1537 	}
1538 	if (n > SSIZE_MAX/PATH_MAX) return 0;
1539 
1540 	if (p->kernel_mapped) {
1541 		/* $ORIGIN searches cannot be performed for the main program
1542 		 * when it is suid/sgid/AT_SECURE. This is because the
1543 		 * pathname is under the control of the caller of execve.
1544 		 * For libraries, however, $ORIGIN can be processed safely
1545 		 * since the library's pathname came from a trusted source
1546 		 * (either system paths or a call to dlopen). */
1547 		if (libc.secure)
1548 			return 0;
1549 		l = readlink("/proc/self/exe", buf, buf_size);
1550 		if (l == -1) switch (errno) {
1551 		case ENOENT:
1552 		case ENOTDIR:
1553 		case EACCES:
1554 			break;
1555 		default:
1556 			return -1;
1557 		}
1558 		if (l >= buf_size)
1559 			return 0;
1560 		buf[l] = 0;
1561 		origin = buf;
1562 	} else {
1563 		origin = p->name;
1564 	}
1565 	t = strrchr(origin, '/');
1566 	if (t) {
1567 		l = t-origin;
1568 	} else {
1569 		/* Normally p->name will always be an absolute or relative
1570 		 * pathname containing at least one '/' character, but in the
1571 		 * case where ldso was invoked as a command to execute a
1572 		 * program in the working directory, app.name may not. Fix. */
1573 		origin = ".";
1574 		l = 1;
1575 	}
1576 	/* Disallow non-absolute origins for suid/sgid/AT_SECURE. */
1577 	if (libc.secure && *origin != '/')
1578 		return 0;
1579 	p->rpath = internal_malloc(strlen(p->rpath_orig) + n*l + 1);
1580 	if (!p->rpath) return -1;
1581 
1582 	d = p->rpath;
1583 	s = p->rpath_orig;
1584 	while ((t=strchr(s, '$'))) {
1585 		memcpy(d, s, t-s);
1586 		d += t-s;
1587 		memcpy(d, origin, l);
1588 		d += l;
1589 		/* It was determined previously that the '$' is followed
1590 		 * either by "ORIGIN" or "{ORIGIN}". */
1591 		s = t + 7 + 2*(t[1]=='{');
1592 	}
1593 	strcpy(d, s);
1594 	return 0;
1595 }
1596 
decode_dyn(struct dso * p)1597 static void decode_dyn(struct dso *p)
1598 {
1599 	size_t dyn[DYN_CNT];
1600 	decode_vec(p->dynv, dyn, DYN_CNT);
1601 	p->syms = laddr(p, dyn[DT_SYMTAB]);
1602 	p->strings = laddr(p, dyn[DT_STRTAB]);
1603 	if (dyn[0]&(1<<DT_HASH))
1604 		p->hashtab = laddr(p, dyn[DT_HASH]);
1605 	if (dyn[0]&(1<<DT_RPATH))
1606 		p->rpath_orig = p->strings + dyn[DT_RPATH];
1607 	if (dyn[0]&(1<<DT_RUNPATH))
1608 		p->rpath_orig = p->strings + dyn[DT_RUNPATH];
1609 	if (dyn[0]&(1<<DT_PLTGOT))
1610 		p->got = laddr(p, dyn[DT_PLTGOT]);
1611 	if (search_vec(p->dynv, dyn, DT_GNU_HASH))
1612 		p->ghashtab = laddr(p, *dyn);
1613 	if (search_vec(p->dynv, dyn, DT_VERSYM))
1614 		p->versym = laddr(p, *dyn);
1615 	if (search_vec(p->dynv, dyn, DT_VERDEF))
1616 		p->verdef = laddr(p, *dyn);
1617 	if (search_vec(p->dynv, dyn, DT_VERNEED))
1618 		p->verneed = laddr(p, *dyn);
1619 }
1620 
count_syms(struct dso * p)1621 static size_t count_syms(struct dso *p)
1622 {
1623 	if (p->hashtab) return p->hashtab[1];
1624 
1625 	size_t nsym, i;
1626 	uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
1627 	uint32_t *hashval;
1628 	for (i = nsym = 0; i < p->ghashtab[0]; i++) {
1629 		if (buckets[i] > nsym)
1630 			nsym = buckets[i];
1631 	}
1632 	if (nsym) {
1633 		hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);
1634 		do nsym++;
1635 		while (!(*hashval++ & 1));
1636 	}
1637 	return nsym;
1638 }
1639 
dl_mmap(size_t n)1640 static void *dl_mmap(size_t n)
1641 {
1642 	void *p;
1643 	int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;
1644 #ifdef SYS_mmap2
1645 	p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);
1646 #else
1647 	p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);
1648 #endif
1649 	return (unsigned long)p > -4096UL ? 0 : p;
1650 }
1651 
makefuncdescs(struct dso * p)1652 static void makefuncdescs(struct dso *p)
1653 {
1654 	static int self_done;
1655 	size_t nsym = count_syms(p);
1656 	size_t i, size = nsym * sizeof(*p->funcdescs);
1657 
1658 	if (!self_done) {
1659 		p->funcdescs = dl_mmap(size);
1660 		self_done = 1;
1661 	} else {
1662 		p->funcdescs = internal_malloc(size);
1663 	}
1664 	if (!p->funcdescs) {
1665 		if (!runtime) a_crash();
1666 		error("Error allocating function descriptors for %s", p->name);
1667 		longjmp(*rtld_fail, 1);
1668 	}
1669 	for (i=0; i<nsym; i++) {
1670 		if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {
1671 			p->funcdescs[i].addr = laddr(p, p->syms[i].st_value);
1672 			p->funcdescs[i].got = p->got;
1673 		} else {
1674 			p->funcdescs[i].addr = 0;
1675 			p->funcdescs[i].got = 0;
1676 		}
1677 	}
1678 }
1679 
get_sys_path(ns_configor * conf)1680 static void get_sys_path(ns_configor *conf)
1681 {
1682 	LD_LOGD("get_sys_path g_is_asan:%{public}d", g_is_asan);
1683 	/* Use ini file's system paths when Asan is not enabled */
1684 	if (!g_is_asan) {
1685 		sys_path = conf->get_sys_paths();
1686 	} else {
1687 		/* Use ini file's asan system paths when the Asan is enabled
1688 		 * Merge two strings when both sys_paths and asan_sys_paths are valid */
1689 		sys_path = conf->get_asan_sys_paths();
1690 		char *sys_path_default = conf->get_sys_paths();
1691 		if (!sys_path) {
1692 			sys_path = sys_path_default;
1693 		} else if (sys_path_default) {
1694 			size_t newlen = strlen(sys_path) + strlen(sys_path_default) + 2;
1695 			char *new_syspath = internal_malloc(newlen);
1696 			memset(new_syspath, 0, newlen);
1697 			strcpy(new_syspath, sys_path);
1698 			strcat(new_syspath, ":");
1699 			strcat(new_syspath, sys_path_default);
1700 			sys_path = new_syspath;
1701 		}
1702 	}
1703 	if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib:/lib64";
1704 	LD_LOGD("get_sys_path sys_path:%{public}s", sys_path);
1705 }
1706 
search_dso_by_name(const char * name,const ns_t * ns)1707 static struct dso *search_dso_by_name(const char *name, const ns_t *ns) {
1708 	LD_LOGD("search_dso_by_name name:%{public}s, ns_name:%{public}s", name, ns ? ns->ns_name: "NULL");
1709 	for (size_t i = 0; i < ns->ns_dsos->num; i++){
1710 		struct dso *p = ns->ns_dsos->dsos[i];
1711 		if (p->shortname && !strcmp(p->shortname, name)) {
1712 			LD_LOGD("search_dso_by_name found name:%{public}s, ns_name:%{public}s", name, ns ? ns->ns_name: "NULL");
1713 			return p;
1714 		}
1715 	}
1716 	return NULL;
1717 }
1718 
search_dso_by_fstat(const struct stat * st,const ns_t * ns,uint64_t file_offset)1719 static struct dso *search_dso_by_fstat(const struct stat *st, const ns_t *ns, uint64_t file_offset) {
1720 	LD_LOGD("search_dso_by_fstat ns_name:%{public}s", ns ? ns->ns_name : "NULL");
1721 	for (size_t i = 0; i < ns->ns_dsos->num; i++){
1722 		struct dso *p = ns->ns_dsos->dsos[i];
1723 		if (p->dev == st->st_dev && p->ino == st->st_ino && p->file_offset == file_offset) {
1724 			LD_LOGD("search_dso_by_fstat found dev:%{public}lu, ino:%{public}lu, ns_name:%{public}s",
1725 				st->st_dev, st->st_ino, ns ? ns->ns_name : "NULL");
1726 			return p;
1727 		}
1728 	}
1729 	return NULL;
1730 }
1731 /* Find loaded so by name */
find_library_by_name(const char * name,const ns_t * ns,bool check_inherited)1732 static struct dso *find_library_by_name(const char *name, const ns_t *ns, bool check_inherited)
1733 {
1734 	LD_LOGD("find_library_by_name name:%{public}s, ns_name:%{public}s, check_inherited:%{public}d",
1735 		name,
1736 		ns ? ns->ns_name : "NULL",
1737 		!!check_inherited);
1738 	struct dso *p = search_dso_by_name(name, ns);
1739 	if (p) return p;
1740 	if (check_inherited && ns->ns_inherits) {
1741 		for (size_t i = 0; i < ns->ns_inherits->num; i++){
1742 			ns_inherit * inherit = ns->ns_inherits->inherits[i];
1743 			p = search_dso_by_name(name, inherit->inherited_ns);
1744 			if (p && is_sharable(inherit, name)) return p;
1745 		}
1746 	}
1747 	return NULL;
1748 }
1749 /* 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)1750 static struct dso *find_library_by_fstat(const struct stat *st, const ns_t *ns, bool check_inherited, uint64_t file_offset) {
1751 	LD_LOGD("find_library_by_fstat ns_name:%{public}s, check_inherited :%{public}d",
1752 		ns ? ns->ns_name : "NULL",
1753 		!!check_inherited);
1754 	struct dso *p = search_dso_by_fstat(st, ns, file_offset);
1755 	if (p) return p;
1756 	if (check_inherited && ns->ns_inherits) {
1757 		for (size_t i = 0; i < ns->ns_inherits->num; i++){
1758 			ns_inherit *inherit = ns->ns_inherits->inherits[i];
1759 			p = search_dso_by_fstat(st, inherit->inherited_ns, file_offset);
1760 			if (p && is_sharable(inherit, p->shortname)) return p;
1761 		}
1762 	}
1763 	return NULL;
1764 }
1765 
1766 #ifndef LOAD_ORDER_RANDOMIZATION
1767 /* add namespace function */
load_library(const char * name,struct dso * needed_by,ns_t * namespace,bool check_inherited,struct reserved_address_params * reserved_params)1768 struct dso *load_library(
1769 	const char *name, struct dso *needed_by, ns_t *namespace, bool check_inherited, struct reserved_address_params *reserved_params)
1770 {
1771 	char buf[PATH_MAX+1];
1772 	const char *pathname;
1773 	unsigned char *map;
1774 	struct dso *p, temp_dso = {0};
1775 	int fd;
1776 	struct stat st;
1777 	size_t alloc_size;
1778 	int n_th = 0;
1779 	int is_self = 0;
1780 
1781 	if (!*name) {
1782 		errno = EINVAL;
1783 		return 0;
1784 	}
1785 
1786 	/* Catch and block attempts to reload the implementation itself */
1787 	if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
1788 		static const char reserved[] =
1789 			"c.pthread.rt.m.dl.util.xnet.";
1790 		const char *rp, *next;
1791 		for (rp=reserved; *rp; rp=next) {
1792 			next = strchr(rp, '.') + 1;
1793 			if (strncmp(name+3, rp, next-rp) == 0)
1794 				break;
1795 		}
1796 		if (*rp) {
1797 			if (ldd_mode) {
1798 				/* Track which names have been resolved
1799 				 * and only report each one once. */
1800 				static unsigned reported;
1801 				unsigned mask = 1U<<(rp-reserved);
1802 				if (!(reported & mask)) {
1803 					reported |= mask;
1804 					dprintf(1, "\t%s => %s (%p)\n",
1805 						name, ldso.name,
1806 						ldso.base);
1807 				}
1808 			}
1809 			is_self = 1;
1810 		}
1811 	}
1812 	if (!strcmp(name, ldso.name)) is_self = 1;
1813 	if (is_self) {
1814 		if (!ldso.prev) {
1815 			tail->next = &ldso;
1816 			ldso.prev = tail;
1817 			tail = &ldso;
1818 			ldso.namespace = namespace;
1819 			ns_add_dso(namespace, &ldso);
1820 		}
1821 		return &ldso;
1822 	}
1823 	if (strchr(name, '/')) {
1824 		pathname = name;
1825 
1826 		if (!is_accessible(namespace, pathname, g_is_asan, check_inherited)) {
1827 			fd = -1;
1828 			LD_LOGD("load_library is_accessible return false,fd = -1");
1829 		} else {
1830 			fd = open(name, O_RDONLY|O_CLOEXEC);
1831 			LD_LOGD("load_library is_accessible return true, open file fd:%{public}d .", fd);
1832 		}
1833 	} else {
1834 		/* Search for the name to see if it's already loaded */
1835 		/* Search in namespace */
1836 		p = find_library_by_name(name, namespace, check_inherited);
1837 		if (p) {
1838 			LD_LOGD("load_library find_library_by_name found p, return it!");
1839 			return p;
1840 		}
1841 		if (strlen(name) > NAME_MAX) {
1842 			LD_LOGE("load_library name exceeding the maximum length, return 0!");
1843 			return 0;
1844 		}
1845 		fd = -1;
1846 		if (namespace->env_paths) fd = path_open(name, namespace->env_paths, buf, sizeof buf);
1847 		for (p = needed_by; fd == -1 && p; p = p->needed_by) {
1848 			if (fixup_rpath(p, buf, sizeof buf) < 0) {
1849 				LD_LOGD("load_library Inhibit further search,fd = -2.");
1850 				fd = -2; /* Inhibit further search. */
1851 			}
1852 			if (p->rpath) {
1853 				fd = path_open(name, p->rpath, buf, sizeof buf);
1854 				LD_LOGD("load_library  p->rpath path_open fd:%{public}d.", fd);
1855 			}
1856 
1857 		}
1858 		if (g_is_asan) {
1859 			fd = handle_asan_path_open(fd, name, namespace, buf, sizeof buf);
1860 			LD_LOGD("load_library handle_asan_path_open fd:%{public}d.", fd);
1861 		} else {
1862 			if (fd == -1 && namespace->lib_paths) {
1863 				fd = path_open(name, namespace->lib_paths, buf, sizeof buf);
1864 				LD_LOGD("load_library no asan lib_paths path_open fd:%{public}d.", fd);
1865 			}
1866 		}
1867 		pathname = buf;
1868 		LD_LOGD("load_library lib_paths pathname:%{public}s.", pathname);
1869 	}
1870 	if (fd < 0) {
1871 		if (!check_inherited || !namespace->ns_inherits) return 0;
1872 		/* Load lib in inherited namespace. Do not check inherited again.*/
1873 		for (size_t i = 0; i < namespace->ns_inherits->num; i++) {
1874 			ns_inherit *inherit = namespace->ns_inherits->inherits[i];
1875 			if (strchr(name, '/')==0 && !is_sharable(inherit, name)) continue;
1876 			p = load_library(name, needed_by, inherit->inherited_ns, false, reserved_params);
1877 			if (p) {
1878 				LD_LOGD("load_library search in inherited, found p ,inherited_ns name:%{public}s",
1879 						inherit->inherited_ns->ns_name);
1880 				return p;
1881 			}
1882 		}
1883 		return 0;
1884 	}
1885 	if (fstat(fd, &st) < 0) {
1886 		close(fd);
1887 		LD_LOGE("load_library fstat < 0,return 0!");
1888 		return 0;
1889 	}
1890 	/* Search in namespace */
1891 	p = find_library_by_fstat(&st, namespace, check_inherited, 0);
1892 	if (p) {
1893 		/* If this library was previously loaded with a
1894 		* pathname but a search found the same inode,
1895 		* setup its shortname so it can be found by name. */
1896 		if (!p->shortname && pathname != name)
1897 			p->shortname = strrchr(p->name, '/')+1;
1898 		close(fd);
1899 		LD_LOGD("load_library find_library_by_fstat, found p and return it!");
1900 		return p;
1901 	}
1902 	map = noload ? 0 : map_library(fd, &temp_dso, reserved_params);
1903 	close(fd);
1904 	if (!map) return 0;
1905 
1906 	/* Avoid the danger of getting two versions of libc mapped into the
1907 	 * same process when an absolute pathname was used. The symbols
1908 	 * checked are chosen to catch both musl and glibc, and to avoid
1909 	 * false positives from interposition-hack libraries. */
1910 	decode_dyn(&temp_dso);
1911 	if (find_sym(&temp_dso, "__libc_start_main", 1).sym &&
1912 		find_sym(&temp_dso, "stdin", 1).sym) {
1913 		unmap_library(&temp_dso);
1914 		return load_library("libc.so", needed_by, namespace, true, reserved_params);
1915 	}
1916 	/* Past this point, if we haven't reached runtime yet, ldso has
1917 	 * committed either to use the mapped library or to abort execution.
1918 	 * Unmapping is not possible, so we can safely reclaim gaps. */
1919 	if (!runtime) reclaim_gaps(&temp_dso);
1920 
1921 	/* Allocate storage for the new DSO. When there is TLS, this
1922 	 * storage must include a reservation for all pre-existing
1923 	 * threads to obtain copies of both the new TLS, and an
1924 	 * extended DTV capable of storing an additional slot for
1925 	 * the newly-loaded DSO. */
1926 	alloc_size = sizeof *p + strlen(pathname) + 1;
1927 	if (runtime && temp_dso.tls.image) {
1928 		size_t per_th = temp_dso.tls.size + temp_dso.tls.align
1929 			+ sizeof(void *) * (tls_cnt+3);
1930 		n_th = libc.threads_minus_1 + 1;
1931 		if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
1932 		else alloc_size += n_th * per_th;
1933 	}
1934 	p = internal_calloc(1, alloc_size);
1935 	if (!p) {
1936 		unmap_library(&temp_dso);
1937 		return 0;
1938 	}
1939 	memcpy(p, &temp_dso, sizeof temp_dso);
1940 	p->dev = st.st_dev;
1941 	p->ino = st.st_ino;
1942 	p->needed_by = needed_by;
1943 	p->name = p->buf;
1944 	p->runtime_loaded = runtime;
1945 	strcpy(p->name, pathname);
1946 	/* Add a shortname only if name arg was not an explicit pathname. */
1947 	if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
1948 	if (p->tls.image) {
1949 		p->tls_id = ++tls_cnt;
1950 		tls_align = MAXP2(tls_align, p->tls.align);
1951 #ifdef TLS_ABOVE_TP
1952 		p->tls.offset = tls_offset + ( (p->tls.align-1) &
1953 			(-tls_offset + (uintptr_t)p->tls.image) );
1954 		tls_offset = p->tls.offset + p->tls.size;
1955 #else
1956 		tls_offset += p->tls.size + p->tls.align - 1;
1957 		tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
1958 			& (p->tls.align-1);
1959 		p->tls.offset = tls_offset;
1960 #endif
1961 		p->new_dtv = (void *)(-sizeof(size_t) &
1962 			(uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
1963 		p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
1964 		if (tls_tail) tls_tail->next = &p->tls;
1965 		else libc.tls_head = &p->tls;
1966 		tls_tail = &p->tls;
1967 	}
1968 
1969 	tail->next = p;
1970 	p->prev = tail;
1971 	tail = p;
1972 
1973 	/* Add dso to namespace */
1974 	p->namespace = namespace;
1975 	ns_add_dso(namespace, p);
1976 	if (runtime)
1977 		p->by_dlopen = 1;
1978 
1979 	if (DL_FDPIC) makefuncdescs(p);
1980 
1981 	if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
1982 
1983 	return p;
1984 }
1985 
load_direct_deps(struct dso * p,ns_t * namespace,struct reserved_address_params * reserved_params)1986 static void load_direct_deps(struct dso *p, ns_t *namespace, struct reserved_address_params *reserved_params)
1987 {
1988 	size_t i, cnt=0;
1989 
1990 	if (p->deps) return;
1991 	/* For head, all preloads are direct pseudo-dependencies.
1992 	 * Count and include them now to avoid realloc later. */
1993 	if (p==head) for (struct dso *q=p->next; q; q=q->next)
1994 		cnt++;
1995 	for (i=0; p->dynv[i]; i+=2)
1996 		if (p->dynv[i] == DT_NEEDED) cnt++;
1997 	/* Use builtin buffer for apps with no external deps, to
1998 	 * preserve property of no runtime failure paths. */
1999 	p->deps = (p==head && cnt<2) ? builtin_deps :
2000 		internal_calloc(cnt+1, sizeof *p->deps);
2001 	if (!p->deps) {
2002 		error("Error loading dependencies for %s", p->name);
2003 		if (runtime) longjmp(*rtld_fail, 1);
2004 	}
2005 	cnt=0;
2006 	if (p==head) for (struct dso *q=p->next; q; q=q->next)
2007 		p->deps[cnt++] = q;
2008 	for (i=0; p->dynv[i]; i+=2) {
2009 		if (p->dynv[i] != DT_NEEDED) continue;
2010 		struct dso *dep = load_library(p->strings + p->dynv[i+1], p, namespace, true, reserved_params);
2011 		LD_LOGD("loading shared library %{public}s: (needed by %{public}s)", p->strings + p->dynv[i+1], p->name);
2012 		if (!dep) {
2013 			error("Error loading shared library %s: %m (needed by %s)",
2014 				p->strings + p->dynv[i+1], p->name);
2015 			if (runtime) longjmp(*rtld_fail, 1);
2016 			continue;
2017 		}
2018 		p->deps[cnt++] = dep;
2019 	}
2020 	p->deps[cnt] = 0;
2021 	p->ndeps_direct = cnt;
2022 	for (i = 0; i < p->ndeps_direct; i++) {
2023 		add_dso_parent(p->deps[i], p);
2024 	}
2025 }
2026 
load_deps(struct dso * p,struct reserved_address_params * reserved_params)2027 static void load_deps(struct dso *p, struct reserved_address_params *reserved_params)
2028 {
2029 	if (p->deps) return;
2030 	for (; p; p=p->next)
2031 		load_direct_deps(p, p->namespace, reserved_params);
2032 }
2033 #endif
2034 
extend_bfs_deps(struct dso * p)2035 static void extend_bfs_deps(struct dso *p)
2036 {
2037 	size_t i, j, cnt, ndeps_all;
2038 	struct dso **tmp;
2039 
2040 	/* Can't use realloc if the original p->deps was allocated at
2041 	 * program entry and malloc has been replaced, or if it's
2042 	 * the builtin non-allocated trivial main program deps array. */
2043 	int no_realloc = (__malloc_replaced && !p->runtime_loaded)
2044 		|| p->deps == builtin_deps;
2045 
2046 	if (p->bfs_built) return;
2047 	ndeps_all = p->ndeps_direct;
2048 
2049 	/* Mark existing (direct) deps so they won't be duplicated. */
2050 	for (i=0; p->deps[i]; i++)
2051 		p->deps[i]->mark = 1;
2052 
2053 	/* For each dependency already in the list, copy its list of direct
2054 	 * dependencies to the list, excluding any items already in the
2055 	 * list. Note that the list this loop iterates over will grow during
2056 	 * the loop, but since duplicates are excluded, growth is bounded. */
2057 	for (i=0; p->deps[i]; i++) {
2058 		struct dso *dep = p->deps[i];
2059 		for (j=cnt=0; j<dep->ndeps_direct; j++)
2060 			if (!dep->deps[j]->mark) cnt++;
2061 		tmp = no_realloc ?
2062 			internal_malloc(sizeof(*tmp) * (ndeps_all+cnt+1)) :
2063 			internal_realloc(p->deps, sizeof(*tmp) * (ndeps_all+cnt+1));
2064 		if (!tmp) {
2065 			error("Error recording dependencies for %s", p->name);
2066 			if (runtime) longjmp(*rtld_fail, 1);
2067 			continue;
2068 		}
2069 		if (no_realloc) {
2070 			memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1));
2071 			no_realloc = 0;
2072 		}
2073 		p->deps = tmp;
2074 		for (j=0; j<dep->ndeps_direct; j++) {
2075 			if (dep->deps[j]->mark) continue;
2076 			dep->deps[j]->mark = 1;
2077 			p->deps[ndeps_all++] = dep->deps[j];
2078 		}
2079 		p->deps[ndeps_all] = 0;
2080 	}
2081 	p->bfs_built = 1;
2082 	for (p=head; p; p=p->next)
2083 		p->mark = 0;
2084 }
2085 
2086 #ifndef LOAD_ORDER_RANDOMIZATION
load_preload(char * s,ns_t * ns)2087 static void load_preload(char *s, ns_t *ns)
2088 {
2089 	int tmp;
2090 	char *z;
2091 	for (z=s; *z; s=z) {
2092 		for (   ; *s && (isspace(*s) || *s==':'); s++);
2093 		for (z=s; *z && !isspace(*z) && *z!=':'; z++);
2094 		tmp = *z;
2095 		*z = 0;
2096 		load_library(s, 0, ns, true, NULL);
2097 		*z = tmp;
2098 	}
2099 }
2100 #endif
2101 
add_syms(struct dso * p)2102 static void add_syms(struct dso *p)
2103 {
2104 	if (!p->syms_next && syms_tail != p) {
2105 		syms_tail->syms_next = p;
2106 		syms_tail = p;
2107 	}
2108 }
2109 
revert_syms(struct dso * old_tail)2110 static void revert_syms(struct dso *old_tail)
2111 {
2112 	struct dso *p, *next;
2113 	/* Chop off the tail of the list of dsos that participate in
2114 	 * the global symbol table, reverting them to RTLD_LOCAL. */
2115 	for (p=old_tail; p; p=next) {
2116 		next = p->syms_next;
2117 		p->syms_next = 0;
2118 	}
2119 	syms_tail = old_tail;
2120 }
2121 
do_mips_relocs(struct dso * p,size_t * got)2122 static void do_mips_relocs(struct dso *p, size_t *got)
2123 {
2124 	size_t i, j, rel[2];
2125 	unsigned char *base = p->base;
2126 	i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
2127 	if (p==&ldso) {
2128 		got += i;
2129 	} else {
2130 		while (i--) *got++ += (size_t)base;
2131 	}
2132 	j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
2133 	i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
2134 	Sym *sym = p->syms + j;
2135 	rel[0] = (unsigned char *)got - base;
2136 	for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
2137 		rel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT);
2138 		do_relocs(p, rel, sizeof rel, 2);
2139 	}
2140 }
2141 
sleb128_decoder(uint8_t * current,uint8_t * end,size_t * value)2142 static uint8_t* sleb128_decoder(uint8_t* current, uint8_t* end, size_t* value)
2143 {
2144 	size_t result = 0;
2145 	static const size_t size = CHAR_BIT * sizeof(result);
2146 
2147 	size_t shift = 0;
2148 	uint8_t byte;
2149 
2150 	do {
2151 		if (current >= end) {
2152 			a_crash();
2153 		}
2154 
2155 		byte = *current++;
2156 		result |= ((size_t)(byte & 127) << shift);
2157 		shift += 7;
2158 	} while (byte & 128);
2159 
2160 	if (shift < size && (byte & 64)) {
2161 		result |= -((size_t)(1) << shift);
2162 	}
2163 
2164 	*value = result;
2165 
2166 	return current;
2167 }
2168 
do_android_relocs(struct dso * p,size_t dt_name,size_t dt_size)2169 static void do_android_relocs(struct dso *p, size_t dt_name, size_t dt_size)
2170 {
2171 	size_t android_rel_addr = 0, android_rel_size = 0;
2172 	uint8_t *android_rel_curr, *android_rel_end;
2173 
2174 	search_vec(p->dynv, &android_rel_addr, dt_name);
2175 	search_vec(p->dynv, &android_rel_size, dt_size);
2176 
2177 	if (!android_rel_addr || (android_rel_size < 4)) {
2178 		return;
2179 	}
2180 
2181 	android_rel_curr = laddr(p, android_rel_addr);
2182 	if (memcmp(android_rel_curr, "APS2", ANDROID_REL_SIGN_SIZE)) {
2183 		return;
2184 	}
2185 
2186 	android_rel_curr += ANDROID_REL_SIGN_SIZE;
2187 	android_rel_size -= ANDROID_REL_SIGN_SIZE;
2188 
2189 	android_rel_end = android_rel_curr + android_rel_size;
2190 
2191 	size_t relocs_num;
2192 	size_t rel[3] = {0};
2193 
2194 	android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &relocs_num);
2195 	android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[0]);
2196 
2197 	for (size_t i = 0; i < relocs_num;) {
2198 
2199 		size_t group_size, group_flags;
2200 
2201 		android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_size);
2202 		android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_flags);
2203 
2204 		size_t group_r_offset_delta = 0;
2205 
2206 		if (group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) {
2207 			android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &group_r_offset_delta);
2208 		}
2209 
2210 		if (group_flags & RELOCATION_GROUPED_BY_INFO_FLAG) {
2211 			android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[1]);
2212 		}
2213 
2214 		const size_t addend_flags = group_flags & (RELOCATION_GROUP_HAS_ADDEND_FLAG | RELOCATION_GROUPED_BY_ADDEND_FLAG);
2215 
2216 		if (addend_flags == RELOCATION_GROUP_HAS_ADDEND_FLAG) {
2217 		} else if (addend_flags == (RELOCATION_GROUP_HAS_ADDEND_FLAG | RELOCATION_GROUPED_BY_ADDEND_FLAG)) {
2218 			size_t addend;
2219 			android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &addend);
2220 			rel[2] += addend;
2221 		} else {
2222 			rel[2] = 0;
2223 		}
2224 
2225 		for (size_t j = 0; j < group_size; j++) {
2226 			if (group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) {
2227 				rel[0] += group_r_offset_delta;
2228 			} else {
2229 				size_t offset_detla;
2230 				android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &offset_detla);
2231 
2232 				rel[0] += offset_detla;
2233 			}
2234 
2235 			if ((group_flags & RELOCATION_GROUPED_BY_INFO_FLAG) == 0) {
2236 				android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &rel[1]);
2237 			}
2238 
2239 			if (addend_flags == RELOCATION_GROUP_HAS_ADDEND_FLAG) {
2240 				size_t addend;
2241 				android_rel_curr = sleb128_decoder(android_rel_curr, android_rel_end, &addend);
2242 				rel[2] += addend;
2243 			}
2244 
2245 			if (dt_name == DT_ANDROID_REL) {
2246 				LD_LOGI("do_android_relocs REL %{public}x %{public}x", rel[0], rel[1]);
2247 				do_relocs(p, rel, sizeof(size_t)*2, 2);
2248 			} else {
2249 				LD_LOGI("do_android_relocs RELA %{public}x %{public}x %{public}x", rel[0], rel[1], rel[2]);
2250 				do_relocs(p, rel, sizeof(size_t)*3, 3);
2251 			}
2252 		}
2253 
2254 		i += group_size;
2255 	}
2256 }
2257 
do_relr_relocs(struct dso * dso,size_t * relr,size_t relr_size)2258 static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)
2259 {
2260 	unsigned char *base = dso->base;
2261 	size_t *reloc_addr;
2262 	for (; relr_size; relr++, relr_size-=sizeof(size_t))
2263 		if ((relr[0]&1) == 0) {
2264 			reloc_addr = laddr(dso, relr[0]);
2265 			*reloc_addr++ += (size_t)base;
2266 		} else {
2267 			int i = 0;
2268 			for (size_t bitmap=relr[0]; (bitmap>>=1); i++)
2269 				if (bitmap&1)
2270 					reloc_addr[i] += (size_t)base;
2271 			reloc_addr += 8*sizeof(size_t)-1;
2272 		}
2273 }
2274 
reloc_all(struct dso * p,const dl_extinfo * extinfo)2275 static void reloc_all(struct dso *p, const dl_extinfo *extinfo)
2276 {
2277 	ssize_t relro_fd_offset = 0;
2278 	size_t dyn[DYN_CNT];
2279 	for (; p; p=p->next) {
2280 		if (p->relocated) continue;
2281 		if (p != &ldso) {
2282 			add_can_search_so_list_in_dso(p, head);
2283 		}
2284 		decode_vec(p->dynv, dyn, DYN_CNT);
2285 		if (NEED_MIPS_GOT_RELOCS)
2286 			do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
2287 		do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
2288 			2+(dyn[DT_PLTREL]==DT_RELA));
2289 		do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
2290 		do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
2291 		if (!DL_FDPIC)
2292 			do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
2293 
2294 		do_android_relocs(p, DT_ANDROID_REL, DT_ANDROID_RELSZ);
2295 		do_android_relocs(p, DT_ANDROID_RELA, DT_ANDROID_RELASZ);
2296 
2297 		if (head != &ldso && p->relro_start != p->relro_end &&
2298 			mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)
2299 			&& errno != ENOSYS) {
2300 			error("Error relocating %s: RELRO protection failed: %m",
2301 				p->name);
2302 			if (runtime) longjmp(*rtld_fail, 1);
2303 		}
2304 		/* Handle serializing/mapping the RELRO segment */
2305 		handle_relro_sharing(p, extinfo, &relro_fd_offset);
2306 
2307 		p->relocated = 1;
2308 		free_reloc_can_search_dso(p);
2309 	}
2310 }
2311 
kernel_mapped_dso(struct dso * p)2312 static void kernel_mapped_dso(struct dso *p)
2313 {
2314 	size_t min_addr = -1, max_addr = 0, cnt;
2315 	Phdr *ph = p->phdr;
2316 	for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
2317 		if (ph->p_type == PT_DYNAMIC) {
2318 			p->dynv = laddr(p, ph->p_vaddr);
2319 		} else if (ph->p_type == PT_GNU_RELRO) {
2320 			p->relro_start = ph->p_vaddr & -PAGE_SIZE;
2321 			p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
2322 		} else if (ph->p_type == PT_GNU_STACK) {
2323 			if (!runtime && ph->p_memsz > __default_stacksize) {
2324 				__default_stacksize =
2325 					ph->p_memsz < DEFAULT_STACK_MAX ?
2326 					ph->p_memsz : DEFAULT_STACK_MAX;
2327 			}
2328 		}
2329 		if (ph->p_type != PT_LOAD) continue;
2330 		if (ph->p_vaddr < min_addr)
2331 			min_addr = ph->p_vaddr;
2332 		if (ph->p_vaddr+ph->p_memsz > max_addr)
2333 			max_addr = ph->p_vaddr+ph->p_memsz;
2334 	}
2335 	min_addr &= -PAGE_SIZE;
2336 	max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
2337 	p->map = p->base + min_addr;
2338 	p->map_len = max_addr - min_addr;
2339 	p->kernel_mapped = 1;
2340 }
2341 
__libc_exit_fini()2342 void __libc_exit_fini()
2343 {
2344 	struct dso *p;
2345 	size_t dyn[DYN_CNT];
2346 	int self = __pthread_self()->tid;
2347 
2348 	/* Take both locks before setting shutting_down, so that
2349 	 * either lock is sufficient to read its value. The lock
2350 	 * order matches that in dlopen to avoid deadlock. */
2351 	pthread_rwlock_wrlock(&lock);
2352 	pthread_mutex_lock(&init_fini_lock);
2353 	shutting_down = 1;
2354 	pthread_rwlock_unlock(&lock);
2355 	for (p=fini_head; p; p=p->fini_next) {
2356 		while (p->ctor_visitor && p->ctor_visitor!=self)
2357 			pthread_cond_wait(&ctor_cond, &init_fini_lock);
2358 		if (!p->constructed) continue;
2359 		decode_vec(p->dynv, dyn, DYN_CNT);
2360 		if (dyn[0] & (1<<DT_FINI_ARRAY)) {
2361 			size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
2362 			size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;
2363 			while (n--) ((void (*)(void))*--fn)();
2364 		}
2365 #ifndef NO_LEGACY_INITFINI
2366 		if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
2367 			fpaddr(p, dyn[DT_FINI])();
2368 #endif
2369 	}
2370 }
2371 
queue_ctors(struct dso * dso)2372 static struct dso **queue_ctors(struct dso *dso)
2373 {
2374 	size_t cnt, qpos, spos, i;
2375 	struct dso *p, **queue, **stack;
2376 
2377 	if (ldd_mode) return 0;
2378 
2379 	/* Bound on queue size is the total number of indirect deps.
2380 	 * If a bfs deps list was built, we can use it. Otherwise,
2381 	 * bound by the total number of DSOs, which is always safe and
2382 	 * is reasonable we use it (for main app at startup). */
2383 	if (dso->bfs_built) {
2384 		for (cnt=0; dso->deps[cnt]; cnt++)
2385 			dso->deps[cnt]->mark = 0;
2386 		cnt++; /* self, not included in deps */
2387 	} else {
2388 		for (cnt=0, p=head; p; cnt++, p=p->next)
2389 			p->mark = 0;
2390 	}
2391 	cnt++; /* termination slot */
2392 	if (dso==head && cnt <= countof(builtin_ctor_queue))
2393 		queue = builtin_ctor_queue;
2394 	else
2395 		queue = internal_calloc(cnt, sizeof *queue);
2396 
2397 	if (!queue) {
2398 		error("Error allocating constructor queue: %m\n");
2399 		if (runtime) longjmp(*rtld_fail, 1);
2400 		return 0;
2401 	}
2402 
2403 	/* Opposite ends of the allocated buffer serve as an output queue
2404 	 * and a working stack. Setup initial stack with just the argument
2405 	 * dso and initial queue empty... */
2406 	stack = queue;
2407 	qpos = 0;
2408 	spos = cnt;
2409 	stack[--spos] = dso;
2410 	dso->next_dep = 0;
2411 	dso->mark = 1;
2412 
2413 	/* Then perform pseudo-DFS sort, but ignoring circular deps. */
2414 	while (spos<cnt) {
2415 		p = stack[spos++];
2416 		while (p->next_dep < p->ndeps_direct) {
2417 			if (p->deps[p->next_dep]->mark) {
2418 				p->next_dep++;
2419 			} else {
2420 				stack[--spos] = p;
2421 				p = p->deps[p->next_dep];
2422 				p->next_dep = 0;
2423 				p->mark = 1;
2424 			}
2425 		}
2426 		queue[qpos++] = p;
2427 	}
2428 	queue[qpos] = 0;
2429 	for (i=0; i<qpos; i++) queue[i]->mark = 0;
2430 
2431 	return queue;
2432 }
2433 
do_init_fini(struct dso ** queue)2434 static void do_init_fini(struct dso **queue)
2435 {
2436 	struct dso *p;
2437 	size_t dyn[DYN_CNT], i;
2438 	int self = __pthread_self()->tid;
2439 
2440 	pthread_mutex_lock(&init_fini_lock);
2441 	for (i=0; (p=queue[i]); i++) {
2442 		while ((p->ctor_visitor && p->ctor_visitor!=self) || shutting_down)
2443 			pthread_cond_wait(&ctor_cond, &init_fini_lock);
2444 		if (p->ctor_visitor || p->constructed)
2445 			continue;
2446 		p->ctor_visitor = self;
2447 
2448 		decode_vec(p->dynv, dyn, DYN_CNT);
2449 		if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
2450 			p->fini_next = fini_head;
2451 			fini_head = p;
2452 		}
2453 
2454 		pthread_mutex_unlock(&init_fini_lock);
2455 
2456 #ifndef NO_LEGACY_INITFINI
2457 		if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
2458 			fpaddr(p, dyn[DT_INIT])();
2459 #endif
2460 		if (dyn[0] & (1<<DT_INIT_ARRAY)) {
2461 			size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
2462 			size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);
2463 			while (n--) ((void (*)(void))*fn++)();
2464 		}
2465 
2466 		pthread_mutex_lock(&init_fini_lock);
2467 		p->ctor_visitor = 0;
2468 		p->constructed = 1;
2469 		pthread_cond_broadcast(&ctor_cond);
2470 	}
2471 	pthread_mutex_unlock(&init_fini_lock);
2472 }
2473 
__libc_start_init(void)2474 void __libc_start_init(void)
2475 {
2476 	do_init_fini(main_ctor_queue);
2477 	if (!__malloc_replaced && main_ctor_queue != builtin_ctor_queue)
2478 		internal_free(main_ctor_queue);
2479 	main_ctor_queue = 0;
2480 }
2481 
dl_debug_state(void)2482 static void dl_debug_state(void)
2483 {
2484 }
2485 
2486 weak_alias(dl_debug_state, _dl_debug_state);
2487 
__init_tls(size_t * auxv)2488 void __init_tls(size_t *auxv)
2489 {
2490 }
2491 
update_tls_size()2492 static void update_tls_size()
2493 {
2494 	libc.tls_cnt = tls_cnt;
2495 	libc.tls_align = tls_align;
2496 	libc.tls_size = ALIGN(
2497 		(1+tls_cnt) * sizeof(void *) +
2498 		tls_offset +
2499 		sizeof(struct pthread) +
2500 		tls_align * 2,
2501 	tls_align);
2502 }
2503 
install_new_tls(void)2504 static void install_new_tls(void)
2505 {
2506 	sigset_t set;
2507 	pthread_t self = __pthread_self(), td;
2508 	struct dso *dtv_provider = container_of(tls_tail, struct dso, tls);
2509 	uintptr_t (*newdtv)[tls_cnt+1] = (void *)dtv_provider->new_dtv;
2510 	struct dso *p;
2511 	size_t i, j;
2512 	size_t old_cnt = self->dtv[0];
2513 
2514 	__block_app_sigs(&set);
2515 	__tl_lock();
2516 	/* Copy existing dtv contents from all existing threads. */
2517 	for (i=0, td=self; !i || td!=self; i++, td=td->next) {
2518 		memcpy(newdtv+i, td->dtv,
2519 			(old_cnt+1)*sizeof(uintptr_t));
2520 		newdtv[i][0] = tls_cnt;
2521 	}
2522 	/* Install new dtls into the enlarged, uninstalled dtv copies. */
2523 	for (p=head; ; p=p->next) {
2524 		if (p->tls_id <= old_cnt) continue;
2525 		unsigned char *mem = p->new_tls;
2526 		for (j=0; j<i; j++) {
2527 			unsigned char *new = mem;
2528 			new += ((uintptr_t)p->tls.image - (uintptr_t)mem)
2529 				& (p->tls.align-1);
2530 			memcpy(new, p->tls.image, p->tls.len);
2531 			newdtv[j][p->tls_id] =
2532 				(uintptr_t)new + DTP_OFFSET;
2533 			mem += p->tls.size + p->tls.align;
2534 		}
2535 		if (p->tls_id == tls_cnt) break;
2536 	}
2537 
2538 	/* Broadcast barrier to ensure contents of new dtv is visible
2539 	 * if the new dtv pointer is. The __membarrier function has a
2540 	 * fallback emulation using signals for kernels that lack the
2541 	 * feature at the syscall level. */
2542 
2543 	__membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0);
2544 
2545 	/* Install new dtv for each thread. */
2546 	for (j=0, td=self; !j || td!=self; j++, td=td->next) {
2547 		td->dtv = td->dtv_copy = newdtv[j];
2548 	}
2549 
2550 	__tl_unlock();
2551 	__restore_sigs(&set);
2552 }
2553 
2554 /* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the
2555  * following stage 2 and stage 3 functions via primitive symbolic lookup
2556  * since it does not have access to their addresses to begin with. */
2557 
2558 /* Stage 2 of the dynamic linker is called after relative relocations
2559  * have been processed. It can make function calls to static functions
2560  * and access string literals and static data, but cannot use extern
2561  * symbols. Its job is to perform symbolic relocations on the dynamic
2562  * linker itself, but some of the relocations performed may need to be
2563  * replaced later due to copy relocations in the main program. */
2564 
__dls2(unsigned char * base,size_t * sp)2565 hidden void __dls2(unsigned char *base, size_t *sp)
2566 {
2567 	size_t *auxv;
2568 	for (auxv=sp+1+*sp+1; *auxv; auxv++);
2569 	auxv++;
2570 	if (DL_FDPIC) {
2571 		void *p1 = (void *)sp[-2];
2572 		void *p2 = (void *)sp[-1];
2573 		if (!p1) {
2574 			size_t aux[AUX_CNT];
2575 			decode_vec(auxv, aux, AUX_CNT);
2576 			if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
2577 			else ldso.base = (void *)(aux[AT_PHDR] & -4096);
2578 		}
2579 		app_loadmap = p2 ? p1 : 0;
2580 		ldso.loadmap = p2 ? p2 : p1;
2581 		ldso.base = laddr(&ldso, 0);
2582 	} else {
2583 		ldso.base = base;
2584 	}
2585 	Ehdr *ehdr = (void *)ldso.base;
2586 	ldso.name = ldso.shortname = "libc.so";
2587 	ldso.phnum = ehdr->e_phnum;
2588 	ldso.phdr = laddr(&ldso, ehdr->e_phoff);
2589 	ldso.phentsize = ehdr->e_phentsize;
2590 	ldso.is_global = true;
2591 	kernel_mapped_dso(&ldso);
2592 	decode_dyn(&ldso);
2593 
2594 	if (DL_FDPIC) makefuncdescs(&ldso);
2595 
2596 	/* Prepare storage for to save clobbered REL addends so they
2597 	 * can be reused in stage 3. There should be very few. If
2598 	 * something goes wrong and there are a huge number, abort
2599 	 * instead of risking stack overflow. */
2600 	size_t dyn[DYN_CNT];
2601 	decode_vec(ldso.dynv, dyn, DYN_CNT);
2602 	size_t *rel = laddr(&ldso, dyn[DT_REL]);
2603 	size_t rel_size = dyn[DT_RELSZ];
2604 	size_t symbolic_rel_cnt = 0;
2605 	apply_addends_to = rel;
2606 	for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
2607 		if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;
2608 	if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
2609 	size_t addends[symbolic_rel_cnt+1];
2610 	saved_addends = addends;
2611 
2612 	head = &ldso;
2613 	reloc_all(&ldso, NULL);
2614 
2615 	ldso.relocated = 0;
2616 
2617 	/* Call dynamic linker stage-2b, __dls2b, looking it up
2618 	 * symbolically as a barrier against moving the address
2619 	 * load across the above relocation processing. */
2620 	struct symdef dls2b_def = find_sym(&ldso, "__dls2b", 0);
2621 	if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp, auxv);
2622 	else ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv);
2623 }
2624 
2625 /* Stage 2b sets up a valid thread pointer, which requires relocations
2626  * completed in stage 2, and on which stage 3 is permitted to depend.
2627  * This is done as a separate stage, with symbolic lookup as a barrier,
2628  * so that loads of the thread pointer and &errno can be pure/const and
2629  * thereby hoistable. */
2630 
__dls2b(size_t * sp,size_t * auxv)2631 void __dls2b(size_t *sp, size_t *auxv)
2632 {
2633 	/* Setup early thread pointer in builtin_tls for ldso/libc itself to
2634 	 * use during dynamic linking. If possible it will also serve as the
2635 	 * thread pointer at runtime. */
2636 	search_vec(auxv, &__hwcap, AT_HWCAP);
2637 	libc.auxv = auxv;
2638 	libc.tls_size = sizeof builtin_tls;
2639 	libc.tls_align = tls_align;
2640 	if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
2641 		a_crash();
2642 	}
2643 
2644 	struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
2645 	if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp, auxv);
2646 	else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv);
2647 }
2648 
2649 /* Stage 3 of the dynamic linker is called with the dynamic linker/libc
2650  * fully functional. Its job is to load (if not already loaded) and
2651  * process dependencies and relocations for the main application and
2652  * transfer control to its entry point. */
2653 
__dls3(size_t * sp,size_t * auxv)2654 void __dls3(size_t *sp, size_t *auxv)
2655 {
2656 	static struct dso app, vdso;
2657 	size_t aux[AUX_CNT];
2658 	size_t i;
2659 	char *env_preload=0;
2660 	char *replace_argv0=0;
2661 	size_t vdso_base;
2662 	int argc = *sp;
2663 	char **argv = (void *)(sp+1);
2664 	char **argv_orig = argv;
2665 	char **envp = argv+argc+1;
2666 
2667 	/* Find aux vector just past environ[] and use it to initialize
2668 	 * global data that may be needed before we can make syscalls. */
2669 	__environ = envp;
2670 	decode_vec(auxv, aux, AUX_CNT);
2671 	search_vec(auxv, &__sysinfo, AT_SYSINFO);
2672 	__pthread_self()->sysinfo = __sysinfo;
2673 	libc.page_size = aux[AT_PAGESZ];
2674 	libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
2675 		|| aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
2676 
2677 	/* Only trust user/env if kernel says we're not suid/sgid */
2678 	if (!libc.secure) {
2679 		env_path = getenv("LD_LIBRARY_PATH");
2680 		env_preload = getenv("LD_PRELOAD");
2681 	}
2682 #ifdef OHOS_ENABLE_PARAMETER
2683 	InitParameterClient();
2684 #endif
2685 	ld_log_reset();
2686 	/* If the main program was already loaded by the kernel,
2687 	 * AT_PHDR will point to some location other than the dynamic
2688 	 * linker's program headers. */
2689 	if (aux[AT_PHDR] != (size_t)ldso.phdr) {
2690 		size_t interp_off = 0;
2691 		size_t tls_image = 0;
2692 		/* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
2693 		Phdr *phdr = app.phdr = (void *)aux[AT_PHDR];
2694 		app.phnum = aux[AT_PHNUM];
2695 		app.phentsize = aux[AT_PHENT];
2696 		for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
2697 			if (phdr->p_type == PT_PHDR)
2698 				app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
2699 			else if (phdr->p_type == PT_INTERP)
2700 				interp_off = (size_t)phdr->p_vaddr;
2701 			else if (phdr->p_type == PT_TLS) {
2702 				tls_image = phdr->p_vaddr;
2703 				app.tls.len = phdr->p_filesz;
2704 				app.tls.size = phdr->p_memsz;
2705 				app.tls.align = phdr->p_align;
2706 			}
2707 		}
2708 		if (DL_FDPIC) app.loadmap = app_loadmap;
2709 		if (app.tls.size) app.tls.image = laddr(&app, tls_image);
2710 		if (interp_off) ldso.name = laddr(&app, interp_off);
2711 		if ((aux[0] & (1UL<<AT_EXECFN))
2712 			&& strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
2713 			app.name = (char *)aux[AT_EXECFN];
2714 		else
2715 			app.name = argv[0];
2716 		kernel_mapped_dso(&app);
2717 	} else {
2718 		int fd;
2719 		char *ldname = argv[0];
2720 		size_t l = strlen(ldname);
2721 		if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
2722 		argv++;
2723 		while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {
2724 			char *opt = argv[0]+2;
2725 			*argv++ = (void *)-1;
2726 			if (!*opt) {
2727 				break;
2728 			} else if (!memcmp(opt, "list", 5)) {
2729 				ldd_mode = 1;
2730 			} else if (!memcmp(opt, "library-path", 12)) {
2731 				if (opt[12]=='=') env_path = opt+13;
2732 				else if (opt[12]) *argv = 0;
2733 				else if (*argv) env_path = *argv++;
2734 			} else if (!memcmp(opt, "preload", 7)) {
2735 				if (opt[7]=='=') env_preload = opt+8;
2736 				else if (opt[7]) *argv = 0;
2737 				else if (*argv) env_preload = *argv++;
2738 			} else if (!memcmp(opt, "argv0", 5)) {
2739 				if (opt[5]=='=') replace_argv0 = opt+6;
2740 				else if (opt[5]) *argv = 0;
2741 				else if (*argv) replace_argv0 = *argv++;
2742 			} else {
2743 				argv[0] = 0;
2744 			}
2745 		}
2746 		argv[-1] = (void *)(argc - (argv-argv_orig));
2747 		if (!argv[0]) {
2748 			dprintf(2, "musl libc (" LDSO_ARCH ")\n"
2749 				"Version %s\n"
2750 				"Dynamic Program Loader\n"
2751 				"Usage: %s [options] [--] pathname%s\n",
2752 				__libc_version, ldname,
2753 				ldd_mode ? "" : " [args]");
2754 			_exit(1);
2755 		}
2756 		fd = open(argv[0], O_RDONLY);
2757 		if (fd < 0) {
2758 			dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
2759 			_exit(1);
2760 		}
2761 		Ehdr *ehdr = (void *)map_library(fd, &app, NULL);
2762 		if (!ehdr) {
2763 			dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
2764 			_exit(1);
2765 		}
2766 		close(fd);
2767 		ldso.name = ldname;
2768 		app.name = argv[0];
2769 		aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);
2770 		/* Find the name that would have been used for the dynamic
2771 		 * linker had ldd not taken its place. */
2772 		if (ldd_mode) {
2773 			for (i=0; i<app.phnum; i++) {
2774 				if (app.phdr[i].p_type == PT_INTERP)
2775 					ldso.name = laddr(&app, app.phdr[i].p_vaddr);
2776 			}
2777 			dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
2778 		}
2779 	}
2780 	if (app.tls.size) {
2781 		libc.tls_head = tls_tail = &app.tls;
2782 		app.tls_id = tls_cnt = 1;
2783 #ifdef TLS_ABOVE_TP
2784 		app.tls.offset = GAP_ABOVE_TP;
2785 		app.tls.offset += (-GAP_ABOVE_TP + (uintptr_t)app.tls.image)
2786 			& (app.tls.align-1);
2787 		tls_offset = app.tls.offset + app.tls.size;
2788 #else
2789 		tls_offset = app.tls.offset = app.tls.size
2790 			+ ( -((uintptr_t)app.tls.image + app.tls.size)
2791 			& (app.tls.align-1) );
2792 #endif
2793 		tls_align = MAXP2(tls_align, app.tls.align);
2794 	}
2795 	decode_dyn(&app);
2796 	if (DL_FDPIC) {
2797 		makefuncdescs(&app);
2798 		if (!app.loadmap) {
2799 			app.loadmap = (void *)&app_dummy_loadmap;
2800 			app.loadmap->nsegs = 1;
2801 			app.loadmap->segs[0].addr = (size_t)app.map;
2802 			app.loadmap->segs[0].p_vaddr = (size_t)app.map
2803 				- (size_t)app.base;
2804 			app.loadmap->segs[0].p_memsz = app.map_len;
2805 		}
2806 		argv[-3] = (void *)app.loadmap;
2807 	}
2808 	app.is_global = true;
2809 
2810 	/* Initial dso chain consists only of the app. */
2811 	head = tail = syms_tail = &app;
2812 
2813 	/* Donate unused parts of app and library mapping to malloc */
2814 	reclaim_gaps(&app);
2815 	reclaim_gaps(&ldso);
2816 
2817 	/* Load preload/needed libraries, add symbols to global namespace. */
2818 	ldso.deps = (struct dso **)no_deps;
2819 	/* Init g_is_asan */
2820 	g_is_asan = false;
2821 	LD_LOGD("__dls3 ldso.name:%{public}s.", ldso.name);
2822 	/* Through ldso Name to judge whether the Asan function is enabled */
2823 	if (strstr(ldso.name, "-asan")) {
2824 		g_is_asan = true;
2825 		LD_LOGD("__dls3 g_is_asan is true.");
2826 	}
2827 	/* Init all namespaces by config file. there is a default namespace always*/
2828 	init_namespace(&app);
2829 
2830 #ifdef LOAD_ORDER_RANDOMIZATION
2831 	struct loadtasks *tasks = create_loadtasks();
2832 	if (!tasks) {
2833 		_exit(1);
2834 	}
2835 	if (env_preload) {
2836 		load_preload(env_preload, get_default_ns(), tasks);
2837 	}
2838 	for (struct dso *q=head; q; q=q->next) {
2839 		q->is_global = true;
2840 	}
2841 	preload_deps(&app, tasks);
2842 	unmap_preloaded_sections(tasks);
2843 	shuffle_loadtasks(tasks);
2844 	run_loadtasks(tasks, NULL);
2845 	free_loadtasks(tasks);
2846 	assign_tls(app.next);
2847 #else
2848 	if (env_preload) load_preload(env_preload, get_default_ns());
2849 	for (struct dso *q=head; q; q=q->next) {
2850 		q->is_global = true;
2851 	}
2852  	load_deps(&app, NULL);
2853 #endif
2854 
2855 	/* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of app, including app self. */
2856 	for (struct dso *p=head; p; p=p->next) {
2857 		p->is_reloc_head_so_dep = true;
2858 		add_syms(p);
2859 	}
2860 
2861 	/* Attach to vdso, if provided by the kernel, last so that it does
2862 	 * not become part of the global namespace.  */
2863 	if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {
2864 		Ehdr *ehdr = (void *)vdso_base;
2865 		Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
2866 		vdso.phnum = ehdr->e_phnum;
2867 		vdso.phentsize = ehdr->e_phentsize;
2868 		for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
2869 			if (phdr->p_type == PT_DYNAMIC)
2870 				vdso.dynv = (void *)(vdso_base + phdr->p_offset);
2871 			if (phdr->p_type == PT_LOAD)
2872 				vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
2873 		}
2874 		vdso.name = "";
2875 		vdso.shortname = "linux-gate.so.1";
2876 		vdso.relocated = 1;
2877 		vdso.deps = (struct dso **)no_deps;
2878 		decode_dyn(&vdso);
2879 		vdso.prev = tail;
2880 		tail->next = &vdso;
2881 		tail = &vdso;
2882 		vdso.namespace = get_default_ns();
2883 		ns_add_dso(vdso.namespace, &vdso);
2884 	}
2885 
2886 	for (i=0; app.dynv[i]; i+=2) {
2887 		if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)
2888 			app.dynv[i+1] = (size_t)&debug;
2889 		if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {
2890 			size_t *ptr = (size_t *) app.dynv[i+1];
2891 			*ptr = (size_t)&debug;
2892 		}
2893 	}
2894 
2895 	/* This must be done before final relocations, since it calls
2896 	 * malloc, which may be provided by the application. Calling any
2897 	 * application code prior to the jump to its entry point is not
2898 	 * valid in our model and does not work with FDPIC, where there
2899 	 * are additional relocation-like fixups that only the entry point
2900 	 * code can see to perform. */
2901 	main_ctor_queue = queue_ctors(&app);
2902 
2903 	/* Initial TLS must also be allocated before final relocations
2904 	 * might result in calloc being a call to application code. */
2905 	update_tls_size();
2906 	void *initial_tls = builtin_tls;
2907 	if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {
2908 		initial_tls = internal_calloc(libc.tls_size, 1);
2909 		if (!initial_tls) {
2910 			dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
2911 				argv[0], libc.tls_size);
2912 			_exit(127);
2913 		}
2914 	}
2915 	static_tls_cnt = tls_cnt;
2916 
2917 	/* The main program must be relocated LAST since it may contain
2918 	 * copy relocations which depend on libraries' relocations. */
2919 	reloc_all(app.next, NULL);
2920 	reloc_all(&app, NULL);
2921 	for (struct dso *q=head; q; q=q->next) {
2922 		q->is_reloc_head_so_dep = false;
2923 	}
2924 
2925 	/* Actual copying to new TLS needs to happen after relocations,
2926 	 * since the TLS images might have contained relocated addresses. */
2927 	if (initial_tls != builtin_tls) {
2928 		pthread_t self = __pthread_self();
2929 		pthread_t td = __copy_tls(initial_tls);
2930 		if (__init_tp(td) < 0) {
2931 			a_crash();
2932 		}
2933 		td->tsd = self->tsd;
2934 	} else {
2935 		size_t tmp_tls_size = libc.tls_size;
2936 		pthread_t self = __pthread_self();
2937 		/* Temporarily set the tls size to the full size of
2938 		 * builtin_tls so that __copy_tls will use the same layout
2939 		 * as it did for before. Then check, just to be safe. */
2940 		libc.tls_size = sizeof builtin_tls;
2941 		if (__copy_tls((void*)builtin_tls) != self) a_crash();
2942 		libc.tls_size = tmp_tls_size;
2943 	}
2944 
2945 	if (ldso_fail) _exit(127);
2946 	if (ldd_mode) _exit(0);
2947 
2948 	/* Determine if malloc was interposed by a replacement implementation
2949 	 * so that calloc and the memalign family can harden against the
2950 	 * possibility of incomplete replacement. */
2951 	if (find_sym(head, "malloc", 1).dso != &ldso)
2952 		__malloc_replaced = 1;
2953 
2954 	/* Switch to runtime mode: any further failures in the dynamic
2955 	 * linker are a reportable failure rather than a fatal startup
2956 	 * error. */
2957 	runtime = 1;
2958 
2959 	debug.ver = 1;
2960 	debug.bp = dl_debug_state;
2961 	debug.head = head;
2962 	debug.base = ldso.base;
2963 	debug.state = RT_CONSISTENT;
2964 	_dl_debug_state();
2965 
2966 	if (replace_argv0) argv[0] = replace_argv0;
2967 
2968 #ifdef DFX_SIGNAL_LIBC
2969 	DFX_InstallSignalHandler();
2970 #endif
2971 	errno = 0;
2972 
2973 	CRTJMP((void *)aux[AT_ENTRY], argv-1);
2974 	for(;;);
2975 }
2976 
prepare_lazy(struct dso * p)2977 static void prepare_lazy(struct dso *p)
2978 {
2979 	size_t dyn[DYN_CNT], n, flags1=0;
2980 	decode_vec(p->dynv, dyn, DYN_CNT);
2981 	search_vec(p->dynv, &flags1, DT_FLAGS_1);
2982 	if (dyn[DT_BIND_NOW] || (dyn[DT_FLAGS] & DF_BIND_NOW) || (flags1 & DF_1_NOW))
2983 		return;
2984 	n = dyn[DT_RELSZ]/2 + dyn[DT_RELASZ]/3 + dyn[DT_PLTRELSZ]/2 + 1;
2985 	if (NEED_MIPS_GOT_RELOCS) {
2986 		size_t j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
2987 		size_t i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
2988 		n += i-j;
2989 	}
2990 	p->lazy = internal_calloc(n, 3*sizeof(size_t));
2991 	if (!p->lazy) {
2992 		error("Error preparing lazy relocation for %s: %m", p->name);
2993 		longjmp(*rtld_fail, 1);
2994 	}
2995 	p->lazy_next = lazy_head;
2996 	lazy_head = p;
2997 }
2998 
dlopen_post(struct dso * p,int mode)2999 static void *dlopen_post(struct dso* p, int mode) {
3000 	if (p == NULL) {
3001 		return p;
3002 	}
3003 
3004 	p->nr_dlopen++;
3005 	if (p->bfs_built) {
3006 		for (int i = 0; p->deps[i]; i++) {
3007 			p->deps[i]->nr_dlopen++;
3008 
3009 			if (mode & RTLD_NODELETE) {
3010 				p->deps[i]->flags |= DSO_FLAGS_NODELETE;
3011 			}
3012 		}
3013 	}
3014 
3015 #ifdef HANDLE_RANDOMIZATION
3016 	void *handle = assign_valid_handle(p);
3017 	if (handle == NULL) {
3018 		LD_LOGE("dlopen_post: generate random handle failed");
3019 		do_dlclose(p);
3020 	}
3021 
3022 	return handle;
3023 #endif
3024 
3025 	return p;
3026 }
3027 
3028 /* add namespace function */
dlopen_impl(const char * file,int mode,const char * namespace,const void * caller_addr,const dl_extinfo * extinfo)3029 static void *dlopen_impl(
3030 	const char *file, int mode, const char *namespace, const void *caller_addr, const dl_extinfo *extinfo)
3031 {
3032 	struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next;
3033 	struct tls_module *orig_tls_tail;
3034 	size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
3035 	size_t i;
3036 	int cs;
3037 	jmp_buf jb;
3038 	struct dso **volatile ctor_queue = 0;
3039 	ns_t *ns;
3040 	struct dso *caller;
3041 	bool reserved_address = false;
3042 	bool reserved_address_recursive = false;
3043 	struct reserved_address_params reserved_params = {0};
3044 #ifdef LOAD_ORDER_RANDOMIZATION
3045 	struct loadtasks *tasks = NULL;
3046 	struct loadtask *task = NULL;
3047 	bool is_task_appended = false;
3048 #endif
3049 
3050 	if (!file) {
3051 		LD_LOGD("dlopen_impl file is null, return head.");
3052 		return dlopen_post(head, mode);
3053 	}
3054 
3055 	if (extinfo) {
3056 		reserved_address_recursive = extinfo->flag & DL_EXT_RESERVED_ADDRESS_RECURSIVE;
3057 		if (extinfo->flag & DL_EXT_RESERVED_ADDRESS) {
3058 			reserved_address = true;
3059 			reserved_params.start_addr = extinfo->reserved_addr;
3060 			reserved_params.reserved_size = extinfo->reserved_size;
3061 			reserved_params.must_use_reserved = true;
3062 			reserved_params.reserved_address_recursive = reserved_address_recursive;
3063 		} else if (extinfo->flag & DL_EXT_RESERVED_ADDRESS_HINT) {
3064 			reserved_address = true;
3065 			reserved_params.start_addr = extinfo->reserved_addr;
3066 			reserved_params.reserved_size = extinfo->reserved_size;
3067 			reserved_params.must_use_reserved = false;
3068 			reserved_params.reserved_address_recursive = reserved_address_recursive;
3069 		}
3070 	}
3071 
3072 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
3073 	pthread_rwlock_wrlock(&lock);
3074 	__inhibit_ptc();
3075 
3076 	debug.state = RT_ADD;
3077 	_dl_debug_state();
3078 	/* When namespace does not exist, use caller's namespce
3079 	 * and when caller does not exist, use default namespce. */
3080 	caller = (struct dso *)addr2dso((size_t)caller_addr);
3081 	ns = find_ns_by_name(namespace);
3082 	if (!ns) ns = ((caller && caller->namespace) ? caller->namespace : get_default_ns());
3083 
3084 	p = 0;
3085 	if (shutting_down) {
3086 		error("Cannot dlopen while program is exiting.");
3087 		goto end;
3088 	}
3089 	orig_tls_tail = tls_tail;
3090 	orig_tls_cnt = tls_cnt;
3091 	orig_tls_offset = tls_offset;
3092 	orig_tls_align = tls_align;
3093 	orig_lazy_head = lazy_head;
3094 	orig_syms_tail = syms_tail;
3095 	orig_tail = tail;
3096 	noload = mode & RTLD_NOLOAD;
3097 
3098 	rtld_fail = &jb;
3099 	if (setjmp(*rtld_fail)) {
3100 		/* Clean up anything new that was (partially) loaded */
3101 		revert_syms(orig_syms_tail);
3102 		for (p=orig_tail->next; p; p=next) {
3103 			next = p->next;
3104 			while (p->td_index) {
3105 				void *tmp = p->td_index->next;
3106 				internal_free(p->td_index);
3107 				p->td_index = tmp;
3108 			}
3109 			internal_free(p->funcdescs);
3110 			if (p->rpath != p->rpath_orig)
3111 				internal_free(p->rpath);
3112 			if (p->deps) {
3113 				for (int i = 0; i < p->ndeps_direct; i++) {
3114 					remove_dso_parent(p->deps[i], p);
3115 				}
3116 			}
3117 			internal_free(p->deps);
3118 			dlclose_ns(p);
3119 			unmap_library(p);
3120 			if (p->parents) {
3121 				internal_free(p->parents);
3122 			}
3123 			free_reloc_can_search_dso(p);
3124 			internal_free(p);
3125 		}
3126 		internal_free(ctor_queue);
3127 		ctor_queue = 0;
3128 		if (!orig_tls_tail) libc.tls_head = 0;
3129 		tls_tail = orig_tls_tail;
3130 		if (tls_tail) tls_tail->next = 0;
3131 		tls_cnt = orig_tls_cnt;
3132 		tls_offset = orig_tls_offset;
3133 		tls_align = orig_tls_align;
3134 		lazy_head = orig_lazy_head;
3135 		tail = orig_tail;
3136 		tail->next = 0;
3137 		p = 0;
3138 		goto end;
3139 	} else {
3140 #ifdef LOAD_ORDER_RANDOMIZATION
3141 		tasks = create_loadtasks();
3142 		if (!tasks) {
3143 			LD_LOGE("dlopen_impl create loadtasks failed");
3144 			goto end;
3145 		}
3146 		task = create_loadtask(file, head, ns, true);
3147 		if (!task) {
3148 			LD_LOGE("dlopen_impl create loadtask failed");
3149 			goto end;
3150 		}
3151 		if (!load_library_header(task)) {
3152 			LD_LOGE("dlopen_impl load library header failed for %{public}s", task->name);
3153 			goto end;
3154 		}
3155 		if (reserved_address) {
3156 			reserved_params.target = task->p;
3157 		}
3158 	}
3159 	if (!task->p) {
3160 		LD_LOGE("dlopen_impl load library failed for %{public}s", task->name);
3161 		error(noload ?
3162 			"Library %s is not already loaded" :
3163 			"Error loading shared library %s: %m",
3164 			file);
3165 		goto end;
3166 	}
3167 	if (!task->isloaded) {
3168 		is_task_appended = append_loadtasks(tasks, task);
3169 	}
3170 	preload_deps(task->p, tasks);
3171 	unmap_preloaded_sections(tasks);
3172 	if (!reserved_address_recursive) {
3173 		shuffle_loadtasks(tasks);
3174 	}
3175 	run_loadtasks(tasks, reserved_address ? &reserved_params : NULL);
3176 	p = task->p;
3177 	if (!task->isloaded) {
3178 		assign_tls(p);
3179 	}
3180 	if (!is_task_appended) {
3181 		free_task(task);
3182 		task = NULL;
3183 	}
3184 	free_loadtasks(tasks);
3185 	tasks = NULL;
3186 #else
3187 		p = load_library(file, head, ns, true, reserved_address ? &reserved_params : NULL);
3188 	}
3189 
3190 	if (!p) {
3191 		error(noload ?
3192 			"Library %s is not already loaded" :
3193 			"Error loading shared library %s: %m",
3194 			file);
3195 		goto end;
3196 	}
3197 	/* First load handling */
3198 	load_deps(p, reserved_address && reserved_address_recursive ? &reserved_params : NULL);
3199 #endif
3200 	extend_bfs_deps(p);
3201 	pthread_mutex_lock(&init_fini_lock);
3202 	if (!p->constructed) ctor_queue = queue_ctors(p);
3203 	pthread_mutex_unlock(&init_fini_lock);
3204 	if (!p->relocated && (mode & RTLD_LAZY)) {
3205 		prepare_lazy(p);
3206 		for (i=0; p->deps[i]; i++)
3207 			if (!p->deps[i]->relocated)
3208 				prepare_lazy(p->deps[i]);
3209 	}
3210 	if (!p->relocated || (mode & RTLD_GLOBAL)) {
3211 		/* Make new symbols global, at least temporarily, so we can do
3212 		 * relocations. If not RTLD_GLOBAL, this is reverted below. */
3213 		add_syms(p);
3214 		/* Set is_reloc_head_so_dep to true for all direct and indirect dependent sos of p, including p self. */
3215 		p->is_reloc_head_so_dep = true;
3216 		for (i=0; p->deps[i]; i++) {
3217 			p->deps[i]->is_reloc_head_so_dep = true;
3218 			add_syms(p->deps[i]);
3219 		}
3220 	}
3221 	struct dso *reloc_head_so = p;
3222 	if (!p->relocated) {
3223 		reloc_all(p, extinfo);
3224 	}
3225 	reloc_head_so->is_reloc_head_so_dep = false;
3226 	for (size_t i=0; reloc_head_so->deps[i]; i++) {
3227 		reloc_head_so->deps[i]->is_reloc_head_so_dep = false;
3228 	}
3229 
3230 	/* If RTLD_GLOBAL was not specified, undo any new additions
3231 	 * to the global symbol table. This is a nop if the library was
3232 	 * previously loaded and already global. */
3233 	if (!(mode & RTLD_GLOBAL))
3234 		revert_syms(orig_syms_tail);
3235 
3236 	/* Processing of deferred lazy relocations must not happen until
3237 	 * the new libraries are committed; otherwise we could end up with
3238 	 * relocations resolved to symbol definitions that get removed. */
3239 	redo_lazy_relocs();
3240 
3241 	if (mode & RTLD_NODELETE) {
3242 		p->flags |= DSO_FLAGS_NODELETE;
3243 	}
3244 
3245 	update_tls_size();
3246 	if (tls_cnt != orig_tls_cnt)
3247 		install_new_tls();
3248 	orig_tail = tail;
3249 
3250 	p = dlopen_post(p, mode);
3251 end:
3252 	debug.state = RT_CONSISTENT;
3253 	_dl_debug_state();
3254 #ifdef LOAD_ORDER_RANDOMIZATION
3255 	if (!is_task_appended) {
3256 		free_task(task);
3257 	}
3258 	free_loadtasks(tasks);
3259 #endif
3260 	__release_ptc();
3261 	if (p) gencnt++;
3262 	pthread_rwlock_unlock(&lock);
3263 	if (ctor_queue) {
3264 		do_init_fini(ctor_queue);
3265 		internal_free(ctor_queue);
3266 	}
3267 	pthread_setcancelstate(cs, 0);
3268 	return p;
3269 }
3270 
dlopen(const char * file,int mode)3271 void *dlopen(const char *file, int mode)
3272 {
3273 	const void *caller_addr = __builtin_return_address(0);
3274 	musl_log_reset();
3275 	ld_log_reset();
3276 	LD_LOGI("dlopen file:%{public}s, mode:%{public}x ,caller_addr:%{public}p .", file, mode, caller_addr);
3277 	return dlopen_impl(file, mode, NULL, caller_addr, NULL);
3278 }
3279 
dlns_init(Dl_namespace * dlns,const char * name)3280 void dlns_init(Dl_namespace *dlns, const char *name)
3281 {
3282 	if (!dlns) {
3283 		LD_LOGE("dlns_init dlns is null.");
3284 		return;
3285 	}
3286 	if (!name) {
3287 		LD_LOGE("dlns_init name is null.");
3288 		dlns->name[0] = 0;
3289 		return;
3290 	}
3291 	snprintf(dlns->name, sizeof dlns->name, name);
3292 	LD_LOGI("dlns_init dlns->name:%{public}s .", dlns->name);
3293 }
3294 
dlns_get(const char * name,Dl_namespace * dlns)3295 int dlns_get(const char *name, Dl_namespace *dlns)
3296 {
3297 	if (!dlns) {
3298 		LD_LOGE("dlns_get dlns is null.");
3299 		return EINVAL;
3300 	}
3301 	int ret = 0;
3302 	ns_t *ns = NULL;
3303 	pthread_rwlock_rdlock(&lock);
3304 	if (!name) {
3305 		struct dso *caller;
3306 		const void *caller_addr = __builtin_return_address(0);
3307 		caller = (struct dso *)addr2dso((size_t)caller_addr);
3308 		ns = ((caller && caller->namespace) ? caller->namespace : get_default_ns());
3309 		(void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
3310 		LD_LOGI("dlns_get name is null, current dlns dlns->name:%{public}s.", dlns->name);
3311 	} else {
3312 		ns = find_ns_by_name(name);
3313 		if (ns) {
3314 			(void)snprintf(dlns->name, sizeof dlns->name, ns->ns_name);
3315 			LD_LOGI("dlns_get found ns, current dlns dlns->name:%{public}s.", dlns->name);
3316 		} else {
3317 			LD_LOGI("dlns_get not found ns! name:%{public}s.", name);
3318 			ret = ENOKEY;
3319 		}
3320 	}
3321 	pthread_rwlock_unlock(&lock);
3322 	return ret;
3323 }
3324 
dlopen_ns(Dl_namespace * dlns,const char * file,int mode)3325 void *dlopen_ns(Dl_namespace *dlns, const char *file, int mode)
3326 {
3327 	const void *caller_addr = __builtin_return_address(0);
3328 	musl_log_reset();
3329 	ld_log_reset();
3330 	LD_LOGI("dlopen_ns file:%{public}s, mode:%{public}x , caller_addr:%{public}p , dlns->name:%{public}s.",
3331 		file,
3332 		mode,
3333 		caller_addr,
3334 		dlns ? dlns->name : "NULL");
3335 	return dlopen_impl(file, mode, dlns->name, caller_addr, NULL);
3336 }
3337 
dlopen_ns_ext(Dl_namespace * dlns,const char * file,int mode,const dl_extinfo * extinfo)3338 void *dlopen_ns_ext(Dl_namespace *dlns, const char *file, int mode, const dl_extinfo *extinfo)
3339 {
3340 	const void *caller_addr = __builtin_return_address(0);
3341 	musl_log_reset();
3342 	ld_log_reset();
3343 	LD_LOGI("dlopen_ns_ext file:%{public}s, mode:%{public}x , caller_addr:%{public}p , "
3344 			"dlns->name:%{public}s. , extinfo->flag:%{public}x",
3345 		file,
3346 		mode,
3347 		caller_addr,
3348 		dlns->name,
3349 		extinfo ? extinfo->flag : 0);
3350 	return dlopen_impl(file, mode, dlns->name, caller_addr, extinfo);
3351 }
3352 
dlns_create2(Dl_namespace * dlns,const char * lib_path,int flags)3353 int dlns_create2(Dl_namespace *dlns, const char *lib_path, int flags)
3354 {
3355 	if (!dlns) {
3356 		LD_LOGE("dlns_create2 dlns is null.");
3357 		return EINVAL;
3358 	}
3359 	ns_t *ns;
3360 
3361 	pthread_rwlock_wrlock(&lock);
3362 	ns = find_ns_by_name(dlns->name);
3363 	if (ns) {
3364 		LD_LOGE("dlns_create2 ns is exist.");
3365 		pthread_rwlock_unlock(&lock);
3366 		return EEXIST;
3367 	}
3368 	ns = ns_alloc();
3369 	if (!ns) {
3370 		LD_LOGE("dlns_create2 no memery.");
3371 		pthread_rwlock_unlock(&lock);
3372 		return ENOMEM;
3373 	}
3374 	ns_set_name(ns, dlns->name);
3375 	ns_add_dso(ns, get_default_ns()->ns_dsos->dsos[0]); /* add main app to this namespace*/
3376 	nslist_add_ns(ns); /* add ns to list*/
3377 	ns_set_lib_paths(ns, lib_path);
3378 
3379 	if ((flags & CREATE_INHERIT_DEFAULT) != 0) {
3380 		ns_add_inherit(ns, get_default_ns(), NULL);
3381 	}
3382 
3383 	if ((flags & CREATE_INHERIT_CURRENT) != 0) {
3384 		struct dso *caller;
3385 		const void *caller_addr = __builtin_return_address(0);
3386 		caller = (struct dso *)addr2dso((size_t)caller_addr);
3387 		if (caller && caller->namespace) {
3388 			ns_add_inherit(ns, caller->namespace, NULL);
3389 		}
3390 	}
3391 
3392 	LD_LOGI("dlns_create2:"
3393 			"ns_name: %{public}s ,"
3394 			"separated:%{public}d ,"
3395 			"lib_paths:%{public}s ",
3396 			ns->ns_name, ns->separated, ns->lib_paths);
3397 	pthread_rwlock_unlock(&lock);
3398 
3399 	return 0;
3400 }
3401 
dlns_create(Dl_namespace * dlns,const char * lib_path)3402 int dlns_create(Dl_namespace *dlns, const char *lib_path)
3403 {
3404 	LD_LOGI("dlns_create lib_paths:%{public}s", lib_path);
3405 	return dlns_create2(dlns, lib_path, CREATE_INHERIT_DEFAULT);
3406 }
3407 
dlns_inherit(Dl_namespace * dlns,Dl_namespace * inherited,const char * shared_libs)3408 int dlns_inherit(Dl_namespace *dlns, Dl_namespace *inherited, const char *shared_libs)
3409 {
3410 	if (!dlns || !inherited) {
3411 		LD_LOGE("dlns_inherit dlns or inherited is null.");
3412 		return EINVAL;
3413 	}
3414 
3415 	pthread_rwlock_wrlock(&lock);
3416 	ns_t* ns = find_ns_by_name(dlns->name);
3417 	ns_t* ns_inherited = find_ns_by_name(inherited->name);
3418 	if (!ns || !ns_inherited) {
3419 		LD_LOGE("dlns_inherit ns or ns_inherited is not found.");
3420 		pthread_rwlock_unlock(&lock);
3421 		return ENOKEY;
3422 	}
3423 	ns_add_inherit(ns, ns_inherited, shared_libs);
3424 	pthread_rwlock_unlock(&lock);
3425 
3426 	return 0;
3427 }
3428 
dlclose_ns(struct dso * p)3429 static void dlclose_ns(struct dso *p)
3430 {
3431 	if (!p) return;
3432 	ns_t * ns = p->namespace;
3433 	if (!ns||!ns->ns_dsos) return;
3434 	for (size_t i=0; i<ns->ns_dsos->num; i++) {
3435 		if (p == ns->ns_dsos->dsos[i]) {
3436 			for (size_t j=i+1; j<ns->ns_dsos->num; j++) {
3437 				ns->ns_dsos->dsos[j-1] = ns->ns_dsos->dsos[j];
3438 			}
3439 			ns->ns_dsos->num--;
3440 			return;
3441 		}
3442 	}
3443 }
3444 
__dl_invalid_handle(void * h)3445 hidden int __dl_invalid_handle(void *h)
3446 {
3447 	struct dso *p;
3448 	for (p=head; p; p=p->next) if (h==p) return 0;
3449 	error("Invalid library handle %p", (void *)h);
3450 	return 1;
3451 }
3452 
addr2dso(size_t a)3453 static void *addr2dso(size_t a)
3454 {
3455 	struct dso *p;
3456 	size_t i;
3457 	if (DL_FDPIC) for (p=head; p; p=p->next) {
3458 		i = count_syms(p);
3459 		if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
3460 			return p;
3461 	}
3462 	for (p=head; p; p=p->next) {
3463 		if (DL_FDPIC && p->loadmap) {
3464 			for (i=0; i<p->loadmap->nsegs; i++) {
3465 				if (a-p->loadmap->segs[i].p_vaddr
3466 					< p->loadmap->segs[i].p_memsz)
3467 					return p;
3468 			}
3469 		} else {
3470 			Phdr *ph = p->phdr;
3471 			size_t phcnt = p->phnum;
3472 			size_t entsz = p->phentsize;
3473 			size_t base = (size_t)p->base;
3474 			for (; phcnt--; ph=(void *)((char *)ph+entsz)) {
3475 				if (ph->p_type != PT_LOAD) continue;
3476 				if (a-base-ph->p_vaddr < ph->p_memsz)
3477 					return p;
3478 			}
3479 			if (a-(size_t)p->map < p->map_len)
3480 				return 0;
3481 		}
3482 	}
3483 	return 0;
3484 }
3485 
do_dlsym(struct dso * p,const char * s,const char * v,void * ra)3486 static void *do_dlsym(struct dso *p, const char *s, const char *v, void *ra)
3487 {
3488 	int use_deps = 0;
3489 	bool ra2dso = false;
3490 	ns_t *ns = NULL;
3491 	struct dso *caller = NULL;
3492 	if (p == head || p == RTLD_DEFAULT) {
3493 		p = head;
3494 		ra2dso = true;
3495 	} else if (p == RTLD_NEXT) {
3496 		p = addr2dso((size_t)ra);
3497 		if (!p) p=head;
3498 		p = p->next;
3499 		ra2dso = true;
3500 #ifndef HANDLE_RANDOMIZATION
3501 	} else if (__dl_invalid_handle(p)) {
3502 		return 0;
3503 #endif
3504 	} else {
3505 		use_deps = 1;
3506 		ns = p->namespace;
3507 	}
3508 	if (ra2dso) {
3509 		caller = (struct dso *)addr2dso((size_t)ra);
3510 		if (caller && caller->namespace) {
3511 			ns = caller->namespace;
3512 		}
3513 	}
3514 	struct verinfo verinfo = { .s = s, .v = v, .use_vna_hash = false };
3515 	struct symdef def = find_sym2(p, &verinfo, 0, use_deps, ns);
3516 	if (!def.sym) {
3517 		LD_LOGE("do_dlsym failed: symbol not found. so=%{public}s s=%{public}s v=%{public}s", p->name, s, v);
3518 		error("Symbol not found: %s, version: %s", s, strlen(v) > 0 ? v : "null");
3519 		return 0;
3520 	}
3521 	if ((def.sym->st_info&0xf) == STT_TLS)
3522 		return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value-DTP_OFFSET});
3523 	if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
3524 		return def.dso->funcdescs + (def.sym - def.dso->syms);
3525 	return laddr(def.dso, def.sym->st_value);
3526 }
3527 
dlclose_impl(struct dso * p)3528 static int dlclose_impl(struct dso *p)
3529 {
3530 	size_t n;
3531 	struct dso *d;
3532 
3533 	if (__dl_invalid_handle(p))
3534 		return -1;
3535 
3536 	if (!p->by_dlopen) {
3537 		error("Library %s is not loaded by dlopen", p->name);
3538 		return -1;
3539 	}
3540 
3541 	/* dso is marked  as RTLD_NODELETE library, do nothing here. */
3542 	if ((p->flags & DSO_FLAGS_NODELETE) != 0) {
3543 		return 0;
3544 	}
3545 
3546 	if (--(p->nr_dlopen) > 0)
3547 		return 0;
3548 
3549 	/* call destructors if needed */
3550 	if (p->constructed) {
3551 		size_t dyn[DYN_CNT];
3552 		decode_vec(p->dynv, dyn, DYN_CNT);
3553 		if (dyn[0] & (1<<DT_FINI_ARRAY)) {
3554 			n = dyn[DT_FINI_ARRAYSZ] / sizeof(size_t);
3555 			size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY]) + n;
3556 			while (n--)
3557 				((void (*)(void))*--fn)();
3558 		}
3559 		p->constructed = 0;
3560 	}
3561 
3562 	/* remove dso symbols from global list */
3563 	if (p->syms_next) {
3564 		for (d = head; d->syms_next != p; d = d->syms_next)
3565 			; /* NOP */
3566 		d->syms_next = p->syms_next;
3567 	} else if (p == syms_tail) {
3568 		for (d = head; d->syms_next != p; d = d->syms_next)
3569 			; /* NOP */
3570 		d->syms_next = NULL;
3571 		syms_tail = d;
3572 	}
3573 
3574 	/* remove dso from lazy list if needed */
3575 	if (p == lazy_head) {
3576 		lazy_head = p->lazy_next;
3577 	} else if (p->lazy_next) {
3578 		for (d = lazy_head; d->lazy_next != p; d = d->lazy_next)
3579 			; /* NOP */
3580 		d->lazy_next = p->lazy_next;
3581 	}
3582 
3583 	/* remove dso from fini list */
3584 	if (p == fini_head) {
3585 		fini_head = p->fini_next;
3586 	} else if (p->fini_next) {
3587 		for (d = fini_head; d->fini_next != p; d = d->fini_next)
3588 			; /* NOP */
3589 		d->fini_next = p->fini_next;
3590 	}
3591 
3592 	/* empty tls image */
3593 	if (p->tls.size != 0) {
3594 		p->tls.image = NULL;
3595 	}
3596 
3597 	/* remove dso from global dso list */
3598 	if (p == tail) {
3599 		tail = p->prev;
3600 		tail->next = NULL;
3601 	} else {
3602 		p->next->prev = p->prev;
3603 		p->prev->next = p->next;
3604 	}
3605 
3606 	/* remove dso from namespace */
3607 	dlclose_ns(p);
3608 
3609 	if (p->lazy != NULL)
3610 		internal_free(p->lazy);
3611 	if (p->deps) {
3612 		for (int i = 0; i < p->ndeps_direct; i++) {
3613 			remove_dso_parent(p->deps[i], p);
3614 		}
3615 	}
3616 	if (p->deps != no_deps)
3617 		internal_free(p->deps);
3618 	unmap_library(p);
3619 
3620 	if (p->parents) {
3621 		internal_free(p->parents);
3622 	}
3623 
3624 	free_reloc_can_search_dso(p);
3625 	if (p->tls.size == 0) {
3626 		internal_free(p);
3627 	}
3628 
3629 	return 0;
3630 }
3631 
3632 static char* dlclose_deps_black_list[] =
3633 {
3634 	"/system/lib/libhidebug.so",
3635 	"/system/lib64/libhidebug.so",
3636 	"/system/lib64/libmsdp_neardetect_algorithm.z.so",
3637 	"/vendor/lib64/libhril_hdf.z.so"
3638 };
3639 
do_dlclose(struct dso * p)3640 static int do_dlclose(struct dso *p)
3641 {
3642 	bool ldclose_deps = true;
3643 
3644 	for (int i = 0; i < sizeof(dlclose_deps_black_list)/sizeof(char*); i++) {
3645 		if (!strcmp(dlclose_deps_black_list[i], p->name)) {
3646 			ldclose_deps = false;
3647 			break;
3648 		}
3649 	}
3650 
3651 	size_t deps_num;
3652 
3653 	for (deps_num = 0; p->deps[deps_num]; deps_num++);
3654 
3655 	struct dso **deps_bak = internal_malloc(deps_num*sizeof(struct dso*));
3656 	if (deps_bak != NULL) {
3657 		memcpy(deps_bak, p->deps, deps_num*sizeof(struct dso*));
3658 	}
3659 
3660 	LD_LOGI("do_dlclose name=%{public}s count=%{public}d by_dlopen=%{public}d", p->name, p->nr_dlopen, p->by_dlopen);
3661 	dlclose_impl(p);
3662 
3663 	if (ldclose_deps) {
3664 		for (size_t i = 0; i < deps_num; i++) {
3665 			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);
3666 			dlclose_impl(deps_bak[i]);
3667 		}
3668 	}
3669 
3670 	internal_free(deps_bak);
3671 
3672 	return 0;
3673 }
3674 
__dlclose(void * p)3675 hidden int __dlclose(void *p)
3676 {
3677 	int rc;
3678 	pthread_rwlock_wrlock(&lock);
3679 	__inhibit_ptc();
3680 #ifdef HANDLE_RANDOMIZATION
3681 	struct dso *dso = find_dso_by_handle(p);
3682 	if (dso == NULL) {
3683 		errno = EINVAL;
3684 		error("Handle is invalid.");
3685 		LD_LOGE("Handle is not find.");
3686 		__release_ptc();
3687 		pthread_rwlock_unlock(&lock);
3688 		return -1;
3689 	}
3690 	rc = do_dlclose(dso);
3691 	if (!rc) {
3692 		struct dso *t = head;
3693 		for (; t && t != dso; t = t->next) {
3694 			;
3695 		}
3696 		if (t == NULL) {
3697 			remove_handle_node(p);
3698 		}
3699 	}
3700 #else
3701 	rc = do_dlclose(p);
3702 #endif
3703 	__release_ptc();
3704 	pthread_rwlock_unlock(&lock);
3705 	return rc;
3706 }
3707 
dladdr(const void * addr_arg,Dl_info * info)3708 int dladdr(const void *addr_arg, Dl_info *info)
3709 {
3710 	size_t addr = (size_t)addr_arg;
3711 	struct dso *p;
3712 	Sym *sym, *bestsym;
3713 	uint32_t nsym;
3714 	char *strings;
3715 	size_t best = 0;
3716 	size_t besterr = -1;
3717 
3718 	pthread_rwlock_rdlock(&lock);
3719 	p = addr2dso(addr);
3720 	pthread_rwlock_unlock(&lock);
3721 
3722 	if (!p) return 0;
3723 
3724 	sym = p->syms;
3725 	strings = p->strings;
3726 	nsym = count_syms(p);
3727 
3728 	if (DL_FDPIC) {
3729 		size_t idx = (addr-(size_t)p->funcdescs)
3730 			/ sizeof(*p->funcdescs);
3731 		if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) {
3732 			best = (size_t)(p->funcdescs + idx);
3733 			bestsym = sym + idx;
3734 			besterr = 0;
3735 		}
3736 	}
3737 
3738 	if (!best) for (; nsym; nsym--, sym++) {
3739 		if (sym->st_value
3740 		 && (1<<(sym->st_info&0xf) & OK_TYPES)
3741 		 && (1<<(sym->st_info>>4) & OK_BINDS)) {
3742 			size_t symaddr = (size_t)laddr(p, sym->st_value);
3743 			if (symaddr > addr || symaddr <= best)
3744 				continue;
3745 			best = symaddr;
3746 			bestsym = sym;
3747 			besterr = addr - symaddr;
3748 			if (addr == symaddr)
3749 				break;
3750 		}
3751 	}
3752 
3753 	if (best && besterr > bestsym->st_size-1) {
3754 		best = 0;
3755 		bestsym = 0;
3756 	}
3757 
3758 	info->dli_fname = p->name;
3759 	info->dli_fbase = p->map;
3760 
3761 	if (!best) {
3762 		info->dli_sname = 0;
3763 		info->dli_saddr = 0;
3764 		return 1;
3765 	}
3766 
3767 	if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC)
3768 		best = (size_t)(p->funcdescs + (bestsym - p->syms));
3769 	info->dli_sname = strings + bestsym->st_name;
3770 	info->dli_saddr = (void *)best;
3771 
3772 	return 1;
3773 }
3774 
__dlsym(void * restrict p,const char * restrict s,void * restrict ra)3775 hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
3776 {
3777 	void *res;
3778 	ld_log_reset();
3779 	pthread_rwlock_rdlock(&lock);
3780 #ifdef HANDLE_RANDOMIZATION
3781 	if ((p != RTLD_DEFAULT) && (p != RTLD_NEXT)) {
3782 		struct dso *dso = find_dso_by_handle(p);
3783 		if (dso == NULL) {
3784 			pthread_rwlock_unlock(&lock);
3785 			return 0;
3786 		}
3787 		res = do_dlsym(dso, s, "", ra);
3788 	} else {
3789 		res = do_dlsym(p, s, "", ra);
3790 	}
3791 #else
3792 	res = do_dlsym(p, s, "", ra);
3793 #endif
3794 	pthread_rwlock_unlock(&lock);
3795 	return res;
3796 }
3797 
__dlvsym(void * restrict p,const char * restrict s,const char * restrict v,void * restrict ra)3798 hidden void *__dlvsym(void *restrict p, const char *restrict s, const char *restrict v, void *restrict ra)
3799 {
3800 	void *res;
3801 	ld_log_reset();
3802 	pthread_rwlock_rdlock(&lock);
3803 #ifdef HANDLE_RANDOMIZATION
3804 	if ((p != RTLD_DEFAULT) && (p != RTLD_NEXT)) {
3805 		struct dso *dso = find_dso_by_handle(p);
3806 		if (dso == NULL) {
3807 			pthread_rwlock_unlock(&lock);
3808 			return 0;
3809 		}
3810 		res = do_dlsym(dso, s, v, ra);
3811 	} else {
3812 		res = do_dlsym(p, s, v, ra);
3813 	}
3814 #else
3815 	res = do_dlsym(p, s, v, ra);
3816 #endif
3817 	pthread_rwlock_unlock(&lock);
3818 	return res;
3819 }
3820 
__dlsym_redir_time64(void * restrict p,const char * restrict s,void * restrict ra)3821 hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)
3822 {
3823 #if _REDIR_TIME64
3824 	const char *suffix, *suffix2 = "";
3825 	char redir[36];
3826 
3827 	/* Map the symbol name to a time64 version of itself according to the
3828 	 * pattern used for naming the redirected time64 symbols. */
3829 	size_t l = strnlen(s, sizeof redir);
3830 	if (l<4 || l==sizeof redir) goto no_redir;
3831 	if (s[l-2]=='_' && s[l-1]=='r') {
3832 		l -= 2;
3833 		suffix2 = s+l;
3834 	}
3835 	if (l<4) goto no_redir;
3836 	if (!strcmp(s+l-4, "time")) suffix = "64";
3837 	else suffix = "_time64";
3838 
3839 	/* Use the presence of the remapped symbol name in libc to determine
3840 	 * whether it's one that requires time64 redirection; replace if so. */
3841 	snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2);
3842 	if (find_sym(&ldso, redir, 1).sym) s = redir;
3843 no_redir:
3844 #endif
3845 	return __dlsym(p, s, ra);
3846 }
3847 
dl_iterate_phdr(int (* callback)(struct dl_phdr_info * info,size_t size,void * data),void * data)3848 int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
3849 {
3850 	struct dso *current;
3851 	struct dl_phdr_info info;
3852 	int ret = 0;
3853 	for(current = head; current;) {
3854 		info.dlpi_addr      = (uintptr_t)current->base;
3855 		info.dlpi_name      = current->name;
3856 		info.dlpi_phdr      = current->phdr;
3857 		info.dlpi_phnum     = current->phnum;
3858 		info.dlpi_adds      = gencnt;
3859 		info.dlpi_subs      = 0;
3860 		info.dlpi_tls_modid = current->tls_id;
3861 		info.dlpi_tls_data  = current->tls.image;
3862 
3863 		ret = (callback)(&info, sizeof (info), data);
3864 
3865 		if (ret != 0) break;
3866 
3867 		pthread_rwlock_rdlock(&lock);
3868 		current = current->next;
3869 		pthread_rwlock_unlock(&lock);
3870 	}
3871 	return ret;
3872 }
3873 
error(const char * fmt,...)3874 static void error(const char *fmt, ...)
3875 {
3876 	va_list ap;
3877 	va_start(ap, fmt);
3878 	if (!runtime) {
3879 		vdprintf(2, fmt, ap);
3880 		dprintf(2, "\n");
3881 		ldso_fail = 1;
3882 		va_end(ap);
3883 		return;
3884 	}
3885 	__dl_vseterr(fmt, ap);
3886 	va_end(ap);
3887 }
3888 
dlns_set_namespace_lib_path(const char * name,const char * lib_path)3889 int dlns_set_namespace_lib_path(const char * name, const char * lib_path)
3890 {
3891 	if (!name || !lib_path) {
3892 		LD_LOGE("dlns_set_namespace_lib_path name or lib_path is null.");
3893 		return EINVAL;
3894 	}
3895 
3896 	pthread_rwlock_wrlock(&lock);
3897 	ns_t* ns = find_ns_by_name(name);
3898 	if (!ns) {
3899 		pthread_rwlock_unlock(&lock);
3900 		LD_LOGE("dlns_set_namespace_lib_path fail, input ns name : [%{public}s] is not found.", name);
3901 		return ENOKEY;
3902 	}
3903 
3904 	ns_set_lib_paths(ns, lib_path);
3905 	pthread_rwlock_unlock(&lock);
3906 	return 0;
3907 }
3908 
dlns_set_namespace_separated(const char * name,const bool separated)3909 int dlns_set_namespace_separated(const char * name, const bool separated)
3910 {
3911 	if (!name) {
3912 		LD_LOGE("dlns_set_namespace_separated name  is null.");
3913 		return EINVAL;
3914 	}
3915 
3916 	pthread_rwlock_wrlock(&lock);
3917 	ns_t* ns = find_ns_by_name(name);
3918 	if (!ns) {
3919 		pthread_rwlock_unlock(&lock);
3920 		LD_LOGE("dlns_set_namespace_separated fail, input ns name : [%{public}s] is not found.", name);
3921 		return ENOKEY;
3922 	}
3923 
3924 	ns_set_separated(ns, separated);
3925 	pthread_rwlock_unlock(&lock);
3926 	return 0;
3927 }
3928 
dlns_set_namespace_permitted_paths(const char * name,const char * permitted_paths)3929 int dlns_set_namespace_permitted_paths(const char * name, const char * permitted_paths)
3930 {
3931 	if (!name || !permitted_paths) {
3932 		LD_LOGE("dlns_set_namespace_permitted_paths name or permitted_paths is null.");
3933 		return EINVAL;
3934 	}
3935 
3936 	pthread_rwlock_wrlock(&lock);
3937 	ns_t* ns = find_ns_by_name(name);
3938 	if (!ns) {
3939 		pthread_rwlock_unlock(&lock);
3940 		LD_LOGE("dlns_set_namespace_permitted_paths fail, input ns name : [%{public}s] is not found.", name);
3941 		return ENOKEY;
3942 	}
3943 
3944 	ns_set_permitted_paths(ns, permitted_paths);
3945 	pthread_rwlock_unlock(&lock);
3946 	return 0;
3947 }
3948 
dlns_set_namespace_allowed_libs(const char * name,const char * allowed_libs)3949 int dlns_set_namespace_allowed_libs(const char * name, const char * allowed_libs)
3950 {
3951 	if (!name || !allowed_libs) {
3952 		LD_LOGE("dlns_set_namespace_allowed_libs name or allowed_libs is null.");
3953 		return EINVAL;
3954 	}
3955 
3956 	pthread_rwlock_wrlock(&lock);
3957 	ns_t* ns = find_ns_by_name(name);
3958 	if (!ns) {
3959 		pthread_rwlock_unlock(&lock);
3960 		LD_LOGE("dlns_set_namespace_allowed_libs fail, input ns name : [%{public}s] is not found.", name);
3961 		return ENOKEY;
3962 	}
3963 
3964 	ns_set_allowed_libs(ns, allowed_libs);
3965 	pthread_rwlock_unlock(&lock);
3966 	return 0;
3967 }
3968 
handle_asan_path_open(int fd,const char * name,ns_t * namespace,char * buf,size_t buf_size)3969 int handle_asan_path_open(int fd, const char *name, ns_t *namespace, char *buf, size_t buf_size)
3970 {
3971 	LD_LOGD("handle_asan_path_open fd:%{public}d, name:%{public}s , namespace:%{public}s .",
3972 		fd,
3973 		name,
3974 		namespace ? namespace->ns_name : "NULL");
3975 	int fd_tmp = fd;
3976 	if (fd == -1 && (namespace->asan_lib_paths || namespace->lib_paths)) {
3977 		if (namespace->lib_paths && namespace->asan_lib_paths) {
3978 			size_t newlen = strlen(namespace->asan_lib_paths) + strlen(namespace->lib_paths) + 2;
3979 			char *new_lib_paths = internal_malloc(newlen);
3980 			memset(new_lib_paths, 0, newlen);
3981 			strcpy(new_lib_paths, namespace->asan_lib_paths);
3982 			strcat(new_lib_paths, ":");
3983 			strcat(new_lib_paths, namespace->lib_paths);
3984 			fd_tmp = path_open(name, new_lib_paths, buf, buf_size);
3985 			LD_LOGD("handle_asan_path_open path_open new_lib_paths:%{public}s ,fd: %{public}d.", new_lib_paths, fd_tmp);
3986 			internal_free(new_lib_paths);
3987 		} else if (namespace->asan_lib_paths) {
3988 			fd_tmp = path_open(name, namespace->asan_lib_paths, buf, buf_size);
3989 			LD_LOGD("handle_asan_path_open path_open asan_lib_paths:%{public}s ,fd: %{public}d.",
3990 				namespace->asan_lib_paths,
3991 				fd_tmp);
3992 		} else {
3993 			fd_tmp = path_open(name, namespace->lib_paths, buf, buf_size);
3994 			LD_LOGD(
3995 				"handle_asan_path_open path_open lib_paths:%{public}s ,fd: %{public}d.", namespace->lib_paths, fd_tmp);
3996 		}
3997 	}
3998 	return fd_tmp;
3999 }
4000 
dlopen_ext(const char * file,int mode,const dl_extinfo * extinfo)4001 void* dlopen_ext(const char *file, int mode, const dl_extinfo *extinfo)
4002 {
4003 	const void *caller_addr = __builtin_return_address(0);
4004 	musl_log_reset();
4005 	ld_log_reset();
4006 	if (extinfo != NULL) {
4007 		if ((extinfo->flag & ~(DL_EXT_VALID_FLAG_BITS)) != 0) {
4008 			LD_LOGE("Error dlopen_ext %{public}s: invalid flag %{public}x", file, extinfo->flag);
4009 			return NULL;
4010 		}
4011 	}
4012 	LD_LOGI("dlopen_ext file:%{public}s, mode:%{public}x , caller_addr:%{public}p , extinfo->flag:%{public}x",
4013 		file,
4014 		mode,
4015 		caller_addr,
4016 		extinfo ? extinfo->flag : 0);
4017   	return dlopen_impl(file, mode, NULL, caller_addr, extinfo);
4018 }
4019 
4020 #ifdef LOAD_ORDER_RANDOMIZATION
open_library_by_path(const char * name,const char * s,struct loadtask * task,struct zip_info * z_info)4021 static void open_library_by_path(const char *name, const char *s, struct loadtask *task, struct zip_info *z_info)
4022 {
4023 	char *buf = task->buf;
4024 	size_t buf_size = sizeof task->buf;
4025 	size_t l;
4026 	for (;;) {
4027 		s += strspn(s, ":\n");
4028 		l = strcspn(s, ":\n");
4029 		if (l-1 >= INT_MAX) return;
4030 		if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
4031 			char *separator = strstr(buf, ZIP_FILE_PATH_SEPARATOR);
4032 			if (separator != NULL) {
4033 				int res = open_uncompressed_library_in_zipfile(buf, z_info, separator);
4034 				if (res == 0) {
4035 					task->fd = z_info->fd;
4036 					task->file_offset = z_info->file_offset;
4037 					break;
4038 				} else {
4039 					memset(z_info->path_buf, 0, sizeof(z_info->path_buf));
4040 				}
4041 			} else {
4042 				if ((task->fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) break;
4043 			}
4044 		}
4045 		s += l;
4046 	}
4047 	return;
4048 }
4049 
handle_asan_path_open_by_task(int fd,const char * name,ns_t * namespace,struct loadtask * task,struct zip_info * z_info)4050 static void handle_asan_path_open_by_task(int fd, const char *name, ns_t *namespace, struct loadtask *task,
4051 										  struct zip_info *z_info)
4052 {
4053 	LD_LOGD("handle_asan_path_open_by_task fd:%{public}d, name:%{public}s , namespace:%{public}s .",
4054 			fd,
4055 			name,
4056 			namespace ? namespace->ns_name : "NULL");
4057 	if (fd == -1 && (namespace->asan_lib_paths || namespace->lib_paths)) {
4058 		if (namespace->lib_paths && namespace->asan_lib_paths) {
4059 			size_t newlen = strlen(namespace->asan_lib_paths) + strlen(namespace->lib_paths) + 2;
4060 			char *new_lib_paths = internal_malloc(newlen);
4061 			memset(new_lib_paths, 0, newlen);
4062 			strcpy(new_lib_paths, namespace->asan_lib_paths);
4063 			strcat(new_lib_paths, ":");
4064 			strcat(new_lib_paths, namespace->lib_paths);
4065 			open_library_by_path(name, new_lib_paths, task, z_info);
4066 			LD_LOGD("handle_asan_path_open_by_task open_library_by_path new_lib_paths:%{public}s ,fd: %{public}d.",
4067 					new_lib_paths,
4068 					task->fd);
4069 			internal_free(new_lib_paths);
4070 		} else if (namespace->asan_lib_paths) {
4071 			open_library_by_path(name, namespace->asan_lib_paths, task, z_info);
4072 			LD_LOGD("handle_asan_path_open_by_task open_library_by_path asan_lib_paths:%{public}s ,fd: %{public}d.",
4073 					namespace->asan_lib_paths,
4074 					task->fd);
4075 		} else {
4076 			open_library_by_path(name, namespace->lib_paths, task, z_info);
4077 			LD_LOGD("handle_asan_path_open_by_task open_library_by_path lib_paths:%{public}s ,fd: %{public}d.",
4078 					namespace->lib_paths,
4079 					task->fd);
4080 		}
4081 	}
4082 	return;
4083 }
4084 
4085 /* 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)4086 int open_uncompressed_library_in_zipfile(const char *path, struct zip_info *z_info, char *separator)
4087 {
4088 	struct local_file_header zip_file_header;
4089 	struct central_dir_entry c_dir_entry;
4090 	struct zip_end_locator end_locator;
4091 
4092 	/* Use "'!/' to split the path into zipfile path and library path in zipfile.
4093 	 * For example:
4094 	 * - path: x/xx/xxx.zip!/x/xx/xxx.so
4095 	 * - zipfile path: x/xx/xxx.zip
4096 	 * - library path in zipfile: x/xx/xxx.so  */
4097 	if (strlcpy(z_info->path_buf, path, PATH_BUF_SIZE) >= PATH_BUF_SIZE) {
4098 		LD_LOGE("Open uncompressed library: input path %{public}s is too long.", path);
4099 		return -1;
4100 	}
4101 	z_info->path_buf[separator - path] = '\0';
4102 	z_info->file_path_index = separator - path + 2;
4103 	char *zip_file_path = z_info->path_buf;
4104 	char *lib_path = &z_info->path_buf[z_info->file_path_index];
4105 	if (zip_file_path == NULL || lib_path == NULL) {
4106 		LD_LOGE("Open uncompressed library: get zip and lib path failed.");
4107 		return -1;
4108 	}
4109 	LD_LOGD("Open uncompressed library: input path: %{public}s, zip file path: %{public}s, library path: %{public}s.",
4110 			path, zip_file_path, lib_path);
4111 
4112 	// Get zip file length
4113 	FILE *zip_file = fopen(zip_file_path, "re");
4114 	if (zip_file == NULL) {
4115 		LD_LOGE("Open uncompressed library: fopen %{public}s failed.", zip_file_path);
4116 		return -1;
4117 	}
4118 	if (fseek(zip_file, 0, SEEK_END) != 0) {
4119 		LD_LOGE("Open uncompressed library: fseek SEEK_END failed.");
4120 		fclose(zip_file);
4121 		return -1;
4122 	}
4123 	int64_t zip_file_len = ftell(zip_file);
4124 	if (zip_file_len == -1) {
4125 		LD_LOGE("Open uncompressed library: get zip file length failed.");
4126 		fclose(zip_file);
4127 		return -1;
4128 	}
4129 
4130 	// Read end of central directory record.
4131 	size_t end_locator_len = sizeof(end_locator);
4132 	size_t end_locator_pos = zip_file_len - end_locator_len;
4133 	if (fseek(zip_file, end_locator_pos, SEEK_SET) != 0) {
4134 		LD_LOGE("Open uncompressed library: fseek end locator position failed.");
4135 		fclose(zip_file);
4136 		return -1;
4137 	}
4138 	if (fread(&end_locator, sizeof(end_locator), 1, zip_file) != 1 || end_locator.signature != EOCD_SIGNATURE) {
4139 		LD_LOGE("Open uncompressed library: fread end locator failed.");
4140 		fclose(zip_file);
4141 		return -1;
4142 	}
4143 
4144 	char file_name[PATH_BUF_SIZE];
4145 	uint64_t current_dir_pos = end_locator.offset;
4146 	for (uint16_t i = 0; i < end_locator.total_entries; i++) {
4147 		// Read central dir entry.
4148 		if (fseek(zip_file, current_dir_pos, SEEK_SET) != 0) {
4149 			LD_LOGE("Open uncompressed library: fseek current centra dir entry position failed.");
4150 			fclose(zip_file);
4151 			return -1;
4152 		}
4153 		if (fread(&c_dir_entry, sizeof(c_dir_entry), 1, zip_file) != 1 || c_dir_entry.signature != CENTRAL_SIGNATURE) {
4154 			LD_LOGE("Open uncompressed library: fread centra dir entry failed.");
4155 			fclose(zip_file);
4156 			return -1;
4157 		}
4158 
4159 		if (fread(file_name, c_dir_entry.name_size, 1, zip_file) != 1) {
4160 			LD_LOGE("Open uncompressed library: fread file name failed.");
4161 			fclose(zip_file);
4162 			return -1;
4163 		}
4164 		if (strcmp(file_name, lib_path) == 0) {
4165 			// Read local file header.
4166 			if (fseek(zip_file, c_dir_entry.local_header_offset, SEEK_SET) != 0) {
4167 				LD_LOGE("Open uncompressed library: fseek local file header failed.");
4168 				fclose(zip_file);
4169 				return -1;
4170 			}
4171 			if (fread(&zip_file_header, sizeof(zip_file_header), 1, zip_file) != 1) {
4172 				LD_LOGE("Open uncompressed library: fread local file header failed.");
4173 				fclose(zip_file);
4174 				return -1;
4175 			}
4176 			if (zip_file_header.signature != LOCAL_FILE_HEADER_SIGNATURE) {
4177 				LD_LOGE("Open uncompressed library: read local file header signature error.");
4178 				fclose(zip_file);
4179 				return -1;
4180 			}
4181 
4182 			z_info->file_offset = c_dir_entry.local_header_offset + sizeof(zip_file_header) +
4183 									zip_file_header.name_size + zip_file_header.extra_size;
4184 			if (zip_file_header.compression_method != COMPRESS_STORED || z_info->file_offset % PAGE_SIZE != 0) {
4185 				LD_LOGE("Open uncompressed library: open %{public}s in %{public}s failed because of misalignment or saved with compression."
4186 						"compress method %{public}d, file offset %{public}lu",
4187 						lib_path, zip_file_path, zip_file_header.compression_method, z_info->file_offset);
4188 				fclose(zip_file);
4189 				return -2;
4190 			}
4191 			z_info->found = true;
4192 			break;
4193 		}
4194 
4195 		memset(file_name, 0, sizeof(file_name));
4196 		current_dir_pos += sizeof(c_dir_entry);
4197 		current_dir_pos += c_dir_entry.name_size + c_dir_entry.extra_size + c_dir_entry.comment_size;
4198 	}
4199 	if(!z_info->found) {
4200 		LD_LOGE("Open uncompressed library: %{public}s was not found in %{public}s.", lib_path, zip_file_path);
4201 		fclose(zip_file);
4202 		return -3;
4203 	}
4204 	z_info->fd = fileno(zip_file);
4205 
4206 	return 0;
4207 }
4208 
map_library_header(struct loadtask * task)4209 static bool map_library_header(struct loadtask *task)
4210 {
4211 	off_t off_start;
4212 	Phdr *ph;
4213 	size_t i;
4214 
4215 	ssize_t l = pread(task->fd, task->ehdr_buf, sizeof task->ehdr_buf, task->file_offset);
4216 	task->eh = task->ehdr_buf;
4217 	if (l < 0) {
4218 		LD_LOGE("Error mapping header %{public}s: failed to read fd", task->name);
4219 		return false;
4220 	}
4221 	if (l < sizeof(Ehdr) || (task->eh->e_type != ET_DYN && task->eh->e_type != ET_EXEC)) {
4222 		LD_LOGE("Error mapping header %{public}s: invaliled Ehdr", task->name);
4223 		goto noexec;
4224 	}
4225 	task->phsize = task->eh->e_phentsize * task->eh->e_phnum;
4226 	if (task->phsize > sizeof task->ehdr_buf - sizeof(Ehdr)) {
4227 		task->allocated_buf = internal_malloc(task->phsize);
4228 		if (!task->allocated_buf) {
4229 			LD_LOGE("Error mapping header %{public}s: failed to alloc memory", task->name);
4230 			return false;
4231 		}
4232 		l = pread(task->fd, task->allocated_buf, task->phsize, task->eh->e_phoff + task->file_offset);
4233 		if (l < 0) {
4234 			LD_LOGE("Error mapping header %{public}s: failed to pread", task->name);
4235 			goto error;
4236 		}
4237 		if (l != task->phsize) {
4238 			LD_LOGE("Error mapping header %{public}s: unmatched phsize", task->name);
4239 			goto noexec;
4240 		}
4241 		ph = task->ph0 = task->allocated_buf;
4242 	} else if (task->eh->e_phoff + task->phsize > l) {
4243 		l = pread(task->fd, task->ehdr_buf + 1, task->phsize, task->eh->e_phoff + task->file_offset);
4244 		if (l < 0) {
4245 			LD_LOGE("Error mapping header %{public}s: failed to pread", task->name);
4246 			goto error;
4247 		}
4248 		if (l != task->phsize) {
4249 			LD_LOGE("Error mapping header %{public}s: unmatched phsize", task->name);
4250 			goto noexec;
4251 		}
4252 		ph = task->ph0 = (void *)(task->ehdr_buf + 1);
4253 	} else {
4254 		ph = task->ph0 = (void *)((char *)task->ehdr_buf + task->eh->e_phoff);
4255 	}
4256 	for (i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4257 		if (ph->p_type == PT_DYNAMIC) {
4258 			task->dyn = ph->p_vaddr;
4259 		} else if (ph->p_type == PT_TLS) {
4260 			task->tls_image = ph->p_vaddr;
4261 			task->tls.align = ph->p_align;
4262 			task->tls.len = ph->p_filesz;
4263 			task->tls.size = ph->p_memsz;
4264 		}
4265 
4266 		if (ph->p_type != PT_DYNAMIC) {
4267 			continue;
4268 		}
4269 		// map the dynamic segment and the string table of the library
4270 		off_start = ph->p_offset;
4271 		off_start &= -PAGE_SIZE;
4272 		task->dyn_map_len = ph->p_memsz + (ph->p_offset - off_start);
4273 		/* The default value of file_offset is 0.
4274 		 * The value of file_offset may be greater than 0 when opening library from zip file.
4275 		 * The value of file_offset ensures PAGE_SIZE aligned. */
4276 		task->dyn_map = mmap(0, task->dyn_map_len, PROT_READ, MAP_PRIVATE, task->fd, off_start + task->file_offset);
4277 		if (task->dyn_map == MAP_FAILED) {
4278 			LD_LOGE("Error mapping header %{public}s: failed to map dynamic section", task->name);
4279 			goto error;
4280 		}
4281 		task->dyn_addr = (size_t *)((unsigned char *)task->dyn_map + (ph->p_offset - off_start));
4282 		size_t dyn_tmp;
4283 		off_t str_table;
4284 		size_t str_size;
4285 		if (search_vec(task->dyn_addr, &dyn_tmp, DT_STRTAB)) {
4286 			str_table = dyn_tmp;
4287 		} else {
4288 			LD_LOGE("Error mapping header %{public}s: DT_STRTAB not found", task->name);
4289 			goto error;
4290 		}
4291 		if (search_vec(task->dyn_addr, &dyn_tmp, DT_STRSZ)) {
4292 			str_size = dyn_tmp;
4293 		} else {
4294 			LD_LOGE("Error mapping header %{public}s: DT_STRSZ not found", task->name);
4295 			goto error;
4296 		}
4297 		off_start = str_table;
4298 		off_start &= -PAGE_SIZE;
4299 		task->str_map_len = str_size + (str_table - off_start);
4300 		task->str_map = mmap(0, task->str_map_len, PROT_READ, MAP_PRIVATE, task->fd, off_start + task->file_offset);
4301 		if (task->str_map == MAP_FAILED) {
4302 			LD_LOGE("Error mapping header %{public}s: failed to map string section", task->name);
4303 			goto error;
4304 		}
4305 		task->str_addr = (char *)task->str_map + str_table - off_start;
4306 	}
4307 	if (!task->dyn) {
4308 		LD_LOGE("Error mapping header %{public}s: dynamic section not found", task->name);
4309 		goto noexec;
4310 	}
4311 	return true;
4312 noexec:
4313 	errno = ENOEXEC;
4314 error:
4315 	internal_free(task->allocated_buf);
4316 	task->allocated_buf = NULL;
4317 	return false;
4318 }
4319 
task_map_library(struct loadtask * task,struct reserved_address_params * reserved_params)4320 static bool task_map_library(struct loadtask *task, struct reserved_address_params *reserved_params)
4321 {
4322 	size_t addr_min = SIZE_MAX, addr_max = 0, map_len;
4323 	size_t this_min, this_max;
4324 	size_t nsegs = 0;
4325 	off_t off_start;
4326 	Phdr *ph = task->ph0;
4327 	unsigned prot;
4328 	unsigned char *map = MAP_FAILED, *base;
4329 	size_t i;
4330 	int map_flags = MAP_PRIVATE;
4331 	size_t start_addr;
4332 
4333 	for (i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4334 		if (ph->p_type == PT_GNU_RELRO) {
4335 			task->p->relro_start = ph->p_vaddr & -PAGE_SIZE;
4336 			task->p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
4337 		} else if (ph->p_type == PT_GNU_STACK) {
4338 			if (!runtime && ph->p_memsz > __default_stacksize) {
4339 				__default_stacksize =
4340 					ph->p_memsz < DEFAULT_STACK_MAX ?
4341 					ph->p_memsz : DEFAULT_STACK_MAX;
4342 			}
4343 		}
4344 		if (ph->p_type != PT_LOAD) {
4345 			continue;
4346 		}
4347 		nsegs++;
4348 		if (ph->p_vaddr < addr_min) {
4349 			addr_min = ph->p_vaddr;
4350 			off_start = ph->p_offset;
4351 			prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4352 				((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4353 				((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4354 		}
4355 		if (ph->p_vaddr + ph->p_memsz > addr_max) {
4356 			addr_max = ph->p_vaddr + ph->p_memsz;
4357 		}
4358 	}
4359 	if (!task->dyn) {
4360 		LD_LOGE("Error mapping library %{public}s: dynamic section not found", task->name);
4361 		goto noexec;
4362 	}
4363 	if (DL_FDPIC && !(task->eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
4364 		task->p->loadmap = internal_calloc(1, sizeof(struct fdpic_loadmap) + nsegs * sizeof(struct fdpic_loadseg));
4365 		if (!task->p->loadmap) {
4366 			goto error;
4367 		}
4368 		task->p->loadmap->nsegs = nsegs;
4369 		for (ph = task->ph0, i = 0; i < nsegs; ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4370 			if (ph->p_type != PT_LOAD) {
4371 				continue;
4372 			}
4373 			prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4374 				((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4375 				((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4376 			map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE - 1),
4377 				prot, MAP_PRIVATE,
4378 				task->fd, ph->p_offset & -PAGE_SIZE + task->file_offset);
4379 			if (map == MAP_FAILED) {
4380 				unmap_library(task->p);
4381 				goto error;
4382 			}
4383 			task->p->loadmap->segs[i].addr = (size_t)map +
4384 				(ph->p_vaddr & PAGE_SIZE - 1);
4385 			task->p->loadmap->segs[i].p_vaddr = ph->p_vaddr;
4386 			task->p->loadmap->segs[i].p_memsz = ph->p_memsz;
4387 			i++;
4388 			if (prot & PROT_WRITE) {
4389 				size_t brk = (ph->p_vaddr & PAGE_SIZE - 1) + ph->p_filesz;
4390 				size_t pgbrk = (brk + PAGE_SIZE - 1) & -PAGE_SIZE;
4391 				size_t pgend = (brk + ph->p_memsz - ph->p_filesz + PAGE_SIZE - 1) & -PAGE_SIZE;
4392 				if (pgend > pgbrk && mmap_fixed(map + pgbrk,
4393 					pgend - pgbrk, prot,
4394 					MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
4395 					-1, off_start) == MAP_FAILED)
4396 					goto error;
4397 				memset(map + brk, 0, pgbrk - brk);
4398 			}
4399 		}
4400 		map = (void *)task->p->loadmap->segs[0].addr;
4401 		map_len = 0;
4402 		goto done_mapping;
4403 	}
4404 	addr_max += PAGE_SIZE - 1;
4405 	addr_max &= -PAGE_SIZE;
4406 	addr_min &= -PAGE_SIZE;
4407 	off_start &= -PAGE_SIZE;
4408 	map_len = addr_max - addr_min + off_start;
4409 	start_addr = addr_min;
4410 	if (reserved_params) {
4411 		if (map_len > reserved_params->reserved_size) {
4412 			if (reserved_params->must_use_reserved) {
4413 				LD_LOGE("Error mapping library %{public}s: map len is larger than reserved address", task->name);
4414 				goto error;
4415 			}
4416 		} else {
4417 			start_addr = ((size_t)reserved_params->start_addr - 1 + PAGE_SIZE) & -PAGE_SIZE;
4418 			map_flags |= MAP_FIXED;
4419 		}
4420 	}
4421 	/* The first time, we map too much, possibly even more than
4422 	 * the length of the file. This is okay because we will not
4423 	 * use the invalid part; we just need to reserve the right
4424 	 * amount of virtual address space to map over later. */
4425 	map = DL_NOMMU_SUPPORT
4426 			? mmap((void *)start_addr, map_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
4427 			: mmap((void *)start_addr, map_len, prot, map_flags, task->fd, off_start + task->file_offset);
4428 	if (map == MAP_FAILED) {
4429 		LD_LOGE("Error mapping library %{public}s: failed to map fd", task->name);
4430 		goto error;
4431 	}
4432 	if (reserved_params && map_len < reserved_params->reserved_size) {
4433 		reserved_params->reserved_size -= (map_len + (start_addr - (size_t)reserved_params->start_addr));
4434 		reserved_params->start_addr = (void *)((uint8_t *)map + map_len);
4435 	}
4436 	task->p->map = map;
4437 	task->p->map_len = map_len;
4438 	/* If the loaded file is not relocatable and the requested address is
4439 	 * not available, then the load operation must fail. */
4440 	if (task->eh->e_type != ET_DYN && addr_min && map != (void *)addr_min) {
4441 		LD_LOGE("Error mapping library %{public}s: device or resource busy", task->name);
4442 		errno = EBUSY;
4443 		goto error;
4444 	}
4445 	base = map - addr_min;
4446 	task->p->phdr = 0;
4447 	task->p->phnum = 0;
4448 	for (ph = task->ph0, i = task->eh->e_phnum; i; i--, ph = (void *)((char *)ph + task->eh->e_phentsize)) {
4449 		if (ph->p_type == PT_OHOS_RANDOMDATA) {
4450 			fill_random_data((void *)(ph->p_vaddr + base), ph->p_memsz);
4451 			continue;
4452 		}
4453 		if (ph->p_type != PT_LOAD) {
4454 			continue;
4455 		}
4456 		/* Check if the programs headers are in this load segment, and
4457 		 * if so, record the address for use by dl_iterate_phdr. */
4458 		if (!task->p->phdr && task->eh->e_phoff >= ph->p_offset
4459 			&& task->eh->e_phoff + task->phsize <= ph->p_offset + ph->p_filesz) {
4460 			task->p->phdr = (void *)(base + ph->p_vaddr + (task->eh->e_phoff - ph->p_offset));
4461 			task->p->phnum = task->eh->e_phnum;
4462 			task->p->phentsize = task->eh->e_phentsize;
4463 		}
4464 		this_min = ph->p_vaddr & -PAGE_SIZE;
4465 		this_max = ph->p_vaddr + ph->p_memsz + PAGE_SIZE - 1 & -PAGE_SIZE;
4466 		off_start = ph->p_offset & -PAGE_SIZE;
4467 		prot = (((ph->p_flags & PF_R) ? PROT_READ : 0) |
4468 			((ph->p_flags & PF_W) ? PROT_WRITE : 0) |
4469 			((ph->p_flags & PF_X) ? PROT_EXEC : 0));
4470 		/* Reuse the existing mapping for the lowest-address LOAD */
4471 		if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT) {
4472 			if (mmap_fixed(
4473 					base + this_min,
4474 					this_max - this_min,
4475 					prot, MAP_PRIVATE | MAP_FIXED,
4476 					task->fd,
4477 					off_start + task->file_offset) == MAP_FAILED) {
4478 				LD_LOGE("Error mapping library %{public}s: mmap fix failed, errno: %{public}d", task->name, errno);
4479 				goto error;
4480 			}
4481 		}
4482 		if (ph->p_memsz > ph->p_filesz && (ph->p_flags & PF_W)) {
4483 			size_t brk = (size_t)base + ph->p_vaddr + ph->p_filesz;
4484 			size_t pgbrk = brk + PAGE_SIZE - 1 & -PAGE_SIZE;
4485 			memset((void *)brk, 0, pgbrk - brk & PAGE_SIZE - 1);
4486 			if (pgbrk - (size_t)base < this_max && mmap_fixed(
4487 				(void *)pgbrk,
4488 				(size_t)base + this_max - pgbrk,
4489 				prot,
4490 				MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
4491 				-1,
4492 				0) == MAP_FAILED) {
4493 				LD_LOGE("Error mapping library: mmap fix failed");
4494 				goto error;
4495 			}
4496 		}
4497 	}
4498 	for (i = 0; ((size_t *)(base + task->dyn))[i]; i += NEXT_DYNAMIC_INDEX) {
4499 		if (((size_t *)(base + task->dyn))[i] == DT_TEXTREL) {
4500 			if (mprotect(map, map_len, PROT_READ | PROT_WRITE | PROT_EXEC) && errno != ENOSYS) {
4501 				LD_LOGE("Error mapping library %{public}s: mprotect failed", task->name);
4502 				goto error;
4503 			}
4504 			break;
4505 		}
4506 	}
4507 done_mapping:
4508 	task->p->base = base;
4509 	task->p->dynv = laddr(task->p, task->dyn);
4510 	if (task->p->tls.size) {
4511 		task->p->tls.image = laddr(task->p, task->tls_image);
4512 	}
4513 	internal_free(task->allocated_buf);
4514 	task->allocated_buf = NULL;
4515 	return true;
4516 noexec:
4517 	errno = ENOEXEC;
4518 error:
4519 	if (map != MAP_FAILED) {
4520 		unmap_library(task->p);
4521 	}
4522 	internal_free(task->allocated_buf);
4523 	task->allocated_buf = NULL;
4524 	return false;
4525 }
4526 
load_library_header(struct loadtask * task)4527 static bool load_library_header(struct loadtask *task)
4528 {
4529 	const char *name = task->name;
4530 	struct dso *needed_by = task->needed_by;
4531 	ns_t *namespace = task->namespace;
4532 	bool check_inherited = task->check_inherited;
4533 	struct zip_info z_info;
4534 
4535 	bool map = false;
4536 	struct stat st;
4537 	size_t alloc_size;
4538 	int n_th = 0;
4539 	int is_self = 0;
4540 
4541 	if (!*name) {
4542 		errno = EINVAL;
4543 		return false;
4544 	}
4545 
4546 	/* Catch and block attempts to reload the implementation itself */
4547 	if (name[NAME_INDEX_ZERO] == 'l' && name[NAME_INDEX_ONE] == 'i' && name[NAME_INDEX_TWO] == 'b') {
4548 		static const char reserved[] =
4549 			"c.pthread.rt.m.dl.util.xnet.";
4550 		const char *rp, *next;
4551 		for (rp = reserved; *rp; rp = next) {
4552 			next = strchr(rp, '.') + 1;
4553 			if (strncmp(name + NAME_INDEX_THREE, rp, next - rp) == 0) {
4554 				break;
4555 			}
4556 		}
4557 		if (*rp) {
4558 			if (ldd_mode) {
4559 				/* Track which names have been resolved
4560 				 * and only report each one once. */
4561 				static unsigned reported;
4562 				unsigned mask = 1U << (rp - reserved);
4563 				if (!(reported & mask)) {
4564 					reported |= mask;
4565 					dprintf(1, "\t%s => %s (%p)\n",
4566 						name, ldso.name,
4567 						ldso.base);
4568 				}
4569 			}
4570 			is_self = 1;
4571 		}
4572 	}
4573 	if (!strcmp(name, ldso.name)) {
4574 		is_self = 1;
4575 	}
4576 	if (is_self) {
4577 		if (!ldso.prev) {
4578 			tail->next = &ldso;
4579 			ldso.prev = tail;
4580 			tail = &ldso;
4581 			ldso.namespace = namespace;
4582 			ns_add_dso(namespace, &ldso);
4583 		}
4584 		task->isloaded = true;
4585 		task->p = &ldso;
4586 		return true;
4587 	}
4588 	if (strchr(name, '/')) {
4589 		char *separator = strstr(name, ZIP_FILE_PATH_SEPARATOR);
4590 		if (separator != NULL) {
4591 			int res = open_uncompressed_library_in_zipfile(name, &z_info, separator);
4592 			if (!res) {
4593 				task->pathname = name;
4594 				if (!is_accessible(namespace, task->pathname, g_is_asan, check_inherited)) {
4595 					LD_LOGE("Open uncompressed library: check ns accessible failed, pathname %{public}s namespace %{public}s.",
4596 							task->pathname, namespace ? namespace->ns_name : "NULL");
4597 					task->fd = -1;
4598 				} else {
4599 					task->fd = z_info.fd;
4600 					task->file_offset = z_info.file_offset;
4601 				}
4602 			} else {
4603 				LD_LOGE("Open uncompressed library in zip file failed, name:%{public}s res:%{public}d", name, res);
4604 				return false;
4605 			}
4606 		} else {
4607 			task->pathname = name;
4608 			if (!is_accessible(namespace, task->pathname, g_is_asan, check_inherited)) {
4609 				task->fd = -1;
4610 			} else {
4611 				task->fd = open(name, O_RDONLY | O_CLOEXEC);
4612 			}
4613 		}
4614 	} else {
4615 		/* Search for the name to see if it's already loaded */
4616 		/* Search in namespace */
4617 		task->p = find_library_by_name(name, namespace, check_inherited);
4618 		if (task->p) {
4619 			task->isloaded = true;
4620 			return true;
4621 		}
4622 		if (strlen(name) > NAME_MAX) {
4623 			LD_LOGE("load_library name length is larger than NAME_MAX:%{public}s.", name);
4624 			return false;
4625 		}
4626 		task->fd = -1;
4627 		if (namespace->env_paths) {
4628 			open_library_by_path(name, namespace->env_paths, task, &z_info);
4629 		}
4630 		for (task->p = needed_by; task->fd == -1 && task->p; task->p = task->p->needed_by) {
4631 			if (fixup_rpath(task->p, task->buf, sizeof task->buf) < 0) {
4632 				task->fd = INVALID_FD_INHIBIT_FURTHER_SEARCH; /* Inhibit further search. */
4633 			}
4634 			if (task->p->rpath) {
4635 				open_library_by_path(name, task->p->rpath, task, &z_info);
4636 			}
4637 		}
4638 		if (g_is_asan) {
4639 			handle_asan_path_open_by_task(task->fd, name, namespace, task, &z_info);
4640 			LD_LOGD("load_library handle_asan_path_open_by_task fd:%{public}d.", task->fd);
4641 		} else {
4642 			if (task->fd == -1 && namespace->lib_paths) {
4643 				open_library_by_path(name, namespace->lib_paths, task, &z_info);
4644 				LD_LOGD("load_library no asan lib_paths path_open fd:%{public}d.", task->fd);
4645 			}
4646 		}
4647 		task->pathname = task->buf;
4648 	}
4649 	if (task->fd < 0) {
4650 		if (!check_inherited || !namespace->ns_inherits) {
4651 			return false;
4652 		}
4653 		/* Load lib in inherited namespace. Do not check inherited again.*/
4654 		for (size_t i = 0; i < namespace->ns_inherits->num; i++) {
4655 			ns_inherit *inherit = namespace->ns_inherits->inherits[i];
4656 			if (strchr(name, '/') == 0 && !is_sharable(inherit, name)) {
4657 				continue;
4658 			}
4659 			task->namespace = inherit->inherited_ns;
4660 			task->check_inherited = false;
4661 			if (load_library_header(task)) {
4662 				return true;
4663 			}
4664 		}
4665 		return false;
4666 	}
4667 
4668 	if (fstat(task->fd, &st) < 0) {
4669 		LD_LOGE("Error loading header %{public}s: failed to get file state", task->name);
4670 		close(task->fd);
4671 		task->fd = -1;
4672 		return false;
4673 	}
4674 	/* Search in namespace */
4675 	task->p = find_library_by_fstat(&st, namespace, check_inherited, task->file_offset);
4676 	if (task->p) {
4677 		/* If this library was previously loaded with a
4678 		* pathname but a search found the same inode,
4679 		* setup its shortname so it can be found by name. */
4680 		if (!task->p->shortname && task->pathname != name) {
4681 			task->p->shortname = strrchr(task->p->name, '/') + 1;
4682 		}
4683 		close(task->fd);
4684 		task->fd = -1;
4685 		task->isloaded = true;
4686 		return true;
4687 	}
4688 
4689 	map = noload ? 0 : map_library_header(task);
4690 	if (!map) {
4691 		LD_LOGE("Error loading header %{public}s: failed to map header", task->name);
4692 		close(task->fd);
4693 		task->fd = -1;
4694 		return false;
4695 	}
4696 
4697 	/* Allocate storage for the new DSO. When there is TLS, this
4698 	 * storage must include a reservation for all pre-existing
4699 	 * threads to obtain copies of both the new TLS, and an
4700 	 * extended DTV capable of storing an additional slot for
4701 	 * the newly-loaded DSO. */
4702 	alloc_size = sizeof(struct dso) + strlen(task->pathname) + 1;
4703 	if (runtime && task->tls.size) {
4704 		size_t per_th = task->tls.size + task->tls.align + sizeof(void *) * (tls_cnt + TLS_CNT_INCREASE);
4705 		n_th = libc.threads_minus_1 + 1;
4706 		if (n_th > SSIZE_MAX / per_th) {
4707 			alloc_size = SIZE_MAX;
4708 		} else {
4709 			alloc_size += n_th * per_th;
4710 		}
4711 	}
4712 	task->p = internal_calloc(1, alloc_size);
4713 	if (!task->p) {
4714 		LD_LOGE("Error loading header %{public}s: failed to allocate dso", task->name);
4715 		close(task->fd);
4716 		task->fd = -1;
4717 		return false;
4718 	}
4719 	task->p->dev = st.st_dev;
4720 	task->p->ino = st.st_ino;
4721 	task->p->file_offset = task->file_offset;
4722 	task->p->needed_by = needed_by;
4723 	task->p->name = task->p->buf;
4724 	strcpy(task->p->name, task->pathname);
4725 	task->p->tls = task->tls;
4726 	task->p->dynv = task->dyn_addr;
4727 	task->p->strings = task->str_addr;
4728 
4729 	/* Add a shortname only if name arg was not an explicit pathname. */
4730 	if (task->pathname != name) {
4731 		task->p->shortname = strrchr(task->p->name, '/') + 1;
4732 	}
4733 
4734 	if (task->p->tls.size) {
4735 		task->p->tls_id = ++tls_cnt;
4736 		task->p->new_dtv = (void *)(-sizeof(size_t) &
4737 			(uintptr_t)(task->p->name + strlen(task->p->name) + sizeof(size_t)));
4738 		task->p->new_tls = (void *)(task->p->new_dtv + n_th * (tls_cnt + 1));
4739 	}
4740 
4741 	tail->next = task->p;
4742 	task->p->prev = tail;
4743 	tail = task->p;
4744 
4745 	/* Add dso to namespace */
4746 	task->p->namespace = namespace;
4747 	ns_add_dso(namespace, task->p);
4748 	return true;
4749 }
4750 
task_load_library(struct loadtask * task,struct reserved_address_params * reserved_params)4751 static void task_load_library(struct loadtask *task, struct reserved_address_params *reserved_params)
4752 {
4753 	bool map = noload ? 0 : task_map_library(task, reserved_params);
4754 	close(task->fd);
4755 	task->fd = -1;
4756 	if (!map) {
4757 		LD_LOGE("Error loading library %{public}s: failed to map library", task->name);
4758 		error("Error loading library %s: failed to map library", task->name);
4759 		if (runtime) {
4760 			longjmp(*rtld_fail, 1);
4761 		}
4762 		return;
4763 	};
4764 
4765 	/* Avoid the danger of getting two versions of libc mapped into the
4766 	 * same process when an absolute pathname was used. The symbols
4767 	 * checked are chosen to catch both musl and glibc, and to avoid
4768 	 * false positives from interposition-hack libraries. */
4769 	decode_dyn(task->p);
4770 	if (find_sym(task->p, "__libc_start_main", 1).sym &&
4771 		find_sym(task->p, "stdin", 1).sym) {
4772 		do_dlclose(task->p);
4773 		task->p = NULL;
4774 		internal_free((void*)task->name);
4775 		task->name = ld_strdup("libc.so");
4776 		task->check_inherited = true;
4777 		if (!load_library_header(task)) {
4778 			LD_LOGE("Error loading library %{public}s: failed to load libc.so", task->name);
4779 			error("Error loading library %s: failed to load libc.so", task->name);
4780 			if (runtime) {
4781 				longjmp(*rtld_fail, 1);
4782 			}
4783 		}
4784 		return;
4785 	}
4786 	/* Past this point, if we haven't reached runtime yet, ldso has
4787 	 * committed either to use the mapped library or to abort execution.
4788 	 * Unmapping is not possible, so we can safely reclaim gaps. */
4789 	if (!runtime) {
4790 		reclaim_gaps(task->p);
4791 	}
4792 	task->p->runtime_loaded = runtime;
4793 	if (runtime)
4794 		task->p->by_dlopen = 1;
4795 
4796 	if (DL_FDPIC) {
4797 		makefuncdescs(task->p);
4798 	}
4799 
4800 	if (ldd_mode) {
4801 		dprintf(1, "\t%s => %s (%p)\n", task->name, task->pathname, task->p->base);
4802 	}
4803 }
4804 
preload_direct_deps(struct dso * p,ns_t * namespace,struct loadtasks * tasks)4805 static void preload_direct_deps(struct dso *p, ns_t *namespace, struct loadtasks *tasks)
4806 {
4807 	size_t i, cnt = 0;
4808 	if (p->deps) {
4809 		return;
4810 	}
4811 	/* For head, all preloads are direct pseudo-dependencies.
4812 	 * Count and include them now to avoid realloc later. */
4813 	if (p == head) {
4814 		for (struct dso *q = p->next; q; q = q->next) {
4815 			cnt++;
4816 		}
4817 	}
4818 	for (i = 0; p->dynv[i]; i += NEXT_DYNAMIC_INDEX) {
4819 		if (p->dynv[i] == DT_NEEDED) {
4820 			cnt++;
4821 		}
4822 	}
4823 	/* Use builtin buffer for apps with no external deps, to
4824 	 * preserve property of no runtime failure paths. */
4825 	p->deps = (p == head && cnt < MIN_DEPS_COUNT) ? builtin_deps :
4826 		internal_calloc(cnt + 1, sizeof *p->deps);
4827 	if (!p->deps) {
4828 		LD_LOGE("Error loading dependencies for %{public}s", p->name);
4829 		error("Error loading dependencies for %s", p->name);
4830 		if (runtime) {
4831 			longjmp(*rtld_fail, 1);
4832 		}
4833 	}
4834 	cnt = 0;
4835 	if (p == head) {
4836 		for (struct dso *q = p->next; q; q = q->next) {
4837 			p->deps[cnt++] = q;
4838 		}
4839 	}
4840 	for (i = 0; p->dynv[i]; i += NEXT_DYNAMIC_INDEX) {
4841 		if (p->dynv[i] != DT_NEEDED) {
4842 			continue;
4843 		}
4844 		struct loadtask *task = create_loadtask(p->strings + p->dynv[i + 1], p, namespace, true);
4845 		if (!task) {
4846 			LD_LOGE("Error loading dependencies %{public}s : create load task failed", p->name);
4847 			error("Error loading dependencies for %s : create load task failed", p->name);
4848 			if (runtime) {
4849 				longjmp(*rtld_fail, 1);
4850 			}
4851 			continue;
4852 		}
4853 		LD_LOGD("loading shared library %{public}s: (needed by %{public}s)", p->strings + p->dynv[i+1], p->name);
4854 		if (!load_library_header(task)) {
4855 			free_task(task);
4856 			task = NULL;
4857 			LD_LOGE("Error loading shared library %{public}s: (needed by %{public}s)",
4858 				p->strings + p->dynv[i + 1],
4859 				p->name);
4860 			error("Error loading shared library %s: %m (needed by %s)",
4861 				p->strings + p->dynv[i + 1], p->name);
4862 			if (runtime) {
4863 				longjmp(*rtld_fail, 1);
4864 			}
4865 			continue;
4866 		}
4867 		p->deps[cnt++] = task->p;
4868 		if (task->isloaded) {
4869 			free_task(task);
4870 			task = NULL;
4871 		} else {
4872 			append_loadtasks(tasks, task);
4873 		}
4874 	}
4875 	p->deps[cnt] = 0;
4876 	p->ndeps_direct = cnt;
4877 	for (i = 0; i < p->ndeps_direct; i++) {
4878 		add_dso_parent(p->deps[i], p);
4879 	}
4880 }
4881 
unmap_preloaded_sections(struct loadtasks * tasks)4882 static void unmap_preloaded_sections(struct loadtasks *tasks)
4883 {
4884 	struct loadtask *task = NULL;
4885 	for (size_t i = 0; i < tasks->length; i++) {
4886 		task = get_loadtask(tasks, i);
4887 		if (!task) {
4888 			continue;
4889 		}
4890 		if (task->dyn_map_len) {
4891 			munmap(task->dyn_map, task->dyn_map_len);
4892 			task->dyn_map = NULL;
4893 			task->dyn_map_len = 0;
4894 			if (task->p) {
4895 				task->p->dynv = NULL;
4896 			}
4897 		}
4898 		if (task->str_map_len) {
4899 			munmap(task->str_map, task->str_map_len);
4900 			task->str_map = NULL;
4901 			task->str_map_len = 0;
4902 			if (task->p) {
4903 				task->p->strings = NULL;
4904 			}
4905 		}
4906 	}
4907 }
4908 
preload_deps(struct dso * p,struct loadtasks * tasks)4909 static void preload_deps(struct dso *p, struct loadtasks *tasks)
4910 {
4911 	if (p->deps) {
4912 		return;
4913 	}
4914 	for (; p; p = p->next) {
4915 		preload_direct_deps(p, p->namespace, tasks);
4916 	}
4917 }
4918 
run_loadtasks(struct loadtasks * tasks,struct reserved_address_params * reserved_params)4919 static void run_loadtasks(struct loadtasks *tasks, struct reserved_address_params *reserved_params)
4920 {
4921 	struct loadtask *task = NULL;
4922 	bool reserved_address = false;
4923 	for (size_t i = 0; i < tasks->length; i++) {
4924 		task = get_loadtask(tasks, i);
4925 		if (task) {
4926 			if (reserved_params) {
4927 				reserved_address = reserved_params->reserved_address_recursive || (reserved_params->target == task->p);
4928 			}
4929 			task_load_library(task, reserved_address ? reserved_params : NULL);
4930 		}
4931 	}
4932 }
4933 
assign_tls(struct dso * p)4934 static void assign_tls(struct dso *p)
4935 {
4936 	while (p) {
4937 		if (p->tls.image) {
4938 			tls_align = MAXP2(tls_align, p->tls.align);
4939 #ifdef TLS_ABOVE_TP
4940 			p->tls.offset = tls_offset + ((p->tls.align - 1) &
4941 				(-tls_offset + (uintptr_t)p->tls.image));
4942 			tls_offset = p->tls.offset + p->tls.size;
4943 #else
4944 			tls_offset += p->tls.size + p->tls.align - 1;
4945 			tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
4946 				& (p->tls.align - 1);
4947 			p->tls.offset = tls_offset;
4948 #endif
4949 			if (tls_tail) {
4950 				tls_tail->next = &p->tls;
4951 			} else {
4952 				libc.tls_head = &p->tls;
4953 			}
4954 			tls_tail = &p->tls;
4955 		}
4956 
4957 		p = p->next;
4958 	}
4959 }
4960 
load_preload(char * s,ns_t * ns,struct loadtasks * tasks)4961 static void load_preload(char *s, ns_t *ns, struct loadtasks *tasks)
4962 {
4963 	int tmp;
4964 	char *z;
4965 
4966 	struct loadtask *task = NULL;
4967 	for (z = s; *z; s = z) {
4968 		for (; *s && (isspace(*s) || *s == ':'); s++) {
4969 			;
4970 		}
4971 		for (z = s; *z && !isspace(*z) && *z != ':'; z++) {
4972 			;
4973 		}
4974 		tmp = *z;
4975 		*z = 0;
4976 		task = create_loadtask(s, NULL, ns, true);
4977 		if (!task) {
4978 			continue;
4979 		}
4980 		if (load_library_header(task)) {
4981 			if (!task->isloaded) {
4982 				append_loadtasks(tasks, task);
4983 				task = NULL;
4984 			}
4985 		}
4986 		if (task) {
4987 			free_task(task);
4988 		}
4989 		*z = tmp;
4990 	}
4991 }
4992 #endif
4993 
serialize_gnu_relro(int fd,struct dso * dso,ssize_t * file_offset)4994 static int serialize_gnu_relro(int fd, struct dso *dso, ssize_t *file_offset)
4995 {
4996 	ssize_t count = dso->relro_end - dso->relro_start;
4997 	ssize_t offset = 0;
4998 	while (count > 0) {
4999 		ssize_t write_size = TEMP_FAILURE_RETRY(write(fd, laddr(dso, dso->relro_start + offset), count));
5000 		if (-1 == write_size) {
5001 			LD_LOGE("Error serializing relro %{public}s: failed to write GNU_RELRO", dso->name);
5002 			return -1;
5003 		}
5004 		offset += write_size;
5005 		count -= write_size;
5006 	}
5007 
5008 	ssize_t size = dso->relro_end - dso->relro_start;
5009 	void *map = mmap(
5010 		laddr(dso, dso->relro_start),
5011 		size,
5012 		PROT_READ,
5013 		MAP_PRIVATE | MAP_FIXED,
5014 		fd,
5015 		*file_offset);
5016 	if (map == MAP_FAILED) {
5017 		LD_LOGE("Error serializing relro %{public}s: failed to map GNU_RELRO", dso->name);
5018 		return -1;
5019 	}
5020 	*file_offset += size;
5021 	return 0;
5022 }
5023 
map_gnu_relro(int fd,struct dso * dso,ssize_t * file_offset)5024 static int map_gnu_relro(int fd, struct dso *dso, ssize_t *file_offset)
5025 {
5026 	ssize_t ext_fd_file_size = 0;
5027 	struct stat ext_fd_file_stat;
5028 	if (TEMP_FAILURE_RETRY(fstat(fd, &ext_fd_file_stat)) != 0) {
5029 		LD_LOGE("Error mapping relro %{public}s: failed to get file state", dso->name);
5030 		return -1;
5031 	}
5032 	ext_fd_file_size = ext_fd_file_stat.st_size;
5033 
5034 	void *ext_temp_map = MAP_FAILED;
5035 	ext_temp_map = mmap(NULL, ext_fd_file_size, PROT_READ, MAP_PRIVATE, fd, 0);
5036 	if (ext_temp_map == MAP_FAILED) {
5037 		LD_LOGE("Error mapping relro %{public}s: failed to map fd", dso->name);
5038 		return -1;
5039 	}
5040 
5041 	char *file_base = (char *)(ext_temp_map) + *file_offset;
5042 	char *mem_base = (char *)(laddr(dso, dso->relro_start));
5043 	ssize_t start_offset = 0;
5044 	ssize_t size = dso->relro_end - dso->relro_start;
5045 
5046 	if (size > ext_fd_file_size - *file_offset) {
5047 		LD_LOGE("Error mapping relro %{public}s: invalid file size", dso->name);
5048 		return -1;
5049 	}
5050 	while (start_offset < size) {
5051 		// Find start location.
5052 		while (start_offset < size) {
5053 			if (memcmp(mem_base + start_offset, file_base + start_offset, PAGE_SIZE) == 0) {
5054 				break;
5055 			}
5056 			start_offset += PAGE_SIZE;
5057 		}
5058 
5059 		// Find end location.
5060 		ssize_t end_offset = start_offset;
5061 		while (end_offset < size) {
5062 			if (memcmp(mem_base + end_offset, file_base + end_offset, PAGE_SIZE) != 0) {
5063 				break;
5064 			}
5065 			end_offset += PAGE_SIZE;
5066 		}
5067 
5068 		// Map pages.
5069 		ssize_t map_length = end_offset - start_offset;
5070 		ssize_t map_offset = *file_offset + start_offset;
5071 		if (map_length > 0) {
5072 			void *map = mmap(
5073 				mem_base + start_offset, map_length, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, map_offset);
5074 			if (map == MAP_FAILED) {
5075 				LD_LOGE("Error mapping relro %{public}s: failed to map GNU_RELRO", dso->name);
5076 				munmap(ext_temp_map, ext_fd_file_size);
5077 				return -1;
5078 			}
5079 		}
5080 
5081 		start_offset = end_offset;
5082 	}
5083 	*file_offset += size;
5084 	munmap(ext_temp_map, ext_fd_file_size);
5085 	return 0;
5086 }
5087 
handle_relro_sharing(struct dso * p,const dl_extinfo * extinfo,ssize_t * relro_fd_offset)5088 static void handle_relro_sharing(struct dso *p, const dl_extinfo *extinfo, ssize_t *relro_fd_offset)
5089 {
5090 	if (extinfo == NULL) {
5091 		return;
5092 	}
5093 	if (extinfo->flag & DL_EXT_WRITE_RELRO) {
5094 		LD_LOGD("Serializing GNU_RELRO %{public}s", p->name);
5095 		if (serialize_gnu_relro(extinfo->relro_fd, p, relro_fd_offset) < 0) {
5096 			LD_LOGE("Error serializing GNU_RELRO %{public}s", p->name);
5097 			error("Error serializing GNU_RELRO");
5098 			if (runtime) longjmp(*rtld_fail, 1);
5099 		}
5100 	} else if (extinfo->flag & DL_EXT_USE_RELRO) {
5101 		LD_LOGD("Mapping GNU_RELRO %{public}s", p->name);
5102 		if (map_gnu_relro(extinfo->relro_fd, p, relro_fd_offset) < 0) {
5103 			LD_LOGE("Error mapping GNU_RELRO %{public}s", p->name);
5104 			error("Error mapping GNU_RELRO");
5105 			if (runtime) longjmp(*rtld_fail, 1);
5106 		}
5107 	}
5108 }