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