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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Remove objects. Objects need removal from a process as part of: 26 * 27 * o a dlclose() request 28 * 29 * o tearing down a dlopen(), lazy-load, or filter hierarchy that failed to 30 * completely load 31 * 32 * Any other failure condition will result in process exit (in which case all 33 * we have to do is execute the fini's - tear down is unnecessary). 34 * 35 * Any removal of objects is therefore associated with a dlopen() handle. There 36 * is a small window between creation of the first dlopen() object and creating 37 * its handle (in which case remove_so() can get rid of the new link-map if 38 * necessary), but other than this all object removal is driven by inspecting 39 * the components of a handle. 40 * 41 * Things to note. The creation of a link-map, and its addition to the link-map 42 * list occurs in {elf|aout}_new_lm(), if this returns success the link-map is 43 * valid and added, otherwise any steps (allocations) in the process of creating 44 * the link-map would have been undone. If a failure occurs between creating 45 * the link-map and adding it to a handle, remove_so() is called to remove the 46 * link-map. If a failures occurs after a handle have been created, 47 * remove_hdl() is called to remove the handle and the link-map. 48 */ 49 #pragma ident "%Z%%M% %I% %E% SMI" 50 51 #include "_synonyms.h" 52 53 #include <string.h> 54 #include <stdio.h> 55 #include <unistd.h> 56 #include <dlfcn.h> 57 #include <sys/debug.h> 58 #include <sys/avl.h> 59 #include <libc_int.h> 60 #include <debug.h> 61 #include "_rtld.h" 62 #include "_audit.h" 63 #include "_elf.h" 64 #include "msg.h" 65 66 /* 67 * Atexit callback provided by libc. As part of dlclose() determine the address 68 * ranges of all objects that are to be deleted. Pass this information to 69 * libc's pre-atexit routine. Libc will purge any registered atexit() calls 70 * related to those objects about to be deleted. 71 */ 72 static int 73 purge_exit_handlers(Lm_list *lml, Rt_map **tobj) 74 { 75 uint_t num; 76 Rt_map **_tobj; 77 Lc_addr_range_t *addr, *_addr; 78 int error; 79 int (*fptr)(Lc_addr_range_t *, uint_t); 80 81 /* 82 * Has a callback been established? 83 */ 84 if ((fptr = lml->lm_lcs[CI_ATEXIT].lc_un.lc_func) == NULL) 85 return (0); 86 87 /* 88 * Determine the total number of mapped segments that will be unloaded. 89 */ 90 for (num = 0, _tobj = tobj; *_tobj != NULL; _tobj++) { 91 Rt_map * lmp = *_tobj; 92 93 num += MMAPCNT(lmp); 94 } 95 96 /* 97 * Account for a null entry at the end of the address range array. 98 */ 99 if (num++ == 0) 100 return (0); 101 102 /* 103 * Allocate an array for the address range. 104 */ 105 if ((addr = malloc(num * sizeof (Lc_addr_range_t))) == 0) 106 return (1); 107 108 /* 109 * Fill the address range with each loadable segments size and address. 110 */ 111 for (_tobj = tobj, _addr = addr; *_tobj != NULL; _tobj++) { 112 Rt_map *lmp = *_tobj; 113 Mmap *mmaps; 114 115 for (mmaps = MMAPS(lmp); mmaps->m_vaddr; mmaps++) { 116 _addr->lb = (void *)mmaps->m_vaddr; 117 _addr->ub = (void *)(mmaps->m_vaddr + mmaps->m_msize); 118 _addr++; 119 } 120 } 121 _addr->lb = _addr->ub = 0; 122 123 leave(LIST(*tobj)); 124 error = (*fptr)(addr, (num - 1)); 125 (void) enter(); 126 127 /* 128 * If we fail to converse with libc, generate an error message to 129 * satisfy any dlerror() usage. 130 */ 131 if (error) 132 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_ARG_ATEXIT), error); 133 134 free(addr); 135 return (error); 136 } 137 138 /* 139 * Remove any rejection message allocations. 140 */ 141 void 142 remove_rej(Rej_desc * rej) 143 { 144 if (rej && (rej->rej_type)) { 145 if (rej->rej_name) 146 free((void *)rej->rej_name); 147 if (rej->rej_str && (rej->rej_str != MSG_ORIG(MSG_EMG_ENOMEM))) 148 free((void *)rej->rej_str); 149 } 150 } 151 152 /* 153 * Break down a Pnode list. 154 */ 155 void 156 remove_pnode(Pnode * pnp) 157 { 158 Pnode * opnp; 159 160 for (opnp = 0; pnp; opnp = pnp, pnp = pnp->p_next) { 161 if (pnp->p_name) 162 free((void *)pnp->p_name); 163 if (pnp->p_oname) 164 free((void *)pnp->p_oname); 165 if (opnp) 166 free((void *)opnp); 167 } 168 if (opnp) 169 free((void *)opnp); 170 } 171 172 173 /* 174 * Remove a link-map list descriptor. This is called to finalize the removal 175 * of an entire link-map list, after all link-maps have been removed, or none 176 * got added. As load_one() can process a list of potential candidates objects, 177 * the link-map descriptor must be maintained as each object is processed. Only 178 * after all objects have been processed can a failure condition finally tear 179 * down the link-map list descriptor. 180 */ 181 void 182 remove_lml(Lm_list *lml) 183 { 184 if (lml && (lml->lm_head == 0)) { 185 if (lml->lm_lmidstr) 186 free(lml->lm_lmidstr); 187 if (lml->lm_alp) 188 free(lml->lm_alp); 189 if (lml->lm_lists) 190 free(lml->lm_lists); 191 192 /* 193 * Cleanup any pending RTLDINFO in the case where it was 194 * allocated but not called (see _relocate_lmc()). 195 */ 196 if (lml->lm_rti) 197 free(lml->lm_rti); 198 if (lml->lm_fpavl) { 199 /* 200 * As we are freeing the link-map list, all nodes must 201 * have previously been removed. 202 */ 203 ASSERT(avl_numnodes(lml->lm_fpavl) == 0); 204 free(lml->lm_fpavl); 205 } 206 list_delete(&dynlm_list, lml); 207 free(lml); 208 } 209 } 210 211 /* 212 * Remove a link-map. This removes a link-map from its associated list and 213 * free's up the link-map itself. Note, all components that are freed are local 214 * to the link-map, no inter-link-map lists are operated on as these are all 215 * broken down by dlclose() while all objects are still mapped. 216 * 217 * This routine is called from dlclose() to zap individual link-maps after their 218 * interdependencies (DEPENDS(), CALLER(), handles, etc.) have been removed. 219 * This routine is also called from the bowels of load_one() in the case of a 220 * link-map creation failure. 221 */ 222 void 223 remove_so(Lm_list *lml, Rt_map *lmp) 224 { 225 Dyninfo *dip; 226 227 if (lmp == 0) 228 return; 229 230 /* 231 * Unlink the link map from the link-map list. 232 */ 233 if (lml && lmp) 234 lm_delete(lml, lmp); 235 236 /* 237 * If this object contributed any local external vectors for the current 238 * link-map list, remove the vectors. If this object contributed any 239 * global external vectors we should find some new candidates, or leave 240 * this object lying around. 241 */ 242 if (lml) { 243 int tag; 244 245 for (tag = 0; tag < CI_MAX; tag++) { 246 if (lml->lm_lcs[tag].lc_lmp == lmp) { 247 lml->lm_lcs[tag].lc_lmp = 0; 248 lml->lm_lcs[tag].lc_un.lc_val = 0; 249 } 250 if (glcs[tag].lc_lmp == lmp) { 251 ASSERT(glcs[tag].lc_lmp != 0); 252 glcs[tag].lc_lmp = 0; 253 glcs[tag].lc_un.lc_val = 0; 254 } 255 } 256 } 257 258 DBG_CALL(Dbg_file_delete(lmp)); 259 260 /* 261 * If this is a temporary link-map, put in place to facilitate the 262 * link-edit or a relocatable object, then the link-map contains no 263 * information that needs to be cleaned up. 264 */ 265 if (FLAGS(lmp) & FLG_RT_OBJECT) 266 return; 267 268 /* 269 * Unmap the object. 270 */ 271 LM_UNMAP_SO(lmp)(lmp); 272 273 /* 274 * Remove any FullpathNode AVL names if they still exist. 275 */ 276 if (FPNODE(lmp)) 277 fpavl_remove(lmp); 278 279 /* 280 * Remove any alias names. 281 */ 282 if (ALIAS(lmp)) { 283 Aliste off; 284 char ** cpp; 285 286 for (ALIST_TRAVERSE(ALIAS(lmp), off, cpp)) 287 free(*cpp); 288 free(ALIAS(lmp)); 289 } 290 291 /* 292 * Free the various names, as these were duplicated so that they were 293 * available in core files. 294 * The original name is set to the pathname by default (see fullpath()), 295 * but is overridden if the file is an alternative. The pathname is set 296 * to the name by default (see [aout|elf]_new_lm()), but is overridden 297 * if the fullpath/resolve path differs (see fullpath()). The original 298 * name is always duplicated, as it typically exists as a text string 299 * (see DT_NEEDED pointer) or was passed in from user code. 300 */ 301 if (ORIGNAME(lmp) != PATHNAME(lmp)) 302 free(ORIGNAME(lmp)); 303 if (PATHNAME(lmp) != NAME(lmp)) 304 free(PATHNAME(lmp)); 305 free(NAME(lmp)); 306 307 /* 308 * Remove any of this objects filtee infrastructure. The filtees them- 309 * selves have already been removed. 310 */ 311 if (((dip = DYNINFO(lmp)) != 0) && (FLAGS1(lmp) & MSK_RT_FILTER)) { 312 uint_t cnt, max = DYNINFOCNT(lmp); 313 314 for (cnt = 0; cnt < max; cnt++, dip++) { 315 if (dip->di_info && (dip->di_flags & MSK_DI_FILTER)) 316 remove_pnode((Pnode *)dip->di_info); 317 } 318 } 319 if (dip) 320 free(DYNINFO(lmp)); 321 322 /* 323 * Deallocate any remaining cruft and free the link-map. 324 */ 325 if (RLIST(lmp)) 326 remove_pnode(RLIST(lmp)); 327 328 if (REFNAME(lmp)) 329 free(REFNAME(lmp)); 330 if (ELFPRV(lmp)) 331 free(ELFPRV(lmp)); 332 if (AUDITORS(lmp)) 333 audit_desc_cleanup(AUDITORS(lmp), lmp); 334 if (AUDINFO(lmp)) 335 audit_info_cleanup(AUDINFO(lmp)); 336 337 if (CONDVAR(lmp)) 338 free(CONDVAR(lmp)); 339 if (COPY(lmp)) 340 free(COPY(lmp)); 341 if (MMAPS(lmp)) 342 free(MMAPS(lmp)); 343 344 /* 345 * During a dlclose() any groups this object was a part of will have 346 * been torn down. However, we can get here to remove an object that 347 * has failed to load, perhaps because its addition to a handle failed. 348 * Therefore if this object indicates that its part of a group tear 349 * these associations down. 350 */ 351 if (GROUPS(lmp)) { 352 Aliste off1; 353 Grp_hdl ** ghpp; 354 355 for (ALIST_TRAVERSE(GROUPS(lmp), off1, ghpp)) { 356 Grp_hdl * ghp = *ghpp; 357 Grp_desc * gdp; 358 Aliste off2; 359 360 for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { 361 if (gdp->gd_depend != lmp) 362 continue; 363 364 (void) alist_delete(ghp->gh_depends, 0, &off2); 365 break; 366 } 367 } 368 free(GROUPS(lmp)); 369 } 370 if (HANDLES(lmp)) 371 free(HANDLES(lmp)); 372 373 /* 374 * Clean up reglist if needed 375 */ 376 if (reglist != (Reglist *)0) { 377 Reglist * cur, * prv, * del; 378 379 cur = prv = reglist; 380 while (cur != (Reglist *)0) { 381 if (cur->rl_lmp == lmp) { 382 del = cur; 383 if (cur == reglist) { 384 reglist = cur->rl_next; 385 cur = prv = reglist; 386 } else { 387 prv->rl_next = cur->rl_next; 388 cur = cur->rl_next; 389 } 390 free(del); 391 } else { 392 prv = cur; 393 cur = cur->rl_next; 394 } 395 } 396 } 397 398 free(lmp); 399 } 400 401 402 /* 403 * Traverse an objects dependency list removing callers and dependencies. 404 * There's a chicken and egg problem with tearing down link-maps. Any 405 * relationship between link-maps is maintained on a DEPENDS, and associated 406 * CALLERS list. These lists can't be broken down at the time a single link- 407 * map is removed as any related link-map may have already been removed. Thus, 408 * lists between link-maps must be broken down before the individual link-maps 409 * themselves. 410 */ 411 void 412 remove_lists(Rt_map * lmp, int lazy) 413 { 414 Aliste off1; 415 Bnd_desc ** bdpp; 416 417 /* 418 * First, traverse this objects dependencies. 419 */ 420 for (ALIST_TRAVERSE(DEPENDS(lmp), off1, bdpp)) { 421 Bnd_desc * bdp = *bdpp; 422 Rt_map * dlmp = bdp->b_depend; 423 424 /* 425 * Remove this object from the dependencies callers. 426 */ 427 (void) alist_delete(CALLERS(dlmp), &bdp, 0); 428 free(bdp); 429 } 430 if (DEPENDS(lmp)) { 431 free(DEPENDS(lmp)); 432 DEPENDS(lmp) = 0; 433 } 434 435 /* 436 * Second, traverse this objects callers. 437 */ 438 for (ALIST_TRAVERSE(CALLERS(lmp), off1, bdpp)) { 439 Bnd_desc * bdp = *bdpp; 440 Rt_map * clmp = bdp->b_caller; 441 442 /* 443 * If we're removing an object that was triggered by a lazyload, 444 * remove the callers DYNINFO() entry and bump the lazy counts. 445 * This reinitialization of the lazy information allows a lazy 446 * object to be reloaded again later. Although we may be 447 * breaking down a group of lazyloaded objects because one has 448 * failed to relocate, it's possible that one or more of the 449 * individual objects can be reloaded without a problem. 450 */ 451 if (lazy) { 452 Dyninfo * dip; 453 454 if ((dip = DYNINFO(clmp)) != 0) { 455 uint_t cnt, max = DYNINFOCNT(clmp); 456 457 for (cnt = 0; cnt < max; cnt++, dip++) { 458 if ((dip->di_flags & 459 FLG_DI_NEEDED) == 0) 460 continue; 461 462 if (dip->di_info == (void *)lmp) { 463 dip->di_info = 0; 464 465 if (LAZY(clmp)++ == 0) 466 LIST(clmp)->lm_lazy++; 467 } 468 } 469 } 470 } 471 472 (void) alist_delete(DEPENDS(clmp), &bdp, 0); 473 free(bdp); 474 } 475 if (CALLERS(lmp)) { 476 free(CALLERS(lmp)); 477 CALLERS(lmp) = 0; 478 } 479 } 480 481 /* 482 * Delete any temporary link-map control list. 483 */ 484 void 485 remove_cntl(Lm_list *lml, Aliste lmco) 486 { 487 if (lmco && (lmco != ALO_DATA)) { 488 Aliste _lmco = lmco; 489 #if DEBUG 490 Lm_cntl *lmc = (Lm_cntl *)((char *)lml->lm_lists + lmco); 491 492 /* 493 * This element should be empty. 494 */ 495 ASSERT(lmc->lc_head == 0); 496 #endif 497 (void) alist_delete(lml->lm_lists, 0, &_lmco); 498 } 499 } 500 501 /* 502 * If a lazy loaded object, or filtee fails to load, possibly because it, or 503 * one of its dependencies can't be relocated, then tear down any objects 504 * that are apart of this link-map control list. 505 */ 506 void 507 remove_incomplete(Lm_list *lml, Aliste lmco) 508 { 509 Rt_map *lmp; 510 Lm_cntl *lmc; 511 512 /* LINTED */ 513 lmc = (Lm_cntl *)((char *)lml->lm_lists + lmco); 514 515 /* 516 * First, remove any lists that may point between objects. 517 */ 518 for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) 519 remove_lists(lmp, 1); 520 521 /* 522 * Finally, remove each object. remove_so() calls lm_delete(), thus 523 * effectively the link-map control head gets updated to point to the 524 * next link-map. 525 */ 526 while ((lmp = lmc->lc_head) != 0) 527 remove_so(lml, lmp); 528 529 lmc->lc_head = lmc->lc_tail = 0; 530 } 531 532 /* 533 * Determine whether an object is deletable. 534 */ 535 int 536 is_deletable(Alist ** lmalp, Alist ** ghalp, Rt_map * lmp) 537 { 538 Aliste off; 539 Bnd_desc ** bdpp; 540 Grp_hdl ** ghpp; 541 542 /* 543 * If the object hasn't yet been relocated take this as a sign that 544 * it's loading failed, thus we're here to cleanup. If the object is 545 * relocated it will only be retained if it was marked non-deletable, 546 * and exists on the main link-map control list. 547 */ 548 if ((FLAGS(lmp) & FLG_RT_RELOCED) && 549 (MODE(lmp) & RTLD_NODELETE) && (CNTL(lmp) == ALO_DATA)) 550 return (0); 551 552 /* 553 * If this object is the head of a handle that has not been captured as 554 * a candidate for deletion, then this object is in use from a dlopen() 555 * outside of the scope of this dlclose() family. Dlopen'ed objects, 556 * and filtees, have group descriptors for their callers. Typically 557 * this parent will have callers that are not apart of this dlclose() 558 * family, and thus would be caught by the CALLERS test below. However, 559 * if the caller had itself been dlopen'ed, it may not have any explicit 560 * callers registered for itself. Thus, but looking for objects with 561 * handles we can ferret out these outsiders. 562 */ 563 for (ALIST_TRAVERSE(HANDLES(lmp), off, ghpp)) { 564 if (alist_test(ghalp, *ghpp, 565 sizeof (Grp_hdl *), 0) != ALE_EXISTS) 566 return (0); 567 } 568 569 /* 570 * If this object is called by any object outside of the family of 571 * objects selected for deletion, it can't be deleted. 572 */ 573 for (ALIST_TRAVERSE(CALLERS(lmp), off, bdpp)) { 574 if (alist_test(lmalp, (*bdpp)->b_caller, 575 sizeof (Rt_map *), 0) != ALE_EXISTS) 576 return (0); 577 } 578 579 /* 580 * This object is a candidate for deletion. 581 */ 582 return (1); 583 } 584 585 /* 586 * Collect the groups (handles) and associated objects that are candidates for 587 * deletion. The criteria for deleting an object is whether it is only refer- 588 * enced from the objects within the groups that are candidates for deletion. 589 */ 590 static int 591 gdp_collect(Alist **ghalpp, Alist **lmalpp, Grp_hdl *ghp1) 592 { 593 Aliste off; 594 Grp_desc *gdp; 595 int action; 596 597 /* 598 * Add this group to our group collection. If it isn't added either an 599 * allocation has failed, or it already exists. 600 */ 601 if ((action = alist_test(ghalpp, ghp1, sizeof (Grp_hdl *), 602 AL_CNT_GRPCLCT)) != ALE_CREATE) 603 return (action); 604 605 /* 606 * Traverse the dependencies of the group and collect the associated 607 * objects. 608 */ 609 for (ALIST_TRAVERSE(ghp1->gh_depends, off, gdp)) { 610 Rt_map * lmp = gdp->gd_depend; 611 612 /* 613 * We only want to process dependencies for deletion. Although 614 * we want to purge group descriptors for parents, we don't want 615 * to analyze the parent itself for additional filters or 616 * deletion. 617 */ 618 if ((gdp->gd_flags & GPD_ADDEPS) == 0) 619 continue; 620 621 if ((action = alist_test(lmalpp, lmp, sizeof (Rt_map *), 622 AL_CNT_GRPCLCT)) == 0) 623 return (0); 624 if (action == ALE_EXISTS) 625 continue; 626 627 /* 628 * If this object hasn't yet been relocated take this as a sign 629 * that it's loading failed, thus we're here to cleanup. Or, 630 * if this object isn't obviously non-deletable, determine 631 * whether it provides any filtees. Add these groups to the 632 * group collection. 633 */ 634 if ((((FLAGS(lmp) & FLG_RT_RELOCED) == 0) || 635 ((MODE(lmp) & RTLD_NODELETE) == 0)) && 636 (FLAGS1(lmp) & MSK_RT_FILTER)) { 637 Dyninfo * dip = DYNINFO(lmp); 638 uint_t cnt, max = DYNINFOCNT(lmp); 639 640 for (cnt = 0; cnt < max; cnt++, dip++) { 641 Pnode * pnp; 642 643 if ((dip->di_info == 0) || 644 ((dip->di_flags & MSK_DI_FILTER) == 0)) 645 continue; 646 647 for (pnp = (Pnode *)dip->di_info; pnp; 648 pnp = pnp->p_next) { 649 Grp_hdl * ghp2; 650 651 if ((pnp->p_len == 0) || ((ghp2 = 652 (Grp_hdl *)pnp->p_info) == 0)) 653 continue; 654 655 if (gdp_collect(ghalpp, lmalpp, 656 ghp2) == 0) 657 return (0); 658 } 659 } 660 } 661 } 662 return (1); 663 } 664 665 /* 666 * Traverse the list of deletable candidates. If an object can't be deleted 667 * then neither can its dependencies or filtees. Any object that is cleared 668 * from being deleted drops the deletion count, plus, if there are no longer 669 * any deletions pending we can discontinue any further processing. 670 */ 671 static int 672 remove_rescan(Alist * lmalp, Alist * ghalp, int *delcnt) 673 { 674 Aliste off1; 675 Rt_map ** lmpp; 676 int rescan = 0; 677 678 for (ALIST_TRAVERSE(lmalp, off1, lmpp)) { 679 Aliste off2; 680 Bnd_desc ** bdpp; 681 Rt_map * lmp = *lmpp; 682 Dyninfo * dip; 683 uint_t cnt, max; 684 685 if (FLAGS(lmp) & FLG_RT_DELETE) 686 continue; 687 688 /* 689 * As this object can't be deleted, make sure its dependencies 690 * aren't deleted either. 691 */ 692 for (ALIST_TRAVERSE(DEPENDS(lmp), off2, bdpp)) { 693 Rt_map * dlmp = (*bdpp)->b_depend; 694 695 if (FLAGS(dlmp) & FLG_RT_DELETE) { 696 FLAGS(dlmp) &= ~FLG_RT_DELETE; 697 if (--(*delcnt) == 0) 698 return (0); 699 rescan = 1; 700 } 701 } 702 703 /* 704 * If this object is a filtee and one of its filters is outside 705 * of this dlclose family, then it can't be deleted either. 706 */ 707 if ((FLAGS1(lmp) & MSK_RT_FILTER) == 0) 708 continue; 709 710 dip = DYNINFO(lmp); 711 max = DYNINFOCNT(lmp); 712 713 for (cnt = 0; cnt < max; cnt++, dip++) { 714 Pnode * pnp; 715 716 if ((dip->di_info == 0) || 717 ((dip->di_flags & MSK_DI_FILTER) == 0)) 718 continue; 719 720 for (pnp = (Pnode *)dip->di_info; pnp; 721 pnp = pnp->p_next) { 722 Grp_hdl * ghp; 723 Grp_desc * gdp; 724 725 if ((pnp->p_len == 0) || 726 ((ghp = (Grp_hdl *)pnp->p_info) == 0)) 727 continue; 728 729 if (alist_test(&ghalp, ghp, 730 sizeof (Grp_hdl *), 0) == ALE_EXISTS) 731 continue; 732 733 for (ALIST_TRAVERSE(ghp->gh_depends, off2, 734 gdp)) { 735 Rt_map * dlmp = gdp->gd_depend; 736 737 if (FLAGS(dlmp) & FLG_RT_DELETE) { 738 FLAGS(dlmp) &= ~FLG_RT_DELETE; 739 if (--(*delcnt) == 0) 740 return (0); 741 rescan = 1; 742 } 743 } 744 745 /* 746 * Remove this group handle from our dynamic 747 * deletion list. 748 */ 749 (void) alist_delete(ghalp, &ghp, 0); 750 } 751 } 752 } 753 return (rescan); 754 } 755 756 /* 757 * Cleanup any collection alists we've created. 758 */ 759 static void 760 remove_collect(Alist * ghalp, Alist * lmalp) 761 { 762 if (ghalp) 763 free(ghalp); 764 if (lmalp) 765 free(lmalp); 766 } 767 768 /* 769 * Remove a handle, leaving the associated objects intact. Besides the classic 770 * dlopen() usage, handles are used as a means of associating a group of objects 771 * and promoting modes. Once object promotion is completed, the handle should 772 * be discarded while leaving the associated objects intact. Leaving the handle 773 * would prevent the object from being deleted (as it looks like it's in use 774 * by another user). 775 */ 776 void 777 free_hdl(Grp_hdl *ghp) 778 { 779 if (--(ghp->gh_refcnt) == 0) { 780 Grp_desc *gdp; 781 uintptr_t ndx; 782 Aliste off; 783 784 for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { 785 Rt_map *lmp = gdp->gd_depend; 786 787 if (ghp->gh_ownlmp == lmp) 788 (void) alist_delete(HANDLES(lmp), &ghp, 0); 789 (void) alist_delete(GROUPS(lmp), &ghp, 0); 790 } 791 (void) free(ghp->gh_depends); 792 793 /* LINTED */ 794 ndx = (uintptr_t)ghp % HDLIST_SZ; 795 list_delete(&hdl_list[ndx], ghp); 796 797 (void) free(ghp); 798 } 799 } 800 801 /* 802 * Remove a caller from a group handle. This breaks the bond between a caller 803 * and a hierarchy of dependencies represented by a handle, thus the caller 804 * doesn't lock the hierarchy and prevent their deletion should their processing 805 * fail to complete. If the handle count drops to zero, the handle is marked 806 * as sticky to prevent it's removal, or to confuse orphan handle processing. 807 * The caller may establish a binding to this handle again, once the hierarchy 808 * processing has completed, thus retaining the handle saves having to recreate 809 * it over and over again. 810 */ 811 void 812 remove_caller(Grp_hdl *ghp, Rt_map *clmp) 813 { 814 Grp_desc *gdp; 815 Aliste off; 816 817 if (--(ghp->gh_refcnt) == 0) 818 ghp->gh_flags |= GPH_STICKY; 819 820 for (ALIST_TRAVERSE(ghp->gh_depends, off, gdp)) { 821 Rt_map *lmp = gdp->gd_depend; 822 823 if (lmp == clmp) { 824 (void) alist_delete(GROUPS(lmp), &ghp, 0); 825 (void) alist_delete(ghp->gh_depends, 0, &off); 826 break; 827 } 828 } 829 } 830 831 /* 832 * Remove the objects associated with a handle. There are two goals here, to 833 * delete the objects associated with the handle, and to remove the handle 834 * itself. Things get a little more complex if the objects selected for 835 * deletion are filters, in this case we also need to collect their filtees, 836 * and process the combined groups as a whole. But, care still must be exer- 837 * cised to make sure any filtees found aren't being used by filters outside of 838 * the groups we've collect. The series of events is basically: 839 * 840 * o Determine the groups (handles) that might be deletable. 841 * 842 * o Determine the objects of these handles that can be deleted. 843 * 844 * o Fire the fini's of those objects selected for deletion. 845 * 846 * o Remove all inter-dependency linked lists while the objects link-maps 847 * are still available. 848 * 849 * o Remove all deletable objects link-maps and unmap the objects themselves. 850 * 851 * o Remove the handle descriptors for each deleted object, and hopefully 852 * the whole handle. 853 * 854 * An handle that can't be deleted is added to an orphans list. This list is 855 * revisited any time another dlclose() request results in handle descriptors 856 * being deleted. These deleted descriptors can be sufficient to allow the 857 * final deletion of the orphaned handles. 858 */ 859 int 860 remove_hdl(Grp_hdl *ghp, Rt_map *clmp, int *removed) 861 { 862 Rt_map * lmp, ** lmpp; 863 int rescan = 0; 864 int delcnt = 0, rmcnt = 0, error = 0, orphans; 865 Alist * lmalp = 0, * ghalp = 0; 866 Aliste off1, off2; 867 Grp_hdl ** ghpp; 868 Grp_desc * gdp; 869 Lm_list * lml = 0; 870 871 /* 872 * Generate the family of groups and objects that are candidates for 873 * deletion. This consists of the objects that are explicitly defined 874 * as dependencies of this handle, plus any filtee handles and their 875 * associated objects. 876 */ 877 if (gdp_collect(&ghalp, &lmalp, ghp) == 0) { 878 remove_collect(ghalp, lmalp); 879 return (0); 880 } 881 882 DBG_CALL(Dbg_file_hdl_title(DBG_DEP_DELETE)); 883 884 /* 885 * Traverse the groups we've collected to determine if any filtees are 886 * included. If so, and the filtee handle is in use by a filter outside 887 * of the family of objects collected for this deletion, it can not be 888 * removed. 889 */ 890 for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { 891 Grp_hdl * ghp = *ghpp; 892 893 DBG_CALL(Dbg_file_hdl_collect(ghp, 0)); 894 895 if ((ghp->gh_flags & GPH_FILTEE) == 0) 896 continue; 897 898 /* 899 * Special case for ld.so.1. There can be multiple instances of 900 * libdl.so.1 using this handle, so although we want the handles 901 * reference count to be decremented, we don't want the handle 902 * removed. 903 */ 904 if (ghp->gh_flags & GPH_LDSO) { 905 DBG_CALL(Dbg_file_hdl_collect(ghp, 906 NAME(lml_rtld.lm_head))); 907 (void) alist_delete(ghalp, 0, &off1); 908 continue; 909 } 910 911 for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { 912 Grp_hdl ** ghpp3; 913 Aliste off3; 914 915 /* 916 * Determine whether this dependency is the filtee's 917 * parent filter, and that it isn't also an explicit 918 * dependency (in which case it would have added its own 919 * dependencies to the handle). 920 */ 921 if ((gdp->gd_flags & 922 (GPD_FILTER | GPD_ADDEPS)) != GPD_FILTER) 923 continue; 924 925 if (alist_test(&lmalp, gdp->gd_depend, 926 sizeof (Rt_map *), 0) == ALE_EXISTS) 927 continue; 928 929 /* 930 * Remove this group handle from our dynamic deletion 931 * list. In addition, recompute the list of objects 932 * that are candidates for deletion to continue this 933 * group verification. 934 */ 935 DBG_CALL(Dbg_file_hdl_collect(ghp, 936 NAME(gdp->gd_depend))); 937 (void) alist_delete(ghalp, 0, &off1); 938 939 free(lmalp); 940 lmalp = 0; 941 for (ALIST_TRAVERSE(ghalp, off3, ghpp3)) { 942 Aliste off4; 943 Grp_desc * gdp4; 944 945 for (ALIST_TRAVERSE((*ghpp3)->gh_depends, 946 off4, gdp4)) { 947 if ((gdp4->gd_flags & GPD_ADDEPS) == 0) 948 continue; 949 if (alist_test(&lmalp, gdp4->gd_depend, 950 sizeof (Rt_map *), 951 AL_CNT_GRPCLCT) == 0) { 952 remove_collect(ghalp, lmalp); 953 return (0); 954 } 955 } 956 } 957 break; 958 } 959 } 960 961 /* 962 * Now that we've collected all the handles dependencies, traverse the 963 * collection determining whether they are a candidate for deletion. 964 */ 965 for (ALIST_TRAVERSE(lmalp, off1, lmpp)) { 966 lmp = *lmpp; 967 968 /* 969 * Establish which link-map list we're dealing with for later 970 * .fini processing. 971 */ 972 if (lml == 0) 973 lml = LIST(lmp); 974 975 /* 976 * If an object isn't a candidate for deletion we'll have to 977 * rescan the handle insuring that this objects dependencies 978 * aren't deleted either. 979 */ 980 if (is_deletable(&lmalp, &ghalp, lmp)) { 981 FLAGS(lmp) |= FLG_RT_DELETE; 982 delcnt++; 983 } else 984 rescan = 1; 985 } 986 987 /* 988 * Rescan the handle if any objects where found non-deletable. 989 */ 990 while (rescan) 991 rescan = remove_rescan(lmalp, ghalp, &delcnt); 992 993 /* 994 * Now that we have determined the number of groups that are candidates 995 * for removal, mark each group descriptor as a candidate for removal 996 * from the group. 997 */ 998 for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { 999 for (ALIST_TRAVERSE((*ghpp)->gh_depends, off2, gdp)) 1000 gdp->gd_flags |= GPD_REMOVE; 1001 } 1002 1003 /* 1004 * Now that we know which objects on this handle can't be deleted 1005 * determine whether they still need to remain identified as belonging 1006 * to this group to be able to continue binding to one another. 1007 */ 1008 for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { 1009 Grp_hdl * ghp = *ghpp; 1010 1011 for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { 1012 Aliste off3; 1013 Bnd_desc ** bdpp; 1014 1015 lmp = gdp->gd_depend; 1016 1017 if (FLAGS(lmp) & FLG_RT_DELETE) 1018 continue; 1019 1020 for (ALIST_TRAVERSE(DEPENDS(lmp), off3, bdpp)) { 1021 Aliste off4; 1022 Grp_desc * gdp4; 1023 Rt_map * dlmp = (*bdpp)->b_depend; 1024 1025 /* 1026 * If this dependency (dlmp) can be referenced 1027 * by the caller (clmp) without being part of 1028 * this group (ghp) then belonging to this group 1029 * is no longer necessary. This can occur when 1030 * objects are part of multiple handles, or if a 1031 * previously deleted handle was moved to the 1032 * orphan list and has been reopened. Note, 1033 * first make sure the caller can reference the 1034 * dependency with this group, if it can't we 1035 * must be bound to a filtee, so there's no need 1036 * to remain a part of this group either. 1037 */ 1038 if ((callable(lmp, dlmp, 0) == 0) || 1039 callable(lmp, dlmp, ghp)) 1040 continue; 1041 1042 if (gdp->gd_flags & GPD_REMOVE) 1043 gdp->gd_flags &= ~GPD_REMOVE; 1044 1045 for (ALIST_TRAVERSE(ghp->gh_depends, 1046 off4, gdp4)) { 1047 if (gdp4->gd_depend != dlmp) 1048 continue; 1049 1050 if (gdp4->gd_flags & GPD_REMOVE) 1051 gdp4->gd_flags &= ~GPD_REMOVE; 1052 } 1053 } 1054 } 1055 } 1056 1057 /* 1058 * If the owner of a handle can't be deleted and it's handle descriptor 1059 * must remain also, don't delete the handle at all. Leave it for 1060 * possible later use. Although it's left intact, it will still be 1061 * moved to the orphans list, as we might be able to revisit it on later 1062 * dlclose() operations and finally remove the underlying objects. Note 1063 * that the handle still remains attached to the owner via the HANDLES 1064 * list, so that it can be re-associated to the owner if a dlopen() 1065 * of this object reoccurs. 1066 */ 1067 for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { 1068 Grp_hdl * ghp = *ghpp; 1069 1070 /* 1071 * If this handle is already an orphan, or if it's owner is 1072 * deletable there's no need to inspect its dependencies. 1073 */ 1074 if ((ghp->gh_ownlmp == 0) || 1075 (FLAGS(ghp->gh_ownlmp) & FLG_RT_DELETE)) 1076 continue; 1077 1078 /* 1079 * Make sure all handle dependencies aren't removed or the 1080 * dependencies themselves aren't deleted. 1081 */ 1082 for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { 1083 lmp = gdp->gd_depend; 1084 1085 /* 1086 * The first dependency of a non-orphaned handle is the 1087 * owner. If the handle descriptor for this isn't 1088 * required there's no need to look at any other of the 1089 * handles dependencies. 1090 */ 1091 if ((lmp == ghp->gh_ownlmp) && 1092 (gdp->gd_flags & GPD_REMOVE)) 1093 break; 1094 1095 if (gdp->gd_flags & GPD_REMOVE) 1096 gdp->gd_flags &= ~GPD_REMOVE; 1097 if (FLAGS(lmp) & FLG_RT_DELETE) { 1098 FLAGS(lmp) &= ~FLG_RT_DELETE; 1099 delcnt--; 1100 } 1101 } 1102 } 1103 1104 /* 1105 * Final scan of objects to see if any objects are to to be deleted. 1106 * Also - display diagnostic information on what operations are to be 1107 * performed on the collected handles before firing .fini's (which 1108 * produces additional diagnostics). 1109 */ 1110 for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { 1111 Grp_hdl * ghp = *ghpp; 1112 1113 DBG_CALL(Dbg_file_hdl_title(DBG_DEP_DELETE)); 1114 1115 for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { 1116 int flag; 1117 1118 lmp = gdp->gd_depend; 1119 1120 if (FLAGS(lmp) & FLG_RT_DELETE) { 1121 flag = DBG_DEP_DELETE; 1122 /* 1123 * Remove any pathnames from the FullpathNode 1124 * AVL tree. As we're about to fire .fini's, 1125 * it's possible this object will be required 1126 * again, in which case we want to make sure a 1127 * new version of the object gets loaded. 1128 */ 1129 if (FPNODE(lmp)) 1130 fpavl_remove(lmp); 1131 } else if (gdp->gd_flags & GPD_REMOVE) 1132 flag = DBG_DEP_REMOVE; 1133 else 1134 flag = DBG_DEP_REMAIN; 1135 1136 DBG_CALL(Dbg_file_hdl_action(ghp, lmp, flag)); 1137 } 1138 } 1139 1140 /* 1141 * If there are objects to be deleted process their .fini's. 1142 */ 1143 if (delcnt) { 1144 Rt_map ** tobj; 1145 1146 /* 1147 * If we're being audited tell the audit library that we're 1148 * about to go deleting dependencies. 1149 */ 1150 if (clmp && ((LIST(clmp)->lm_tflags | FLAGS1(clmp)) & 1151 LML_TFLG_AUD_ACTIVITY)) 1152 audit_activity(clmp, LA_ACT_DELETE); 1153 1154 /* 1155 * Sort and fire all fini's of the objects selected for 1156 * deletion. Note that we have to start our search from the 1157 * link-map head - there's no telling whether this object has 1158 * dependencies on objects that were loaded before it and which 1159 * can now be deleted. If the tsort() fails because of an 1160 * allocation error then that might just be a symptom of why 1161 * we're here in the first place - forgo the fini's but 1162 * continue to try cleaning up. 1163 */ 1164 lml->lm_flags |= LML_FLG_OBJDELETED; 1165 1166 if (((tobj = tsort(lml->lm_head, delcnt, 1167 (RT_SORT_DELETE | RT_SORT_FWD))) != 0) && 1168 (tobj != (Rt_map **)S_ERROR)) { 1169 error = purge_exit_handlers(lml, tobj); 1170 call_fini(lml, tobj); 1171 } 1172 1173 /* 1174 * Audit the closure of the dlopen'ed object to any local 1175 * auditors. Any global auditors would have been caught by 1176 * call_fini(), but as the link-maps CALLERS was removed 1177 * already we do the local auditors explicitly. 1178 */ 1179 for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { 1180 Grp_hdl * ghp = *ghpp; 1181 Rt_map * dlmp = ghp->gh_ownlmp; 1182 1183 if (clmp && dlmp && 1184 ((LIST(dlmp)->lm_flags & LML_FLG_NOAUDIT) == 0) && 1185 (FLAGS1(clmp) & LML_TFLG_AUD_OBJCLOSE)) 1186 _audit_objclose(&(AUDITORS(clmp)->ad_list), 1187 dlmp); 1188 } 1189 } 1190 1191 /* 1192 * Now that .fini processing (which may have involved new bindings) 1193 * is complete, remove all inter-dependency lists from those objects 1194 * selected for deletion. 1195 */ 1196 for (ALIST_TRAVERSE(lmalp, off1, lmpp)) { 1197 Dyninfo * dip; 1198 uint_t cnt, max; 1199 1200 lmp = *lmpp; 1201 1202 if (FLAGS(lmp) & FLG_RT_DELETE) 1203 remove_lists(lmp, 0); 1204 1205 /* 1206 * Determine whether we're dealing with a filter, and if so 1207 * process any inter-dependencies with its filtee's. 1208 */ 1209 if ((FLAGS1(lmp) & MSK_RT_FILTER) == 0) 1210 continue; 1211 1212 dip = DYNINFO(lmp); 1213 max = DYNINFOCNT(lmp); 1214 1215 for (cnt = 0; cnt < max; cnt++, dip++) { 1216 Pnode * pnp; 1217 1218 if ((dip->di_info == 0) || 1219 ((dip->di_flags & MSK_DI_FILTER) == 0)) 1220 continue; 1221 1222 for (pnp = (Pnode *)dip->di_info; pnp; 1223 pnp = pnp->p_next) { 1224 Grp_hdl * ghp; 1225 1226 if ((pnp->p_len == 0) || 1227 ((ghp = (Grp_hdl *)pnp->p_info) == 0)) 1228 continue; 1229 1230 /* 1231 * Determine whether this filtee's handle is a 1232 * part of the list of handles being deleted. 1233 */ 1234 if (alist_test(&ghalp, ghp, 1235 sizeof (Grp_hdl *), 0) == ALE_EXISTS) { 1236 /* 1237 * If this handle exists on the deletion 1238 * list, then it has been removed. If 1239 * this filter isn't going to be 1240 * deleted, server its reference to the 1241 * handle. 1242 */ 1243 pnp->p_info = 0; 1244 } else { 1245 /* 1246 * If this handle isn't on the deletion 1247 * list, then it must still exist. If 1248 * this filter is being deleted, make 1249 * sure the filtees reference count 1250 * gets decremented. 1251 */ 1252 if (FLAGS(lmp) & FLG_RT_DELETE) 1253 (void) dlclose_core(ghp, lmp); 1254 } 1255 } 1256 } 1257 } 1258 1259 /* 1260 * If called from dlclose(), determine if there are already handles on 1261 * the orphans list that we can reinvestigate. 1262 */ 1263 if ((removed == 0) && hdl_list[HDLIST_ORP].head) 1264 orphans = 1; 1265 else 1266 orphans = 0; 1267 1268 /* 1269 * Finally remove any handle infrastructure and remove any objects 1270 * marked for deletion. 1271 */ 1272 for (ALIST_TRAVERSE(ghalp, off1, ghpp)) { 1273 Grp_hdl * ghp = *ghpp; 1274 1275 /* 1276 * If we're not dealing with orphaned handles remove this handle 1277 * from its present handle list. 1278 */ 1279 if (removed == 0) { 1280 uintptr_t ndx; 1281 1282 /* LINTED */ 1283 ndx = (uintptr_t)ghp % HDLIST_SZ; 1284 list_delete(&hdl_list[ndx], ghp); 1285 } 1286 1287 /* 1288 * Traverse each handle dependency. 1289 */ 1290 for (ALIST_TRAVERSE(ghp->gh_depends, off2, gdp)) { 1291 if ((gdp->gd_flags & GPD_REMOVE) == 0) 1292 continue; 1293 1294 lmp = gdp->gd_depend; 1295 rmcnt++; 1296 1297 /* 1298 * If this object is the owner of the handle break that 1299 * association in case the handle is retained. 1300 */ 1301 if (ghp->gh_ownlmp == lmp) { 1302 (void) alist_delete(HANDLES(lmp), &ghp, 0); 1303 ghp->gh_ownlmp = 0; 1304 } 1305 1306 (void) alist_delete(GROUPS(lmp), &ghp, 0); 1307 (void) alist_delete(ghp->gh_depends, 0, &off2); 1308 1309 /* 1310 * Complete the link-map deletion if appropriate. 1311 */ 1312 if (FLAGS(lmp) & FLG_RT_DELETE) { 1313 tls_modaddrem(lmp, TM_FLG_MODREM); 1314 remove_so(LIST(lmp), lmp); 1315 } 1316 } 1317 1318 /* 1319 * If we've deleted all the dependencies of the handle finalize 1320 * the cleanup by removing the handle itself. 1321 * 1322 * Otherwise we're left with a handle containing one or more 1323 * objects that can not be deleted (they're in use by other 1324 * handles, non-deletable, etc.), but require to remain a part 1325 * of this group to allow them to continue binding to one 1326 * another. Should any other dlclose() operation occur that 1327 * results in the removal of handle descriptors, these orphan 1328 * handles are re-examined to determine if their deletion can be 1329 * completed. 1330 */ 1331 if (ghp->gh_depends->al_data[0] == 0) { 1332 remove_lml(lml); 1333 free(ghp->gh_depends); 1334 free(ghp); 1335 } else if (removed == 0) { 1336 /* 1337 * Move this handle to the orphans list (if it isn't 1338 * already there). 1339 */ 1340 (void) list_append(&hdl_list[HDLIST_ORP], ghp); 1341 1342 if (DBG_ENABLED) { 1343 DBG_CALL(Dbg_file_hdl_title(DBG_DEP_ORPHAN)); 1344 for (ALIST_TRAVERSE(ghp->gh_depends, off1, gdp)) 1345 DBG_CALL(Dbg_file_hdl_action(ghp, 1346 gdp->gd_depend, DBG_DEP_REMAIN)); 1347 } 1348 } 1349 } 1350 1351 /* 1352 * If no handle descriptors got removed there's no point in looking for 1353 * orphans to process. 1354 */ 1355 if (rmcnt == 0) 1356 orphans = 0; 1357 1358 /* 1359 * Cleanup any alists we've created. 1360 */ 1361 remove_collect(ghalp, lmalp); 1362 1363 /* 1364 * If orphan processing isn't required we're done. If our processing 1365 * originated from investigating orphans, return the number of handle 1366 * descriptors removed as an indication whether orphan processing 1367 * should continue. 1368 */ 1369 if (orphans == 0) { 1370 if (removed) 1371 *removed = rmcnt; 1372 return (error); 1373 } 1374 1375 /* 1376 * Traverse the orphans list as many times as necessary until no 1377 * handle removals occur. 1378 */ 1379 do { 1380 List list; 1381 Listnode *lnp; 1382 Grp_hdl *ghp, *oghp = 0; 1383 int title = 0; 1384 1385 /* 1386 * Effectively clean the HDLIST_ORP list. Any object that can't 1387 * be removed will be re-added to the list. 1388 */ 1389 list = hdl_list[HDLIST_ORP]; 1390 hdl_list[HDLIST_ORP].head = hdl_list[HDLIST_ORP].tail = 0; 1391 1392 rescan = 0; 1393 for (LIST_TRAVERSE(&list, lnp, ghp)) { 1394 int _error, _remove; 1395 1396 if (title++ == 0) 1397 DBG_CALL(Dbg_file_del_rescan(ghp->gh_ownlml)); 1398 1399 if (oghp) { 1400 list_delete(&list, oghp); 1401 oghp = 0; 1402 } 1403 1404 if (((_error = remove_hdl(ghp, clmp, &_remove)) != 0) && 1405 (error == 0)) 1406 error = _error; 1407 1408 if (_remove) 1409 rescan++; 1410 1411 oghp = ghp; 1412 } 1413 if (oghp) { 1414 list_delete(&list, oghp); 1415 oghp = 0; 1416 } 1417 1418 } while (rescan && hdl_list[HDLIST_ORP].head); 1419 1420 return (error); 1421 } 1422