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