1 /* $OpenBSD: loader.c,v 1.191 2021/03/16 18:03:06 kurt Exp $ */ 2 3 /* 4 * Copyright (c) 1998 Per Fogelstrom, Opsycon AB 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29 #define _DYN_LOADER 30 31 #include <sys/types.h> 32 #include <sys/mman.h> 33 #include <sys/exec.h> 34 #include <sys/sysctl.h> 35 #include <machine/vmparam.h> 36 #include <nlist.h> 37 #include <string.h> 38 #include <link.h> 39 #include <limits.h> /* NAME_MAX */ 40 #include <dlfcn.h> 41 #include <tib.h> 42 43 #include "syscall.h" 44 #include "archdep.h" 45 #include "path.h" 46 #include "resolve.h" 47 #include "sod.h" 48 #include "stdlib.h" 49 50 /* 51 * Local decls. 52 */ 53 unsigned long _dl_boot(const char **, char **, const long, long *) __boot; 54 void _dl_debug_state(void); 55 void _dl_setup_env(const char *_argv0, char **_envp) __boot; 56 void _dl_dtors(void); 57 void _dl_dopreload(char *_paths) __boot; 58 void _dl_fixup_user_env(void) __boot; 59 void _dl_call_preinit(elf_object_t *) __boot; 60 void _dl_call_init_recurse(elf_object_t *object, int initfirst); 61 void _dl_clean_boot(void); 62 static inline void unprotect_if_textrel(elf_object_t *_object); 63 static inline void reprotect_if_textrel(elf_object_t *_object); 64 65 int _dl_pagesz __relro = 4096; 66 int _dl_bindnow __relro = 0; 67 int _dl_debug __relro = 0; 68 int _dl_trust __relro = 0; 69 char **_dl_libpath __relro = NULL; 70 const char **_dl_argv __relro = NULL; 71 int _dl_argc __relro = 0; 72 73 char *_dl_preload __boot_data = NULL; 74 char *_dl_tracefmt1 __boot_data = NULL; 75 char *_dl_tracefmt2 __boot_data = NULL; 76 char *_dl_traceprog __boot_data = NULL; 77 void *_dl_exec_hint __boot_data = NULL; 78 79 char **environ = NULL; 80 char *__progname = NULL; 81 82 int _dl_traceld; 83 struct r_debug *_dl_debug_map; 84 85 static dl_cb_cb _dl_cb_cb; 86 const struct dl_cb_0 callbacks_0 = { 87 .dl_allocate_tib = &_dl_allocate_tib, 88 .dl_free_tib = &_dl_free_tib, 89 #if DO_CLEAN_BOOT 90 .dl_clean_boot = &_dl_clean_boot, 91 #endif 92 .dlopen = &dlopen, 93 .dlclose = &dlclose, 94 .dlsym = &dlsym, 95 .dladdr = &dladdr, 96 .dlctl = &dlctl, 97 .dlerror = &dlerror, 98 .dl_iterate_phdr = &dl_iterate_phdr, 99 }; 100 101 102 /* 103 * Run dtors for a single object. 104 */ 105 void 106 _dl_run_dtors(elf_object_t *obj) 107 { 108 if (obj->dyn.fini_array) { 109 int num = obj->dyn.fini_arraysz / sizeof(Elf_Addr); 110 int i; 111 112 DL_DEB(("doing finiarray obj %p @%p: [%s]\n", 113 obj, obj->dyn.fini_array, obj->load_name)); 114 for (i = num; i > 0; i--) 115 (*obj->dyn.fini_array[i-1])(); 116 } 117 118 if (obj->dyn.fini) { 119 DL_DEB(("doing dtors obj %p @%p: [%s]\n", 120 obj, obj->dyn.fini, obj->load_name)); 121 (*obj->dyn.fini)(); 122 } 123 } 124 125 /* 126 * Run dtors for all objects that are eligible. 127 */ 128 void 129 _dl_run_all_dtors(void) 130 { 131 elf_object_t *node; 132 int fini_complete; 133 int skip_initfirst; 134 int initfirst_skipped; 135 136 fini_complete = 0; 137 skip_initfirst = 1; 138 initfirst_skipped = 0; 139 140 while (fini_complete == 0) { 141 fini_complete = 1; 142 for (node = _dl_objects; 143 node != NULL; 144 node = node->next) { 145 if ((node->dyn.fini || node->dyn.fini_array) && 146 (OBJECT_REF_CNT(node) == 0) && 147 (node->status & STAT_INIT_DONE) && 148 ((node->status & STAT_FINI_DONE) == 0)) { 149 if (skip_initfirst && 150 (node->obj_flags & DF_1_INITFIRST)) 151 initfirst_skipped = 1; 152 else 153 node->status |= STAT_FINI_READY; 154 } 155 } 156 for (node = _dl_objects; 157 node != NULL; 158 node = node->next ) { 159 if ((node->dyn.fini || node->dyn.fini_array) && 160 (OBJECT_REF_CNT(node) == 0) && 161 (node->status & STAT_INIT_DONE) && 162 ((node->status & STAT_FINI_DONE) == 0) && 163 (!skip_initfirst || 164 (node->obj_flags & DF_1_INITFIRST) == 0)) { 165 struct object_vector vec = node->child_vec; 166 int i; 167 168 for (i = 0; i < vec.len; i++) 169 vec.vec[i]->status &= ~STAT_FINI_READY; 170 } 171 } 172 173 174 for (node = _dl_objects; 175 node != NULL; 176 node = node->next ) { 177 if (node->status & STAT_FINI_READY) { 178 fini_complete = 0; 179 node->status |= STAT_FINI_DONE; 180 node->status &= ~STAT_FINI_READY; 181 _dl_run_dtors(node); 182 } 183 } 184 185 if (fini_complete && initfirst_skipped) 186 fini_complete = initfirst_skipped = skip_initfirst = 0; 187 } 188 } 189 190 /* 191 * Routine to walk through all of the objects except the first 192 * (main executable). 193 * 194 * Big question, should dlopen()ed objects be unloaded before or after 195 * the destructor for the main application runs? 196 */ 197 void 198 _dl_dtors(void) 199 { 200 _dl_thread_kern_stop(); 201 202 /* ORDER? */ 203 _dl_unload_dlopen(); 204 205 DL_DEB(("doing dtors\n")); 206 207 _dl_objects->opencount--; 208 _dl_notify_unload_shlib(_dl_objects); 209 210 _dl_run_all_dtors(); 211 } 212 213 #if DO_CLEAN_BOOT 214 void 215 _dl_clean_boot(void) 216 { 217 extern char boot_text_start[], boot_text_end[]; 218 #if 0 /* XXX breaks boehm-gc?!? */ 219 extern char boot_data_start[], boot_data_end[]; 220 #endif 221 222 _dl_munmap(boot_text_start, boot_text_end - boot_text_start); 223 #if 0 /* XXX breaks boehm-gc?!? */ 224 _dl_munmap(boot_data_start, boot_data_end - boot_data_start); 225 #endif 226 } 227 #endif /* DO_CLEAN_BOOT */ 228 229 void 230 _dl_dopreload(char *paths) 231 { 232 char *cp, *dp; 233 elf_object_t *shlib; 234 int count; 235 236 dp = paths = _dl_strdup(paths); 237 if (dp == NULL) 238 _dl_oom(); 239 240 /* preallocate child_vec for the LD_PRELOAD objects */ 241 count = 1; 242 while (*dp++ != '\0') 243 if (*dp == ':') 244 count++; 245 object_vec_grow(&_dl_objects->child_vec, count); 246 247 dp = paths; 248 while ((cp = _dl_strsep(&dp, ":")) != NULL) { 249 shlib = _dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB, 250 _dl_objects->obj_flags); 251 if (shlib == NULL) 252 _dl_die("can't preload library '%s'", cp); 253 _dl_add_object(shlib); 254 _dl_link_child(shlib, _dl_objects); 255 } 256 _dl_free(paths); 257 return; 258 } 259 260 /* 261 * grab interesting environment variables, zap bad env vars if 262 * issetugid, and set the exported environ and __progname variables 263 */ 264 void 265 _dl_setup_env(const char *argv0, char **envp) 266 { 267 static char progname_storage[NAME_MAX+1] = ""; 268 269 /* 270 * Don't allow someone to change the search paths if he runs 271 * a suid program without credentials high enough. 272 */ 273 _dl_trust = !_dl_issetugid(); 274 if (!_dl_trust) { /* Zap paths if s[ug]id... */ 275 _dl_unsetenv("LD_DEBUG", envp); 276 _dl_unsetenv("LD_LIBRARY_PATH", envp); 277 _dl_unsetenv("LD_PRELOAD", envp); 278 _dl_unsetenv("LD_BIND_NOW", envp); 279 } else { 280 /* 281 * Get paths to various things we are going to use. 282 */ 283 _dl_debug = _dl_getenv("LD_DEBUG", envp) != NULL; 284 _dl_libpath = _dl_split_path(_dl_getenv("LD_LIBRARY_PATH", 285 envp)); 286 _dl_preload = _dl_getenv("LD_PRELOAD", envp); 287 _dl_bindnow = _dl_getenv("LD_BIND_NOW", envp) != NULL; 288 } 289 290 /* these are usable even in setugid processes */ 291 _dl_traceld = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL; 292 _dl_tracefmt1 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT1", envp); 293 _dl_tracefmt2 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT2", envp); 294 _dl_traceprog = _dl_getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", envp); 295 296 environ = envp; 297 298 _dl_trace_setup(envp); 299 300 if (argv0 != NULL) { /* NULL ptr if argc = 0 */ 301 const char *p = _dl_strrchr(argv0, '/'); 302 303 if (p == NULL) 304 p = argv0; 305 else 306 p++; 307 _dl_strlcpy(progname_storage, p, sizeof(progname_storage)); 308 } 309 __progname = progname_storage; 310 } 311 312 int 313 _dl_load_dep_libs(elf_object_t *object, int flags, int booting) 314 { 315 elf_object_t *dynobj; 316 Elf_Dyn *dynp; 317 unsigned int loop; 318 int libcount; 319 int depflags; 320 321 dynobj = object; 322 while (dynobj) { 323 DL_DEB(("examining: '%s'\n", dynobj->load_name)); 324 libcount = 0; 325 326 /* propagate DF_1_NOW to deplibs (can be set by dynamic tags) */ 327 depflags = flags | (dynobj->obj_flags & DF_1_NOW); 328 329 for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) { 330 if (dynp->d_tag == DT_NEEDED) { 331 libcount++; 332 } 333 } 334 335 if ( libcount != 0) { 336 struct listent { 337 Elf_Dyn *dynp; 338 elf_object_t *depobj; 339 } *liblist; 340 int *randomlist; 341 342 liblist = _dl_reallocarray(NULL, libcount, 343 sizeof(struct listent)); 344 randomlist = _dl_reallocarray(NULL, libcount, 345 sizeof(int)); 346 347 if (liblist == NULL || randomlist == NULL) 348 _dl_oom(); 349 350 for (dynp = dynobj->load_dyn, loop = 0; dynp->d_tag; 351 dynp++) 352 if (dynp->d_tag == DT_NEEDED) 353 liblist[loop++].dynp = dynp; 354 355 /* Randomize these */ 356 for (loop = 0; loop < libcount; loop++) 357 randomlist[loop] = loop; 358 359 for (loop = 1; loop < libcount; loop++) { 360 unsigned int rnd; 361 int cur; 362 rnd = _dl_arc4random(); 363 rnd = rnd % (loop+1); 364 cur = randomlist[rnd]; 365 randomlist[rnd] = randomlist[loop]; 366 randomlist[loop] = cur; 367 } 368 369 for (loop = 0; loop < libcount; loop++) { 370 elf_object_t *depobj; 371 const char *libname; 372 libname = dynobj->dyn.strtab; 373 libname += 374 liblist[randomlist[loop]].dynp->d_un.d_val; 375 DL_DEB(("loading: %s required by %s\n", libname, 376 dynobj->load_name)); 377 depobj = _dl_load_shlib(libname, dynobj, 378 OBJTYPE_LIB, depflags); 379 if (depobj == 0) { 380 if (booting) { 381 _dl_die( 382 "can't load library '%s'", 383 libname); 384 } 385 DL_DEB(("dlopen: failed to open %s\n", 386 libname)); 387 _dl_free(liblist); 388 _dl_free(randomlist); 389 return (1); 390 } 391 liblist[randomlist[loop]].depobj = depobj; 392 } 393 394 object_vec_grow(&dynobj->child_vec, libcount); 395 for (loop = 0; loop < libcount; loop++) { 396 _dl_add_object(liblist[loop].depobj); 397 _dl_link_child(liblist[loop].depobj, dynobj); 398 } 399 _dl_free(liblist); 400 _dl_free(randomlist); 401 } 402 dynobj = dynobj->next; 403 } 404 405 _dl_cache_grpsym_list_setup(object); 406 407 return(0); 408 } 409 410 411 /* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */ 412 static inline void 413 _dl_self_relro(long loff) 414 { 415 Elf_Ehdr *ehdp; 416 Elf_Phdr *phdp; 417 int i; 418 419 ehdp = (Elf_Ehdr *)loff; 420 phdp = (Elf_Phdr *)(loff + ehdp->e_phoff); 421 for (i = 0; i < ehdp->e_phnum; i++, phdp++) { 422 switch (phdp->p_type) { 423 #if defined(__alpha__) || defined(__hppa__) || defined(__powerpc__) || \ 424 defined(__sparc64__) 425 case PT_LOAD: 426 if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W)) 427 break; 428 _dl_mprotect((void *)(phdp->p_vaddr + loff), 429 phdp->p_memsz, PROT_READ); 430 break; 431 #endif 432 case PT_GNU_RELRO: 433 _dl_mprotect((void *)(phdp->p_vaddr + loff), 434 phdp->p_memsz, PROT_READ); 435 break; 436 } 437 } 438 } 439 440 441 #define PFLAGS(X) ((((X) & PF_R) ? PROT_READ : 0) | \ 442 (((X) & PF_W) ? PROT_WRITE : 0) | \ 443 (((X) & PF_X) ? PROT_EXEC : 0)) 444 445 /* 446 * This is the dynamic loader entrypoint. When entering here, depending 447 * on architecture type, the stack and registers are set up according 448 * to the architectures ABI specification. The first thing required 449 * to do is to dig out all information we need to accomplish our task. 450 */ 451 unsigned long 452 _dl_boot(const char **argv, char **envp, const long dyn_loff, long *dl_data) 453 { 454 struct elf_object *exe_obj; /* Pointer to executable object */ 455 struct elf_object *dyn_obj; /* Pointer to ld.so object */ 456 struct r_debug **map_link; /* Where to put pointer for gdb */ 457 struct r_debug *debug_map; 458 struct load_list *next_load, *load_list = NULL; 459 Elf_Dyn *dynp; 460 Elf_Phdr *phdp; 461 Elf_Ehdr *ehdr; 462 char *us = NULL; 463 unsigned int loop; 464 int failed; 465 struct dep_node *n; 466 Elf_Addr minva, maxva, exe_loff, exec_end, cur_exec_end; 467 Elf_Phdr *ptls = NULL; 468 int align; 469 470 if (dl_data[AUX_pagesz] != 0) 471 _dl_pagesz = dl_data[AUX_pagesz]; 472 _dl_malloc_init(); 473 474 _dl_argv = argv; 475 while (_dl_argv[_dl_argc] != NULL) 476 _dl_argc++; 477 _dl_setup_env(argv[0], envp); 478 479 /* 480 * Make read-only the GOT and PLT and variables initialized 481 * during the ld.so setup above. 482 */ 483 _dl_self_relro(dyn_loff); 484 485 align = _dl_pagesz - 1; 486 487 #define ROUND_PG(x) (((x) + align) & ~(align)) 488 #define TRUNC_PG(x) ((x) & ~(align)) 489 490 if (_dl_bindnow) { 491 /* Lazy binding disabled, so disable kbind */ 492 _dl___syscall(SYS_kbind, (void *)NULL, (size_t)0, (long long)0); 493 } 494 495 DL_DEB(("ld.so loading: '%s'\n", __progname)); 496 497 /* init this in runtime, not statically */ 498 TAILQ_INIT(&_dlopened_child_list); 499 500 exe_obj = NULL; 501 _dl_loading_object = NULL; 502 503 minva = ELF_NO_ADDR; 504 maxva = exe_loff = exec_end = 0; 505 506 /* 507 * Examine the user application and set up object information. 508 */ 509 phdp = (Elf_Phdr *)dl_data[AUX_phdr]; 510 for (loop = 0; loop < dl_data[AUX_phnum]; loop++) { 511 switch (phdp->p_type) { 512 case PT_PHDR: 513 exe_loff = (Elf_Addr)dl_data[AUX_phdr] - phdp->p_vaddr; 514 us += exe_loff; 515 DL_DEB(("exe load offset: 0x%lx\n", exe_loff)); 516 break; 517 case PT_DYNAMIC: 518 minva = TRUNC_PG(minva); 519 maxva = ROUND_PG(maxva); 520 exe_obj = _dl_finalize_object(argv[0] ? argv[0] : "", 521 (Elf_Dyn *)(phdp->p_vaddr + exe_loff), 522 (Elf_Phdr *)dl_data[AUX_phdr], 523 dl_data[AUX_phnum], OBJTYPE_EXE, minva + exe_loff, 524 exe_loff); 525 _dl_add_object(exe_obj); 526 break; 527 case PT_INTERP: 528 us += phdp->p_vaddr; 529 break; 530 case PT_LOAD: 531 if (phdp->p_vaddr < minva) 532 minva = phdp->p_vaddr; 533 if (phdp->p_vaddr > maxva) 534 maxva = phdp->p_vaddr + phdp->p_memsz; 535 536 next_load = _dl_calloc(1, sizeof(struct load_list)); 537 if (next_load == NULL) 538 _dl_oom(); 539 next_load->next = load_list; 540 load_list = next_load; 541 next_load->start = (char *)TRUNC_PG(phdp->p_vaddr) + exe_loff; 542 next_load->size = (phdp->p_vaddr & align) + phdp->p_filesz; 543 next_load->prot = PFLAGS(phdp->p_flags); 544 cur_exec_end = (Elf_Addr)next_load->start + next_load->size; 545 if ((next_load->prot & PROT_EXEC) != 0 && 546 cur_exec_end > exec_end) 547 exec_end = cur_exec_end; 548 break; 549 case PT_TLS: 550 if (phdp->p_filesz > phdp->p_memsz) 551 _dl_die("invalid tls data"); 552 ptls = phdp; 553 break; 554 case PT_GNU_RELRO: 555 exe_obj->relro_addr = phdp->p_vaddr + exe_loff; 556 exe_obj->relro_size = phdp->p_memsz; 557 break; 558 } 559 phdp++; 560 } 561 exe_obj->load_list = load_list; 562 exe_obj->obj_flags |= DF_1_GLOBAL; 563 exe_obj->load_size = maxva - minva; 564 _dl_set_sod(exe_obj->load_name, &exe_obj->sod); 565 566 #ifdef __i386__ 567 if (exec_end > I386_MAX_EXE_ADDR) 568 _dl_exec_hint = (void *)ROUND_PG(exec_end-I386_MAX_EXE_ADDR); 569 DL_DEB(("_dl_exec_hint: 0x%lx\n", _dl_exec_hint)); 570 #endif 571 572 /* TLS bits in the base executable */ 573 if (ptls != NULL && ptls->p_memsz) 574 _dl_set_tls(exe_obj, ptls, exe_loff, NULL); 575 576 n = _dl_malloc(sizeof *n); 577 if (n == NULL) 578 _dl_oom(); 579 n->data = exe_obj; 580 TAILQ_INSERT_TAIL(&_dlopened_child_list, n, next_sib); 581 exe_obj->opencount++; 582 583 if (_dl_preload != NULL) 584 _dl_dopreload(_dl_preload); 585 586 _dl_load_dep_libs(exe_obj, exe_obj->obj_flags, 1); 587 588 /* 589 * Now add the dynamic loader itself last in the object list 590 * so we can use the _dl_ code when serving dl.... calls. 591 * Intentionally left off the exe child_vec. 592 */ 593 dynp = (Elf_Dyn *)((void *)_DYNAMIC); 594 ehdr = (Elf_Ehdr *)dl_data[AUX_base]; 595 dyn_obj = _dl_finalize_object(us, dynp, 596 (Elf_Phdr *)((char *)dl_data[AUX_base] + ehdr->e_phoff), 597 ehdr->e_phnum, OBJTYPE_LDR, dl_data[AUX_base], dyn_loff); 598 _dl_add_object(dyn_obj); 599 600 dyn_obj->refcount++; 601 _dl_link_grpsym(dyn_obj); 602 603 dyn_obj->status |= STAT_RELOC_DONE; 604 _dl_set_sod(dyn_obj->load_name, &dyn_obj->sod); 605 606 /* calculate the offsets for static TLS allocations */ 607 _dl_allocate_tls_offsets(); 608 609 /* 610 * Make something to help gdb when poking around in the code. 611 * Do this poking at the .dynamic section now, before relocation 612 * renders it read-only 613 */ 614 map_link = NULL; 615 #ifdef __mips__ 616 if (exe_obj->Dyn.info[DT_MIPS_RLD_MAP - DT_LOPROC + DT_NUM] != 0) 617 map_link = (struct r_debug **)(exe_obj->Dyn.info[ 618 DT_MIPS_RLD_MAP - DT_LOPROC + DT_NUM] + exe_loff); 619 #endif 620 if (map_link == NULL) { 621 for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) { 622 if (dynp->d_tag == DT_DEBUG) { 623 map_link = (struct r_debug **)&dynp->d_un.d_ptr; 624 break; 625 } 626 } 627 if (dynp->d_tag != DT_DEBUG) 628 DL_DEB(("failed to mark DTDEBUG\n")); 629 } 630 if (map_link) { 631 debug_map = _dl_malloc(sizeof(*debug_map)); 632 if (debug_map == NULL) 633 _dl_oom(); 634 debug_map->r_version = 1; 635 debug_map->r_map = (struct link_map *)_dl_objects; 636 debug_map->r_brk = (Elf_Addr)_dl_debug_state; 637 debug_map->r_state = RT_CONSISTENT; 638 debug_map->r_ldbase = dyn_loff; 639 _dl_debug_map = debug_map; 640 #ifdef __mips__ 641 Elf_Addr relro_addr = exe_obj->relro_addr; 642 if (dynp->d_tag == DT_DEBUG && 643 ((Elf_Addr)map_link + sizeof(*map_link) <= relro_addr || 644 (Elf_Addr)map_link >= relro_addr + exe_obj->relro_size)) { 645 _dl_mprotect(map_link, sizeof(*map_link), 646 PROT_READ|PROT_WRITE); 647 *map_link = _dl_debug_map; 648 _dl_mprotect(map_link, sizeof(*map_link), 649 PROT_READ|PROT_EXEC); 650 } else 651 #endif 652 *map_link = _dl_debug_map; 653 } 654 655 656 /* 657 * Everything should be in place now for doing the relocation 658 * and binding. Call _dl_rtld to do the job. Fingers crossed. 659 */ 660 661 failed = 0; 662 if (!_dl_traceld) 663 failed = _dl_rtld(_dl_objects); 664 665 if (_dl_debug || _dl_traceld) { 666 if (_dl_traceld) 667 _dl_pledge("stdio rpath", NULL); 668 _dl_show_objects(); 669 } 670 671 DL_DEB(("dynamic loading done, %s.\n", 672 (failed == 0) ? "success":"failed")); 673 674 if (failed != 0) 675 _dl_die("relocation failed"); 676 677 if (_dl_traceld) 678 _dl_exit(0); 679 680 _dl_loading_object = NULL; 681 682 /* set up the TIB for the initial thread */ 683 _dl_allocate_first_tib(); 684 685 _dl_fixup_user_env(); 686 687 _dl_debug_state(); 688 689 /* 690 * Do not run init code if run from ldd. 691 */ 692 if (_dl_objects->next != NULL) { 693 _dl_call_preinit(_dl_objects); 694 _dl_call_init(_dl_objects); 695 } 696 697 DL_DEB(("entry point: 0x%lx\n", dl_data[AUX_entry])); 698 699 /* 700 * Return the entry point. 701 */ 702 return(dl_data[AUX_entry]); 703 } 704 705 int 706 _dl_rtld(elf_object_t *object) 707 { 708 struct load_list *llist; 709 int fails = 0; 710 711 if (object->next) 712 fails += _dl_rtld(object->next); 713 714 if (object->status & STAT_RELOC_DONE) 715 return 0; 716 717 /* 718 * Do relocation information first, then GOT. 719 */ 720 unprotect_if_textrel(object); 721 fails =_dl_md_reloc(object, DT_REL, DT_RELSZ); 722 fails += _dl_md_reloc(object, DT_RELA, DT_RELASZ); 723 reprotect_if_textrel(object); 724 725 /* 726 * We do lazy resolution by default, doing eager resolution if 727 * - the object requests it with -znow, OR 728 * - LD_BIND_NOW is set and this object isn't being ltraced 729 * 730 * Note that -znow disables ltrace for the object: on at least 731 * amd64 'ld' doesn't generate the trampoline for lazy relocation 732 * when -znow is used. 733 */ 734 fails += _dl_md_reloc_got(object, !(object->obj_flags & DF_1_NOW) && 735 !(_dl_bindnow && !object->traced)); 736 737 /* 738 * Look for W&X segments and make them read-only. 739 */ 740 for (llist = object->load_list; llist != NULL; llist = llist->next) { 741 if ((llist->prot & PROT_WRITE) && (llist->prot & PROT_EXEC)) { 742 _dl_mprotect(llist->start, llist->size, 743 llist->prot & ~PROT_WRITE); 744 } 745 } 746 747 if (fails == 0) 748 object->status |= STAT_RELOC_DONE; 749 750 return (fails); 751 } 752 753 void 754 _dl_call_preinit(elf_object_t *object) 755 { 756 if (object->dyn.preinit_array) { 757 int num = object->dyn.preinit_arraysz / sizeof(Elf_Addr); 758 int i; 759 760 DL_DEB(("doing preinitarray obj %p @%p: [%s]\n", 761 object, object->dyn.preinit_array, object->load_name)); 762 for (i = 0; i < num; i++) 763 (*object->dyn.preinit_array[i])(_dl_argc, _dl_argv, 764 environ, &_dl_cb_cb); 765 } 766 } 767 768 void 769 _dl_call_init(elf_object_t *object) 770 { 771 _dl_call_init_recurse(object, 1); 772 _dl_call_init_recurse(object, 0); 773 } 774 775 static void 776 _dl_relro(elf_object_t *object) 777 { 778 /* 779 * Handle GNU_RELRO 780 */ 781 if (object->relro_addr != 0 && object->relro_size != 0) { 782 Elf_Addr addr = object->relro_addr; 783 784 DL_DEB(("protect RELRO [0x%lx,0x%lx) in %s\n", 785 addr, addr + object->relro_size, object->load_name)); 786 _dl_mprotect((void *)addr, object->relro_size, PROT_READ); 787 } 788 } 789 790 void 791 _dl_call_init_recurse(elf_object_t *object, int initfirst) 792 { 793 struct object_vector vec; 794 int visited_flag = initfirst ? STAT_VISIT_INITFIRST : STAT_VISIT_INIT; 795 int i; 796 797 object->status |= visited_flag; 798 799 for (vec = object->child_vec, i = 0; i < vec.len; i++) { 800 if (vec.vec[i]->status & visited_flag) 801 continue; 802 _dl_call_init_recurse(vec.vec[i], initfirst); 803 } 804 805 if (object->status & STAT_INIT_DONE) 806 return; 807 808 if (initfirst && (object->obj_flags & DF_1_INITFIRST) == 0) 809 return; 810 811 if (!initfirst) 812 _dl_relro(object); 813 814 if (object->dyn.init) { 815 DL_DEB(("doing ctors obj %p @%p: [%s]\n", 816 object, object->dyn.init, object->load_name)); 817 (*object->dyn.init)(); 818 } 819 820 if (object->dyn.init_array) { 821 int num = object->dyn.init_arraysz / sizeof(Elf_Addr); 822 int i; 823 824 DL_DEB(("doing initarray obj %p @%p: [%s]\n", 825 object, object->dyn.init_array, object->load_name)); 826 for (i = 0; i < num; i++) 827 (*object->dyn.init_array[i])(_dl_argc, _dl_argv, 828 environ, &_dl_cb_cb); 829 } 830 831 if (initfirst) 832 _dl_relro(object); 833 834 object->status |= STAT_INIT_DONE; 835 } 836 837 char * 838 _dl_getenv(const char *var, char **env) 839 { 840 const char *ep; 841 842 while ((ep = *env++)) { 843 const char *vp = var; 844 845 while (*vp && *vp == *ep) { 846 vp++; 847 ep++; 848 } 849 if (*vp == '\0' && *ep++ == '=') 850 return((char *)ep); 851 } 852 return(NULL); 853 } 854 855 void 856 _dl_unsetenv(const char *var, char **env) 857 { 858 char *ep; 859 860 while ((ep = *env)) { 861 const char *vp = var; 862 863 while (*vp && *vp == *ep) { 864 vp++; 865 ep++; 866 } 867 if (*vp == '\0' && *ep++ == '=') { 868 char **P; 869 870 for (P = env;; ++P) 871 if (!(*P = *(P + 1))) 872 break; 873 } else 874 env++; 875 } 876 } 877 878 static inline void 879 fixup_sym(struct elf_object *dummy_obj, const char *name, void *addr) 880 { 881 struct sym_res sr; 882 883 sr = _dl_find_symbol(name, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, 884 NULL, dummy_obj); 885 if (sr.sym != NULL) { 886 void *p = (void *)(sr.sym->st_value + sr.obj->obj_base); 887 if (p != addr) { 888 DL_DEB(("setting %s %p@%s[%p] from %p\n", name, 889 p, sr.obj->load_name, (void *)sr.obj, addr)); 890 *(void **)p = *(void **)addr; 891 } 892 } 893 } 894 895 /* 896 * _dl_fixup_user_env() 897 * 898 * Set the user environment so that programs can use the environment 899 * while running constructors. Specifically, MALLOC_OPTIONS= for malloc() 900 */ 901 void 902 _dl_fixup_user_env(void) 903 { 904 struct elf_object dummy_obj; 905 906 dummy_obj.dyn.symbolic = 0; 907 dummy_obj.load_name = "ld.so"; 908 fixup_sym(&dummy_obj, "environ", &environ); 909 fixup_sym(&dummy_obj, "__progname", &__progname); 910 } 911 912 const void * 913 _dl_cb_cb(int version) 914 { 915 DL_DEB(("version %d callbacks requested\n", version)); 916 if (version == 0) 917 return &callbacks_0; 918 return NULL; 919 } 920 921 static inline void 922 unprotect_if_textrel(elf_object_t *object) 923 { 924 struct load_list *ll; 925 926 if (__predict_false(object->dyn.textrel == 1)) { 927 for (ll = object->load_list; ll != NULL; ll = ll->next) { 928 if ((ll->prot & PROT_WRITE) == 0) 929 _dl_mprotect(ll->start, ll->size, 930 PROT_READ | PROT_WRITE); 931 } 932 } 933 } 934 935 static inline void 936 reprotect_if_textrel(elf_object_t *object) 937 { 938 struct load_list *ll; 939 940 if (__predict_false(object->dyn.textrel == 1)) { 941 for (ll = object->load_list; ll != NULL; ll = ll->next) { 942 if ((ll->prot & PROT_WRITE) == 0) 943 _dl_mprotect(ll->start, ll->size, ll->prot); 944 } 945 } 946 } 947