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