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