1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. 24 * 25 * Audit interfaces. Auditing can be enabled in two ways: 26 * 27 * - Using the LD_AUDIT environment variable 28 * 29 * - From individual objects containing a DT_DEPAUDIT entry 30 * (see ld(1) -P/-p options). 31 * 32 * The former establishes a global set of audit libraries which can inspect all 33 * objects from a given process. The latter establishes a local set of audit 34 * libraries which can inspect the immediate dependencies of the caller. 35 * 36 * Audit library capabilities are indicated by flags within the link-map list 37 * header (for global auditing), see LML_TFLG_AUD_* flags, or by the same flags 38 * within the individual link-map (for local auditing). Although both sets of 39 * flags can occur in different data items they are defined as one to simplify 40 * audit interface requirements. The basic test for all audit interfaces is: 41 * 42 * if ((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_MASK) 43 * 44 * Note. Auditors themselves are identified with the LML_TFLG_NOAUDIT link-map 45 * list flag, and no LML_TFLG_AUD_MASK flags. These flags get propagated from 46 * a callers link-map list to any new link-map lists created. Thus, standard 47 * link-maps lists have the LML_TFLG_AUD_MASK flags propagated, and should a 48 * new link-map list be created by an auditor, that list gets tagged as 49 * LML_TFLG_NOAUDIT. 50 * 51 * The latter link-map list equivalence test insures that auditors themselves 52 * (invoked through DT_DEPAUDIT) are not audited. 53 * 54 * The history of version changes: 55 * 56 * LAV_VERSION1 (Solaris 2.6) 57 * Auditing implementation added. 58 * 59 * LAV_VERSION2 (Solaris 2.6) 60 * LA_SYMB_ALTVALUE support added. 61 * 62 * LAV_VERSION3 (Solaris 9 update 7) 63 * ld_objfilter() added. 64 * 65 * LAV_VERSION4 (Solaris 10 update 5) 66 * Correction of activity calls for local auditors, and introduction of 67 * -z globalaudit concept. 68 * 69 * LAV_VERSION5 (Solaris 11) 70 * Under this version, preinit and activity events are enabled from local 71 * auditors. The la_preinit and la_activity interfaces require a cookie 72 * that represents the head of the link-map list being audited. If a 73 * local preinit or activity interface is detected, the local auditors 74 * la_objopen() routine is called with a cookie that represents the object 75 * that heads the link-map list of the object being audited. 76 * 77 * A local auditor is loaded through adding a new dependency that requests 78 * auditing, and therefore an la_activity(ADD) event is already in effect. 79 * Regardless, the local auditors la_activity() routine is called with the 80 * cookie that represents the object that heads the link-map list of the 81 * object being audited. 82 * 83 * A local auditor can be loaded prior to the preinit event. In this case, 84 * the local auditors la_preinit() routine is called with the cookie that 85 * represents the object that heads the link-map list of the object being 86 * audited. After the preinit event, any la_preinit() routine within a 87 * local auditor will not be called. 88 * 89 * These events are intended to follow the expected sequence of events 90 * received by global auditors, ie: 91 * 92 * - la_objopen(main) 93 * - la_activity(ADD) 94 * - la_objopen(dependency) 95 * - la_activity(CONSISTENT) 96 * - la_preinit(main) 97 */ 98 99 #include <stdio.h> 100 #include <sys/types.h> 101 #include <sys/lwp.h> 102 #include <stdio.h> 103 #include <stdarg.h> 104 #include <dlfcn.h> 105 #include <string.h> 106 #include <debug.h> 107 #include "_rtld.h" 108 #include "_audit.h" 109 #include "_elf.h" 110 #include "msg.h" 111 112 uint_t audit_flags = 0; /* Copy of specific audit flags to */ 113 /* simplify boot_elf.s access. */ 114 115 /* 116 * Obtain a head link-map cookie. Local auditors can provide la_preinit() and 117 * la_activity() routines, and these routines require a cookie that represents 118 * the object that heads the link-map of the object being audited. A list of 119 * these cookies is maintained on the link-map list. This list allows multiple 120 * local objects to specify the same auditor, and to obtain the same cookie 121 * for the link-map that heads the link-map list. 122 * 123 * The initial cookie is created by _audit_create_head_client() which is called 124 * from _audit_add_head(). This cookies address is then passed to the local 125 * auditors ld_objopen() and la_activity() routines. Subsequent preinit and 126 * activity events use _audit_get_head_client() to dynamically retrieve the 127 * cookies address. 128 */ 129 static Audit_client * 130 _audit_get_head_client(Rt_map *hlmp, Rt_map *almp) 131 { 132 Audit_client *acp; 133 Aliste idx; 134 Lm_list *hlml = LIST(hlmp); 135 136 for (ALIST_TRAVERSE(hlml->lm_aud_cookies, idx, acp)) { 137 if (acp->ac_lmp == almp) 138 return (acp); 139 } 140 return (NULL); 141 } 142 143 static Audit_client * 144 _audit_create_head_client(Rt_map *hlmp, Rt_map *almp) 145 { 146 Audit_client ac, *acp; 147 Lm_list *hlml = LIST(hlmp); 148 149 ac.ac_lmp = almp; 150 ac.ac_cookie = (uintptr_t)hlmp; 151 ac.ac_flags = 0; 152 153 if ((acp = alist_append(&(hlml->lm_aud_cookies), &ac, 154 sizeof (Audit_client), AL_CNT_COOKIES)) == NULL) 155 return (NULL); 156 157 return (acp); 158 } 159 160 /* 161 * Determine the appropriate client. Each client structure identifies the 162 * link-map of the auditor it is associated with. From the client structure, 163 * the address of the associated cookie, that represents the object being 164 * audited, is retrieved so that the address can be passed to any audit call. 165 * 166 * Note, objects that are being locally audited, can provide la_preinit() and 167 * la_activity() routines. These routines must be passed cookies that represent 168 * the object that heads the link-map list of the object being audited. These 169 * cookies are not maintained on this objects Audit_client structure, but are 170 * obtained from the associated link-map lists lm_cookies alist. 171 */ 172 static Audit_client * 173 _audit_client(Audit_info *aip, Rt_map *almp) 174 { 175 int ndx; 176 177 if (aip == NULL) 178 return (NULL); 179 180 for (ndx = 0; ndx < aip->ai_cnt; ndx++) { 181 if (aip->ai_clients[ndx].ac_lmp == almp) 182 return (&(aip->ai_clients[ndx])); 183 } 184 return (NULL); 185 } 186 187 /* 188 * la_filter() caller. Traverse through all audit libraries and call any 189 * la_filter() entry points found. A zero return from an auditor indicates 190 * that the filtee should be ignored. 191 */ 192 static int 193 _audit_objfilter(APlist *list, Rt_map *frlmp, const char *ref, Rt_map *felmp, 194 uint_t flags) 195 { 196 Audit_list *alp; 197 Aliste idx; 198 Lm_list *frlml = LIST(frlmp); 199 200 for (APLIST_TRAVERSE(list, idx, alp)) { 201 Audit_client *fracp, *feacp; 202 Rt_map *almp = alp->al_lmp; 203 Lm_list *alml = LIST(almp); 204 int ret; 205 206 if (alp->al_objfilter == NULL) 207 continue; 208 if ((fracp = _audit_client(AUDINFO(frlmp), almp)) == NULL) 209 continue; 210 if ((feacp = _audit_client(AUDINFO(felmp), almp)) == NULL) 211 continue; 212 213 DBG_CALL(Dbg_audit_objfilter(frlml, DBG_AUD_CALL, 214 alp->al_libname, NAME(frlmp), NAME(felmp), ref)); 215 216 leave(alml, thr_flg_reenter); 217 ret = (*alp->al_objfilter)(&(fracp->ac_cookie), ref, 218 &(feacp->ac_cookie), flags); 219 (void) enter(thr_flg_reenter); 220 221 if (ret == 0) { 222 DBG_CALL(Dbg_audit_objfilter(frlml, DBG_AUD_RET, 223 alp->al_libname, NAME(frlmp), NULL, NULL)); 224 return (0); 225 } 226 } 227 return (1); 228 } 229 230 int 231 audit_objfilter(Rt_map *frlmp, const char *ref, Rt_map *felmp, uint_t flags) 232 { 233 uint_t rtldflags; 234 int respond = 1; 235 236 if (rt_critical()) 237 return (respond); 238 239 APPLICATION_ENTER(rtldflags); 240 241 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_OBJFILTER)) 242 respond = _audit_objfilter(auditors->ad_list, frlmp, 243 ref, felmp, flags); 244 if (respond && AUDITORS(frlmp) && 245 (AUDITORS(frlmp)->ad_flags & LML_TFLG_AUD_OBJFILTER)) 246 respond = _audit_objfilter(AUDITORS(frlmp)->ad_list, frlmp, 247 ref, felmp, flags); 248 249 APPLICATION_RETURN(rtldflags); 250 251 return (respond); 252 } 253 254 /* 255 * la_objsearch() caller. Traverse through all audit libraries and call any 256 * la_objsearch() entry points found. 257 * 258 * Effectively any audit library can change the name we're working with, so we 259 * continue to propagate the new name to each audit library. Any 0 return 260 * terminates the search. 261 */ 262 static char * 263 _audit_objsearch(APlist *list, char *oname, Rt_map *clmp, uint_t flags) 264 { 265 Audit_list *alp; 266 Aliste idx; 267 Lm_list *clml = LIST(clmp); 268 269 for (APLIST_TRAVERSE(list, idx, alp)) { 270 Audit_client *acp; 271 Rt_map *almp = alp->al_lmp; 272 Lm_list *alml = LIST(almp); 273 char *nname = oname; 274 275 if (alp->al_objsearch == NULL) 276 continue; 277 if ((acp = _audit_client(AUDINFO(clmp), almp)) == NULL) 278 continue; 279 280 DBG_CALL(Dbg_audit_objsearch(clml, DBG_AUD_CALL, 281 alp->al_libname, nname, flags, NULL)); 282 283 leave(alml, thr_flg_reenter); 284 nname = (*alp->al_objsearch)(nname, &(acp->ac_cookie), flags); 285 (void) enter(thr_flg_reenter); 286 287 /* 288 * Diagnose any return name that differs from the original name 289 * passed to the auditor. 290 */ 291 if (nname && (nname[0] == '\0')) 292 nname = NULL; 293 if ((nname != oname) || strcmp(nname, oname)) 294 DBG_CALL(Dbg_audit_objsearch(clml, DBG_AUD_RET, 295 alp->al_libname, oname, flags, nname)); 296 297 if ((oname = nname) == NULL) 298 break; 299 300 } 301 return (oname); 302 } 303 304 char * 305 audit_objsearch(Rt_map *clmp, const char *name, uint_t flags) 306 { 307 char *nname = (char *)name; 308 uint_t rtldflags; 309 310 if (rt_critical()) 311 return (nname); 312 313 APPLICATION_ENTER(rtldflags); 314 315 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_OBJSEARCH)) 316 nname = _audit_objsearch(auditors->ad_list, nname, 317 clmp, flags); 318 if (nname && AUDITORS(clmp) && 319 (AUDITORS(clmp)->ad_flags & LML_TFLG_AUD_OBJSEARCH)) 320 nname = _audit_objsearch(AUDITORS(clmp)->ad_list, nname, 321 clmp, flags); 322 323 APPLICATION_RETURN(rtldflags); 324 325 DBG_CALL(Dbg_libs_audit(LIST(clmp), name, nname)); 326 return (nname); 327 } 328 329 /* 330 * la_activity() caller. Traverse through all audit libraries and call any 331 * la_activity() entry points found. 332 */ 333 static void 334 _audit_activity(APlist *list, Rt_map *clmp, uint_t flags, Boolean client) 335 { 336 Audit_list *alp; 337 Aliste idx; 338 Lm_list *clml = LIST(clmp); 339 340 for (APLIST_TRAVERSE(list, idx, alp)) { 341 Audit_client *acp; 342 Rt_map *almp = alp->al_lmp; 343 Lm_list *alml = LIST(almp); 344 uintptr_t *cookie; 345 346 if (alp->al_activity == 0) 347 continue; 348 349 /* 350 * Determine what cookie is required. Any auditing that 351 * originates from the object that heads the link-map list has 352 * its own cookie. Local auditors must obtain the cookie that 353 * represents the object that heads the link-map list. 354 */ 355 if (client) 356 acp = _audit_client(AUDINFO(clmp), almp); 357 else 358 acp = _audit_get_head_client(clml->lm_head, almp); 359 360 if (acp == NULL) 361 continue; 362 cookie = &(acp->ac_cookie); 363 364 /* 365 * Make sure the audit library only sees one addition/deletion 366 * at a time. This ensures the library doesn't see numerous 367 * events from lazy loading a series of libraries. Keep track 368 * of this caller having called an auditor, so that the 369 * appropriate "consistent" event can be supplied on leaving 370 * ld.so.1. 371 */ 372 if ((flags == LA_ACT_ADD) || (flags == LA_ACT_DELETE)) { 373 if (alml->lm_flags & LML_FLG_AUDITNOTIFY) 374 continue; 375 376 alml->lm_flags |= LML_FLG_AUDITNOTIFY; 377 clml->lm_flags |= LML_FLG_ACTAUDIT; 378 } else { 379 if ((alml->lm_flags & LML_FLG_AUDITNOTIFY) == 0) 380 continue; 381 382 alml->lm_flags &= ~LML_FLG_AUDITNOTIFY; 383 } 384 385 DBG_CALL(Dbg_audit_activity(clml, alp->al_libname, 386 NAME(clml->lm_head), flags)); 387 388 leave(alml, thr_flg_reenter); 389 (*alp->al_activity)(cookie, flags); 390 (void) enter(thr_flg_reenter); 391 } 392 } 393 394 void 395 audit_activity(Rt_map *clmp, uint_t flags) 396 { 397 Rt_map *lmp; 398 Aliste idx; 399 uint_t rtldflags; 400 401 if (rt_critical()) 402 return; 403 404 APPLICATION_ENTER(rtldflags); 405 406 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_ACTIVITY)) 407 _audit_activity(auditors->ad_list, clmp, flags, TRUE); 408 if (AUDITORS(clmp) && 409 (AUDITORS(clmp)->ad_flags & LML_TFLG_AUD_ACTIVITY)) 410 _audit_activity(AUDITORS(clmp)->ad_list, clmp, flags, TRUE); 411 412 for (APLIST_TRAVERSE(aud_activity, idx, lmp)) { 413 if ((clmp != lmp) && AUDITORS(lmp) && 414 (AUDITORS(lmp)->ad_flags & LML_TFLG_AUD_ACTIVITY)) { 415 _audit_activity(AUDITORS(lmp)->ad_list, lmp, flags, 416 FALSE); 417 } 418 } 419 420 APPLICATION_RETURN(rtldflags); 421 } 422 423 /* 424 * Determine whether an auditor is in use by the head link-map object. 425 */ 426 static int 427 _audit_used_by_head(Rt_map *hlmp, Rt_map *almp) 428 { 429 Audit_list *alp; 430 Aliste idx; 431 432 for (APLIST_TRAVERSE(AUDITORS(hlmp)->ad_list, idx, alp)) { 433 if (alp->al_lmp == almp) 434 return (1); 435 } 436 return (0); 437 } 438 439 /* 440 * la_objopen() caller for the head link-map. Global auditors, or an auditor 441 * started from the object that heads a link-map list (typically the dynamic 442 * executable), are passed to la_objopen(). However, local auditors can 443 * provide activity and preinit events, and for these events, a cookie 444 * representing the head link-map list object is expected. This routine obtains 445 * these cookies from the link-map list lm_cookies element. This element 446 * ensures all clients of the same auditor use the same cookie. 447 * 448 * Although a local auditor will get an la_objopen() call for the object that 449 * heads the link-map list of the object being audited, the auditor is not 450 * permitted to request binding information for this head object. The head 451 * object has already been in existence, and bindings may have been resolved 452 * with it. This local auditor is coming into existence too late, and thus we 453 * don't allow any bindings to be caught at all. 454 */ 455 static int 456 _audit_add_head(Rt_map *clmp, Rt_map *hlmp, int preinit, int activity) 457 { 458 Lm_list *clml = LIST(clmp); 459 Lmid_t lmid = get_linkmap_id(clml); 460 Audit_list *alp; 461 Aliste idx; 462 int save = 0; 463 464 for (APLIST_TRAVERSE(AUDITORS(clmp)->ad_list, idx, alp)) { 465 Audit_client *acp; 466 Rt_map *almp = alp->al_lmp; 467 Lm_list *alml = LIST(almp); 468 uintptr_t *cookie; 469 uint_t rtldflags; 470 471 /* 472 * Ensure this local auditor isn't already in existence as an 473 * auditor for the head of the link-map list. If it is, then 474 * this auditor will have already receive preinit and activity 475 * events. 476 */ 477 if (AUDITORS(hlmp) && _audit_used_by_head(hlmp, almp)) 478 continue; 479 480 /* 481 * Create a cookie that represents the object that heads the 482 * link-map list. If the cookie already exists, then this 483 * auditor has already been established for another objects 484 * local auditing. In this case, do not issue a la_objopen() 485 * or la_activity() event, as these will have already occurred. 486 */ 487 if ((acp = _audit_get_head_client(clml->lm_head, almp)) != NULL) 488 continue; 489 if ((acp = 490 _audit_create_head_client(clml->lm_head, almp)) == NULL) 491 return (0); 492 493 cookie = &(acp->ac_cookie); 494 save++; 495 496 /* 497 * Call the la_objopen() if available. 498 */ 499 if (alp->al_objopen) { 500 uint_t flags; 501 502 DBG_CALL(Dbg_audit_objopen(clml, DBG_AUD_CALL, 503 alp->al_libname, NAME(hlmp), 0, FALSE)); 504 505 APPLICATION_ENTER(rtldflags); 506 leave(alml, thr_flg_reenter); 507 flags = (*alp->al_objopen)((Link_map *)hlmp, lmid, 508 cookie); 509 (void) enter(thr_flg_reenter); 510 APPLICATION_RETURN(rtldflags); 511 512 if (flags) { 513 DBG_CALL(Dbg_audit_objopen(clml, DBG_AUD_RET, 514 alp->al_libname, NAME(hlmp), flags, TRUE)); 515 } 516 } 517 518 /* 519 * Call the la_activity() if available. 520 */ 521 if (alp->al_activity) { 522 alml->lm_flags |= LML_FLG_AUDITNOTIFY; 523 clml->lm_flags |= LML_FLG_ACTAUDIT; 524 525 DBG_CALL(Dbg_audit_activity(clml, alp->al_libname, 526 NAME(clml->lm_head), LA_ACT_ADD)); 527 528 APPLICATION_ENTER(rtldflags); 529 leave(alml, thr_flg_reenter); 530 (*alp->al_activity)(cookie, LA_ACT_ADD); 531 (void) enter(thr_flg_reenter); 532 APPLICATION_RETURN(rtldflags); 533 } 534 } 535 536 /* 537 * If new head link-map cookies have been generated, then maintain 538 * any preinit and/or activity requirements. 539 */ 540 if (save) { 541 if (preinit && (aplist_append(&aud_preinit, clmp, 542 AL_CNT_AUDITORS) == NULL)) 543 return (0); 544 if (activity && (aplist_append(&aud_activity, clmp, 545 AL_CNT_AUDITORS) == NULL)) 546 return (0); 547 } 548 return (1); 549 } 550 551 /* 552 * la_objopen() caller. Create an audit information structure for the indicated 553 * link-map, regardless of an la_objopen() entry point. This structure is used 554 * to supply information to various audit interfaces (see LML_MSK_AUDINFO). 555 * Traverse through all audit libraries and call any la_objopen() entry points 556 * found. 557 */ 558 static int 559 _audit_objopen(APlist *list, Rt_map *nlmp, Lmid_t lmid, Audit_info *aip, 560 int *ndx) 561 { 562 Lm_list *nlml = LIST(nlmp); 563 Audit_list *alp; 564 Aliste idx; 565 566 for (APLIST_TRAVERSE(list, idx, alp)) { 567 uint_t flags; 568 Audit_client *acp; 569 Rt_map *almp = alp->al_lmp; 570 Lm_list *alml = LIST(almp); 571 572 /* 573 * Associate a cookie with the audit library, and assign the 574 * initial cookie as the present link-map. 575 */ 576 acp = &aip->ai_clients[(*ndx)++]; 577 acp->ac_lmp = alp->al_lmp; 578 acp->ac_cookie = (uintptr_t)nlmp; 579 580 if (alp->al_objopen == NULL) 581 continue; 582 583 DBG_CALL(Dbg_audit_objopen(nlml, DBG_AUD_CALL, alp->al_libname, 584 NAME(nlmp), 0, FALSE)); 585 586 leave(alml, thr_flg_reenter); 587 flags = (*alp->al_objopen)((Link_map *)nlmp, lmid, 588 &(acp->ac_cookie)); 589 (void) enter(thr_flg_reenter); 590 591 /* 592 * Diagnose any flags returned by the auditor. 593 */ 594 if (flags) { 595 DBG_CALL(Dbg_audit_objopen(nlml, DBG_AUD_RET, 596 alp->al_libname, NAME(nlmp), flags, FALSE)); 597 } 598 599 if (flags & LA_FLG_BINDTO) 600 acp->ac_flags |= FLG_AC_BINDTO; 601 602 if (flags & LA_FLG_BINDFROM) { 603 ulong_t pltcnt; 604 605 acp->ac_flags |= FLG_AC_BINDFROM; 606 607 /* 608 * We only need dynamic plt's if a pltenter and/or a 609 * pltexit() entry point exist in one of our auditing 610 * libraries. 611 */ 612 if (aip->ai_dynplts || (JMPREL(nlmp) == 0) || 613 ((audit_flags & (AF_PLTENTER | AF_PLTEXIT)) == 0)) 614 continue; 615 616 /* 617 * Create one dynplt for every 'PLT' that exists in the 618 * object. 619 */ 620 pltcnt = PLTRELSZ(nlmp) / RELENT(nlmp); 621 if ((aip->ai_dynplts = calloc(pltcnt, 622 dyn_plt_ent_size)) == NULL) 623 return (0); 624 } 625 } 626 return (1); 627 } 628 629 int 630 audit_objopen(Rt_map *clmp, Rt_map *nlmp) 631 { 632 Lmid_t lmid = get_linkmap_id(LIST(nlmp)); 633 int respond = 1, ndx = 0; 634 uint_t rtldflags; 635 uint_t clients = 0; 636 Audit_info *aip; 637 638 if (rt_critical()) 639 return (respond); 640 641 /* 642 * Determine the number of auditors that can receive information 643 * regarding this object. This provides the number of client 644 * structures required for this object. 645 */ 646 if (auditors) 647 clients = auditors->ad_cnt; 648 if (AUDITORS(clmp)) 649 clients += AUDITORS(clmp)->ad_cnt; 650 if ((nlmp != clmp) && AUDITORS(nlmp)) 651 clients += AUDITORS(nlmp)->ad_cnt; 652 653 /* 654 * Allocate an audit information structure. Each audited object 655 * maintains a AUDINFO() structure. As this structure can only be 656 * created once all auditors are loaded, a client count can now be 657 * computed. 658 * 659 * The allocation of the audit information structure includes an array 660 * of audit clients, 1 per audit library that has been loaded. 661 * 662 * --------------- 663 * | ai_cnt | 664 * Audit_info | ai_clients |------- 665 * | ai_dynplts | | 666 * |---------------| | 667 * Audit_client | 1 |<------ 668 * |---------------| 669 * | 2 | 670 * ......... 671 */ 672 if ((AUDINFO(nlmp) = aip = calloc(1, sizeof (Audit_info) + 673 (sizeof (Audit_client) * clients))) == NULL) 674 return (0); 675 676 aip->ai_cnt = clients; 677 aip->ai_clients = (Audit_client *)((uintptr_t)aip + 678 sizeof (Audit_info)); 679 680 APPLICATION_ENTER(rtldflags); 681 682 if (auditors) 683 respond = _audit_objopen(auditors->ad_list, nlmp, 684 lmid, aip, &ndx); 685 if (respond && AUDITORS(clmp)) 686 respond = _audit_objopen(AUDITORS(clmp)->ad_list, nlmp, 687 lmid, aip, &ndx); 688 if (respond && (nlmp != clmp) && AUDITORS(nlmp)) 689 respond = _audit_objopen(AUDITORS(nlmp)->ad_list, nlmp, 690 lmid, aip, &ndx); 691 692 APPLICATION_RETURN(rtldflags); 693 694 return (respond); 695 } 696 697 /* 698 * la_objclose() caller. Traverse through all audit libraries and call any 699 * la_objclose() entry points found. 700 */ 701 void 702 _audit_objclose(APlist *list, Rt_map *lmp) 703 { 704 Audit_list *alp; 705 Aliste idx; 706 Lm_list *lml = LIST(lmp); 707 708 for (APLIST_TRAVERSE(list, idx, alp)) { 709 Audit_client *acp; 710 Rt_map *almp = alp->al_lmp; 711 Lm_list *alml = LIST(almp); 712 713 if (alp->al_objclose == NULL) 714 continue; 715 if ((acp = _audit_client(AUDINFO(lmp), almp)) == NULL) 716 continue; 717 718 DBG_CALL(Dbg_audit_objclose(lml, alp->al_libname, NAME(lmp))); 719 720 leave(alml, thr_flg_reenter); 721 (*alp->al_objclose)(&(acp->ac_cookie)); 722 (void) enter(thr_flg_reenter); 723 } 724 } 725 726 /* 727 * Determine any la_objclose() requirements. An object that is about to be 728 * deleted needs to trigger an la_objclose() event to any associated auditors. 729 * In the case of local auditing, a deleted object may have a number of callers, 730 * and each of these callers may have their own auditing requirements. To 731 * ensure only one la_objclose() event is sent to each auditor, collect the 732 * auditors from any callers and make sure there's no duplication. 733 */ 734 inline static void 735 add_objclose_list(Rt_map *lmp, APlist **alpp) 736 { 737 if (AFLAGS(lmp) & LML_TFLG_AUD_OBJCLOSE) { 738 Audit_list *alp; 739 Aliste idx; 740 741 for (APLIST_TRAVERSE(AUDITORS(lmp)->ad_list, idx, alp)) { 742 if (aplist_test(alpp, alp, AL_CNT_AUDITORS) == 0) 743 return; 744 } 745 } 746 } 747 748 void 749 audit_objclose(Rt_map *lmp, Rt_map *clmp) 750 { 751 APlist *alp = NULL; 752 uint_t rtldflags; 753 754 if (rt_critical()) 755 return; 756 757 APPLICATION_ENTER(rtldflags); 758 759 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_OBJCLOSE)) 760 _audit_objclose(auditors->ad_list, lmp); 761 762 /* 763 * If this link-map list contains local auditors, determine if this 764 * object, or any of this objects CALLERS have instantiated auditors 765 * that need to know of la_objclose() events. 766 */ 767 if (LIST(lmp)->lm_flags & LML_FLG_LOCAUDIT) { 768 Bnd_desc *bdp; 769 Aliste idx; 770 771 add_objclose_list(lmp, &alp); 772 773 for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) 774 add_objclose_list(bdp->b_caller, &alp); 775 } 776 777 /* 778 * If this close originated from dlclose(), determine whether the caller 779 * requires a la_objclose() event. 780 */ 781 if (clmp) 782 add_objclose_list(clmp, &alp); 783 784 if (alp) { 785 _audit_objclose(alp, lmp); 786 free((void *)alp); 787 } 788 789 APPLICATION_RETURN(rtldflags); 790 } 791 792 /* 793 * la_pltenter() caller. Traverse through all audit libraries and call any 794 * la_pltenter() entry points found. NOTE: this routine is called via the 795 * glue code established in elf_plt_trace_write(), the symbol descriptor is 796 * created as part of the glue and for 32bit environments the st_name is a 797 * pointer to the real symbol name (ie. it's already been adjusted with the 798 * objects base offset). For 64bit environments the st_name remains the 799 * original symbol offset and in this case it is used to compute the real name 800 * pointer and pass as a separate argument to the auditor. 801 */ 802 static void 803 _audit_pltenter(APlist *list, Rt_map *rlmp, Rt_map *dlmp, Sym *sym, 804 uint_t ndx, void *regs, uint_t *flags) 805 { 806 Audit_list *alp; 807 Aliste idx; 808 Lm_list *rlml = LIST(rlmp); 809 #if defined(_ELF64) 810 const char *name = (const char *)(sym->st_name + STRTAB(dlmp)); 811 #else 812 const char *name = (const char *)(sym->st_name); 813 #endif 814 815 for (APLIST_TRAVERSE(list, idx, alp)) { 816 Audit_client *racp, *dacp; 817 Rt_map *almp = alp->al_lmp; 818 Lm_list *alml = LIST(almp); 819 Addr ovalue = sym->st_value; 820 821 if (alp->al_pltenter == 0) 822 continue; 823 if ((racp = _audit_client(AUDINFO(rlmp), almp)) == NULL) 824 continue; 825 if ((dacp = _audit_client(AUDINFO(dlmp), almp)) == NULL) 826 continue; 827 if (((racp->ac_flags & FLG_AC_BINDFROM) == 0) || 828 ((dacp->ac_flags & FLG_AC_BINDTO) == 0)) 829 continue; 830 831 DBG_CALL(Dbg_audit_pltenter(rlml, DBG_AUD_CALL, 832 alp->al_libname, name, ovalue)); 833 834 leave(alml, thr_flg_reenter); 835 sym->st_value = (Addr)(*alp->al_pltenter)(sym, ndx, 836 &(racp->ac_cookie), &(dacp->ac_cookie), regs, 837 /* BEGIN CSTYLED */ 838 #if defined(_ELF64) 839 flags, name); 840 #else 841 flags); 842 #endif 843 /* END CSTYLED */ 844 (void) enter(thr_flg_reenter); 845 846 if (ovalue != sym->st_value) { 847 DBG_CALL(Dbg_audit_pltenter(rlml, DBG_AUD_RET, 848 alp->al_libname, name, sym->st_value)); 849 } 850 } 851 } 852 853 Addr 854 audit_pltenter(Rt_map *rlmp, Rt_map *dlmp, Sym *sym, uint_t ndx, 855 void *regs, uint_t *flags) 856 { 857 Sym nsym = *sym; 858 uint_t rtldflags; 859 860 if (rt_critical()) 861 return (nsym.st_value); 862 863 /* 864 * We're effectively entering ld.so.1 from user (glue) code. 865 */ 866 (void) enter(0); 867 APPLICATION_ENTER(rtldflags); 868 869 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_PLTENTER)) 870 _audit_pltenter(auditors->ad_list, rlmp, dlmp, &nsym, 871 ndx, regs, flags); 872 if (AUDITORS(rlmp) && 873 (AUDITORS(rlmp)->ad_flags & LML_TFLG_AUD_PLTENTER)) 874 _audit_pltenter(AUDITORS(rlmp)->ad_list, rlmp, dlmp, &nsym, 875 ndx, regs, flags); 876 877 APPLICATION_RETURN(rtldflags); 878 leave(LIST(rlmp), 0); 879 880 return (nsym.st_value); 881 } 882 883 /* 884 * la_pltexit() caller. Traverse through all audit libraries and call any 885 * la_pltexit() entry points found. See notes above (_audit_pltenter) for 886 * discussion on st_name. 887 */ 888 static Addr 889 _audit_pltexit(APlist *list, uintptr_t retval, Rt_map *rlmp, Rt_map *dlmp, 890 Sym *sym, uint_t ndx) 891 { 892 Audit_list *alp; 893 Aliste idx; 894 #if defined(_ELF64) 895 const char *name = (const char *)(sym->st_name + STRTAB(dlmp)); 896 #else 897 const char *name = (const char *)(sym->st_name); 898 #endif 899 Lm_list *rlml = LIST(rlmp); 900 901 for (APLIST_TRAVERSE(list, idx, alp)) { 902 Audit_client *racp, *dacp; 903 Rt_map *almp = alp->al_lmp; 904 Lm_list *alml = LIST(almp); 905 906 if (alp->al_pltexit == 0) 907 continue; 908 if ((racp = _audit_client(AUDINFO(rlmp), almp)) == NULL) 909 continue; 910 if ((dacp = _audit_client(AUDINFO(dlmp), almp)) == NULL) 911 continue; 912 if (((racp->ac_flags & FLG_AC_BINDFROM) == 0) || 913 ((dacp->ac_flags & FLG_AC_BINDTO) == 0)) 914 continue; 915 916 DBG_CALL(Dbg_audit_pltexit(rlml, alp->al_libname, name)); 917 918 leave(alml, thr_flg_reenter); 919 retval = (*alp->al_pltexit)(sym, ndx, 920 &(racp->ac_cookie), &(dacp->ac_cookie), 921 /* BEGIN CSTYLED */ 922 #if defined(_ELF64) 923 retval, name); 924 #else 925 retval); 926 #endif 927 /* END CSTYLED */ 928 (void) enter(thr_flg_reenter); 929 } 930 return (retval); 931 } 932 933 Addr 934 audit_pltexit(uintptr_t retval, Rt_map *rlmp, Rt_map *dlmp, Sym *sym, 935 uint_t ndx) 936 { 937 uintptr_t _retval = retval; 938 uint_t rtldflags; 939 940 if (rt_critical()) 941 return (_retval); 942 943 /* 944 * We're effectively entering ld.so.1 from user (glue) code. 945 */ 946 (void) enter(0); 947 APPLICATION_ENTER(rtldflags); 948 949 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_PLTEXIT)) 950 _retval = _audit_pltexit(auditors->ad_list, _retval, 951 rlmp, dlmp, sym, ndx); 952 if (AUDITORS(rlmp) && (AUDITORS(rlmp)->ad_flags & LML_TFLG_AUD_PLTEXIT)) 953 _retval = _audit_pltexit(AUDITORS(rlmp)->ad_list, _retval, 954 rlmp, dlmp, sym, ndx); 955 956 APPLICATION_RETURN(rtldflags); 957 leave(LIST(rlmp), 0); 958 959 return (_retval); 960 } 961 962 963 /* 964 * la_symbind() caller. Traverse through all audit libraries and call any 965 * la_symbind() entry points found. 966 */ 967 static Addr 968 _audit_symbind(APlist *list, Rt_map *rlmp, Rt_map *dlmp, Sym *sym, uint_t ndx, 969 uint_t *flags, int *called) 970 { 971 Audit_list *alp; 972 Aliste idx; 973 Lm_list *rlml = LIST(rlmp); 974 #if defined(_ELF64) 975 const char *name = (const char *)(sym->st_name + STRTAB(dlmp)); 976 #else 977 const char *name = (const char *)(sym->st_name); 978 #endif 979 980 for (APLIST_TRAVERSE(list, idx, alp)) { 981 Audit_client *racp, *dacp; 982 Rt_map *almp = alp->al_lmp; 983 Lm_list *alml = LIST(almp); 984 Addr ovalue = sym->st_value; 985 uint_t lflags, oflags = *flags; 986 987 if (alp->al_symbind == 0) 988 continue; 989 if ((racp = _audit_client(AUDINFO(rlmp), almp)) == NULL) 990 continue; 991 if ((dacp = _audit_client(AUDINFO(dlmp), almp)) == NULL) 992 continue; 993 if (((racp->ac_flags & FLG_AC_BINDFROM) == 0) || 994 ((dacp->ac_flags & FLG_AC_BINDTO) == 0)) 995 continue; 996 997 /* 998 * The la_symbind interface is only called when the calling 999 * object has been identified as BINDFROM, and the destination 1000 * object has been identified as BINDTO. Use a local version of 1001 * the flags, so that any user update can be collected. 1002 */ 1003 (*called)++; 1004 lflags = (oflags & ~(LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)); 1005 1006 DBG_CALL(Dbg_audit_symbind(rlml, DBG_AUD_CALL, 1007 alp->al_libname, name, ovalue, oflags)); 1008 1009 leave(alml, thr_flg_reenter); 1010 sym->st_value = (*alp->al_symbind)(sym, ndx, 1011 &(racp->ac_cookie), &(dacp->ac_cookie), 1012 /* BEGIN CSTYLED */ 1013 #if defined(_ELF64) 1014 &lflags, name); 1015 #else 1016 &lflags); 1017 #endif 1018 /* END CSTYLED */ 1019 (void) enter(thr_flg_reenter); 1020 1021 /* 1022 * If the auditor indicated that they did not want to process 1023 * pltenter, or pltexit audits for this symbol, retain this 1024 * information. Also retain whether an alternative symbol value 1025 * has been supplied. 1026 */ 1027 *flags |= (lflags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)); 1028 if ((ovalue != sym->st_value) && 1029 (alp->al_vernum >= LAV_VERSION2)) 1030 *flags |= LA_SYMB_ALTVALUE; 1031 1032 if ((ovalue != sym->st_value) || (oflags != *flags)) { 1033 DBG_CALL(Dbg_audit_symbind(rlml, DBG_AUD_RET, 1034 alp->al_libname, name, sym->st_value, *flags)); 1035 } 1036 } 1037 return (sym->st_value); 1038 } 1039 1040 Addr 1041 audit_symbind(Rt_map *rlmp, Rt_map *dlmp, Sym *sym, uint_t ndx, Addr value, 1042 uint_t *flags) 1043 { 1044 Sym nsym; 1045 int called = 0; 1046 uint_t rtldflags; 1047 1048 /* 1049 * Construct a new symbol from that supplied but with the real address. 1050 * In the 64-bit world the st_name field is only 32-bits which isn't 1051 * big enough to hold a character pointer. We pass this pointer as a 1052 * separate parameter for 64-bit audit libraries. 1053 */ 1054 nsym = *sym; 1055 nsym.st_value = value; 1056 1057 if (rt_critical()) 1058 return (nsym.st_value); 1059 1060 #if !defined(_ELF64) 1061 nsym.st_name += (Word)STRTAB(dlmp); 1062 #endif 1063 APPLICATION_ENTER(rtldflags); 1064 1065 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_SYMBIND)) 1066 nsym.st_value = _audit_symbind(auditors->ad_list, 1067 rlmp, dlmp, &nsym, ndx, flags, &called); 1068 if (AUDITORS(rlmp) && (AUDITORS(rlmp)->ad_flags & LML_TFLG_AUD_SYMBIND)) 1069 nsym.st_value = _audit_symbind(AUDITORS(rlmp)->ad_list, 1070 rlmp, dlmp, &nsym, ndx, flags, &called); 1071 1072 /* 1073 * If no la_symbind() was called for this interface, fabricate that no 1074 * la_pltenter, or la_pltexit is required. This helps reduce the glue 1075 * code created for further auditing. 1076 */ 1077 if (called == 0) 1078 *flags |= (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT); 1079 1080 APPLICATION_RETURN(rtldflags); 1081 1082 return (nsym.st_value); 1083 } 1084 1085 /* 1086 * la_preinit() caller. Traverse through all audit libraries and call any 1087 * la_preinit() entry points found. 1088 */ 1089 static void 1090 _audit_preinit(APlist *list, Rt_map *clmp, Boolean client) 1091 { 1092 Audit_list *alp; 1093 Aliste idx; 1094 Lm_list *clml = LIST(clmp); 1095 1096 for (APLIST_TRAVERSE(list, idx, alp)) { 1097 Audit_client *acp; 1098 Rt_map *almp = alp->al_lmp; 1099 Lm_list *alml = LIST(almp); 1100 uintptr_t *cookie; 1101 1102 if (alp->al_preinit == 0) 1103 continue; 1104 1105 /* 1106 * Determine what cookie is required. Any auditing that 1107 * originates from the object that heads the link-map list has 1108 * its own cookie. Local auditors must obtain the cookie that 1109 * represents the object that heads the link-map list. 1110 */ 1111 if (client) 1112 acp = _audit_client(AUDINFO(clmp), almp); 1113 else 1114 acp = _audit_get_head_client(clml->lm_head, almp); 1115 1116 if (acp == NULL) 1117 continue; 1118 cookie = &(acp->ac_cookie); 1119 1120 DBG_CALL(Dbg_audit_preinit(clml, alp->al_libname, 1121 NAME(clml->lm_head))); 1122 1123 leave(alml, thr_flg_reenter); 1124 (*alp->al_preinit)(cookie); 1125 (void) enter(thr_flg_reenter); 1126 } 1127 } 1128 1129 void 1130 audit_preinit(Rt_map *mlmp) 1131 { 1132 Rt_map *clmp; 1133 Aliste idx; 1134 uint_t rtldflags; 1135 1136 if (rt_critical()) 1137 return; 1138 1139 APPLICATION_ENTER(rtldflags); 1140 1141 if (auditors && (auditors->ad_flags & LML_TFLG_AUD_PREINIT)) 1142 _audit_preinit(auditors->ad_list, mlmp, TRUE); 1143 1144 if (AUDITORS(mlmp) && (AUDITORS(mlmp)->ad_flags & LML_TFLG_AUD_PREINIT)) 1145 _audit_preinit(AUDITORS(mlmp)->ad_list, mlmp, TRUE); 1146 1147 for (APLIST_TRAVERSE(aud_preinit, idx, clmp)) { 1148 if (AUDITORS(clmp) && 1149 (AUDITORS(clmp)->ad_flags & LML_TFLG_AUD_PREINIT)) 1150 _audit_preinit(AUDITORS(clmp)->ad_list, clmp, FALSE); 1151 } 1152 1153 APPLICATION_RETURN(rtldflags); 1154 } 1155 1156 /* 1157 * Clean up (free) an audit descriptor. First, gather a list of all handles, 1158 * and then close each one down. This is done rather than using the handles 1159 * directly from the auditors, as the audit list can be torn down as a result 1160 * of the dlclose. In other words, what you're pointing at can be removed 1161 * while you're still pointing at it. 1162 */ 1163 void 1164 audit_desc_cleanup(Rt_map *clmp) 1165 { 1166 Audit_desc *adp = AUDITORS(clmp); 1167 Audit_list *alp; 1168 Aliste idx; 1169 APlist *ghalp = NULL; 1170 1171 if (adp == NULL) 1172 return; 1173 if (adp->ad_name) 1174 free(adp->ad_name); 1175 1176 for (APLIST_TRAVERSE(adp->ad_list, idx, alp)) 1177 (void) aplist_append(&ghalp, alp->al_ghp, AL_CNT_GROUPS); 1178 1179 free(adp->ad_list); 1180 adp->ad_list = NULL; 1181 1182 free(adp); 1183 1184 /* 1185 * Indicate that the caller is no longer being audited. 1186 */ 1187 AUDITORS(clmp) = NULL; 1188 AFLAGS(clmp) &= ~LML_TFLG_AUD_MASK; 1189 1190 if (ghalp) { 1191 Grp_hdl *ghp; 1192 Aliste idx; 1193 1194 for (APLIST_TRAVERSE(ghalp, idx, ghp)) { 1195 (void) dlclose_intn(ghp, clmp); 1196 } 1197 free(ghalp); 1198 } 1199 } 1200 1201 /* 1202 * Objects that establish local auditors may have been added to preinit or 1203 * activity lists. Remove the object from this list if it is present. 1204 */ 1205 static void 1206 remove_auditor(APlist *alp, Rt_map *clmp) 1207 { 1208 Rt_map *lmp; 1209 Aliste idx; 1210 1211 for (APLIST_TRAVERSE(alp, idx, lmp)) { 1212 if (lmp == clmp) { 1213 aplist_delete(alp, &idx); 1214 return; 1215 } 1216 } 1217 } 1218 1219 /* 1220 * Clean up (free) an audit information structure. 1221 */ 1222 void 1223 audit_info_cleanup(Rt_map *clmp) 1224 { 1225 Audit_info *aip = AUDINFO(clmp); 1226 1227 if (aip == NULL) 1228 return; 1229 1230 if (aip->ai_dynplts) 1231 free(aip->ai_dynplts); 1232 1233 if (aud_preinit) 1234 remove_auditor(aud_preinit, clmp); 1235 if (aud_activity) 1236 remove_auditor(aud_activity, clmp); 1237 1238 free(aip); 1239 } 1240 1241 /* 1242 * Create a data structure of symbol lookup names and associated flags to help 1243 * simplify audit_symget() use. 1244 */ 1245 typedef struct { 1246 Msg sname; 1247 uint_t alflag; 1248 uint_t auflag; 1249 } Aud_info; 1250 1251 static const Aud_info aud_info[] = { 1252 { MSG_SYM_LAVERSION, 0, 0 }, /* MSG_ORIG(MSG_SYM_LAVERSION) */ 1253 { MSG_SYM_LAPREINIT, /* MSG_ORIG(MSG_SYM_LAPREINIT) */ 1254 LML_TFLG_AUD_PREINIT, 0 }, 1255 { MSG_SYM_LAOBJSEARCH, /* MSG_ORIG(MSG_SYM_LAOBJSEARCH) */ 1256 LML_TFLG_AUD_OBJSEARCH, 0 }, 1257 { MSG_SYM_LAOBJOPEN, /* MSG_ORIG(MSG_SYM_LAOBJOPEN) */ 1258 LML_TFLG_AUD_OBJOPEN, 0 }, 1259 { MSG_SYM_LAOBJFILTER, /* MSG_ORIG(MSG_SYM_LAOBJFILTER */ 1260 LML_TFLG_AUD_OBJFILTER, 0 }, 1261 { MSG_SYM_LAOBJCLOSE, /* MSG_ORIG(MSG_SYM_LAOBJCLOSE) */ 1262 LML_TFLG_AUD_OBJCLOSE, 0 }, 1263 { MSG_SYM_LAACTIVITY, /* MSG_ORIG(MSG_SYM_LAACTIVITY) */ 1264 LML_TFLG_AUD_ACTIVITY, 0 }, 1265 1266 #if defined(_ELF64) 1267 { MSG_SYM_LASYMBIND_64, /* MSG_ORIG(MSG_SYM_LASYMBIND_64) */ 1268 #else 1269 { MSG_SYM_LASYMBIND, /* MSG_ORIG(MSG_SYM_LASYMBIND) */ 1270 #endif 1271 LML_TFLG_AUD_SYMBIND, 0 }, 1272 1273 #if defined(__sparcv9) 1274 { MSG_SYM_LAV9PLTENTER, /* MSG_ORIG(MSG_SYM_LAV9PLTENTER) */ 1275 #elif defined(__sparc) 1276 { MSG_SYM_LAV8PLTENTER, /* MSG_ORIG(MSG_SYM_LAV8PLTENTER) */ 1277 #elif defined(__amd64) 1278 { MSG_SYM_LAAMD64PLTENTER, /* MSG_ORIG(MSG_SYM_LAAMD64PLTENTER) */ 1279 #elif defined(__i386) 1280 { MSG_SYM_LAX86PLTENTER, /* MSG_ORIG(MSG_SYM_LAX86PLTENTER) */ 1281 #else 1282 #error platform not defined! 1283 #endif 1284 LML_TFLG_AUD_PLTENTER, AF_PLTENTER }, 1285 1286 #if defined(_ELF64) 1287 { MSG_SYM_LAPLTEXIT_64, /* MSG_ORIG(MSG_SYM_LAPLTEXIT_64) */ 1288 #else 1289 { MSG_SYM_LAPLTEXIT, /* MSG_ORIG(MSG_SYM_LAPLTEXIT) */ 1290 #endif 1291 LML_TFLG_AUD_PLTEXIT, AF_PLTEXIT } 1292 }; 1293 1294 #define AI_LAVERSION 0 1295 #define AI_LAPREINIT 1 1296 #define AI_LAOBJSEARCH 2 1297 #define AI_LAOBJOPEN 3 1298 #define AI_LAOBJFILTER 4 1299 #define AI_LAOBJCLOSE 5 1300 #define AI_LAACTIVITY 6 1301 #define AI_LASYMBIND 7 1302 #define AI_LAPLTENTER 8 1303 #define AI_LAPLTEXIT 9 1304 1305 static Addr 1306 audit_symget(Audit_list *alp, int info, int *in_nfavl) 1307 { 1308 Rt_map *lmp = alp->al_lmp; 1309 const char *sname = MSG_ORIG(aud_info[info].sname); 1310 uint_t alflag = aud_info[info].alflag; 1311 uint_t auflag = aud_info[info].auflag; 1312 uint_t binfo; 1313 Slookup sl; 1314 Sresult sr; 1315 1316 /* 1317 * Initialize the symbol lookup, and symbol result, data structures. 1318 */ 1319 SLOOKUP_INIT(sl, sname, lml_rtld.lm_head, lmp, ld_entry_cnt, 1320 0, 0, 0, 0, (LKUP_FIRST | LKUP_DLSYM)); 1321 SRESULT_INIT(sr, sname); 1322 1323 if (LM_LOOKUP_SYM(lmp)(&sl, &sr, &binfo, in_nfavl)) { 1324 Addr addr = sr.sr_sym->st_value; 1325 1326 if (!(FLAGS(lmp) & FLG_RT_FIXED)) 1327 addr += ADDR(lmp); 1328 1329 if (alflag) 1330 alp->al_flags |= alflag; 1331 if (auflag) 1332 audit_flags |= auflag; 1333 1334 /* 1335 * Note, unlike most other diagnostics, where we wish to 1336 * identify the lmid of the caller, here we use the lmid of 1337 * the auditor itself to show the association of the auditor 1338 * and the interfaces it provides. 1339 */ 1340 DBG_CALL(Dbg_audit_interface(LIST(alp->al_lmp), 1341 alp->al_libname, sr.sr_name)); 1342 return (addr); 1343 } 1344 return (0); 1345 } 1346 1347 /* 1348 * Centralize cleanup routines. 1349 */ 1350 static int 1351 audit_disable(char *name, Rt_map *clmp, Grp_hdl *ghp, Audit_list *alp) 1352 { 1353 eprintf(LIST(clmp), ERR_FATAL, MSG_INTL(MSG_AUD_DISABLED), name); 1354 if (ghp) 1355 (void) dlclose_intn(ghp, clmp); 1356 if (alp) 1357 free(alp); 1358 1359 return (0); 1360 } 1361 1362 /* 1363 * Given a list of one or more audit libraries, open each one and establish a 1364 * a descriptor representing the entry points it provides. 1365 */ 1366 int 1367 audit_setup(Rt_map *clmp, Audit_desc *adp, uint_t orig, int *in_nfavl) 1368 { 1369 char *ptr, *next; 1370 Lm_list *clml = LIST(clmp); 1371 Rt_map *hlmp; 1372 int error = 1, activity = 0, preinit = 0; 1373 uint_t rtldflags; 1374 1375 /* 1376 * Determine the type of auditing for diagnostics. 1377 */ 1378 if (DBG_ENABLED) { 1379 int type; 1380 1381 if (orig & PD_FLG_EXTLOAD) 1382 type = DBG_AUD_PRELOAD; 1383 else if (FLAGS1(clmp) & FL1_RT_GLOBAUD) 1384 type = DBG_AUD_GLOBAL; 1385 else 1386 type = DBG_AUD_LOCAL; 1387 1388 DBG_CALL(Dbg_audit_lib(clmp, adp->ad_name, type)); 1389 } 1390 1391 /* 1392 * Mark that we have at least one auditing link map 1393 */ 1394 rtld_flags2 |= RT_FL2_HASAUDIT; 1395 1396 /* 1397 * The audit definitions may be a list (which will already have been 1398 * dupped) so split it into individual tokens. 1399 */ 1400 for (ptr = strtok_r(adp->ad_name, MSG_ORIG(MSG_STR_DELIMIT), &next); 1401 ptr; ptr = strtok_r(NULL, MSG_ORIG(MSG_STR_DELIMIT), &next)) { 1402 Grp_hdl *ghp; 1403 Rt_map *lmp; 1404 Lm_list *lml; 1405 Rt_map **tobj; 1406 Audit_list *alp; 1407 1408 DBG_CALL(Dbg_util_nl(clml, DBG_NL_STD)); 1409 1410 /* 1411 * Open the audit library on its own link-map. 1412 */ 1413 if ((ghp = dlmopen_intn((Lm_list *)LM_ID_NEWLM, ptr, 1414 (RTLD_FIRST | RTLD_GLOBAL | RTLD_WORLD), clmp, 1415 FLG_RT_AUDIT, orig)) == NULL) { 1416 error = audit_disable(ptr, clmp, 0, 0); 1417 continue; 1418 } 1419 lmp = ghp->gh_ownlmp; 1420 lml = LIST(lmp); 1421 1422 /* 1423 * If this auditor has already been loaded, reuse it. 1424 */ 1425 if ((alp = lml->lm_alp) != NULL) { 1426 if (aplist_append(&(adp->ad_list), alp, 1427 AL_CNT_AUDITORS) == NULL) 1428 return (audit_disable(ptr, clmp, ghp, alp)); 1429 1430 adp->ad_cnt++; 1431 adp->ad_flags |= alp->al_flags; 1432 1433 /* 1434 * If this existing auditor provides preinit or 1435 * activity routines, track their existence. The 1436 * instantiation of a local auditor requires a cookie 1437 * be created that represents the object that heads 1438 * the link-map list of the object being audited. 1439 */ 1440 if (alp->al_preinit) 1441 preinit++; 1442 if (alp->al_activity) 1443 activity++; 1444 1445 continue; 1446 } 1447 1448 /* 1449 * Prior to the Unified Process Model (UPM) environment, an 1450 * rtld lock had to be held upon leave(). However, even within 1451 * a UPM environment, an old auditor, that has a lazy dependency 1452 * on libc, is still a possibility. As libc isn't loaded, we 1453 * don't know the process model, and will determine this later. 1454 * Refer to external.c:get_lcinterface(). 1455 */ 1456 if ((rtld_flags2 & RT_FL2_UNIFPROC) == 0) 1457 lml->lm_flags |= LML_FLG_HOLDLOCK; 1458 1459 /* 1460 * Allocate an audit list descriptor for this object and 1461 * search for all known entry points. 1462 */ 1463 if ((alp = calloc(1, sizeof (Audit_list))) == NULL) 1464 return (audit_disable(ptr, clmp, ghp, 0)); 1465 1466 alp->al_libname = NAME(lmp); 1467 alp->al_lmp = lmp; 1468 alp->al_ghp = ghp; 1469 1470 /* 1471 * All audit libraries must handshake through la_version(). 1472 * Determine that the symbol exists, finish initializing the 1473 * object, and then call the function. 1474 */ 1475 if ((alp->al_version = (uint_t(*)())audit_symget(alp, 1476 AI_LAVERSION, in_nfavl)) == 0) { 1477 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_GEN_NOSYM), 1478 MSG_ORIG(MSG_SYM_LAVERSION)); 1479 error = audit_disable(ptr, clmp, ghp, alp); 1480 continue; 1481 } 1482 1483 if ((tobj = tsort(lmp, lml->lm_init, RT_SORT_REV)) == 1484 (Rt_map **)S_ERROR) 1485 return (audit_disable(ptr, clmp, ghp, alp)); 1486 1487 if (tobj) 1488 call_init(tobj, DBG_INIT_SORT); 1489 1490 APPLICATION_ENTER(rtldflags); 1491 leave(lml, thr_flg_reenter); 1492 alp->al_vernum = (*alp->al_version)(LAV_CURRENT); 1493 (void) enter(thr_flg_reenter); 1494 APPLICATION_RETURN(rtldflags); 1495 1496 DBG_CALL(Dbg_audit_version(clml, alp->al_libname, 1497 LAV_CURRENT, alp->al_vernum)); 1498 1499 if ((alp->al_vernum < LAV_VERSION1) || 1500 (alp->al_vernum > LAV_CURRENT)) { 1501 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_AUD_BADVERS), 1502 LAV_CURRENT, alp->al_vernum); 1503 error = audit_disable(ptr, clmp, ghp, alp); 1504 continue; 1505 } 1506 1507 if (aplist_append(&(adp->ad_list), alp, 1508 AL_CNT_AUDITORS) == NULL) 1509 return (audit_disable(ptr, clmp, ghp, alp)); 1510 1511 adp->ad_cnt++; 1512 1513 /* 1514 * Collect any remaining entry points. 1515 */ 1516 alp->al_objsearch = (char *(*)())audit_symget(alp, 1517 AI_LAOBJSEARCH, in_nfavl); 1518 alp->al_objopen = (uint_t(*)())audit_symget(alp, 1519 AI_LAOBJOPEN, in_nfavl); 1520 alp->al_objfilter = (int(*)())audit_symget(alp, 1521 AI_LAOBJFILTER, in_nfavl); 1522 alp->al_objclose = (uint_t(*)())audit_symget(alp, 1523 AI_LAOBJCLOSE, in_nfavl); 1524 alp->al_symbind = (uintptr_t(*)())audit_symget(alp, 1525 AI_LASYMBIND, in_nfavl); 1526 alp->al_pltenter = (uintptr_t(*)())audit_symget(alp, 1527 AI_LAPLTENTER, in_nfavl); 1528 alp->al_pltexit = (uintptr_t(*)())audit_symget(alp, 1529 AI_LAPLTEXIT, in_nfavl); 1530 1531 if ((alp->al_preinit = (void(*)())audit_symget(alp, 1532 AI_LAPREINIT, in_nfavl)) != NULL) 1533 preinit++; 1534 if ((alp->al_activity = (void(*)())audit_symget(alp, 1535 AI_LAACTIVITY, in_nfavl)) != NULL) 1536 activity++; 1537 1538 /* 1539 * Collect the individual object flags, and assign this audit 1540 * list descriptor to its associated link-map list. 1541 */ 1542 adp->ad_flags |= alp->al_flags; 1543 lml->lm_alp = alp; 1544 } 1545 1546 /* 1547 * If the caller isn't the head of its own link-map list, then any 1548 * preinit or activity entry points need to be tracked separately. 1549 * These "events" are not associated with a particular link-map, and 1550 * thus a traversal of any existing preinit and activity clients is 1551 * required. 1552 * 1553 * If either of these events are required, establish a cookie for the 1554 * object at the head of the link-map list, and make an initial ADD 1555 * activity for these local auditors. 1556 */ 1557 if ((preinit || activity) && ((hlmp = clml->lm_head) != clmp) && 1558 (_audit_add_head(clmp, hlmp, preinit, activity) == 0)) 1559 return (0); 1560 1561 /* 1562 * Free the original audit string, as this descriptor may be used again 1563 * to add additional auditing. 1564 */ 1565 free(adp->ad_name); 1566 adp->ad_name = NULL; 1567 1568 return (error); 1569 } 1570