1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * Copyright (c) 1988 AT&T 28 * All Rights Reserved 29 */ 30 31 #include <string.h> 32 #include <stdio.h> 33 #include <unistd.h> 34 #include <sys/stat.h> 35 #include <sys/mman.h> 36 #include <sys/debug.h> 37 #include <fcntl.h> 38 #include <limits.h> 39 #include <dlfcn.h> 40 #include <errno.h> 41 #include <link.h> 42 #include <debug.h> 43 #include <conv.h> 44 #include "_rtld.h" 45 #include "_audit.h" 46 #include "_elf.h" 47 #include "_a.out.h" 48 #include "_inline_gen.h" 49 #include "msg.h" 50 51 /* 52 * If a load filter flag is in effect, and this object is a filter, trigger the 53 * loading of all its filtees. The load filter flag is in effect when creating 54 * configuration files, or when under the control of ldd(1), or the LD_LOADFLTR 55 * environment variable is set, or this object was built with the -zloadfltr 56 * flag. Otherwise, filtee loading is deferred until triggered by a relocation. 57 */ 58 static void 59 load_filtees(Rt_map *lmp, int *in_nfavl) 60 { 61 if ((FLAGS1(lmp) & MSK_RT_FILTER) && 62 ((FLAGS(lmp) & FLG_RT_LOADFLTR) || 63 (LIST(lmp)->lm_tflags & LML_TFLG_LOADFLTR))) { 64 Dyninfo *dip = DYNINFO(lmp); 65 uint_t cnt, max = DYNINFOCNT(lmp); 66 Slookup sl; 67 68 /* 69 * Initialize the symbol lookup data structure. Note, no symbol 70 * name is supplied. This NULL name causes filters to be loaded 71 * but no symbol to be searched for. 72 */ 73 SLOOKUP_INIT(sl, 0, lmp, lmp, ld_entry_cnt, 0, 0, 0, 0, 0); 74 75 for (cnt = 0; cnt < max; cnt++, dip++) { 76 uint_t binfo; 77 Sresult sr; 78 79 SRESULT_INIT(sr, NULL); 80 81 if (((dip->di_flags & MSK_DI_FILTER) == 0) || 82 ((dip->di_flags & FLG_DI_AUXFLTR) && 83 (rtld_flags & RT_FL_NOAUXFLTR))) 84 continue; 85 (void) elf_lookup_filtee(&sl, &sr, &binfo, cnt, 86 in_nfavl); 87 } 88 } 89 } 90 91 /* 92 * Analyze one or more link-maps of a link map control list. This routine is 93 * called at startup to continue the processing of the main executable. It is 94 * also called each time a new set of objects are loaded, ie. from filters, 95 * lazy-loaded objects, or dlopen(). 96 * 97 * In each instance we traverse the link-map control list starting with the 98 * initial object. As dependencies are analyzed they are added to the link-map 99 * control list. Thus the list grows as we traverse it - this results in the 100 * breadth first ordering of all needed objects. 101 * 102 * Return the initial link-map from which analysis starts for relocate_lmc(). 103 */ 104 Rt_map * 105 analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, int *in_nfavl) 106 { 107 Rt_map *lmp; 108 Lm_cntl *nlmc; 109 110 /* 111 * If this link-map control list is being analyzed, return. The object 112 * that has just been added will be picked up by the existing analysis 113 * thread. Note, this is only really meaningful during process init- 114 * ialization, as objects are added to the main link-map control list. 115 * Following this initialization, each family of objects that are loaded 116 * are added to a new link-map control list. 117 */ 118 /* LINTED */ 119 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 120 if (nlmc->lc_flags & LMC_FLG_ANALYZING) 121 return (nlmp); 122 123 /* 124 * If this object doesn't belong to the present link-map control list 125 * then it must already have been analyzed, or it is in the process of 126 * being analyzed prior to us recursing into this analysis. In either 127 * case, ignore the object as it's already being taken care of. 128 */ 129 if (nlmco != CNTL(nlmp)) 130 return (nlmp); 131 132 nlmc->lc_flags |= LMC_FLG_ANALYZING; 133 134 for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) { 135 if (FLAGS(lmp) & 136 (FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE)) 137 continue; 138 139 /* 140 * Indicate that analyzing is under way. 141 */ 142 FLAGS(lmp) |= FLG_RT_ANALZING; 143 144 /* 145 * If this link map represents a relocatable object, then we 146 * need to finish the link-editing of the object at this point. 147 */ 148 if (FLAGS(lmp) & FLG_RT_OBJECT) { 149 Rt_map *olmp; 150 151 if ((olmp = elf_obj_fini(lml, lmp, in_nfavl)) == NULL) { 152 if (lml->lm_flags & LML_FLG_TRC_ENABLE) 153 continue; 154 nlmp = NULL; 155 break; 156 } 157 158 /* 159 * The original link-map that captured a relocatable 160 * object is a temporary link-map, that basically acts 161 * as a place holder in the link-map list. On 162 * completion of relocatable object processing, a new 163 * link-map is created, and switched with the place 164 * holder. Therefore, reassign both the present 165 * link-map pointer and the return link-map pointer. 166 * The former resets this routines link-map processing, 167 * while the latter provides for later functions, like 168 * relocate_lmc(), to start processing from this new 169 * link-map. 170 */ 171 if (nlmp == lmp) 172 nlmp = olmp; 173 lmp = olmp; 174 } 175 176 DBG_CALL(Dbg_file_analyze(lmp)); 177 178 /* 179 * Establish any dependencies this object requires. 180 */ 181 if (LM_NEEDED(lmp)(lml, nlmco, lmp, in_nfavl) == 0) { 182 if (lml->lm_flags & LML_FLG_TRC_ENABLE) 183 continue; 184 nlmp = NULL; 185 break; 186 } 187 188 FLAGS(lmp) &= ~FLG_RT_ANALZING; 189 FLAGS(lmp) |= FLG_RT_ANALYZED; 190 191 /* 192 * If we're building a configuration file, determine if this 193 * object is a filter and if so load its filtees. This 194 * traversal is only necessary for crle(1), as typical use of 195 * an object will load filters as part of relocation processing. 196 */ 197 if (MODE(nlmp) & RTLD_CONFGEN) 198 load_filtees(lmp, in_nfavl); 199 200 /* 201 * If an interposer has been added, it will have been inserted 202 * in the link-map before the link we're presently analyzing. 203 * Break out of this analysis loop and return to the head of 204 * the link-map control list to analyze the interposer. Note 205 * that this rescan preserves the breadth first loading of 206 * dependencies. 207 */ 208 /* LINTED */ 209 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 210 if (nlmc->lc_flags & LMC_FLG_REANALYZE) { 211 nlmc->lc_flags &= ~LMC_FLG_REANALYZE; 212 lmp = nlmc->lc_head; 213 } 214 } 215 216 /* LINTED */ 217 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 218 nlmc->lc_flags &= ~LMC_FLG_ANALYZING; 219 220 return (nlmp); 221 } 222 223 /* 224 * Determine whether a symbol represents zero, .bss, bits. Most commonly this 225 * function is used to determine whether the data for a copy relocation refers 226 * to initialized data or .bss. If the data definition is within .bss, then the 227 * data is zero filled, and as the copy destination within the executable is 228 * .bss, we can skip copying zero's to zero's. 229 * 230 * However, if the defining object has MOVE data, it's .bss might contain 231 * non-zero data, in which case copy the definition regardless. 232 * 233 * For backward compatibility copy relocation processing, this routine can be 234 * used to determine precisely if a copy destination is a move record recipient. 235 */ 236 static int 237 are_bits_zero(Rt_map *dlmp, Sym *dsym, int dest) 238 { 239 mmapobj_result_t *mpp; 240 caddr_t daddr = (caddr_t)dsym->st_value; 241 242 if ((FLAGS(dlmp) & FLG_RT_FIXED) == 0) 243 daddr += ADDR(dlmp); 244 245 /* 246 * Determine the segment that contains the copy definition. Given that 247 * the copy relocation records have already been captured and verified, 248 * a segment must be found (but we add an escape clause never the less). 249 */ 250 if ((mpp = find_segment(daddr, dlmp)) == NULL) 251 return (1); 252 253 /* 254 * If the definition is not within .bss, indicate this is not zero data. 255 */ 256 if (daddr < (mpp->mr_addr + mpp->mr_offset + mpp->mr_fsize)) 257 return (0); 258 259 /* 260 * If the definition is within .bss, make sure the definition isn't the 261 * recipient of a move record. Note, we don't precisely analyze whether 262 * the address is a move record recipient, as the infrastructure to 263 * prepare for, and carry out this analysis, is probably more costly 264 * than just copying the bytes regardless. 265 */ 266 if ((FLAGS(dlmp) & FLG_RT_MOVE) == 0) 267 return (1); 268 269 /* 270 * However, for backward compatibility copy relocation processing, we 271 * can afford to work a little harder. Here, determine precisely 272 * whether the destination in the executable is a move record recipient. 273 * See comments in lookup_sym_interpose(), below. 274 */ 275 if (dest && is_move_data(daddr)) 276 return (0); 277 278 return (1); 279 } 280 281 /* 282 * Relocate an individual object. 283 */ 284 static int 285 relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now, int *in_nfavl) 286 { 287 APlist *textrel = NULL; 288 int ret = 1; 289 290 /* 291 * If we're running under ldd(1), and haven't been asked to trace any 292 * warnings, skip any actual relocation processing. 293 */ 294 if (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) || 295 (lml->lm_flags & LML_FLG_TRC_WARN)) { 296 297 if (relocated) 298 (*relocated)++; 299 300 if ((LM_RELOC(lmp)(lmp, now, in_nfavl, &textrel) == 0) && 301 ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0)) 302 ret = 0; 303 304 /* 305 * Finally process any move data. Note, this is carried out 306 * with ldd(1) under relocation processing too, as it can flush 307 * out move errors, and enables lari(1) to provide a true 308 * representation of the runtime bindings. 309 */ 310 if ((FLAGS(lmp) & FLG_RT_MOVE) && 311 (move_data(lmp, &textrel) == 0) && 312 ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0)) 313 ret = 0; 314 } 315 316 /* 317 * If a text segment was write enabled to perform any relocations or 318 * move records, then re-protect the segment by disabling writes. 319 */ 320 if (textrel) { 321 mmapobj_result_t *mpp; 322 Aliste idx; 323 324 for (APLIST_TRAVERSE(textrel, idx, mpp)) 325 (void) set_prot(lmp, mpp, 0); 326 free(textrel); 327 } 328 329 return (ret); 330 } 331 332 /* 333 * Relocate the objects on a link-map control list. 334 */ 335 static int 336 _relocate_lmc(Lm_list *lml, Aliste lmco, Rt_map *nlmp, int *relocated, 337 int *in_nfavl) 338 { 339 Rt_map *lmp; 340 341 for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) { 342 /* 343 * If this object has already been relocated, we're done. If 344 * this object is being deleted, skip it, there's probably a 345 * relocation error somewhere that's causing this deletion. 346 */ 347 if (FLAGS(lmp) & 348 (FLG_RT_RELOCING | FLG_RT_RELOCED | FLG_RT_DELETE)) 349 continue; 350 351 /* 352 * Indicate that relocation processing is under way. 353 */ 354 FLAGS(lmp) |= FLG_RT_RELOCING; 355 356 /* 357 * Relocate the object. 358 */ 359 if (relocate_so(lml, lmp, relocated, 0, in_nfavl) == 0) 360 return (0); 361 362 /* 363 * Indicate that the objects relocation is complete. 364 */ 365 FLAGS(lmp) &= ~FLG_RT_RELOCING; 366 FLAGS(lmp) |= FLG_RT_RELOCED; 367 368 /* 369 * If this object is being relocated on the main link-map list 370 * indicate that this object's init is available for harvesting. 371 * Objects that are being collected on other link-map lists 372 * will have there init availability tagged when the objects 373 * are move to the main link-map list (ie, after we know they, 374 * and their dependencies, are fully relocated and ready for 375 * use). 376 * 377 * Note, even under ldd(1) this init identification is necessary 378 * for -i (tsort) gathering. 379 */ 380 if (lmco == ALIST_OFF_DATA) { 381 lml->lm_init++; 382 lml->lm_flags |= LML_FLG_OBJADDED; 383 } 384 385 /* 386 * Determine if this object is a filter, and if a load filter 387 * flag is in effect, trigger the loading of all its filtees. 388 */ 389 load_filtees(lmp, in_nfavl); 390 } 391 392 /* 393 * Perform special copy relocations. These are only meaningful for 394 * dynamic executables (fixed and head of their link-map list). If 395 * this ever has to change then the infrastructure of COPY() has to 396 * change. Presently, a given link map can only have a receiver or 397 * supplier of copy data, so a union is used to overlap the storage 398 * for the COPY_R() and COPY_S() lists. These lists would need to 399 * be separated. 400 */ 401 if ((FLAGS(nlmp) & FLG_RT_FIXED) && (nlmp == LIST(nlmp)->lm_head) && 402 (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) || 403 (lml->lm_flags & LML_FLG_TRC_WARN))) { 404 Rt_map *lmp; 405 Aliste idx1; 406 Word tracing; 407 408 #if defined(__i386) 409 if (elf_copy_gen(nlmp) == 0) 410 return (0); 411 #endif 412 if (COPY_S(nlmp) == NULL) 413 return (1); 414 415 if ((LIST(nlmp)->lm_flags & LML_FLG_TRC_ENABLE) && 416 (((rtld_flags & RT_FL_SILENCERR) == 0) || 417 (LIST(nlmp)->lm_flags & LML_FLG_TRC_VERBOSE))) 418 tracing = 1; 419 else 420 tracing = 0; 421 422 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); 423 424 for (APLIST_TRAVERSE(COPY_S(nlmp), idx1, lmp)) { 425 Rel_copy *rcp; 426 Aliste idx2; 427 428 for (ALIST_TRAVERSE(COPY_R(lmp), idx2, rcp)) { 429 int zero; 430 431 /* 432 * Only copy the data if the data is from 433 * a non-zero definition (ie. not .bss). 434 */ 435 zero = are_bits_zero(rcp->r_dlmp, 436 rcp->r_dsym, 0); 437 DBG_CALL(Dbg_reloc_copy(rcp->r_dlmp, nlmp, 438 rcp->r_name, zero)); 439 if (zero) 440 continue; 441 442 (void) memcpy(rcp->r_radd, rcp->r_dadd, 443 rcp->r_size); 444 445 if ((tracing == 0) || ((FLAGS1(rcp->r_dlmp) & 446 FL1_RT_DISPREL) == 0)) 447 continue; 448 449 (void) printf(MSG_INTL(MSG_LDD_REL_CPYDISP), 450 demangle(rcp->r_name), NAME(rcp->r_dlmp)); 451 } 452 } 453 454 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); 455 456 free(COPY_S(nlmp)); 457 COPY_S(nlmp) = NULL; 458 } 459 return (1); 460 } 461 462 int 463 relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp, 464 int *in_nfavl) 465 { 466 int lret = 1, pret = 1; 467 APlist *alp; 468 Aliste plmco; 469 Lm_cntl *plmc, *nlmc; 470 471 /* 472 * If this link-map control list is being relocated, return. The object 473 * that has just been added will be picked up by the existing relocation 474 * thread. Note, this is only really meaningful during process init- 475 * ialization, as objects are added to the main link-map control list. 476 * Following this initialization, each family of objects that are loaded 477 * are added to a new link-map control list. 478 */ 479 /* LINTED */ 480 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 481 482 if (nlmc->lc_flags & LMC_FLG_RELOCATING) 483 return (1); 484 485 nlmc->lc_flags |= LMC_FLG_RELOCATING; 486 487 /* 488 * Relocate one or more link-maps of a link map control list. If this 489 * object doesn't belong to the present link-map control list then it 490 * must already have been relocated, or it is in the process of being 491 * relocated prior to us recursing into this relocation. In either 492 * case, ignore the object as it's already being taken care of, however, 493 * fall through and capture any relocation promotions that might have 494 * been established from the reference mode of this object. 495 * 496 * If we're generating a configuration file using crle(1), two passes 497 * may be involved. Under the first pass, RTLD_CONFGEN is set. Under 498 * this pass, crle() loads objects into the process address space. No 499 * relocation is necessary at this point, we simply need to analyze the 500 * objects to ensure any directly bound dependencies, filtees, etc. 501 * get loaded. Although we skip the relocation, fall through to ensure 502 * any control lists are maintained appropriately. 503 * 504 * If objects are to be dldump(3c)'ed, crle(1) makes a second pass, 505 * using RTLD_NOW and RTLD_CONFGEN. The RTLD_NOW effectively carries 506 * out the relocations of all loaded objects. 507 */ 508 if ((nlmco == CNTL(nlmp)) && 509 ((MODE(nlmp) & (RTLD_NOW | RTLD_CONFGEN)) != RTLD_CONFGEN)) { 510 int relocated = 0; 511 512 /* 513 * Determine whether the initial link-map control list has 514 * started relocation. From this point, should any interposing 515 * objects be added to this link-map control list, the objects 516 * are demoted to standard objects. Their interposition can't 517 * be guaranteed once relocations have been carried out. 518 */ 519 if (nlmco == ALIST_OFF_DATA) 520 lml->lm_flags |= LML_FLG_STARTREL; 521 522 /* 523 * Relocate the link-map control list. Should this relocation 524 * fail, clean up this link-map list. Relocations within this 525 * list may have required relocation promotions on other lists, 526 * so before acting upon these, and possibly adding more objects 527 * to the present link-map control list, try and clean up any 528 * failed objects now. 529 */ 530 lret = _relocate_lmc(lml, nlmco, nlmp, &relocated, in_nfavl); 531 if ((lret == 0) && (nlmco != ALIST_OFF_DATA)) 532 remove_lmc(lml, clmp, nlmco, NAME(nlmp)); 533 } 534 535 /* 536 * Determine the new, and previous link-map control lists. 537 */ 538 /* LINTED */ 539 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 540 if (nlmco == ALIST_OFF_DATA) { 541 plmco = nlmco; 542 plmc = nlmc; 543 } else { 544 plmco = nlmco - lml->lm_lists->al_size; 545 /* LINTED */ 546 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco); 547 } 548 549 /* 550 * Having completed this control list of objects, they can now be bound 551 * to from other objects. Move this control list to the control list 552 * that precedes it. Although this control list may have only bound to 553 * controls lists much higher up the control list stack, it must only 554 * be moved up one control list so as to preserve the link-map order 555 * that may have already been traversed in search of symbols. 556 */ 557 if (lret && (nlmco != ALIST_OFF_DATA) && nlmc->lc_head) 558 lm_move(lml, nlmco, plmco, nlmc, plmc); 559 560 /* 561 * Determine whether existing objects that have already been relocated, 562 * need any additional relocations performed. This can occur when new 563 * objects are loaded with RTLD_NOW, and these new objects have 564 * dependencies on objects that are already loaded. Note, that we peel 565 * any relocation promotions off of one control list at a time. This 566 * prevents relocations from being bound to objects that might yet fail 567 * to relocate themselves. 568 */ 569 while ((alp = plmc->lc_now) != NULL) { 570 Aliste idx; 571 Rt_map *lmp; 572 573 /* 574 * Remove the relocation promotion list, as performing more 575 * relocations may result in discovering more objects that need 576 * promotion. 577 */ 578 plmc->lc_now = NULL; 579 580 for (APLIST_TRAVERSE(alp, idx, lmp)) { 581 /* 582 * If the original relocation of the link-map control 583 * list failed, or one of the relocation promotions of 584 * this loop has failed, demote any pending objects 585 * relocation mode. 586 */ 587 if ((lret == 0) || (pret == 0)) { 588 MODE(lmp) &= ~RTLD_NOW; 589 MODE(lmp) |= RTLD_LAZY; 590 continue; 591 } 592 593 /* 594 * If a relocation fails, save the error condition. 595 * It's possible that all new objects on the original 596 * link-map control list have been relocated 597 * successfully, but if the user request requires 598 * promoting objects that have already been loaded, we 599 * have to indicate that this operation couldn't be 600 * performed. The unrelocated objects are in use on 601 * another control list, and may continue to be used. 602 * If the .plt that resulted in the error is called, 603 * then the process will receive a fatal error at that 604 * time. But, the .plt may never be called. 605 */ 606 if (relocate_so(lml, lmp, 0, 1, in_nfavl) == 0) 607 pret = 0; 608 } 609 610 /* 611 * Having promoted any objects, determine whether additional 612 * dependencies were added, and if so move them to the previous 613 * link-map control list. 614 */ 615 /* LINTED */ 616 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 617 /* LINTED */ 618 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco); 619 if ((nlmco != ALIST_OFF_DATA) && nlmc->lc_head) 620 lm_move(lml, nlmco, plmco, nlmc, plmc); 621 free(alp); 622 } 623 624 /* 625 * If relocations have been successful, indicate that relocations are 626 * no longer active for this control list. Otherwise, leave the 627 * relocation flag, as this flag is used to determine the style of 628 * cleanup (see remove_lmc()). 629 */ 630 if (lret && pret) { 631 /* LINTED */ 632 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 633 nlmc->lc_flags &= ~LMC_FLG_RELOCATING; 634 635 return (1); 636 } 637 638 return (0); 639 } 640 641 /* 642 * Inherit the first rejection message for possible later diagnostics. 643 * 644 * Any attempt to process a file that is unsuccessful, should be accompanied 645 * with an error diagnostic. However, some operations like searching for a 646 * simple filename, involve trying numerous paths, and an error message for each 647 * lookup is not required. Although a multiple search can fail, it's possible 648 * that a file was found, but was rejected because it was the wrong type. 649 * To satisfy these possibilities, the first failure is recorded as a rejection 650 * message, and this message is used later for a more specific diagnostic. 651 * 652 * File searches are focused at load_one(), and from here a rejection descriptor 653 * is passed down to various child routines. If these child routines can 654 * process multiple files, then they will maintain their own rejection desc- 655 * riptor. This is filled in for any failures, and a diagnostic produced to 656 * reflect the failure. The child routines then employ rejection_inherit() to 657 * pass the first rejection message back to load_one(). 658 * 659 * Note that the name, and rejection string must be duplicated, as the name 660 * buffer and error string buffer (see conv_ routines) may be reused for 661 * additional processing or rejection messages. 662 */ 663 void 664 rejection_inherit(Rej_desc *rej1, Rej_desc *rej2) 665 { 666 if (rej2->rej_type && (rej1->rej_type == 0)) { 667 rej1->rej_type = rej2->rej_type; 668 rej1->rej_info = rej2->rej_info; 669 rej1->rej_flags = rej2->rej_flags; 670 if (rej2->rej_name) 671 rej1->rej_name = stravl_insert(rej2->rej_name, 0, 0, 0); 672 if ((rej2->rej_str) && ((rej1->rej_str = 673 stravl_insert(rej2->rej_str, 0, 0, 0)) == NULL)) 674 rej1->rej_str = MSG_ORIG(MSG_EMG_ENOMEM); 675 } 676 } 677 678 /* 679 * Helper routine for is_so_matched() that consolidates matching a path name, 680 * or file name component of a link-map name. 681 */ 682 inline static int 683 _is_so_matched(const char *name, const char *str, int path) 684 { 685 const char *_str; 686 687 if ((path == 0) && ((_str = strrchr(str, '/')) != NULL)) 688 _str++; 689 else 690 _str = str; 691 692 return (strcmp(name, _str)); 693 } 694 695 /* 696 * Determine whether a search name matches one of the names associated with a 697 * link-map. A link-map contains several names: 698 * 699 * - a NAME() - this is the basename of the dynamic executable that started 700 * the process, and the path name of any dependencies used by the process. 701 * Most executables are received as full path names, as exec() prepends a 702 * search $PATH to locate the executable. However, simple file names can 703 * be received from exec() if the file is executed from the present working 704 * directory. Regardless, ld.so.1 maintains NAME() as the basename, as 705 * this has always been the name used in diagnostics and error messages. 706 * Most dependencies are full path names, as the typical search for a 707 * dependency, say "libx.so.1", results in search paths being prepended to 708 * the name, which eventually open "/lib/libx.so.1". However, relative 709 * path names can be supplied as dependencies, e.g. dlopen("../libx.so.1"). 710 * 711 * - a PATHNAME() - this is the fully resolved path name of the object. This 712 * name will differ from NAME() for all dynamic executables, and may differ 713 * from the NAME() of dependencies, if the dependency is not a full path 714 * name, or the dependency resolves to a symbolic link. 715 * 716 * - an ALIAS() name - these are alternative names by which the object has 717 * been found, ie. when dependencies are loaded through a variety of 718 * different symbolic links. 719 * 720 * The name pattern matching can differ depending on whether we are looking 721 * for a full path name (path != 0), or a simple file name (path == 0). Full 722 * path names typically match NAME() or PATHNAME() entries. 723 * 724 * For all full path name searches, the link-map names are taken as is. For 725 * simple file name searches, only the file name component of any link-map 726 * names are used for comparison. 727 */ 728 inline static Rt_map * 729 is_so_matched(Rt_map *lmp, const char *name, int path) 730 { 731 Aliste idx; 732 const char *cp; 733 734 if (_is_so_matched(name, NAME(lmp), path) == 0) 735 return (lmp); 736 737 if (PATHNAME(lmp) != NAME(lmp)) { 738 if (_is_so_matched(name, PATHNAME(lmp), path) == 0) 739 return (lmp); 740 } 741 742 for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) { 743 if (_is_so_matched(name, cp, path) == 0) 744 return (lmp); 745 } 746 747 return (NULL); 748 } 749 750 /* 751 * Files are opened by ld.so.1 to satisfy dependencies, filtees and dlopen() 752 * requests. Each request investigates the file based upon the callers 753 * environment. Once a full path name has been established, the following 754 * checks are made: 755 * 756 * - does the path exist in the link-map lists FullPathNode AVL tree? if 757 * so, the file is already loaded, and its associated link-map pointer 758 * is returned. 759 * - does the path exist in the not-found AVL tree? if so, this path has 760 * already been determined to not exist, and a failure is returned. 761 * - a device/inode check, to ensure the same file isn't mapped multiple 762 * times through different paths. See file_open(). 763 * 764 * However, there are cases where a test for an existing file name needs to be 765 * carried out, such as dlopen(NOLOAD) requests, dldump() requests, and as a 766 * final fallback to dependency loading. These requests are handled by 767 * is_so_loaded(). 768 * 769 * A traversal through the callers link-map list is carried out, and from each 770 * link-map, a comparison is made against all of the various names by which the 771 * object has been referenced. is_so_matched() is used to compare the link-map 772 * names against the name being searched for. Whether the search name is a full 773 * path name or a simple file name, governs what comparisons are made. 774 * 775 * A full path name, which is a fully resolved path name that starts with a "/" 776 * character, or a relative path name that includes a "/" character, must match 777 * the link-map names exactly. A simple file name, which is any name *not* 778 * containing a "/" character, are matched against the file name component of 779 * any link-map names. 780 */ 781 Rt_map * 782 is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl) 783 { 784 Rt_map *lmp; 785 avl_index_t where; 786 Lm_cntl *lmc; 787 Aliste idx; 788 int path = 0; 789 790 /* 791 * If the name is a full path name, first determine if the path name is 792 * registered on the FullPathNode AVL, or not-found AVL trees. 793 */ 794 if (name[0] == '/') { 795 uint_t hash = sgs_str_hash(name); 796 797 if (((lmp = fpavl_recorded(lml, name, hash, &where)) != NULL) && 798 ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0)) 799 return (lmp); 800 801 if (pnavl_recorded(&nfavl, name, hash, NULL)) { 802 /* 803 * For dlopen() and dlsym() fall backs, indicate that 804 * a registered not-found path has indicated that this 805 * object does not exist. 806 */ 807 if (in_nfavl) 808 (*in_nfavl)++; 809 return (NULL); 810 } 811 } 812 813 /* 814 * Determine whether the name is a simple file name, or a path name. 815 */ 816 if (strchr(name, '/')) 817 path++; 818 819 /* 820 * Loop through the callers link-map lists. 821 */ 822 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { 823 for (lmp = lmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) { 824 if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) 825 continue; 826 827 if (is_so_matched(lmp, name, path)) 828 return (lmp); 829 } 830 } 831 return (NULL); 832 } 833 834 /* 835 * Tracing is enabled by the LD_TRACE_LOADED_OPTIONS environment variable which 836 * is normally set from ldd(1). For each link map we load, print the load name 837 * and the full pathname of the associated object. 838 */ 839 /* ARGSUSED4 */ 840 static void 841 trace_so(Rt_map *clmp, Rej_desc *rej, const char *name, const char *path, 842 int alter, const char *nfound) 843 { 844 const char *str = MSG_ORIG(MSG_STR_EMPTY); 845 const char *reject = MSG_ORIG(MSG_STR_EMPTY); 846 char _reject[PATH_MAX]; 847 848 /* 849 * The first time through trace_so() will only have lddstub on the 850 * link-map list and the preloaded shared object is supplied as "path". 851 * As we don't want to print this shared object as a dependency, but 852 * instead inspect *its* dependencies, return. 853 */ 854 if (FLAGS1(clmp) & FL1_RT_LDDSTUB) 855 return; 856 857 /* 858 * Without any rejection info, this is a supplied not-found condition. 859 */ 860 if (rej && (rej->rej_type == 0)) { 861 (void) printf(nfound, name); 862 return; 863 } 864 865 /* 866 * If rejection information exists then establish what object was 867 * found and the reason for its rejection. 868 */ 869 if (rej) { 870 Conv_reject_desc_buf_t rej_buf; 871 872 /* LINTED */ 873 (void) snprintf(_reject, PATH_MAX, 874 MSG_INTL(ldd_reject[rej->rej_type]), 875 conv_reject_desc(rej, &rej_buf, M_MACH)); 876 if (rej->rej_name) 877 path = rej->rej_name; 878 reject = (char *)_reject; 879 880 /* 881 * Was an alternative pathname defined (from a configuration 882 * file). 883 */ 884 if (rej->rej_flags & FLG_REJ_ALTER) 885 str = MSG_INTL(MSG_LDD_FIL_ALTER); 886 } else { 887 if (alter) 888 str = MSG_INTL(MSG_LDD_FIL_ALTER); 889 } 890 891 /* 892 * If the load name isn't a full pathname print its associated pathname 893 * together with all the other information we've gathered. 894 */ 895 if (*name == '/') 896 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), path, str, reject); 897 else 898 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), name, path, str, 899 reject); 900 } 901 902 /* 903 * Establish a link-map mode, initializing it if it has just been loaded, or 904 * potentially updating it if it already exists. 905 */ 906 int 907 update_mode(Rt_map *lmp, int omode, int nmode) 908 { 909 Lm_list *lml = LIST(lmp); 910 int pmode = 0; 911 912 /* 913 * A newly loaded object hasn't had its mode set yet. Modes are used to 914 * load dependencies, so don't propagate any parent or no-load flags, as 915 * these would adversely affect this objects ability to load any of its 916 * dependencies that aren't already loaded. RTLD_FIRST is applicable to 917 * this objects handle creation only, and should not be propagated. 918 */ 919 if ((FLAGS(lmp) & FLG_RT_MODESET) == 0) { 920 MODE(lmp) |= nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST); 921 FLAGS(lmp) |= FLG_RT_MODESET; 922 return (1); 923 } 924 925 /* 926 * Establish any new overriding modes. RTLD_LAZY and RTLD_NOW should be 927 * represented individually (this is historic, as these two flags were 928 * the only flags originally available to dlopen()). Other flags are 929 * accumulative, but have a hierarchy of preference. 930 */ 931 if ((omode & RTLD_LAZY) && (nmode & RTLD_NOW)) { 932 MODE(lmp) &= ~RTLD_LAZY; 933 pmode |= RTLD_NOW; 934 } 935 936 pmode |= ((~omode & nmode) & 937 (RTLD_GLOBAL | RTLD_WORLD | RTLD_NODELETE)); 938 if (pmode) { 939 DBG_CALL(Dbg_file_mode_promote(lmp, pmode)); 940 MODE(lmp) |= pmode; 941 } 942 943 /* 944 * If this load is an RTLD_NOW request and the object has already been 945 * loaded non-RTLD_NOW, append this object to the relocation-now list 946 * of the objects associated control list. Note, if the object hasn't 947 * yet been relocated, setting its MODE() to RTLD_NOW will establish 948 * full relocation processing when it eventually gets relocated. 949 */ 950 if ((pmode & RTLD_NOW) && 951 (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))) { 952 Lm_cntl *lmc; 953 954 /* LINTED */ 955 lmc = (Lm_cntl *)alist_item_by_offset(LIST(lmp)->lm_lists, 956 CNTL(lmp)); 957 (void) aplist_append(&lmc->lc_now, lmp, AL_CNT_LMNOW); 958 } 959 960 /* 961 * If this objects .init has been collected but has not yet been called, 962 * it may be necessary to reevaluate the object using tsort(). For 963 * example, a new dlopen() hierarchy may bind to uninitialized objects 964 * that are already loaded, or a dlopen(RTLD_NOW) can establish new 965 * bindings between already loaded objects that require the tsort() 966 * information be recomputed. If however, no new objects have been 967 * added to the process, and this object hasn't been promoted, don't 968 * bother reevaluating the .init. The present tsort() information is 969 * probably as accurate as necessary, and by not establishing a parallel 970 * tsort() we can help reduce the amount of recursion possible between 971 * .inits. 972 */ 973 if (((FLAGS(lmp) & 974 (FLG_RT_INITCLCT | FLG_RT_INITCALL)) == FLG_RT_INITCLCT) && 975 ((lml->lm_flags & LML_FLG_OBJADDED) || ((pmode & RTLD_NOW) && 976 (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))))) { 977 FLAGS(lmp) &= ~FLG_RT_INITCLCT; 978 LIST(lmp)->lm_init++; 979 LIST(lmp)->lm_flags |= LML_FLG_OBJREEVAL; 980 } 981 982 return (pmode); 983 } 984 985 /* 986 * Determine whether an alias name already exists, and if not create one. This 987 * is typically used to retain dependency names, such as "libc.so.1", which 988 * would have been expanded to full path names when they were loaded. The 989 * full path names (NAME() and possibly PATHNAME()) are maintained on the 990 * FullPathNode AVL tree, and thus would have been matched by fpavl_loaded() 991 * during file_open(). 992 */ 993 int 994 append_alias(Rt_map *lmp, const char *str, int *added) 995 { 996 const char *cp; 997 Aliste idx; 998 999 /* 1000 * Determine if this filename is already on the alias list. 1001 */ 1002 for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) { 1003 if (strcmp(cp, str) == 0) 1004 return (1); 1005 } 1006 1007 /* 1008 * This is a new alias, append it to the alias list. 1009 */ 1010 if (((cp = stravl_insert(str, 0, 0, 0)) == NULL) || 1011 (aplist_append(&ALIAS(lmp), cp, AL_CNT_ALIAS) == NULL)) 1012 return (0); 1013 1014 if (added) 1015 *added = 1; 1016 return (1); 1017 } 1018 1019 /* 1020 * Determine whether a file is already loaded by comparing device and inode 1021 * values. 1022 */ 1023 static Rt_map * 1024 is_devinode_loaded(rtld_stat_t *status, Lm_list *lml, const char *name, 1025 uint_t flags) 1026 { 1027 Lm_cntl *lmc; 1028 Aliste idx; 1029 1030 /* 1031 * If this is an auditor, it will have been opened on a new link-map. 1032 * To prevent multiple occurrences of the same auditor on multiple 1033 * link-maps, search the head of each link-map list and see if this 1034 * object is already loaded as an auditor. 1035 */ 1036 if (flags & FLG_RT_AUDIT) { 1037 Lm_list *lml; 1038 1039 for (APLIST_TRAVERSE(dynlm_list, idx, lml)) { 1040 Rt_map *nlmp = lml->lm_head; 1041 1042 if (nlmp && ((FLAGS(nlmp) & 1043 (FLG_RT_AUDIT | FLG_RT_DELETE)) == FLG_RT_AUDIT) && 1044 (STDEV(nlmp) == status->st_dev) && 1045 (STINO(nlmp) == status->st_ino)) 1046 return (nlmp); 1047 } 1048 return (NULL); 1049 } 1050 1051 /* 1052 * If the file has been found determine from the new files status 1053 * information if this file is actually linked to one we already have 1054 * mapped. This catches symlink names not caught by is_so_loaded(). 1055 */ 1056 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { 1057 Rt_map *nlmp; 1058 1059 for (nlmp = lmc->lc_head; nlmp; nlmp = NEXT_RT_MAP(nlmp)) { 1060 if ((FLAGS(nlmp) & FLG_RT_DELETE) || 1061 (FLAGS1(nlmp) & FL1_RT_LDDSTUB)) 1062 continue; 1063 1064 if ((STDEV(nlmp) != status->st_dev) || 1065 (STINO(nlmp) != status->st_ino)) 1066 continue; 1067 1068 if (lml->lm_flags & LML_FLG_TRC_VERBOSE) { 1069 /* BEGIN CSTYLED */ 1070 if (*name == '/') 1071 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), 1072 name, MSG_ORIG(MSG_STR_EMPTY), 1073 MSG_ORIG(MSG_STR_EMPTY)); 1074 else 1075 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), 1076 name, NAME(nlmp), 1077 MSG_ORIG(MSG_STR_EMPTY), 1078 MSG_ORIG(MSG_STR_EMPTY)); 1079 /* END CSTYLED */ 1080 } 1081 return (nlmp); 1082 } 1083 } 1084 return (NULL); 1085 } 1086 1087 /* 1088 * Generate any error messages indicating a file could not be found. When 1089 * preloading or auditing a secure application, it can be a little more helpful 1090 * to indicate that a search of secure directories has failed, so adjust the 1091 * messages accordingly. 1092 */ 1093 void 1094 file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags, 1095 Rej_desc *rej) 1096 { 1097 int secure = 0; 1098 1099 if ((rtld_flags & RT_FL_SECURE) && 1100 (flags & (FLG_RT_PRELOAD | FLG_RT_AUDIT))) 1101 secure++; 1102 1103 if (lml->lm_flags & LML_FLG_TRC_ENABLE) { 1104 /* 1105 * Under ldd(1), auxiliary filtees that can't be loaded are 1106 * ignored, unless verbose errors are requested. 1107 */ 1108 if ((rtld_flags & RT_FL_SILENCERR) && 1109 ((lml->lm_flags & LML_FLG_TRC_VERBOSE) == 0)) 1110 return; 1111 1112 if (secure) 1113 trace_so(clmp, rej, name, 0, 0, 1114 MSG_INTL(MSG_LDD_SEC_NFOUND)); 1115 else 1116 trace_so(clmp, rej, name, 0, 0, 1117 MSG_INTL(MSG_LDD_FIL_NFOUND)); 1118 return; 1119 } 1120 1121 if (rej->rej_type) { 1122 Conv_reject_desc_buf_t rej_buf; 1123 1124 eprintf(lml, ERR_FATAL, MSG_INTL(err_reject[rej->rej_type]), 1125 rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN), 1126 conv_reject_desc(rej, &rej_buf, M_MACH)); 1127 return; 1128 } 1129 1130 if (secure) 1131 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SEC_OPEN), name); 1132 else 1133 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), name, 1134 strerror(ENOENT)); 1135 } 1136 1137 static int 1138 file_open(int err, Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, 1139 Rej_desc *rej, int *in_nfavl) 1140 { 1141 rtld_stat_t status; 1142 Rt_map *nlmp; 1143 avl_index_t nfavlwhere = 0; 1144 const char *oname = fdp->fd_oname, *nname = fdp->fd_nname; 1145 uint_t hash = sgs_str_hash(nname); 1146 1147 1148 if ((nname = stravl_insert(fdp->fd_nname, hash, 0, 0)) == NULL) 1149 return (0); 1150 fdp->fd_nname = nname; 1151 1152 if ((err == 0) && (fdp->fd_flags & FLG_FD_ALTER)) 1153 DBG_CALL(Dbg_file_config_obj(lml, oname, 0, nname)); 1154 1155 /* 1156 * If we're dealing with a full pathname, determine whether this 1157 * pathname is already known. Other pathnames fall through to the 1158 * dev/inode check, as even though the pathname may look the same as 1159 * one previously used, the process may have changed directory. 1160 */ 1161 if ((err == 0) && (nname[0] == '/')) { 1162 if ((nlmp = fpavl_recorded(lml, nname, hash, 1163 &(fdp->fd_avlwhere))) != NULL) { 1164 fdp->fd_lmp = nlmp; 1165 return (1); 1166 } 1167 if (pnavl_recorded(&nfavl, nname, hash, &nfavlwhere)) { 1168 /* 1169 * For dlopen() and dlsym() fall backs, indicate that 1170 * a registered not-found path has indicated that this 1171 * object does not exist. If this path has been 1172 * constructed as part of expanding a CAPABILITY 1173 * directory, this is a silent failure, where no 1174 * rejection message is created. 1175 */ 1176 if (in_nfavl) 1177 (*in_nfavl)++; 1178 return (0); 1179 } 1180 } 1181 1182 if ((err == 0) && ((rtld_stat(nname, &status)) != -1)) { 1183 char path[PATH_MAX]; 1184 int fd, size, added; 1185 1186 /* 1187 * If this path has been constructed as part of expanding a 1188 * CAPABILITY directory, ignore any subdirectories. As this 1189 * is a silent failure, no rejection message is created. For 1190 * any other reference that expands to a directory, fall 1191 * through to construct a meaningful rejection message. 1192 */ 1193 if ((flags & FLG_RT_CAP) && 1194 ((status.st_mode & S_IFMT) == S_IFDIR)) 1195 return (0); 1196 1197 /* 1198 * If this is a directory (which can't be mmap()'ed) generate a 1199 * precise error message. 1200 */ 1201 if ((status.st_mode & S_IFMT) == S_IFDIR) { 1202 rej->rej_name = nname; 1203 if (fdp->fd_flags & FLG_FD_ALTER) 1204 rej->rej_flags = FLG_REJ_ALTER; 1205 rej->rej_type = SGS_REJ_STR; 1206 rej->rej_str = strerror(EISDIR); 1207 DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH)); 1208 return (0); 1209 } 1210 1211 /* 1212 * Resolve the filename and determine whether the resolved name 1213 * is already known. Typically, the previous fpavl_loaded() 1214 * will have caught this, as both NAME() and PATHNAME() for a 1215 * link-map are recorded in the FullPathNode AVL tree. However, 1216 * instances exist where a file can be replaced (loop-back 1217 * mounts, bfu, etc.), and reference is made to the original 1218 * file through a symbolic link. By checking the pathname here, 1219 * we don't fall through to the dev/inode check and conclude 1220 * that a new file should be loaded. 1221 */ 1222 if ((nname[0] == '/') && 1223 ((size = resolvepath(nname, path, (PATH_MAX - 1))) > 0)) { 1224 path[size] = '\0'; 1225 1226 fdp->fd_flags |= FLG_FD_RESOLVED; 1227 1228 if (strcmp(nname, path)) { 1229 if ((nlmp = 1230 fpavl_recorded(lml, path, 0, 0)) != NULL) { 1231 added = 0; 1232 1233 if (append_alias(nlmp, nname, 1234 &added) == 0) 1235 return (0); 1236 /* BEGIN CSTYLED */ 1237 if (added) 1238 DBG_CALL(Dbg_file_skip(LIST(clmp), 1239 NAME(nlmp), nname)); 1240 /* END CSTYLED */ 1241 fdp->fd_lmp = nlmp; 1242 return (1); 1243 } 1244 1245 /* 1246 * If this pathname hasn't been loaded, save 1247 * the resolved pathname so that it doesn't 1248 * have to be recomputed as part of fullpath() 1249 * processing. 1250 */ 1251 if ((fdp->fd_pname = stravl_insert(path, 0, 1252 (size + 1), 0)) == NULL) 1253 return (0); 1254 } 1255 } 1256 1257 if (nlmp = is_devinode_loaded(&status, lml, nname, flags)) { 1258 if (flags & FLG_RT_AUDIT) { 1259 /* 1260 * If we've been requested to load an auditor, 1261 * and an auditor of the same name already 1262 * exists, then the original auditor is used. 1263 */ 1264 DBG_CALL(Dbg_audit_skip(LIST(clmp), 1265 NAME(nlmp), LIST(nlmp)->lm_lmidstr)); 1266 } else { 1267 /* 1268 * Otherwise, if an alternatively named file 1269 * has been found for the same dev/inode, add 1270 * a new name alias. Insert any alias full path 1271 * name in the FullPathNode AVL tree. 1272 */ 1273 added = 0; 1274 1275 if (append_alias(nlmp, nname, &added) == 0) 1276 return (0); 1277 if (added) { 1278 if ((nname[0] == '/') && 1279 (fpavl_insert(lml, nlmp, 1280 nname, 0) == 0)) 1281 return (0); 1282 DBG_CALL(Dbg_file_skip(LIST(clmp), 1283 NAME(nlmp), nname)); 1284 } 1285 } 1286 1287 /* 1288 * Record in the file descriptor the existing object 1289 * that satisfies this open request. 1290 */ 1291 fdp->fd_lmp = nlmp; 1292 return (1); 1293 } 1294 1295 if ((fd = open(nname, O_RDONLY, 0)) == -1) { 1296 /* 1297 * As the file must exist for the previous stat() to 1298 * have succeeded, record the error condition. 1299 */ 1300 rej->rej_type = SGS_REJ_STR; 1301 rej->rej_str = strerror(errno); 1302 } else { 1303 /* 1304 * Map the object. A successful return indicates that 1305 * the object is appropriate for ld.so.1 processing. 1306 */ 1307 fdp->fd_ftp = map_obj(lml, fdp, status.st_size, nname, 1308 fd, rej); 1309 (void) close(fd); 1310 1311 if (fdp->fd_ftp != NULL) { 1312 fdp->fd_dev = status.st_dev; 1313 fdp->fd_ino = status.st_ino; 1314 return (1); 1315 } 1316 } 1317 1318 } else if (errno != ENOENT) { 1319 /* 1320 * If the open() failed for anything other than the file not 1321 * existing, record the error condition. 1322 */ 1323 rej->rej_type = SGS_REJ_STR; 1324 rej->rej_str = strerror(errno); 1325 } 1326 1327 /* 1328 * Regardless of error, duplicate and record any full path names that 1329 * can't be used on the "not-found" AVL tree. 1330 */ 1331 if (nname[0] == '/') 1332 nfavl_insert(nname, nfavlwhere); 1333 1334 /* 1335 * Indicate any rejection. 1336 */ 1337 if (rej->rej_type) { 1338 rej->rej_name = nname; 1339 if (fdp->fd_flags & FLG_FD_ALTER) 1340 rej->rej_flags = FLG_REJ_ALTER; 1341 DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH)); 1342 } 1343 return (0); 1344 } 1345 1346 /* 1347 * Find a full pathname (it contains a "/"). 1348 */ 1349 int 1350 find_path(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej, 1351 int *in_nfavl) 1352 { 1353 const char *oname = fdp->fd_oname; 1354 int err = 0; 1355 1356 /* 1357 * If directory configuration exists determine if this path is known. 1358 */ 1359 if (rtld_flags & RT_FL_DIRCFG) { 1360 Rtc_obj *obj; 1361 const char *aname; 1362 1363 if ((obj = elf_config_ent(oname, (Word)elf_hash(oname), 1364 0, &aname)) != 0) { 1365 /* 1366 * If the configuration file states that this path is a 1367 * directory, or the path is explicitly defined as 1368 * non-existent (ie. a unused platform specific 1369 * library), then go no further. 1370 */ 1371 if (obj->co_flags & RTC_OBJ_DIRENT) { 1372 err = EISDIR; 1373 } else if ((obj->co_flags & 1374 (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == 1375 RTC_OBJ_NOEXIST) { 1376 err = ENOENT; 1377 } else if ((obj->co_flags & RTC_OBJ_ALTER) && 1378 (rtld_flags & RT_FL_OBJALT) && (lml == &lml_main)) { 1379 int ret; 1380 1381 fdp->fd_flags |= FLG_FD_ALTER; 1382 fdp->fd_nname = aname; 1383 1384 /* 1385 * Attempt to open the alternative path. If 1386 * this fails, and the alternative is flagged 1387 * as optional, fall through to open the 1388 * original path. 1389 */ 1390 DBG_CALL(Dbg_libs_found(lml, aname, 1391 FLG_FD_ALTER)); 1392 ret = file_open(0, lml, clmp, flags, fdp, 1393 rej, in_nfavl); 1394 if (ret || ((obj->co_flags & 1395 RTC_OBJ_OPTINAL) == 0)) 1396 return (ret); 1397 1398 fdp->fd_flags &= ~FLG_FD_ALTER; 1399 } 1400 } 1401 } 1402 DBG_CALL(Dbg_libs_found(lml, oname, 0)); 1403 fdp->fd_nname = oname; 1404 return (file_open(err, lml, clmp, flags, fdp, rej, in_nfavl)); 1405 } 1406 1407 /* 1408 * Find a simple filename (it doesn't contain a "/"). 1409 */ 1410 static int 1411 _find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej, 1412 Pdesc *pdp, int aflag, int *in_nfavl) 1413 { 1414 const char *nname = fdp->fd_nname; 1415 1416 DBG_CALL(Dbg_libs_found(lml, nname, aflag)); 1417 if ((lml->lm_flags & LML_FLG_TRC_SEARCH) && 1418 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) { 1419 (void) printf(MSG_INTL(MSG_LDD_PTH_TRYING), nname, aflag ? 1420 MSG_INTL(MSG_LDD_FIL_ALTER) : MSG_ORIG(MSG_STR_EMPTY)); 1421 } 1422 1423 /* 1424 * If we're being audited tell the audit library of the file we're about 1425 * to go search for. The audit library may offer an alternative 1426 * dependency, or indicate that this dependency should be ignored. 1427 */ 1428 if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) { 1429 char *aname; 1430 1431 if ((aname = audit_objsearch(clmp, nname, 1432 (pdp->pd_flags & LA_SER_MASK))) == NULL) { 1433 DBG_CALL(Dbg_audit_terminate(lml, nname)); 1434 return (0); 1435 } 1436 1437 if (aname != nname) { 1438 fdp->fd_flags &= ~FLG_FD_SLASH; 1439 fdp->fd_nname = aname; 1440 } 1441 } 1442 return (file_open(0, lml, clmp, flags, fdp, rej, in_nfavl)); 1443 } 1444 1445 static int 1446 find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej, 1447 Pdesc *pdp, Word *strhash, int *in_nfavl) 1448 { 1449 static Rtc_obj Obj = { 0 }; 1450 Rtc_obj *dobj; 1451 const char *oname = fdp->fd_oname; 1452 size_t olen = strlen(oname); 1453 1454 if (pdp->pd_pname == NULL) 1455 return (0); 1456 if (pdp->pd_info) { 1457 dobj = (Rtc_obj *)pdp->pd_info; 1458 if ((dobj->co_flags & 1459 (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST) 1460 return (0); 1461 } else 1462 dobj = NULL; 1463 1464 /* 1465 * If configuration information exists see if this directory/file 1466 * combination exists. 1467 */ 1468 if ((rtld_flags & RT_FL_DIRCFG) && 1469 ((dobj == NULL) || (dobj->co_id != 0))) { 1470 Rtc_obj *fobj; 1471 const char *aname = NULL; 1472 1473 /* 1474 * If this object descriptor has not yet been searched for in 1475 * the configuration file go find it. 1476 */ 1477 if (dobj == NULL) { 1478 dobj = elf_config_ent(pdp->pd_pname, 1479 (Word)elf_hash(pdp->pd_pname), 0, 0); 1480 if (dobj == NULL) 1481 dobj = &Obj; 1482 pdp->pd_info = (void *)dobj; 1483 1484 if ((dobj->co_flags & (RTC_OBJ_NOEXIST | 1485 RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST) 1486 return (0); 1487 } 1488 1489 /* 1490 * If we found a directory search for the file. 1491 */ 1492 if (dobj->co_id != 0) { 1493 if (*strhash == NULL) 1494 *strhash = (Word)elf_hash(oname); 1495 fobj = elf_config_ent(oname, *strhash, 1496 dobj->co_id, &aname); 1497 1498 /* 1499 * If this object specifically does not exist, or the 1500 * object can't be found in a know-all-entries 1501 * directory, continue looking. If the object does 1502 * exist determine if an alternative object exists. 1503 */ 1504 if (fobj == NULL) { 1505 if (dobj->co_flags & RTC_OBJ_ALLENTS) 1506 return (0); 1507 } else { 1508 if ((fobj->co_flags & (RTC_OBJ_NOEXIST | 1509 RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST) 1510 return (0); 1511 1512 if ((fobj->co_flags & RTC_OBJ_ALTER) && 1513 (rtld_flags & RT_FL_OBJALT) && 1514 (lml == &lml_main)) { 1515 int ret; 1516 1517 fdp->fd_flags |= FLG_FD_ALTER; 1518 fdp->fd_nname = aname; 1519 1520 /* 1521 * Attempt to open the alternative path. 1522 * If this fails, and the alternative is 1523 * flagged as optional, fall through to 1524 * open the original path. 1525 */ 1526 ret = _find_file(lml, clmp, flags, fdp, 1527 rej, pdp, 1, in_nfavl); 1528 if (ret || ((fobj->co_flags & 1529 RTC_OBJ_OPTINAL) == 0)) 1530 return (ret); 1531 1532 fdp->fd_flags &= ~FLG_FD_ALTER; 1533 } 1534 } 1535 } 1536 } 1537 1538 /* 1539 * Protect ourselves from building an invalid pathname. 1540 */ 1541 if ((olen + pdp->pd_plen + 1) >= PATH_MAX) { 1542 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), oname, 1543 strerror(ENAMETOOLONG)); 1544 return (0); 1545 } 1546 if ((fdp->fd_nname = (LM_GET_SO(clmp)(pdp->pd_pname, oname, 1547 pdp->pd_plen, olen))) == NULL) 1548 return (0); 1549 1550 return (_find_file(lml, clmp, flags, fdp, rej, pdp, 0, in_nfavl)); 1551 } 1552 1553 static Fct *Vector[] = { 1554 &elf_fct, 1555 #ifdef A_OUT 1556 &aout_fct, 1557 #endif 1558 0 1559 }; 1560 1561 /* 1562 * Remap the first page of a file to provide a better diagnostic as to why 1563 * an mmapobj(2) operation on this file failed. Sadly, mmapobj(), and all 1564 * system calls for that matter, only pass back a generic failure in errno. 1565 * Hopefully one day this will be improved, but in the mean time we repeat 1566 * the kernels ELF verification to try and provide more detailed information. 1567 */ 1568 static int 1569 map_fail(Fdesc *fdp, size_t fsize, const char *name, int fd, Rej_desc *rej) 1570 { 1571 caddr_t addr; 1572 int vnum; 1573 size_t size; 1574 1575 /* 1576 * Use the original file size to determine what to map, and catch the 1577 * obvious error of a zero sized file. 1578 */ 1579 if (fsize == 0) { 1580 rej->rej_type = SGS_REJ_UNKFILE; 1581 return (1); 1582 } else if (fsize < syspagsz) 1583 size = fsize; 1584 else 1585 size = syspagsz; 1586 1587 if ((addr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) 1588 return (0); 1589 1590 rej->rej_type = 0; 1591 1592 /* 1593 * Validate the file against each supported file type. Should a 1594 * characteristic of the file be found invalid for this platform, a 1595 * rejection message will have been recorded. 1596 */ 1597 for (vnum = 0; Vector[vnum]; vnum++) { 1598 if (((Vector[vnum]->fct_verify_file)(addr, size, 1599 fdp, name, rej) == 0) && rej->rej_type) 1600 break; 1601 } 1602 1603 /* 1604 * If no rejection message has been recorded, then this is simply an 1605 * unknown file type. 1606 */ 1607 if (rej->rej_type == 0) 1608 rej->rej_type = SGS_REJ_UNKFILE; 1609 1610 (void) munmap(addr, size); 1611 return (1); 1612 } 1613 1614 /* 1615 * Unmap a file. 1616 */ 1617 void 1618 unmap_obj(mmapobj_result_t *mpp, uint_t mapnum) 1619 { 1620 uint_t num; 1621 1622 for (num = 0; num < mapnum; num++) { 1623 /* LINTED */ 1624 (void) munmap((void *)(uintptr_t)mpp[num].mr_addr, 1625 mpp[num].mr_msize); 1626 } 1627 cnt_unmap++; 1628 } 1629 1630 /* 1631 * Map a file. 1632 */ 1633 Fct * 1634 map_obj(Lm_list *lml, Fdesc *fdp, size_t fsize, const char *name, int fd, 1635 Rej_desc *rej) 1636 { 1637 static mmapobj_result_t *smpp = NULL; 1638 static uint_t smapnum; 1639 mmapobj_result_t *mpp; 1640 uint_t mnum, mapnum, mflags; 1641 void *padding; 1642 1643 /* 1644 * Allocate an initial mapping array. The initial size should be large 1645 * enough to handle the normal ELF objects we come across. 1646 */ 1647 if (smpp == NULL) { 1648 smpp = malloc(sizeof (mmapobj_result_t) * MMAPFD_NUM); 1649 if (smpp == NULL) 1650 return (NULL); 1651 smapnum = MMAPFD_NUM; 1652 } 1653 1654 /* 1655 * If object padding is required, set the necessary flags. 1656 */ 1657 if (r_debug.rtd_objpad) { 1658 mflags = MMOBJ_INTERPRET | MMOBJ_PADDING; 1659 padding = &r_debug.rtd_objpad; 1660 } else { 1661 mflags = MMOBJ_INTERPRET; 1662 padding = NULL; 1663 } 1664 1665 /* 1666 * Map the file. If the number of mappings required by this file 1667 * exceeds the present mapping structure, an error indicating the 1668 * return data is too big is returned. Bail on any other error. 1669 */ 1670 mapnum = smapnum; 1671 if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) { 1672 if (errno != E2BIG) { 1673 int err = errno; 1674 1675 /* 1676 * An unsupported error indicates that there's something 1677 * incompatible with this ELF file, and the process that 1678 * is already running. Map the first page of the file 1679 * and see if we can generate a better error message. 1680 */ 1681 if ((errno == ENOTSUP) && map_fail(fdp, fsize, name, 1682 fd, rej)) 1683 return (NULL); 1684 1685 rej->rej_type = SGS_REJ_STR; 1686 rej->rej_str = strerror(err); 1687 return (NULL); 1688 } 1689 1690 /* 1691 * The mapping requirement exceeds the present mapping 1692 * structure, however the number of mapping required is 1693 * available in the mapping number. 1694 */ 1695 free((void *)smpp); 1696 if ((smpp = malloc(sizeof (mmapobj_result_t) * mapnum)) == NULL) 1697 return (NULL); 1698 smapnum = mapnum; 1699 1700 /* 1701 * With the appropriate mapping structure, try the mapping 1702 * request again. 1703 */ 1704 if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) { 1705 rej->rej_type = SGS_REJ_STR; 1706 rej->rej_str = strerror(errno); 1707 return (NULL); 1708 } 1709 } 1710 ASSERT(mapnum != 0); 1711 1712 /* 1713 * Traverse the mappings in search of a file type ld.so.1 can process. 1714 * If the file type is verified as one ld.so.1 can process, retain the 1715 * mapping information, and the number of mappings this object uses, 1716 * and clear the static mapping pointer for the next map_obj() use of 1717 * mmapobj(). 1718 */ 1719 DBG_CALL(Dbg_file_mmapobj(lml, name, smpp, mapnum)); 1720 cnt_map++; 1721 1722 for (mnum = 0, mpp = smpp; mnum < mapnum; mnum++, mpp++) { 1723 uint_t flags = (mpp->mr_flags & MR_TYPE_MASK); 1724 Fct *fptr = NULL; 1725 1726 if (flags == MR_HDR_ELF) { 1727 fptr = elf_verify((mpp->mr_addr + mpp->mr_offset), 1728 mpp->mr_fsize, fdp, name, rej); 1729 } 1730 #ifdef A_OUT 1731 if (flags == MR_HDR_AOUT) { 1732 fptr = aout_verify((mpp->mr_addr + mpp->mr_offset), 1733 mpp->mr_fsize, fdp, name, rej); 1734 } 1735 #endif 1736 if (fptr) { 1737 fdp->fd_mapn = mapnum; 1738 fdp->fd_mapp = smpp; 1739 1740 smpp = NULL; 1741 1742 return (fptr); 1743 } 1744 } 1745 1746 /* 1747 * If the mapped file is inappropriate, indicate that the file type is 1748 * unknown, and free the mapping. 1749 */ 1750 if (rej->rej_type == 0) 1751 rej->rej_type = SGS_REJ_UNKFILE; 1752 unmap_obj(smpp, mapnum); 1753 1754 return (NULL); 1755 } 1756 1757 /* 1758 * A unique file has been opened. Create a link-map to represent it, and 1759 * process the various names by which it can be referenced. 1760 */ 1761 Rt_map * 1762 load_file(Lm_list *lml, Aliste lmco, Fdesc *fdp, int *in_nfavl) 1763 { 1764 mmapobj_result_t *fpmpp = NULL, *fmpp = NULL, *lpmpp, *lmpp; 1765 mmapobj_result_t *hmpp, *mpp, *ompp = fdp->fd_mapp; 1766 uint_t mnum, omapnum = fdp->fd_mapn; 1767 const char *nname = fdp->fd_nname; 1768 Rt_map *nlmp; 1769 Ehdr *ehdr = NULL; 1770 1771 /* 1772 * Traverse the mappings for the input file to capture generic mapping 1773 * information, and create a link-map to represent the file. 1774 */ 1775 for (mnum = 0, mpp = ompp; mnum < omapnum; mnum++, mpp++) { 1776 uint_t flags = (mpp->mr_flags & MR_TYPE_MASK); 1777 1778 /* 1779 * Keep track of the first and last mappings that may include 1780 * padding. 1781 */ 1782 if (fpmpp == NULL) 1783 fpmpp = mpp; 1784 lpmpp = mpp; 1785 1786 /* 1787 * Keep track of the first and last mappings that do not include 1788 * padding. 1789 */ 1790 if (flags != MR_PADDING) { 1791 if (fmpp == NULL) 1792 fmpp = mpp; 1793 lmpp = mpp; 1794 } 1795 if (flags == MR_HDR_ELF) { 1796 /* LINTED */ 1797 ehdr = (Ehdr *)(mpp->mr_addr + mpp->mr_offset); 1798 hmpp = mpp; 1799 } else if (flags == MR_HDR_AOUT) 1800 hmpp = mpp; 1801 } 1802 1803 /* 1804 * The only ELF files we can handle are ET_EXEC, ET_DYN, and ET_REL. 1805 * 1806 * ET_REL must be processed by ld(1) to create an in-memory ET_DYN. 1807 * The initial processing carried out by elf_obj_file() creates a 1808 * temporary link-map, that acts as a place holder, until the objects 1809 * processing is finished with elf_obj_fini(). 1810 */ 1811 if (ehdr && (ehdr->e_type == ET_REL)) { 1812 if ((nlmp = elf_obj_file(lml, lmco, nname, hmpp, ompp, 1813 omapnum)) == NULL) 1814 return (nlmp); 1815 } else { 1816 Addr addr; 1817 size_t msize; 1818 1819 /* 1820 * The size of the total reservation, and the padding range, 1821 * are a historic artifact required by debuggers. Although 1822 * these values express the range of the associated mappings, 1823 * there can be holes between segments (in which small objects 1824 * could be mapped). Anyone who needs to verify offsets 1825 * against segments should analyze all the object mappings, 1826 * rather than relying on these address ranges. 1827 */ 1828 addr = (Addr)(hmpp->mr_addr + hmpp->mr_offset); 1829 msize = lmpp->mr_addr + lmpp->mr_msize - fmpp->mr_addr; 1830 1831 if ((nlmp = ((fdp->fd_ftp)->fct_new_lmp)(lml, lmco, fdp, addr, 1832 msize, NULL, in_nfavl)) == NULL) 1833 return (NULL); 1834 1835 /* 1836 * Save generic mapping information. 1837 */ 1838 MMAPS(nlmp) = ompp; 1839 MMAPCNT(nlmp) = omapnum; 1840 PADSTART(nlmp) = (ulong_t)fpmpp->mr_addr; 1841 PADIMLEN(nlmp) = lpmpp->mr_addr + lpmpp->mr_msize - 1842 fpmpp->mr_addr; 1843 } 1844 1845 /* 1846 * Save the dev/inode information for later comparisons, and identify 1847 * this as a new object. 1848 */ 1849 STDEV(nlmp) = fdp->fd_dev; 1850 STINO(nlmp) = fdp->fd_ino; 1851 FLAGS(nlmp) |= FLG_RT_NEWLOAD; 1852 1853 /* 1854 * If this is ELF relocatable object, we're done for now. 1855 */ 1856 if (ehdr && (ehdr->e_type == ET_REL)) 1857 return (nlmp); 1858 1859 /* 1860 * Insert the names of this link-map into the FullPathNode AVL tree. 1861 * Save both the NAME() and PATHNAME() if the names differ. 1862 */ 1863 (void) fullpath(nlmp, fdp); 1864 1865 if ((NAME(nlmp)[0] == '/') && (fpavl_insert(lml, nlmp, NAME(nlmp), 1866 fdp->fd_avlwhere) == 0)) { 1867 remove_so(lml, nlmp); 1868 return (NULL); 1869 } 1870 if (((NAME(nlmp)[0] != '/') || (NAME(nlmp) != PATHNAME(nlmp))) && 1871 (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)) { 1872 remove_so(lml, nlmp); 1873 return (NULL); 1874 } 1875 1876 /* 1877 * If this is a secure application, record any full path name directory 1878 * in which this dependency has been found. This directory can be 1879 * deemed safe (as we've already found a dependency here). This 1880 * recording provides a fall-back should another objects $ORIGIN 1881 * definition expands to this directory, an expansion that would 1882 * ordinarily be deemed insecure. 1883 */ 1884 if (rtld_flags & RT_FL_SECURE) { 1885 if (NAME(nlmp)[0] == '/') 1886 spavl_insert(NAME(nlmp)); 1887 if ((NAME(nlmp) != PATHNAME(nlmp)) && 1888 (PATHNAME(nlmp)[0] == '/')) 1889 spavl_insert(PATHNAME(nlmp)); 1890 } 1891 1892 /* 1893 * If we're processing an alternative object reset the original name 1894 * for possible $ORIGIN processing. 1895 */ 1896 if (fdp->fd_flags & FLG_FD_ALTER) { 1897 const char *odir, *ndir; 1898 size_t olen; 1899 1900 FLAGS(nlmp) |= FLG_RT_ALTER; 1901 1902 /* 1903 * If we were given a pathname containing a slash then the 1904 * original name is still in oname. Otherwise the original 1905 * directory is in dir->p_name (which is all we need for 1906 * $ORIGIN). 1907 */ 1908 if (fdp->fd_flags & FLG_FD_SLASH) { 1909 char *ofil; 1910 1911 odir = fdp->fd_oname; 1912 ofil = strrchr(fdp->fd_oname, '/'); 1913 olen = ofil - odir + 1; 1914 } else { 1915 odir = fdp->fd_odir; 1916 olen = strlen(odir) + 1; 1917 } 1918 if ((ndir = stravl_insert(odir, 0, olen, 1)) == NULL) { 1919 remove_so(lml, nlmp); 1920 return (NULL); 1921 } 1922 ORIGNAME(nlmp) = ndir; 1923 DIRSZ(nlmp) = --olen; 1924 } 1925 1926 return (nlmp); 1927 } 1928 1929 /* 1930 * This function loads the named file and returns a pointer to its link map. 1931 * It is assumed that the caller has already checked that the file is not 1932 * already loaded before calling this function (refer is_so_loaded()). 1933 * Find and open the file, map it into memory, add it to the end of the list 1934 * of link maps and return a pointer to the new link map. Return 0 on error. 1935 */ 1936 static Rt_map * 1937 load_so(Lm_list *lml, Aliste lmco, Rt_map *clmp, uint_t flags, 1938 Fdesc *fdp, Rej_desc *rej, int *in_nfavl) 1939 { 1940 const char *oname = fdp->fd_oname; 1941 Pdesc *pdp; 1942 1943 /* 1944 * If this path name hasn't already been identified as containing a 1945 * slash, check the path name. Most paths have been constructed 1946 * through appending a file name to a search path, and/or have been 1947 * inspected by expand(), and thus have a slash. However, we can 1948 * receive path names via auditors or configuration files, and thus 1949 * an evaluation here catches these instances. 1950 */ 1951 if ((fdp->fd_flags & FLG_FD_SLASH) == 0) { 1952 const char *str; 1953 1954 for (str = oname; *str; str++) { 1955 if (*str == '/') { 1956 fdp->fd_flags |= FLG_FD_SLASH; 1957 break; 1958 } 1959 } 1960 } 1961 1962 /* 1963 * If we are passed a 'null' link-map this means that this is the first 1964 * object to be loaded on this link-map list. In that case we set the 1965 * link-map to ld.so.1's link-map. 1966 * 1967 * This link-map is referenced to determine what lookup rules to use 1968 * when searching for files. By using ld.so.1's we are defaulting to 1969 * ELF look-up rules. 1970 * 1971 * Note: This case happens when loading the first object onto 1972 * the plt_tracing link-map. 1973 */ 1974 if (clmp == 0) 1975 clmp = lml_rtld.lm_head; 1976 1977 /* 1978 * If this path resulted from a $CAPABILITY specification, then the 1979 * best capability object has already been establish, and is available 1980 * in the calling file descriptor. Perform some minor book-keeping so 1981 * that we can fall through into common code. 1982 */ 1983 if (flags & FLG_RT_CAP) { 1984 /* 1985 * If this object is already loaded, we're done. 1986 */ 1987 if (fdp->fd_lmp) 1988 return (fdp->fd_lmp); 1989 1990 /* 1991 * Obtain the avl index for this object. 1992 */ 1993 (void) fpavl_recorded(lml, fdp->fd_nname, 0, 1994 &(fdp->fd_avlwhere)); 1995 1996 } else if (fdp->fd_flags & FLG_FD_SLASH) { 1997 Rej_desc _rej = { 0 }; 1998 1999 if (find_path(lml, clmp, flags, fdp, &_rej, in_nfavl) == 0) { 2000 rejection_inherit(rej, &_rej); 2001 return (NULL); 2002 } 2003 2004 /* 2005 * If this object is already loaded, we're done. 2006 */ 2007 if (fdp->fd_lmp) 2008 return (fdp->fd_lmp); 2009 2010 } else { 2011 /* 2012 * No '/' - for each directory on list, make a pathname using 2013 * that directory and filename and try to open that file. 2014 */ 2015 Spath_desc sd = { search_rules, NULL, 0 }; 2016 Word strhash = 0; 2017 int found = 0; 2018 2019 DBG_CALL(Dbg_libs_find(lml, oname)); 2020 2021 /* 2022 * Traverse the search path lists, creating full pathnames and 2023 * attempt to load each path. 2024 */ 2025 for (pdp = get_next_dir(&sd, clmp, flags); pdp; 2026 pdp = get_next_dir(&sd, clmp, flags)) { 2027 Rej_desc _rej = { 0 }; 2028 Fdesc fd = { 0 }; 2029 2030 /* 2031 * Under debugging, duplicate path name entries are 2032 * tagged but remain part of the search path list so 2033 * that they can be diagnosed under "unused" processing. 2034 * Skip these entries, as this path would have already 2035 * been attempted. 2036 */ 2037 if (pdp->pd_flags & PD_FLG_DUPLICAT) 2038 continue; 2039 2040 fd = *fdp; 2041 2042 /* 2043 * Try and locate this file. Make sure to clean up 2044 * any rejection information should the file have 2045 * been found, but not appropriate. 2046 */ 2047 if (find_file(lml, clmp, flags, &fd, &_rej, pdp, 2048 &strhash, in_nfavl) == 0) { 2049 rejection_inherit(rej, &_rej); 2050 continue; 2051 } 2052 2053 /* 2054 * Indicate that this search path has been used. If 2055 * this is an LD_LIBRARY_PATH setting, ignore any use 2056 * by ld.so.1 itself. 2057 */ 2058 if (((pdp->pd_flags & LA_SER_LIBPATH) == 0) || 2059 ((lml->lm_flags & LML_FLG_RTLDLM) == 0)) 2060 pdp->pd_flags |= PD_FLG_USED; 2061 2062 /* 2063 * If this object is already loaded, we're done. 2064 */ 2065 *fdp = fd; 2066 if (fdp->fd_lmp) 2067 return (fdp->fd_lmp); 2068 2069 fdp->fd_odir = pdp->pd_pname; 2070 found = 1; 2071 break; 2072 } 2073 2074 /* 2075 * If the file couldn't be loaded, do another comparison of 2076 * loaded files using just the basename. This catches folks 2077 * who may have loaded multiple full pathname files (possibly 2078 * from setxid applications) to satisfy dependency relationships 2079 * (i.e., a file might have a dependency on foo.so.1 which has 2080 * already been opened using its full pathname). 2081 */ 2082 if (found == 0) 2083 return (is_so_loaded(lml, oname, in_nfavl)); 2084 } 2085 2086 /* 2087 * Trace that this successfully opened file is about to be processed. 2088 * Note, as part of processing a family of hardware capabilities filtees 2089 * a number of candidates may have been opened and mapped to determine 2090 * their capability requirements. At this point we've decided which 2091 * of the candidates to use. 2092 */ 2093 if (lml->lm_flags & LML_FLG_TRC_ENABLE) { 2094 trace_so(clmp, 0, fdp->fd_oname, fdp->fd_nname, 2095 (fdp->fd_flags & FLG_FD_ALTER), 0); 2096 } 2097 2098 /* 2099 * Finish mapping the file and return the link-map descriptor. 2100 */ 2101 return (load_file(lml, lmco, fdp, in_nfavl)); 2102 } 2103 2104 /* 2105 * Trace an attempt to load an object, and seed the originating name. 2106 */ 2107 const char * 2108 load_trace(Lm_list *lml, Pdesc *pdp, Rt_map *clmp, Fdesc *fdp) 2109 { 2110 const char *name = pdp->pd_pname; 2111 2112 /* 2113 * First generate any ldd(1) diagnostics. 2114 */ 2115 if ((lml->lm_flags & (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_SEARCH)) && 2116 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) 2117 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, NAME(clmp)); 2118 2119 /* 2120 * Propagate any knowledge of a slash within the path name. 2121 */ 2122 if (pdp->pd_flags & PD_FLG_PNSLASH) 2123 fdp->fd_flags |= FLG_FD_SLASH; 2124 2125 /* 2126 * If we're being audited tell the audit library of the file we're 2127 * about to go search for. 2128 */ 2129 if (((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_ACTIVITY) && 2130 (lml == LIST(clmp))) 2131 audit_activity(clmp, LA_ACT_ADD); 2132 2133 if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) { 2134 char *aname; 2135 2136 /* 2137 * The auditor can indicate that this object should be ignored. 2138 */ 2139 if ((aname = 2140 audit_objsearch(clmp, name, LA_SER_ORIG)) == NULL) { 2141 DBG_CALL(Dbg_audit_terminate(lml, name)); 2142 return (NULL); 2143 } 2144 2145 if (name != aname) { 2146 fdp->fd_flags &= ~FLG_FD_SLASH; 2147 name = aname; 2148 } 2149 } 2150 fdp->fd_oname = name; 2151 return (name); 2152 } 2153 2154 /* 2155 * Having loaded an object and created a link-map to describe it, finish 2156 * processing this stage, including verifying any versioning requirements, 2157 * updating the objects mode, creating a handle if necessary, and adding this 2158 * object to existing handles if required. 2159 */ 2160 static int 2161 load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode, 2162 uint_t flags, Grp_hdl **hdl, Rt_map *nlmp) 2163 { 2164 Aliste idx1; 2165 Grp_hdl *ghp; 2166 int promote; 2167 uint_t rdflags; 2168 2169 /* 2170 * If this dependency is associated with a required version ensure that 2171 * the version is present in the loaded file. 2172 */ 2173 if (((rtld_flags & RT_FL_NOVERSION) == 0) && THIS_IS_ELF(clmp) && 2174 VERNEED(clmp) && (elf_verify_vers(name, clmp, nlmp) == 0)) 2175 return (0); 2176 2177 /* 2178 * If this object has indicated that it should be isolated as a group 2179 * (DT_FLAGS_1 contains DF_1_GROUP - object was built with -B group), 2180 * or if the callers direct bindings indicate it should be isolated as 2181 * a group (DYNINFO flags contains FLG_DI_GROUP - dependency following 2182 * -zgroupperm), establish the appropriate mode. 2183 * 2184 * The intent of an object defining itself as a group is to isolate the 2185 * relocation of the group within its own members, however, unless 2186 * opened through dlopen(), in which case we assume dlsym() will be used 2187 * to locate symbols in the new object, we still need to associate the 2188 * new object with the caller so that the caller can bind to this new 2189 * object. This is equivalent to a dlopen(RTLD_GROUP) and dlsym() 2190 * using the returned handle. 2191 */ 2192 if ((FLAGS(nlmp) | flags) & FLG_RT_SETGROUP) { 2193 nmode &= ~RTLD_WORLD; 2194 nmode |= RTLD_GROUP; 2195 2196 /* 2197 * If the object wasn't explicitly dlopen()'ed, in which case a 2198 * handle would have been requested, associate the object with 2199 * the parent. 2200 */ 2201 if ((flags & FLG_RT_PUBHDL) == 0) 2202 nmode |= RTLD_PARENT; 2203 } 2204 2205 /* 2206 * Establish new mode and flags. 2207 */ 2208 promote = update_mode(nlmp, MODE(nlmp), nmode); 2209 FLAGS(nlmp) |= flags; 2210 2211 /* 2212 * Establish the flags for any referenced dependency descriptors 2213 * (Grp_desc). 2214 * 2215 * - The referenced object is available for dlsym(). 2216 * - The referenced object is available to relocate against. 2217 * - The referenced object should have it's dependencies 2218 * added to this handle 2219 */ 2220 rdflags = (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS); 2221 2222 /* 2223 * If we've been asked to establish a handle create one for this object. 2224 * Or, if this object has already been analyzed, but this reference 2225 * requires that the mode of the object be promoted, create a private 2226 * handle to propagate the new modes to all this objects dependencies. 2227 */ 2228 if ((FLAGS(nlmp) & (FLG_RT_PUBHDL | FLG_RT_PRIHDL)) || 2229 (promote && (FLAGS(nlmp) & FLG_RT_ANALYZED))) { 2230 uint_t oflags, hflags, cdflags = 0; 2231 2232 /* 2233 * Establish any flags for the handle (Grp_hdl). 2234 * 2235 * - Public handles establish dependencies between objects 2236 * that must be taken into account when dlclose()'ing 2237 * objects. Private handles provide for collecting 2238 * dependencies, but do not affect dlclose(). Note that 2239 * a handle may already exist, but the public/private 2240 * state is set to trigger the required propagation of the 2241 * handle's flags and any dependency gathering. 2242 * - Use of the RTLD_FIRST flag indicates that only the first 2243 * dependency on the handle (the new object) can be used 2244 * to satisfy dlsym() requests. 2245 */ 2246 if (FLAGS(nlmp) & FLG_RT_PUBHDL) 2247 hflags = GPH_PUBLIC; 2248 else 2249 hflags = GPH_PRIVATE; 2250 2251 if (nmode & RTLD_FIRST) 2252 hflags |= GPH_FIRST; 2253 2254 /* 2255 * Establish the flags for this callers dependency descriptor 2256 * (Grp_desc). 2257 * 2258 * - The creation of a public handle creates a descriptor 2259 * for the referenced object and the caller (parent). 2260 * Typically, the handle is created for dlopen() or for 2261 * filtering. A private handle does not need to maintain 2262 * a descriptor to the parent. 2263 * - Use of the RTLD_PARENT flag indicates that the parent 2264 * can be relocated against. 2265 */ 2266 if (FLAGS(nlmp) & FLG_RT_PUBHDL) { 2267 cdflags |= GPD_PARENT; 2268 if (nmode & RTLD_PARENT) 2269 cdflags |= GPD_RELOC; 2270 } 2271 2272 /* 2273 * Now that the handle flags have been established, remove any 2274 * handle definition from the referenced object so that the 2275 * definitions don't mistakenly get inherited by a dependency. 2276 */ 2277 oflags = FLAGS(nlmp); 2278 FLAGS(nlmp) &= ~(FLG_RT_PUBHDL | FLG_RT_PRIHDL); 2279 2280 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD)); 2281 if ((ghp = hdl_create(lml, nlmp, clmp, hflags, rdflags, 2282 cdflags)) == NULL) 2283 return (0); 2284 2285 /* 2286 * Add any dependencies that are already loaded, to the handle. 2287 */ 2288 if (hdl_initialize(ghp, nlmp, nmode, promote) == 0) 2289 return (0); 2290 2291 if (hdl) 2292 *hdl = ghp; 2293 2294 /* 2295 * If we were asked to create a public handle, we're done. 2296 * 2297 * If this is a private handle request, then the handle is left 2298 * intact with a GPH_PRIVATE identifier. This handle is a 2299 * convenience for processing the dependencies of this object, 2300 * but does not affect how this object might be dlclose()'d. 2301 * For a private handle, fall through to carry out any group 2302 * processing. 2303 */ 2304 if (oflags & FLG_RT_PUBHDL) 2305 return (1); 2306 } 2307 2308 /* 2309 * If the caller isn't part of a group we're done. 2310 */ 2311 if (GROUPS(clmp) == NULL) 2312 return (1); 2313 2314 /* 2315 * Determine if our caller is already associated with a handle, if so 2316 * we need to add this object to any handles that already exist. 2317 * Traverse the list of groups our caller is a member of and add this 2318 * new link-map to those groups. 2319 */ 2320 for (APLIST_TRAVERSE(GROUPS(clmp), idx1, ghp)) { 2321 Aliste idx2; 2322 Grp_desc *gdp; 2323 int ale; 2324 Rt_map *dlmp1; 2325 APlist *lmalp = NULL; 2326 2327 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD)); 2328 2329 /* 2330 * If the caller doesn't indicate that its dependencies should 2331 * be added to a handle, ignore it. This case identifies a 2332 * parent of a dlopen(RTLD_PARENT) request. 2333 */ 2334 for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) { 2335 if (gdp->gd_depend == clmp) 2336 break; 2337 } 2338 if ((gdp->gd_flags & GPD_ADDEPS) == 0) 2339 continue; 2340 2341 if ((gdp = hdl_add(ghp, nlmp, rdflags, &ale)) == NULL) 2342 return (0); 2343 2344 /* 2345 * If this member already exists then its dependencies will 2346 * have already been processed. 2347 */ 2348 if (ale == ALE_EXISTS) 2349 continue; 2350 2351 /* 2352 * If the object we've added has just been opened, it will not 2353 * yet have been processed for its dependencies, these will be 2354 * added on later calls to load_one(). If it doesn't have any 2355 * dependencies we're also done. 2356 */ 2357 if (((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) || 2358 (DEPENDS(nlmp) == NULL)) 2359 continue; 2360 2361 /* 2362 * Otherwise, this object exists and has dependencies, so add 2363 * all of its dependencies to the handle were operating on. 2364 */ 2365 if (aplist_append(&lmalp, nlmp, AL_CNT_DEPCLCT) == NULL) 2366 return (0); 2367 2368 for (APLIST_TRAVERSE(lmalp, idx2, dlmp1)) { 2369 Aliste idx3; 2370 Bnd_desc *bdp; 2371 2372 /* 2373 * Add any dependencies of this dependency to the 2374 * dynamic dependency list so they can be further 2375 * processed. 2376 */ 2377 for (APLIST_TRAVERSE(DEPENDS(dlmp1), idx3, bdp)) { 2378 Rt_map *dlmp2 = bdp->b_depend; 2379 2380 if ((bdp->b_flags & BND_NEEDED) == 0) 2381 continue; 2382 2383 if (aplist_test(&lmalp, dlmp2, 2384 AL_CNT_DEPCLCT) == 0) { 2385 free(lmalp); 2386 return (0); 2387 } 2388 } 2389 2390 if (nlmp == dlmp1) 2391 continue; 2392 2393 if ((gdp = 2394 hdl_add(ghp, dlmp1, rdflags, &ale)) == NULL) { 2395 free(lmalp); 2396 return (0); 2397 } 2398 2399 if (ale == ALE_CREATE) 2400 (void) update_mode(dlmp1, MODE(dlmp1), nmode); 2401 } 2402 free(lmalp); 2403 } 2404 return (1); 2405 } 2406 2407 /* 2408 * The central routine for loading shared objects. Insures ldd() diagnostics, 2409 * handles and any other related additions are all done in one place. 2410 */ 2411 Rt_map * 2412 load_path(Lm_list *lml, Aliste lmco, Rt_map *clmp, int nmode, uint_t flags, 2413 Grp_hdl **hdl, Fdesc *fdp, Rej_desc *rej, int *in_nfavl) 2414 { 2415 const char *name = fdp->fd_oname; 2416 Rt_map *nlmp; 2417 2418 if ((nmode & RTLD_NOLOAD) == 0) { 2419 int oin_nfavl; 2420 2421 /* 2422 * Keep track of the number of not-found loads. 2423 */ 2424 if (in_nfavl) 2425 oin_nfavl = *in_nfavl; 2426 2427 /* 2428 * If this isn't a noload request attempt to load the file. 2429 */ 2430 if ((nlmp = load_so(lml, lmco, clmp, flags, fdp, rej, 2431 in_nfavl)) == NULL) 2432 return (NULL); 2433 2434 /* 2435 * If this file has been found, reset the not-found load count. 2436 * Although a search for this file might have inspected a number 2437 * of non-existent path names, the file has been found so there 2438 * is no need to accumulate a non-found count, as this may 2439 * trigger unnecessary fall back (retry) processing. 2440 */ 2441 if (in_nfavl) 2442 *in_nfavl = oin_nfavl; 2443 2444 /* 2445 * If we've loaded a library which identifies itself as not 2446 * being dlopen()'able catch it here. Let non-dlopen()'able 2447 * objects through under RTLD_CONFGEN as they're only being 2448 * mapped to be dldump()'ed. 2449 */ 2450 if ((rtld_flags & RT_FL_APPLIC) && ((FLAGS(nlmp) & 2451 (FLG_RT_NOOPEN | FLG_RT_RELOCED)) == FLG_RT_NOOPEN) && 2452 ((nmode & RTLD_CONFGEN) == 0)) { 2453 Rej_desc _rej = { 0 }; 2454 2455 _rej.rej_name = name; 2456 _rej.rej_type = SGS_REJ_STR; 2457 _rej.rej_str = MSG_INTL(MSG_GEN_NOOPEN); 2458 DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH)); 2459 rejection_inherit(rej, &_rej); 2460 remove_so(lml, nlmp); 2461 return (NULL); 2462 } 2463 } else { 2464 /* 2465 * If it's a NOLOAD request - check to see if the object 2466 * has already been loaded. 2467 */ 2468 /* LINTED */ 2469 if (nlmp = is_so_loaded(lml, name, in_nfavl)) { 2470 if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) && 2471 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) { 2472 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, 2473 NAME(clmp)); 2474 /* BEGIN CSTYLED */ 2475 if (*name == '/') 2476 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), 2477 name, MSG_ORIG(MSG_STR_EMPTY), 2478 MSG_ORIG(MSG_STR_EMPTY)); 2479 else 2480 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), 2481 name, NAME(nlmp), 2482 MSG_ORIG(MSG_STR_EMPTY), 2483 MSG_ORIG(MSG_STR_EMPTY)); 2484 /* END CSTYLED */ 2485 } 2486 } else { 2487 Rej_desc _rej = { 0 }; 2488 2489 _rej.rej_name = name; 2490 _rej.rej_type = SGS_REJ_STR; 2491 _rej.rej_str = strerror(ENOENT); 2492 DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH)); 2493 rejection_inherit(rej, &_rej); 2494 return (NULL); 2495 } 2496 } 2497 2498 /* 2499 * Finish processing this loaded object. 2500 */ 2501 if (load_finish(lml, name, clmp, nmode, flags, hdl, nlmp) == 0) { 2502 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD; 2503 2504 /* 2505 * If this object has already been analyzed, then it is in use, 2506 * so even though this operation has failed, it should not be 2507 * torn down. 2508 */ 2509 if ((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) 2510 remove_so(lml, nlmp); 2511 return (NULL); 2512 } 2513 2514 /* 2515 * If this object is new, and we're being audited, tell the audit 2516 * library of the file we've just opened. Note, if the new link-map 2517 * requires local auditing of its dependencies we also register its 2518 * opening. 2519 */ 2520 if (FLAGS(nlmp) & FLG_RT_NEWLOAD) { 2521 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD; 2522 2523 if (((lml->lm_tflags | AFLAGS(clmp) | AFLAGS(nlmp)) & 2524 LML_TFLG_AUD_MASK) && (((lml->lm_flags | 2525 LIST(clmp)->lm_flags) & LML_FLG_NOAUDIT) == 0)) { 2526 if (audit_objopen(clmp, nlmp) == 0) { 2527 remove_so(lml, nlmp); 2528 return (NULL); 2529 } 2530 } 2531 } 2532 return (nlmp); 2533 } 2534 2535 /* 2536 * Load one object from a possible list of objects. Typically, for requests 2537 * such as NEEDED's, only one object is specified. However, this object could 2538 * be specified using $ISALIST or $CAPABILITY, in which case only the first 2539 * object that can be loaded is used (ie. the best). 2540 */ 2541 Rt_map * 2542 load_one(Lm_list *lml, Aliste lmco, Alist *palp, Rt_map *clmp, int mode, 2543 uint_t flags, Grp_hdl **hdl, int *in_nfavl) 2544 { 2545 Rej_desc rej = { 0 }; 2546 Aliste idx; 2547 Pdesc *pdp; 2548 const char *name; 2549 2550 for (ALIST_TRAVERSE(palp, idx, pdp)) { 2551 Rt_map *lmp = NULL; 2552 2553 /* 2554 * A $CAPABILITY/$HWCAP requirement can expand into a number of 2555 * candidates. 2556 */ 2557 if (pdp->pd_flags & PD_TKN_CAP) { 2558 lmp = load_cap(lml, lmco, pdp->pd_pname, clmp, 2559 mode, (flags | FLG_RT_CAP), hdl, &rej, in_nfavl); 2560 } else { 2561 Fdesc fd = { 0 }; 2562 2563 /* 2564 * Trace the inspection of this file, determine any 2565 * auditor substitution, and seed the file descriptor 2566 * with the originating name. 2567 */ 2568 if (load_trace(lml, pdp, clmp, &fd) == NULL) 2569 continue; 2570 2571 /* 2572 * Locate and load the file. 2573 */ 2574 lmp = load_path(lml, lmco, clmp, mode, flags, hdl, &fd, 2575 &rej, in_nfavl); 2576 } 2577 if (lmp) 2578 return (lmp); 2579 } 2580 2581 /* 2582 * If no objects can be found, use the first path name from the Alist 2583 * to provide a diagnostic. If this pathname originated from an 2584 * expanded token, use the original name for any diagnostic output. 2585 */ 2586 pdp = alist_item(palp, 0); 2587 2588 if ((name = pdp->pd_oname) == 0) 2589 name = pdp->pd_pname; 2590 2591 file_notfound(lml, name, clmp, flags, &rej); 2592 return (NULL); 2593 } 2594 2595 /* 2596 * Determine whether a symbol is defined as an interposer. 2597 */ 2598 int 2599 is_sym_interposer(Rt_map *lmp, Sym *sym) 2600 { 2601 Syminfo *sip = SYMINFO(lmp); 2602 2603 if (sip) { 2604 ulong_t ndx; 2605 2606 ndx = (((ulong_t)sym - (ulong_t)SYMTAB(lmp)) / SYMENT(lmp)); 2607 /* LINTED */ 2608 sip = (Syminfo *)((char *)sip + (ndx * SYMINENT(lmp))); 2609 if (sip->si_flags & SYMINFO_FLG_INTERPOSE) 2610 return (1); 2611 } 2612 return (0); 2613 } 2614 2615 /* 2616 * While processing direct or group bindings, determine whether the object to 2617 * which we've bound can be interposed upon. In this context, copy relocations 2618 * are a form of interposition. 2619 */ 2620 static int 2621 lookup_sym_interpose(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl) 2622 { 2623 Rt_map *lmp, *clmp, *dlmp = srp->sr_dmap; 2624 Sym *osym = srp->sr_sym; 2625 Slookup sl; 2626 Lm_list *lml; 2627 2628 /* 2629 * If we've bound to a copy relocation definition then we need to assign 2630 * this binding to the original copy reference. Fabricate an inter- 2631 * position diagnostic, as this is a legitimate form of interposition. 2632 */ 2633 if (osym && (FLAGS1(dlmp) & FL1_RT_COPYTOOK)) { 2634 Rel_copy *rcp; 2635 Aliste idx; 2636 2637 for (ALIST_TRAVERSE(COPY_R(dlmp), idx, rcp)) { 2638 if ((osym == rcp->r_dsym) || (osym->st_value && 2639 (osym->st_value == rcp->r_dsym->st_value))) { 2640 srp->sr_dmap = rcp->r_rlmp; 2641 srp->sr_sym = rcp->r_rsym; 2642 *binfo |= 2643 (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF); 2644 return (1); 2645 } 2646 } 2647 } 2648 2649 /* 2650 * If a symbol binding has been established, inspect the link-map list 2651 * of the destination object, otherwise use the link-map list of the 2652 * original caller. 2653 */ 2654 if (osym) 2655 clmp = dlmp; 2656 else 2657 clmp = slp->sl_cmap; 2658 2659 lml = LIST(clmp); 2660 lmp = lml->lm_head; 2661 2662 /* 2663 * Prior to Solaris 8, external references from an executable that were 2664 * bound to an uninitialized variable (.bss) within a shared object did 2665 * not establish a copy relocation. This was thought to be an 2666 * optimization, to prevent copying zero's to zero's. Typically, 2667 * interposition took its course, with the shared object binding to the 2668 * executables data definition. 2669 * 2670 * This scenario can be broken when this old executable runs against a 2671 * new shared object that is directly bound. With no copy-relocation 2672 * record, ld.so.1 has no data to trigger the normal vectoring of the 2673 * binding to the executable. 2674 * 2675 * Starting with Solaris 8, a DT_FLAGS entry is written to all objects, 2676 * regardless of there being any DF_ flags entries. Therefore, an 2677 * object without this dynamic tag is susceptible to the copy relocation 2678 * issue. If the executable has no DT_FLAGS tag, and contains the same 2679 * .bss symbol definition as has been directly bound to, redirect the 2680 * binding to the executables data definition. 2681 */ 2682 if (osym && ((FLAGS1(lmp) & FL1_RT_DTFLAGS) == 0) && 2683 (FCT(lmp) == &elf_fct) && 2684 (ELF_ST_TYPE(osym->st_info) != STT_FUNC) && 2685 are_bits_zero(dlmp, osym, 0)) { 2686 Sresult sr; 2687 2688 /* 2689 * Initialize a local symbol result descriptor, using the 2690 * original symbol name. Initialize a local symbol lookup 2691 * descriptor, using the original lookup information, and a 2692 * new initial link-map. 2693 */ 2694 SRESULT_INIT(sr, slp->sl_name); 2695 sl = *slp; 2696 sl.sl_imap = lmp; 2697 2698 /* 2699 * Determine whether the same symbol name exists within the 2700 * executable, that the size and type of symbol are the same, 2701 * and that the symbol is also associated with .bss. 2702 */ 2703 if (SYMINTP(lmp)(&sl, &sr, binfo, in_nfavl)) { 2704 Sym *isym = sr.sr_sym; 2705 2706 if ((isym->st_size == osym->st_size) && 2707 (isym->st_info == osym->st_info) && 2708 are_bits_zero(lmp, isym, 1)) { 2709 *srp = sr; 2710 *binfo |= 2711 (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF); 2712 return (1); 2713 } 2714 } 2715 } 2716 2717 if ((lml->lm_flags & LML_FLG_INTRPOSE) == 0) 2718 return (NULL); 2719 2720 /* 2721 * Traverse the list of known interposers to determine whether any 2722 * offer the same symbol. Note, the head of the link-map could be 2723 * identified as an interposer. Otherwise, skip the head of the 2724 * link-map, so that we don't bind to any .plt references, or 2725 * copy-relocation destinations unintentionally. 2726 */ 2727 lmp = lml->lm_head; 2728 sl = *slp; 2729 2730 if (((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) || (sl.sl_flags & LKUP_COPY)) 2731 lmp = NEXT_RT_MAP(lmp); 2732 2733 for (; lmp; lmp = NEXT_RT_MAP(lmp)) { 2734 if (FLAGS(lmp) & FLG_RT_DELETE) 2735 continue; 2736 if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) 2737 break; 2738 2739 /* 2740 * If we had already bound to this object, there's no point in 2741 * searching it again, we're done. 2742 */ 2743 if (lmp == dlmp) 2744 break; 2745 2746 /* 2747 * If this interposer can be inspected by the caller, look for 2748 * the symbol within the interposer. 2749 */ 2750 if (callable(clmp, lmp, 0, sl.sl_flags)) { 2751 Sresult sr; 2752 2753 /* 2754 * Initialize a local symbol result descriptor, using 2755 * the original symbol name. Initialize a local symbol 2756 * lookup descriptor, using the original lookup 2757 * information, and a new initial link-map. 2758 */ 2759 SRESULT_INIT(sr, slp->sl_name); 2760 sl.sl_imap = lmp; 2761 2762 if (SYMINTP(lmp)(&sl, &sr, binfo, in_nfavl)) { 2763 Sym *isym = sr.sr_sym; 2764 Rt_map *ilmp = sr.sr_dmap; 2765 2766 /* 2767 * If this object provides individual symbol 2768 * interposers, make sure that the symbol we 2769 * have found is tagged as an interposer. 2770 */ 2771 if ((FLAGS(ilmp) & FLG_RT_SYMINTPO) && 2772 (is_sym_interposer(ilmp, isym) == 0)) 2773 continue; 2774 2775 /* 2776 * Indicate this binding has occurred to an 2777 * interposer, and return the symbol. 2778 */ 2779 *srp = sr; 2780 *binfo |= DBG_BINFO_INTERPOSE; 2781 return (1); 2782 } 2783 } 2784 } 2785 return (0); 2786 } 2787 2788 /* 2789 * If an object specifies direct bindings (it contains a syminfo structure 2790 * describing where each binding was established during link-editing, and the 2791 * object was built -Bdirect), then look for the symbol in the specific object. 2792 */ 2793 static int 2794 lookup_sym_direct(Slookup *slp, Sresult *srp, uint_t *binfo, Syminfo *sip, 2795 Rt_map *lmp, int *in_nfavl) 2796 { 2797 Rt_map *dlmp, *clmp = slp->sl_cmap; 2798 int ret; 2799 Slookup sl; 2800 2801 /* 2802 * If a direct binding resolves to the definition of a copy relocated 2803 * variable, it must be redirected to the copy (in the executable) that 2804 * will eventually be made. Typically, this redirection occurs in 2805 * lookup_sym_interpose(). But, there's an edge condition. If a 2806 * directly bound executable contains pic code, there may be a 2807 * reference to a definition that will eventually have a copy made. 2808 * However, this copy relocation may not yet have occurred, because 2809 * the relocation making this reference comes before the relocation 2810 * that will create the copy. 2811 * Under direct bindings, the syminfo indicates that a copy will be 2812 * taken (SYMINFO_FLG_COPY). This can only be set in an executable. 2813 * Thus, the caller must be the executable, so bind to the destination 2814 * of the copy within the executable. 2815 */ 2816 if (((slp->sl_flags & LKUP_COPY) == 0) && 2817 (sip->si_flags & SYMINFO_FLG_COPY)) { 2818 slp->sl_imap = LIST(clmp)->lm_head; 2819 2820 if (ret = SYMINTP(clmp)(slp, srp, binfo, in_nfavl)) 2821 *binfo |= (DBG_BINFO_DIRECT | DBG_BINFO_COPYREF); 2822 return (ret); 2823 } 2824 2825 /* 2826 * If we need to directly bind to our parent, start looking in each 2827 * callers link map. 2828 */ 2829 sl = *slp; 2830 sl.sl_flags |= LKUP_DIRECT; 2831 ret = 0; 2832 2833 if (sip->si_boundto == SYMINFO_BT_PARENT) { 2834 Aliste idx1; 2835 Bnd_desc *bdp; 2836 Grp_hdl *ghp; 2837 2838 /* 2839 * Determine the parent of this explicit dependency from its 2840 * CALLERS()'s list. 2841 */ 2842 for (APLIST_TRAVERSE(CALLERS(clmp), idx1, bdp)) { 2843 sl.sl_imap = lmp = bdp->b_caller; 2844 if (ret = SYMINTP(lmp)(&sl, srp, binfo, in_nfavl)) 2845 goto found; 2846 } 2847 2848 /* 2849 * A caller can also be defined as the parent of a dlopen() 2850 * call. Determine whether this object has any handles. The 2851 * dependencies maintained with the handle represent the 2852 * explicit dependencies of the dlopen()'ed object, and the 2853 * calling parent. 2854 */ 2855 for (APLIST_TRAVERSE(HANDLES(clmp), idx1, ghp)) { 2856 Grp_desc *gdp; 2857 Aliste idx2; 2858 2859 for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) { 2860 if ((gdp->gd_flags & GPD_PARENT) == 0) 2861 continue; 2862 sl.sl_imap = lmp = gdp->gd_depend; 2863 if (ret = SYMINTP(lmp)(&sl, srp, binfo, 2864 in_nfavl)) 2865 goto found; 2866 } 2867 } 2868 } else { 2869 /* 2870 * If we need to direct bind to anything else look in the 2871 * link map associated with this symbol reference. 2872 */ 2873 if (sip->si_boundto == SYMINFO_BT_SELF) 2874 sl.sl_imap = lmp = clmp; 2875 else 2876 sl.sl_imap = lmp; 2877 2878 if (lmp) 2879 ret = SYMINTP(lmp)(&sl, srp, binfo, in_nfavl); 2880 } 2881 found: 2882 if (ret) 2883 *binfo |= DBG_BINFO_DIRECT; 2884 2885 /* 2886 * If a reference to a directly bound symbol can't be satisfied, then 2887 * determine whether an interposer can provide the missing symbol. If 2888 * a reference to a directly bound symbol is satisfied, then determine 2889 * whether that object can be interposed upon for this symbol. 2890 */ 2891 dlmp = srp->sr_dmap; 2892 if ((ret == 0) || (dlmp && (LIST(dlmp)->lm_head != dlmp) && 2893 (LIST(dlmp) == LIST(clmp)))) { 2894 if (lookup_sym_interpose(slp, srp, binfo, in_nfavl)) 2895 return (1); 2896 } 2897 2898 return (ret); 2899 } 2900 2901 static int 2902 core_lookup_sym(Rt_map *ilmp, Slookup *slp, Sresult *srp, uint_t *binfo, 2903 Aliste off, int *in_nfavl) 2904 { 2905 Rt_map *lmp; 2906 2907 /* 2908 * Copy relocations should start their search after the head of the 2909 * main link-map control list. 2910 */ 2911 if ((off == ALIST_OFF_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp) 2912 lmp = NEXT_RT_MAP(ilmp); 2913 else 2914 lmp = ilmp; 2915 2916 for (; lmp; lmp = NEXT_RT_MAP(lmp)) { 2917 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) { 2918 2919 slp->sl_imap = lmp; 2920 if ((SYMINTP(lmp)(slp, srp, binfo, in_nfavl)) || 2921 (*binfo & BINFO_MSK_TRYAGAIN)) 2922 return (1); 2923 } 2924 } 2925 return (0); 2926 } 2927 2928 static int 2929 rescan_lazy_find_sym(Rt_map *ilmp, Slookup *slp, Sresult *srp, uint_t *binfo, 2930 int *in_nfavl) 2931 { 2932 Rt_map *lmp; 2933 2934 for (lmp = ilmp; lmp; lmp = NEXT_RT_MAP(lmp)) { 2935 if (LAZY(lmp) == 0) 2936 continue; 2937 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) { 2938 2939 slp->sl_imap = lmp; 2940 if (elf_lazy_find_sym(slp, srp, binfo, in_nfavl)) 2941 return (1); 2942 } 2943 } 2944 return (0); 2945 } 2946 2947 static int 2948 _lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl) 2949 { 2950 const char *name = slp->sl_name; 2951 Rt_map *clmp = slp->sl_cmap; 2952 Lm_list *lml = LIST(clmp); 2953 Rt_map *ilmp = slp->sl_imap, *lmp; 2954 ulong_t rsymndx; 2955 int ret; 2956 Syminfo *sip; 2957 Slookup sl; 2958 2959 /* 2960 * Search the initial link map for the required symbol (this category is 2961 * selected by dlsym(), where individual link maps are searched for a 2962 * required symbol. Therefore, we know we have permission to look at 2963 * the link map). 2964 */ 2965 if (slp->sl_flags & LKUP_FIRST) 2966 return (SYMINTP(ilmp)(slp, srp, binfo, in_nfavl)); 2967 2968 /* 2969 * Determine whether this lookup can be satisfied by an objects direct, 2970 * or lazy binding information. This is triggered by a relocation from 2971 * the object (hence rsymndx is set). 2972 */ 2973 if (((rsymndx = slp->sl_rsymndx) != 0) && 2974 ((sip = SYMINFO(clmp)) != NULL)) { 2975 uint_t bound; 2976 2977 /* 2978 * Find the corresponding Syminfo entry for the original 2979 * referencing symbol. 2980 */ 2981 /* LINTED */ 2982 sip = (Syminfo *)((char *)sip + (rsymndx * SYMINENT(clmp))); 2983 bound = sip->si_boundto; 2984 2985 /* 2986 * Identify any EXTERN or PARENT references for ldd(1). 2987 */ 2988 if ((lml->lm_flags & LML_FLG_TRC_WARN) && 2989 (bound > SYMINFO_BT_LOWRESERVE)) { 2990 if (bound == SYMINFO_BT_PARENT) 2991 *binfo |= DBG_BINFO_REF_PARENT; 2992 if (bound == SYMINFO_BT_EXTERN) 2993 *binfo |= DBG_BINFO_REF_EXTERN; 2994 } 2995 2996 /* 2997 * If the symbol information indicates a direct binding, 2998 * determine the link map that is required to satisfy the 2999 * binding. Note, if the dependency can not be found, but a 3000 * direct binding isn't required, we will still fall through 3001 * to perform any default symbol search. 3002 */ 3003 if (sip->si_flags & SYMINFO_FLG_DIRECT) { 3004 3005 lmp = 0; 3006 if (bound < SYMINFO_BT_LOWRESERVE) 3007 lmp = elf_lazy_load(clmp, slp, bound, 3008 name, 0, NULL, in_nfavl); 3009 3010 /* 3011 * If direct bindings have been disabled, and this isn't 3012 * a translator, skip any direct binding now that we've 3013 * ensured the resolving object has been loaded. 3014 * 3015 * If we need to direct bind to anything, we look in 3016 * ourselves, our parent, or in the link map we've just 3017 * loaded. Otherwise, even though we may have lazily 3018 * loaded an object we still continue to search for 3019 * symbols from the head of the link map list. 3020 */ 3021 if (((FLAGS(clmp) & FLG_RT_TRANS) || 3022 (((lml->lm_tflags & LML_TFLG_NODIRECT) == 0) && 3023 ((slp->sl_flags & LKUP_SINGLETON) == 0))) && 3024 ((FLAGS1(clmp) & FL1_RT_DIRECT) || 3025 (sip->si_flags & SYMINFO_FLG_DIRECTBIND))) { 3026 ret = lookup_sym_direct(slp, srp, binfo, 3027 sip, lmp, in_nfavl); 3028 3029 /* 3030 * Determine whether this direct binding has 3031 * been rejected. If we've bound to a singleton 3032 * without following a singleton search, then 3033 * return. The caller detects this condition 3034 * and will trigger a new singleton search. 3035 * 3036 * For any other rejection (such as binding to 3037 * a symbol labeled as nodirect - presumably 3038 * because the symbol definition has been 3039 * changed since the referring object was last 3040 * built), fall through to a standard symbol 3041 * search. 3042 */ 3043 if (((*binfo & BINFO_MSK_REJECTED) == 0) || 3044 (*binfo & BINFO_MSK_TRYAGAIN)) 3045 return (ret); 3046 3047 *binfo &= ~BINFO_MSK_REJECTED; 3048 } 3049 } 3050 } 3051 3052 /* 3053 * Duplicate the lookup information, as we'll need to modify this 3054 * information for some of the following searches. 3055 */ 3056 sl = *slp; 3057 3058 /* 3059 * If the referencing object has the DF_SYMBOLIC flag set, look in the 3060 * referencing object for the symbol first. Failing that, fall back to 3061 * our generic search. 3062 */ 3063 if ((FLAGS1(clmp) & FL1_RT_SYMBOLIC) && 3064 ((sl.sl_flags & LKUP_SINGLETON) == 0)) { 3065 3066 sl.sl_imap = clmp; 3067 if (SYMINTP(clmp)(&sl, srp, binfo, in_nfavl)) { 3068 Rt_map *dlmp = srp->sr_dmap; 3069 ulong_t dsymndx = (((ulong_t)srp->sr_sym - 3070 (ulong_t)SYMTAB(dlmp)) / SYMENT(dlmp)); 3071 3072 /* 3073 * Make sure this symbol hasn't explicitly been defined 3074 * as nodirect. 3075 */ 3076 if (((sip = SYMINFO(dlmp)) == 0) || 3077 /* LINTED */ 3078 ((sip = (Syminfo *)((char *)sip + 3079 (dsymndx * SYMINENT(dlmp)))) == 0) || 3080 ((sip->si_flags & SYMINFO_FLG_NOEXTDIRECT) == 0)) 3081 return (1); 3082 } 3083 } 3084 3085 sl.sl_flags |= LKUP_STANDARD; 3086 3087 /* 3088 * If this lookup originates from a standard relocation, then traverse 3089 * all link-map control lists, inspecting any object that is available 3090 * to this caller. Otherwise, traverse the link-map control list 3091 * associated with the caller. 3092 */ 3093 if (sl.sl_flags & LKUP_STDRELOC) { 3094 Aliste off; 3095 Lm_cntl *lmc; 3096 3097 ret = 0; 3098 3099 for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) { 3100 if (((ret = core_lookup_sym(lmc->lc_head, &sl, srp, 3101 binfo, off, in_nfavl)) != 0) || 3102 (*binfo & BINFO_MSK_TRYAGAIN)) 3103 break; 3104 } 3105 } else 3106 ret = core_lookup_sym(ilmp, &sl, srp, binfo, ALIST_OFF_DATA, 3107 in_nfavl); 3108 3109 /* 3110 * If a symbol binding should be retried, return so that the search can 3111 * be repeated. 3112 */ 3113 if (*binfo & BINFO_MSK_TRYAGAIN) 3114 return (0); 3115 3116 /* 3117 * To allow transitioning into a world of lazy loading dependencies see 3118 * if this link map contains objects that have lazy dependencies still 3119 * outstanding. If so, and we haven't been able to locate a non-weak 3120 * symbol reference, start bringing in any lazy dependencies to see if 3121 * the reference can be satisfied. Use of dlsym(RTLD_PROBE) sets the 3122 * LKUP_NOFALLBACK flag, and this flag disables this fall back. 3123 */ 3124 if ((ret == 0) && ((sl.sl_flags & LKUP_NOFALLBACK) == 0)) { 3125 if ((lmp = ilmp) == 0) 3126 lmp = LIST(clmp)->lm_head; 3127 3128 lml = LIST(lmp); 3129 if ((sl.sl_flags & LKUP_WEAK) || (lml->lm_lazy == 0)) 3130 return (NULL); 3131 3132 DBG_CALL(Dbg_syms_lazy_rescan(lml, name)); 3133 3134 /* 3135 * If this request originated from a dlsym(RTLD_NEXT) then start 3136 * looking for dependencies from the caller, otherwise use the 3137 * initial link-map. 3138 */ 3139 if (sl.sl_flags & LKUP_NEXT) 3140 ret = rescan_lazy_find_sym(clmp, &sl, srp, binfo, 3141 in_nfavl); 3142 else { 3143 Aliste idx; 3144 Lm_cntl *lmc; 3145 3146 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { 3147 sl.sl_flags |= LKUP_NOFALLBACK; 3148 if (ret = rescan_lazy_find_sym(lmc->lc_head, 3149 &sl, srp, binfo, in_nfavl)) 3150 break; 3151 } 3152 } 3153 } 3154 return (ret); 3155 } 3156 3157 /* 3158 * Symbol lookup routine. Takes an ELF symbol name, and a list of link maps to 3159 * search. If successful, return a pointer to the symbol table entry, a 3160 * pointer to the link map of the enclosing object, and information relating 3161 * to the type of binding. Else return a null pointer. 3162 * 3163 * To improve ELF performance, we first compute the ELF hash value and pass 3164 * it to each _lookup_sym() routine. The ELF function will use this value to 3165 * locate the symbol, the a.out function will simply ignore it. 3166 */ 3167 int 3168 lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl) 3169 { 3170 Rt_map *clmp = slp->sl_cmap; 3171 Sym *rsym = slp->sl_rsym; 3172 uchar_t rtype = slp->sl_rtype, vis; 3173 int ret, mode; 3174 3175 if (slp->sl_hash == 0) 3176 slp->sl_hash = elf_hash(slp->sl_name); 3177 *binfo = 0; 3178 3179 if (rsym) { 3180 vis = ELF_ST_VISIBILITY(rsym->st_other); 3181 3182 /* 3183 * Symbols that are defined as protected, or hidden, within an 3184 * object usually have any relocation references from within 3185 * the same object bound at link-edit time. Therefore, ld.so.1 3186 * is not involved. However, if a reference is to a 3187 * capabilities symbol, this reference must be resolved at 3188 * runtime. In this case look directly within the calling 3189 * object, and only within the calling object, for these 3190 * symbols. Note, an object may still use dlsym() to search 3191 * externally for a symbol which is defined as protected within 3192 * the same object. 3193 */ 3194 if ((rsym->st_shndx != SHN_UNDEF) && 3195 ((slp->sl_flags & LKUP_DLSYM) == 0) && 3196 ((vis == STV_PROTECTED) || (vis == STV_HIDDEN))) { 3197 slp->sl_imap = clmp; 3198 return (SYMINTP(clmp)(slp, srp, binfo, in_nfavl)); 3199 } 3200 3201 /* 3202 * Establish any state that might be associated with a symbol 3203 * reference. 3204 */ 3205 if ((slp->sl_flags & LKUP_STDRELOC) && 3206 (ELF_ST_BIND(rsym->st_info) == STB_WEAK)) 3207 slp->sl_flags |= LKUP_WEAK; 3208 3209 if (vis == STV_SINGLETON) 3210 slp->sl_flags |= LKUP_SINGLETON; 3211 } 3212 3213 /* 3214 * Establish any lookup state required for this type of relocation. 3215 */ 3216 if ((slp->sl_flags & LKUP_STDRELOC) && rtype) { 3217 if (rtype == M_R_COPY) 3218 slp->sl_flags |= LKUP_COPY; 3219 3220 if (rtype != M_R_JMP_SLOT) 3221 slp->sl_flags |= LKUP_SPEC; 3222 } 3223 3224 /* 3225 * Under ldd -w, any unresolved weak references are diagnosed. Set the 3226 * symbol binding as global to trigger a relocation error if the symbol 3227 * can not be found. 3228 */ 3229 if (rsym) { 3230 if (LIST(slp->sl_cmap)->lm_flags & LML_FLG_TRC_NOUNRESWEAK) 3231 slp->sl_bind = STB_GLOBAL; 3232 else if ((slp->sl_bind = ELF_ST_BIND(rsym->st_info)) == 3233 STB_WEAK) 3234 slp->sl_flags |= LKUP_WEAK; 3235 } 3236 3237 /* 3238 * Save the callers MODE(). 3239 */ 3240 mode = MODE(clmp); 3241 3242 /* 3243 * Carry out an initial symbol search. This search takes into account 3244 * all the modes of the requested search. 3245 */ 3246 if (((ret = _lookup_sym(slp, srp, binfo, in_nfavl)) == 0) && 3247 (*binfo & BINFO_MSK_TRYAGAIN)) { 3248 Slookup sl = *slp; 3249 3250 /* 3251 * Try the symbol search again. This retry can be necessary if: 3252 * 3253 * - a binding has been rejected because of binding to a 3254 * singleton without going through a singleton search. 3255 * - a group binding has resulted in binding to a symbol 3256 * that indicates no-direct binding. 3257 * 3258 * Reset the lookup data, and try again. 3259 */ 3260 sl.sl_imap = LIST(sl.sl_cmap)->lm_head; 3261 sl.sl_flags &= ~(LKUP_FIRST | LKUP_SELF | LKUP_NEXT); 3262 sl.sl_rsymndx = 0; 3263 3264 if (*binfo & BINFO_REJSINGLE) 3265 sl.sl_flags |= LKUP_SINGLETON; 3266 if (*binfo & BINFO_REJGROUP) { 3267 sl.sl_flags |= LKUP_WORLD; 3268 mode |= RTLD_WORLD; 3269 } 3270 *binfo &= ~BINFO_MSK_REJECTED; 3271 3272 ret = _lookup_sym(&sl, srp, binfo, in_nfavl); 3273 } 3274 3275 /* 3276 * If the caller is restricted to a symbol search within its group, 3277 * determine if it is necessary to follow a binding from outside of 3278 * the group. 3279 */ 3280 if (((mode & (RTLD_GROUP | RTLD_WORLD)) == RTLD_GROUP) && 3281 (lookup_sym_interpose(slp, srp, binfo, in_nfavl))) 3282 return (1); 3283 3284 return (ret); 3285 } 3286 3287 /* 3288 * Associate a binding descriptor with a caller and its dependency, or update 3289 * an existing descriptor. 3290 */ 3291 int 3292 bind_one(Rt_map *clmp, Rt_map *dlmp, uint_t flags) 3293 { 3294 Bnd_desc *bdp; 3295 Aliste idx; 3296 int found = ALE_CREATE; 3297 3298 /* 3299 * Determine whether a binding descriptor already exists between the 3300 * two objects. 3301 */ 3302 for (APLIST_TRAVERSE(DEPENDS(clmp), idx, bdp)) { 3303 if (bdp->b_depend == dlmp) { 3304 found = ALE_EXISTS; 3305 break; 3306 } 3307 } 3308 3309 if (found == ALE_CREATE) { 3310 /* 3311 * Create a new binding descriptor. 3312 */ 3313 if ((bdp = malloc(sizeof (Bnd_desc))) == NULL) 3314 return (0); 3315 3316 bdp->b_caller = clmp; 3317 bdp->b_depend = dlmp; 3318 bdp->b_flags = 0; 3319 3320 /* 3321 * Append the binding descriptor to the caller and the 3322 * dependency. 3323 */ 3324 if (aplist_append(&DEPENDS(clmp), bdp, AL_CNT_DEPENDS) == NULL) 3325 return (0); 3326 3327 if (aplist_append(&CALLERS(dlmp), bdp, AL_CNT_CALLERS) == NULL) 3328 return (0); 3329 } 3330 3331 if ((found == ALE_CREATE) || ((bdp->b_flags & flags) != flags)) { 3332 bdp->b_flags |= flags; 3333 3334 if (flags & BND_REFER) 3335 FLAGS1(dlmp) |= FL1_RT_USED; 3336 3337 DBG_CALL(Dbg_file_bind_entry(LIST(clmp), bdp)); 3338 } 3339 return (found); 3340 } 3341 3342 /* 3343 * Cleanup after relocation processing. 3344 */ 3345 int 3346 relocate_finish(Rt_map *lmp, APlist *bound, int ret) 3347 { 3348 DBG_CALL(Dbg_reloc_run(lmp, 0, ret, DBG_REL_FINISH)); 3349 3350 /* 3351 * Establish bindings to all objects that have been bound to. 3352 */ 3353 if (bound) { 3354 Rt_map *_lmp; 3355 Word used; 3356 3357 /* 3358 * Only create bindings if the callers relocation was 3359 * successful (ret != 0), otherwise the object will eventually 3360 * be torn down. Create these bindings if running under ldd(1) 3361 * with the -U/-u options regardless of relocation errors, as 3362 * the unused processing needs to traverse these bindings to 3363 * diagnose unused objects. 3364 */ 3365 used = LIST(lmp)->lm_flags & 3366 (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED); 3367 3368 if (ret || used) { 3369 Aliste idx; 3370 3371 for (APLIST_TRAVERSE(bound, idx, _lmp)) { 3372 if (bind_one(lmp, _lmp, BND_REFER) || used) 3373 continue; 3374 3375 ret = 0; 3376 break; 3377 } 3378 } 3379 free(bound); 3380 } 3381 3382 return (ret); 3383 } 3384 3385 /* 3386 * Function to correct protection settings. Segments are all mapped initially 3387 * with permissions as given in the segment header. We need to turn on write 3388 * permissions on a text segment if there are any relocations against that 3389 * segment, and then turn write permission back off again before returning 3390 * control to the caller. This function turns the permission on or off 3391 * depending on the value of the permission argument. 3392 */ 3393 int 3394 set_prot(Rt_map *lmp, mmapobj_result_t *mpp, int perm) 3395 { 3396 int prot; 3397 3398 /* 3399 * If this is an allocated image (ie. a relocatable object) we can't 3400 * mprotect() anything. 3401 */ 3402 if (FLAGS(lmp) & FLG_RT_IMGALLOC) 3403 return (1); 3404 3405 DBG_CALL(Dbg_file_prot(lmp, perm)); 3406 3407 if (perm) 3408 prot = mpp->mr_prot | PROT_WRITE; 3409 else 3410 prot = mpp->mr_prot & ~PROT_WRITE; 3411 3412 if (mprotect((void *)(uintptr_t)mpp->mr_addr, 3413 mpp->mr_msize, prot) == -1) { 3414 int err = errno; 3415 eprintf(LIST(lmp), ERR_FATAL, MSG_INTL(MSG_SYS_MPROT), 3416 NAME(lmp), strerror(err)); 3417 return (0); 3418 } 3419 mpp->mr_prot = prot; 3420 return (1); 3421 } 3422