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