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