1 /* $OpenBSD: loader.c,v 1.209 2022/12/25 09:39:37 visa 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 #ifdef __i386__ 35 # include <machine/vmparam.h> 36 #endif 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 "util.h" 45 #include "resolve.h" 46 #include "path.h" 47 #include "sod.h" 48 49 /* 50 * Local decls. 51 */ 52 unsigned long _dl_boot(const char **, char **, const long, long *) __boot; 53 void _dl_debug_state(void); 54 void _dl_setup_env(const char *_argv0, char **_envp) __boot; 55 void _dl_dtors(void); 56 void _dl_dopreload(char *_paths) __boot; 57 void _dl_fixup_user_env(void) __boot; 58 void _dl_call_preinit(elf_object_t *) __boot; 59 void _dl_call_init_recurse(elf_object_t *object, int initfirst); 60 void _dl_clean_boot(void); 61 static inline void unprotect_if_textrel(elf_object_t *_object); 62 static inline void reprotect_if_textrel(elf_object_t *_object); 63 static void _dl_rreloc(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_mmap(boot_text_start, boot_text_end - boot_text_start, 223 PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); 224 _dl_mimmutable(boot_text_start, boot_text_end - boot_text_start); 225 #if 0 /* XXX breaks boehm-gc?!? */ 226 _dl_mmap(boot_data_start, boot_data_end - boot_data_start, 227 PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); 228 _dl_mimmutable(boot_data_start, boot_data_end - boot_data_start); 229 #endif 230 } 231 #endif /* DO_CLEAN_BOOT */ 232 233 void 234 _dl_dopreload(char *paths) 235 { 236 char *cp, *dp; 237 elf_object_t *shlib; 238 int count; 239 240 dp = paths = _dl_strdup(paths); 241 if (dp == NULL) 242 _dl_oom(); 243 244 /* preallocate child_vec for the LD_PRELOAD objects */ 245 count = 1; 246 while (*dp++ != '\0') 247 if (*dp == ':') 248 count++; 249 object_vec_grow(&_dl_objects->child_vec, count); 250 251 dp = paths; 252 while ((cp = _dl_strsep(&dp, ":")) != NULL) { 253 shlib = _dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB, 254 _dl_objects->obj_flags, 1); 255 if (shlib == NULL) 256 _dl_die("can't preload library '%s'", cp); 257 _dl_add_object(shlib); 258 _dl_link_child(shlib, _dl_objects); 259 } 260 _dl_free(paths); 261 return; 262 } 263 264 /* 265 * grab interesting environment variables, zap bad env vars if 266 * issetugid, and set the exported environ and __progname variables 267 */ 268 void 269 _dl_setup_env(const char *argv0, char **envp) 270 { 271 static char progname_storage[NAME_MAX+1] = ""; 272 273 /* 274 * Don't allow someone to change the search paths if he runs 275 * a suid program without credentials high enough. 276 */ 277 _dl_trust = !_dl_issetugid(); 278 if (!_dl_trust) { /* Zap paths if s[ug]id... */ 279 _dl_unsetenv("LD_DEBUG", envp); 280 _dl_unsetenv("LD_LIBRARY_PATH", envp); 281 _dl_unsetenv("LD_PRELOAD", envp); 282 _dl_unsetenv("LD_BIND_NOW", envp); 283 } else { 284 /* 285 * Get paths to various things we are going to use. 286 */ 287 _dl_debug = _dl_getenv("LD_DEBUG", envp) != NULL; 288 _dl_libpath = _dl_split_path(_dl_getenv("LD_LIBRARY_PATH", 289 envp)); 290 _dl_preload = _dl_getenv("LD_PRELOAD", envp); 291 _dl_bindnow = _dl_getenv("LD_BIND_NOW", envp) != NULL; 292 } 293 294 /* these are usable even in setugid processes */ 295 _dl_traceld = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL; 296 _dl_tracefmt1 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT1", envp); 297 _dl_tracefmt2 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT2", envp); 298 _dl_traceprog = _dl_getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", envp); 299 300 environ = envp; 301 302 _dl_trace_setup(envp); 303 304 if (argv0 != NULL) { /* NULL ptr if argc = 0 */ 305 const char *p = _dl_strrchr(argv0, '/'); 306 307 if (p == NULL) 308 p = argv0; 309 else 310 p++; 311 _dl_strlcpy(progname_storage, p, sizeof(progname_storage)); 312 } 313 __progname = progname_storage; 314 } 315 316 int 317 _dl_load_dep_libs(elf_object_t *object, int flags, int booting) 318 { 319 elf_object_t *dynobj; 320 Elf_Dyn *dynp; 321 unsigned int loop; 322 int libcount; 323 int depflags, nodelete = 0; 324 325 dynobj = object; 326 while (dynobj) { 327 DL_DEB(("examining: '%s'\n", dynobj->load_name)); 328 libcount = 0; 329 330 /* propagate DF_1_NOW to deplibs (can be set by dynamic tags) */ 331 depflags = flags | (dynobj->obj_flags & DF_1_NOW); 332 if (booting || object->nodelete) 333 nodelete = 1; 334 335 for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) { 336 if (dynp->d_tag == DT_NEEDED) { 337 libcount++; 338 } 339 } 340 341 if ( libcount != 0) { 342 struct listent { 343 Elf_Dyn *dynp; 344 elf_object_t *depobj; 345 } *liblist; 346 int *randomlist; 347 348 liblist = _dl_reallocarray(NULL, libcount, 349 sizeof(struct listent)); 350 randomlist = _dl_reallocarray(NULL, libcount, 351 sizeof(int)); 352 353 if (liblist == NULL || randomlist == NULL) 354 _dl_oom(); 355 356 for (dynp = dynobj->load_dyn, loop = 0; dynp->d_tag; 357 dynp++) 358 if (dynp->d_tag == DT_NEEDED) 359 liblist[loop++].dynp = dynp; 360 361 /* Randomize these */ 362 for (loop = 0; loop < libcount; loop++) 363 randomlist[loop] = loop; 364 365 for (loop = 1; loop < libcount; loop++) { 366 unsigned int rnd; 367 int cur; 368 rnd = _dl_arc4random(); 369 rnd = rnd % (loop+1); 370 cur = randomlist[rnd]; 371 randomlist[rnd] = randomlist[loop]; 372 randomlist[loop] = cur; 373 } 374 375 for (loop = 0; loop < libcount; loop++) { 376 elf_object_t *depobj; 377 const char *libname; 378 libname = dynobj->dyn.strtab; 379 libname += 380 liblist[randomlist[loop]].dynp->d_un.d_val; 381 DL_DEB(("loading: %s required by %s\n", libname, 382 dynobj->load_name)); 383 depobj = _dl_load_shlib(libname, dynobj, 384 OBJTYPE_LIB, depflags, nodelete); 385 if (depobj == 0) { 386 if (booting) { 387 _dl_die( 388 "can't load library '%s'", 389 libname); 390 } 391 DL_DEB(("dlopen: failed to open %s\n", 392 libname)); 393 _dl_free(liblist); 394 _dl_free(randomlist); 395 return (1); 396 } 397 liblist[randomlist[loop]].depobj = depobj; 398 } 399 400 object_vec_grow(&dynobj->child_vec, libcount); 401 for (loop = 0; loop < libcount; loop++) { 402 _dl_add_object(liblist[loop].depobj); 403 _dl_link_child(liblist[loop].depobj, dynobj); 404 } 405 _dl_free(liblist); 406 _dl_free(randomlist); 407 } 408 dynobj = dynobj->next; 409 } 410 411 _dl_cache_grpsym_list_setup(object); 412 413 return(0); 414 } 415 416 417 /* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */ 418 static inline void 419 _dl_self_relro(long loff) 420 { 421 Elf_Ehdr *ehdp; 422 Elf_Phdr *phdp; 423 int i; 424 425 ehdp = (Elf_Ehdr *)loff; 426 phdp = (Elf_Phdr *)(loff + ehdp->e_phoff); 427 for (i = 0; i < ehdp->e_phnum; i++, phdp++) { 428 switch (phdp->p_type) { 429 #if defined(__alpha__) || defined(__hppa__) || defined(__powerpc__) || \ 430 defined(__sparc64__) 431 case PT_LOAD: 432 if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W)) 433 break; 434 _dl_mprotect((void *)(phdp->p_vaddr + loff), 435 phdp->p_memsz, PROT_READ); 436 break; 437 #endif 438 case PT_GNU_RELRO: 439 _dl_mprotect((void *)(phdp->p_vaddr + loff), 440 phdp->p_memsz, PROT_READ); 441 _dl_mimmutable((void *)(phdp->p_vaddr + loff), 442 phdp->p_memsz); 443 break; 444 } 445 } 446 } 447 448 449 #define PFLAGS(X) ((((X) & PF_R) ? PROT_READ : 0) | \ 450 (((X) & PF_W) ? PROT_WRITE : 0) | \ 451 (((X) & PF_X) ? PROT_EXEC : 0)) 452 453 /* 454 * This is the dynamic loader entrypoint. When entering here, depending 455 * on architecture type, the stack and registers are set up according 456 * to the architectures ABI specification. The first thing required 457 * to do is to dig out all information we need to accomplish our task. 458 */ 459 unsigned long 460 _dl_boot(const char **argv, char **envp, const long dyn_loff, long *dl_data) 461 { 462 struct elf_object *exe_obj; /* Pointer to executable object */ 463 struct elf_object *dyn_obj; /* Pointer to ld.so object */ 464 struct r_debug **map_link; /* Where to put pointer for gdb */ 465 struct r_debug *debug_map; 466 struct load_list *next_load, *load_list = NULL; 467 Elf_Dyn *dynp; 468 Elf_Phdr *phdp; 469 Elf_Ehdr *ehdr; 470 char *us = NULL; 471 unsigned int loop; 472 int failed; 473 struct dep_node *n; 474 Elf_Addr minva, maxva, exe_loff, exec_end, cur_exec_end; 475 Elf_Addr relro_addr = 0, relro_size = 0; 476 Elf_Phdr *ptls = NULL; 477 int align; 478 479 if (dl_data[AUX_pagesz] != 0) 480 _dl_pagesz = dl_data[AUX_pagesz]; 481 _dl_malloc_init(); 482 483 _dl_argv = argv; 484 while (_dl_argv[_dl_argc] != NULL) 485 _dl_argc++; 486 _dl_setup_env(argv[0], envp); 487 488 /* 489 * Make read-only the GOT and PLT and variables initialized 490 * during the ld.so setup above. 491 */ 492 _dl_self_relro(dyn_loff); 493 494 align = _dl_pagesz - 1; 495 496 #define ROUND_PG(x) (((x) + align) & ~(align)) 497 #define TRUNC_PG(x) ((x) & ~(align)) 498 499 if (_dl_bindnow) { 500 /* Lazy binding disabled, so disable kbind */ 501 _dl_kbind(NULL, 0, 0); 502 } 503 504 DL_DEB(("ld.so loading: '%s'\n", __progname)); 505 506 /* init this in runtime, not statically */ 507 TAILQ_INIT(&_dlopened_child_list); 508 509 exe_obj = NULL; 510 _dl_loading_object = NULL; 511 512 minva = ELF_NO_ADDR; 513 maxva = exe_loff = exec_end = 0; 514 515 /* 516 * Examine the user application and set up object information. 517 */ 518 phdp = (Elf_Phdr *)dl_data[AUX_phdr]; 519 for (loop = 0; loop < dl_data[AUX_phnum]; loop++) { 520 switch (phdp->p_type) { 521 case PT_PHDR: 522 exe_loff = (Elf_Addr)dl_data[AUX_phdr] - phdp->p_vaddr; 523 us += exe_loff; 524 DL_DEB(("exe load offset: 0x%lx\n", exe_loff)); 525 break; 526 case PT_DYNAMIC: 527 minva = TRUNC_PG(minva); 528 maxva = ROUND_PG(maxva); 529 exe_obj = _dl_finalize_object(argv[0] ? argv[0] : "", 530 (Elf_Dyn *)(phdp->p_vaddr + exe_loff), 531 (Elf_Phdr *)dl_data[AUX_phdr], 532 dl_data[AUX_phnum], OBJTYPE_EXE, minva + exe_loff, 533 exe_loff); 534 _dl_add_object(exe_obj); 535 break; 536 case PT_INTERP: 537 us += phdp->p_vaddr; 538 break; 539 case PT_LOAD: 540 if (phdp->p_vaddr < minva) 541 minva = phdp->p_vaddr; 542 if (phdp->p_vaddr > maxva) 543 maxva = phdp->p_vaddr + phdp->p_memsz; 544 545 next_load = _dl_calloc(1, sizeof(struct load_list)); 546 if (next_load == NULL) 547 _dl_oom(); 548 next_load->next = load_list; 549 load_list = next_load; 550 next_load->start = (char *)TRUNC_PG(phdp->p_vaddr) + exe_loff; 551 next_load->size = (phdp->p_vaddr & align) + phdp->p_filesz; 552 next_load->prot = PFLAGS(phdp->p_flags); 553 cur_exec_end = (Elf_Addr)next_load->start + next_load->size; 554 if ((next_load->prot & PROT_EXEC) != 0 && 555 cur_exec_end > exec_end) 556 exec_end = cur_exec_end; 557 break; 558 case PT_TLS: 559 if (phdp->p_filesz > phdp->p_memsz) 560 _dl_die("invalid tls data"); 561 ptls = phdp; 562 break; 563 case PT_GNU_RELRO: 564 relro_addr = phdp->p_vaddr + exe_loff; 565 relro_size = phdp->p_memsz; 566 break; 567 } 568 phdp++; 569 } 570 exe_obj->load_list = load_list; 571 exe_obj->obj_flags |= DF_1_GLOBAL; 572 exe_obj->nodelete = 1; 573 exe_obj->load_size = maxva - minva; 574 exe_obj->relro_addr = relro_addr; 575 exe_obj->relro_size = relro_size; 576 _dl_set_sod(exe_obj->load_name, &exe_obj->sod); 577 578 #ifdef __i386__ 579 if (exec_end > I386_MAX_EXE_ADDR) 580 _dl_exec_hint = (void *)ROUND_PG(exec_end-I386_MAX_EXE_ADDR); 581 DL_DEB(("_dl_exec_hint: 0x%lx\n", _dl_exec_hint)); 582 #endif 583 584 /* TLS bits in the base executable */ 585 if (ptls != NULL && ptls->p_memsz) 586 _dl_set_tls(exe_obj, ptls, exe_loff, NULL); 587 588 n = _dl_malloc(sizeof *n); 589 if (n == NULL) 590 _dl_oom(); 591 n->data = exe_obj; 592 TAILQ_INSERT_TAIL(&_dlopened_child_list, n, next_sib); 593 exe_obj->opencount++; 594 595 if (_dl_preload != NULL) 596 _dl_dopreload(_dl_preload); 597 598 _dl_load_dep_libs(exe_obj, exe_obj->obj_flags, 1); 599 600 /* 601 * Now add the dynamic loader itself last in the object list 602 * so we can use the _dl_ code when serving dl.... calls. 603 * Intentionally left off the exe child_vec. 604 */ 605 dynp = (Elf_Dyn *)((void *)_DYNAMIC); 606 ehdr = (Elf_Ehdr *)dl_data[AUX_base]; 607 dyn_obj = _dl_finalize_object(us, dynp, 608 (Elf_Phdr *)((char *)dl_data[AUX_base] + ehdr->e_phoff), 609 ehdr->e_phnum, OBJTYPE_LDR, dl_data[AUX_base], dyn_loff); 610 _dl_add_object(dyn_obj); 611 612 dyn_obj->refcount++; 613 _dl_link_grpsym(dyn_obj); 614 615 dyn_obj->status |= STAT_RELOC_DONE; 616 _dl_set_sod(dyn_obj->load_name, &dyn_obj->sod); 617 618 /* calculate the offsets for static TLS allocations */ 619 _dl_allocate_tls_offsets(); 620 621 /* 622 * Make something to help gdb when poking around in the code. 623 * Do this poking at the .dynamic section now, before relocation 624 * renders it read-only 625 */ 626 map_link = NULL; 627 #ifdef __mips__ 628 for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) { 629 if (dynp->d_tag == DT_MIPS_RLD_MAP_REL) { 630 map_link = (struct r_debug **) 631 (dynp->d_un.d_ptr + (Elf_Addr)dynp); 632 break; 633 } else if (dynp->d_tag == DT_MIPS_RLD_MAP) { 634 map_link = (struct r_debug **) 635 (dynp->d_un.d_ptr + exe_loff); 636 break; 637 } 638 } 639 #endif 640 if (map_link == NULL) { 641 for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) { 642 if (dynp->d_tag == DT_DEBUG) { 643 map_link = (struct r_debug **)&dynp->d_un.d_ptr; 644 break; 645 } 646 } 647 if (dynp->d_tag != DT_DEBUG) 648 DL_DEB(("failed to mark DTDEBUG\n")); 649 } 650 if (map_link) { 651 debug_map = _dl_malloc(sizeof(*debug_map)); 652 if (debug_map == NULL) 653 _dl_oom(); 654 debug_map->r_version = 1; 655 debug_map->r_map = (struct link_map *)_dl_objects; 656 debug_map->r_brk = (Elf_Addr)_dl_debug_state; 657 debug_map->r_state = RT_CONSISTENT; 658 debug_map->r_ldbase = dyn_loff; 659 _dl_debug_map = debug_map; 660 #ifdef __mips__ 661 relro_addr = exe_obj->relro_addr; 662 if (dynp->d_tag == DT_DEBUG && 663 ((Elf_Addr)map_link + sizeof(*map_link) <= relro_addr || 664 (Elf_Addr)map_link >= relro_addr + exe_obj->relro_size)) { 665 _dl_mprotect(map_link, sizeof(*map_link), 666 PROT_READ|PROT_WRITE); 667 *map_link = _dl_debug_map; 668 _dl_mprotect(map_link, sizeof(*map_link), 669 PROT_READ|PROT_EXEC); 670 } else 671 #endif 672 *map_link = _dl_debug_map; 673 } 674 675 676 /* 677 * Everything should be in place now for doing the relocation 678 * and binding. Call _dl_rtld to do the job. Fingers crossed. 679 */ 680 681 failed = 0; 682 if (!_dl_traceld) 683 failed = _dl_rtld(_dl_objects); 684 685 if (_dl_debug || _dl_traceld) { 686 if (_dl_traceld) 687 _dl_pledge("stdio rpath", NULL); 688 _dl_show_objects(); 689 } 690 691 DL_DEB(("dynamic loading done, %s.\n", 692 (failed == 0) ? "success":"failed")); 693 694 if (failed != 0) 695 _dl_die("relocation failed"); 696 697 if (_dl_traceld) 698 _dl_exit(0); 699 700 _dl_loading_object = NULL; 701 702 /* set up the TIB for the initial thread */ 703 _dl_allocate_first_tib(); 704 705 _dl_fixup_user_env(); 706 707 _dl_debug_state(); 708 709 /* 710 * Do not run init code if run from ldd. 711 */ 712 if (_dl_objects->next != NULL) { 713 _dl_call_preinit(_dl_objects); 714 _dl_call_init(_dl_objects); 715 } 716 717 DL_DEB(("entry point: 0x%lx\n", dl_data[AUX_entry])); 718 719 /* 720 * Return the entry point. 721 */ 722 return(dl_data[AUX_entry]); 723 } 724 725 int 726 _dl_rtld(elf_object_t *object) 727 { 728 struct load_list *llist; 729 int fails = 0; 730 731 if (object->next) 732 fails += _dl_rtld(object->next); 733 734 if (object->status & STAT_RELOC_DONE) 735 return 0; 736 737 /* 738 * Do relocation information first, then GOT. 739 */ 740 unprotect_if_textrel(object); 741 _dl_rreloc(object); 742 fails =_dl_md_reloc(object, DT_REL, DT_RELSZ); 743 fails += _dl_md_reloc(object, DT_RELA, DT_RELASZ); 744 reprotect_if_textrel(object); 745 746 /* 747 * We do lazy resolution by default, doing eager resolution if 748 * - the object requests it with -znow, OR 749 * - LD_BIND_NOW is set and this object isn't being ltraced 750 * 751 * Note that -znow disables ltrace for the object: on at least 752 * amd64 'ld' doesn't generate the trampoline for lazy relocation 753 * when -znow is used. 754 */ 755 fails += _dl_md_reloc_got(object, !(object->obj_flags & DF_1_NOW) && 756 !(_dl_bindnow && !object->traced)); 757 758 /* 759 * Look for W&X segments and make them read-only. 760 */ 761 for (llist = object->load_list; llist != NULL; llist = llist->next) { 762 if ((llist->prot & PROT_WRITE) && (llist->prot & PROT_EXEC)) { 763 _dl_mprotect(llist->start, llist->size, 764 llist->prot & ~PROT_WRITE); 765 } 766 } 767 768 /* 769 * TEXTREL binaries are loaded without immutable on un-writeable sections. 770 * After text relocations are finished, these regions can become 771 * immutable. OPENBSD_MUTABLE section always overlaps writeable LOADs, 772 * so don't be afraid. 773 */ 774 if (object->dyn.textrel) { 775 for (llist = object->load_list; llist != NULL; llist = llist->next) 776 if ((llist->prot & PROT_WRITE) == 0) 777 _dl_mimmutable(llist->start, llist->size); 778 } 779 780 if (fails == 0) 781 object->status |= STAT_RELOC_DONE; 782 783 return (fails); 784 } 785 786 void 787 _dl_call_preinit(elf_object_t *object) 788 { 789 if (object->dyn.preinit_array) { 790 int num = object->dyn.preinit_arraysz / sizeof(Elf_Addr); 791 int i; 792 793 DL_DEB(("doing preinitarray obj %p @%p: [%s]\n", 794 object, object->dyn.preinit_array, object->load_name)); 795 for (i = 0; i < num; i++) 796 (*object->dyn.preinit_array[i])(_dl_argc, _dl_argv, 797 environ, &_dl_cb_cb); 798 } 799 } 800 801 void 802 _dl_call_init(elf_object_t *object) 803 { 804 _dl_call_init_recurse(object, 1); 805 _dl_call_init_recurse(object, 0); 806 } 807 808 static void 809 _dl_relro(elf_object_t *object) 810 { 811 /* 812 * Handle GNU_RELRO 813 */ 814 if (object->relro_addr != 0 && object->relro_size != 0) { 815 Elf_Addr addr = object->relro_addr; 816 817 DL_DEB(("protect RELRO [0x%lx,0x%lx) in %s\n", 818 addr, addr + object->relro_size, object->load_name)); 819 _dl_mprotect((void *)addr, object->relro_size, PROT_READ); 820 821 /* if library will never be unloaded, RELRO can be immutable */ 822 if (object->nodelete) 823 _dl_mimmutable((void *)addr, object->relro_size); 824 } 825 } 826 827 void 828 _dl_call_init_recurse(elf_object_t *object, int initfirst) 829 { 830 struct object_vector vec; 831 int visited_flag = initfirst ? STAT_VISIT_INITFIRST : STAT_VISIT_INIT; 832 int i; 833 834 object->status |= visited_flag; 835 836 for (vec = object->child_vec, i = 0; i < vec.len; i++) { 837 if (vec.vec[i]->status & visited_flag) 838 continue; 839 _dl_call_init_recurse(vec.vec[i], initfirst); 840 } 841 842 if (object->status & STAT_INIT_DONE) 843 return; 844 845 if (initfirst && (object->obj_flags & DF_1_INITFIRST) == 0) 846 return; 847 848 if (!initfirst) { 849 _dl_relro(object); 850 _dl_apply_immutable(object); 851 } 852 853 if (object->dyn.init) { 854 DL_DEB(("doing ctors obj %p @%p: [%s]\n", 855 object, object->dyn.init, object->load_name)); 856 (*object->dyn.init)(); 857 } 858 859 if (object->dyn.init_array) { 860 int num = object->dyn.init_arraysz / sizeof(Elf_Addr); 861 int i; 862 863 DL_DEB(("doing initarray obj %p @%p: [%s]\n", 864 object, object->dyn.init_array, object->load_name)); 865 for (i = 0; i < num; i++) 866 (*object->dyn.init_array[i])(_dl_argc, _dl_argv, 867 environ, &_dl_cb_cb); 868 } 869 870 if (initfirst) { 871 _dl_relro(object); 872 _dl_apply_immutable(object); 873 } 874 875 object->status |= STAT_INIT_DONE; 876 } 877 878 char * 879 _dl_getenv(const char *var, char **env) 880 { 881 const char *ep; 882 883 while ((ep = *env++)) { 884 const char *vp = var; 885 886 while (*vp && *vp == *ep) { 887 vp++; 888 ep++; 889 } 890 if (*vp == '\0' && *ep++ == '=') 891 return((char *)ep); 892 } 893 return(NULL); 894 } 895 896 void 897 _dl_unsetenv(const char *var, char **env) 898 { 899 char *ep; 900 901 while ((ep = *env)) { 902 const char *vp = var; 903 904 while (*vp && *vp == *ep) { 905 vp++; 906 ep++; 907 } 908 if (*vp == '\0' && *ep++ == '=') { 909 char **P; 910 911 for (P = env;; ++P) 912 if (!(*P = *(P + 1))) 913 break; 914 } else 915 env++; 916 } 917 } 918 919 static inline void 920 fixup_sym(struct elf_object *dummy_obj, const char *name, void *addr) 921 { 922 struct sym_res sr; 923 924 sr = _dl_find_symbol(name, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, 925 NULL, dummy_obj); 926 if (sr.sym != NULL) { 927 void *p = (void *)(sr.sym->st_value + sr.obj->obj_base); 928 if (p != addr) { 929 DL_DEB(("setting %s %p@%s[%p] from %p\n", name, 930 p, sr.obj->load_name, (void *)sr.obj, addr)); 931 *(void **)p = *(void **)addr; 932 } 933 } 934 } 935 936 /* 937 * _dl_fixup_user_env() 938 * 939 * Set the user environment so that programs can use the environment 940 * while running constructors. Specifically, MALLOC_OPTIONS= for malloc() 941 */ 942 void 943 _dl_fixup_user_env(void) 944 { 945 struct elf_object dummy_obj; 946 947 dummy_obj.dyn.symbolic = 0; 948 dummy_obj.load_name = "ld.so"; 949 fixup_sym(&dummy_obj, "environ", &environ); 950 fixup_sym(&dummy_obj, "__progname", &__progname); 951 } 952 953 const void * 954 _dl_cb_cb(int version) 955 { 956 DL_DEB(("version %d callbacks requested\n", version)); 957 if (version == 0) 958 return &callbacks_0; 959 return NULL; 960 } 961 962 static inline void 963 unprotect_if_textrel(elf_object_t *object) 964 { 965 struct load_list *ll; 966 967 if (__predict_false(object->dyn.textrel == 1)) { 968 for (ll = object->load_list; ll != NULL; ll = ll->next) { 969 if ((ll->prot & PROT_WRITE) == 0) 970 _dl_mprotect(ll->start, ll->size, 971 PROT_READ | PROT_WRITE); 972 } 973 } 974 } 975 976 static inline void 977 reprotect_if_textrel(elf_object_t *object) 978 { 979 struct load_list *ll; 980 981 if (__predict_false(object->dyn.textrel == 1)) { 982 for (ll = object->load_list; ll != NULL; ll = ll->next) { 983 if ((ll->prot & PROT_WRITE) == 0) 984 _dl_mprotect(ll->start, ll->size, ll->prot); 985 } 986 } 987 } 988 989 static void 990 _dl_rreloc(elf_object_t *object) 991 { 992 const Elf_Relr *reloc, *rend; 993 Elf_Addr loff = object->obj_base; 994 995 reloc = object->dyn.relr; 996 rend = (const Elf_Relr *)((char *)reloc + object->dyn.relrsz); 997 998 while (reloc < rend) { 999 Elf_Addr *where; 1000 1001 where = (Elf_Addr *)(*reloc + loff); 1002 *where++ += loff; 1003 1004 for (reloc++; reloc < rend && (*reloc & 1); reloc++) { 1005 Elf_Addr bits = *reloc >> 1; 1006 1007 Elf_Addr *here = where; 1008 while (bits != 0) { 1009 if (bits & 1) { 1010 *here += loff; 1011 } 1012 bits >>= 1; 1013 here++; 1014 } 1015 where += (8 * sizeof *reloc) - 1; 1016 } 1017 } 1018 } 1019 1020 void 1021 _dl_defer_immut(struct mutate *m, vaddr_t start, vsize_t len) 1022 { 1023 int i; 1024 1025 for (i = 0; i < MAXMUT; i++) { 1026 if (m[i].valid == 0) { 1027 m[i].start = start; 1028 m[i].end = start + len; 1029 m[i].valid = 1; 1030 return; 1031 } 1032 } 1033 if (i == MAXMUT) 1034 _dl_die("too many _dl_defer_immut"); 1035 } 1036 1037 void 1038 _dl_defer_mut(struct mutate *m, vaddr_t start, size_t len) 1039 { 1040 int i; 1041 1042 for (i = 0; i < MAXMUT; i++) { 1043 if (m[i].valid == 0) { 1044 m[i].start = start; 1045 m[i].end = start + len; 1046 m[i].valid = 1; 1047 return; 1048 } 1049 } 1050 if (i == MAXMUT) 1051 _dl_die("too many _dl_defer_mut"); 1052 } 1053 1054 void 1055 _dl_apply_immutable(elf_object_t *object) 1056 { 1057 struct mutate *m, *im, *imtail; 1058 int mut, imut; 1059 1060 if (object->obj_type != OBJTYPE_LIB) 1061 return; 1062 1063 imtail = &object->imut[MAXMUT - 1]; 1064 1065 for (imut = 0; imut < MAXMUT; imut++) { 1066 im = &object->imut[imut]; 1067 if (im->valid == 0) 1068 continue; 1069 1070 for (mut = 0; mut < MAXMUT; mut++) { 1071 m = &object->mut[mut]; 1072 if (m->valid == 0) 1073 continue; 1074 if (m->start <= im->start) { 1075 if (m->end < im->start) { 1076 ; 1077 } else if (m->end >= im->end) { 1078 im->start = im->end = im->valid = 0; 1079 } else { 1080 im->start = m->end; 1081 } 1082 } else if (m->start > im->start) { 1083 if (m->end > im->end) { 1084 ; 1085 } else if (m->end == im->end) { 1086 im->end = m->start; 1087 } else if (m->end < im->end) { 1088 imtail->start = im->start; 1089 imtail->end = m->start; 1090 imtail->valid = 1; 1091 imtail--; 1092 imtail->start = m->end; 1093 imtail->end = im->end; 1094 imtail->valid = 1; 1095 imtail--; 1096 im->start = im->end = im->valid = 0; 1097 } 1098 } 1099 } 1100 } 1101 1102 /* and now, install immutability for objects */ 1103 for (imut = 0; imut < MAXMUT; imut++) { 1104 im = &object->imut[imut]; 1105 if (im->valid == 0) 1106 continue; 1107 _dl_mimmutable((void *)im->start, im->end - im->start); 1108 } 1109 } 1110