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 }