1RTLD-AUDIT(7)          Miscellaneous Information Manual          RTLD-AUDIT(7)
2
3
4

NAME

6       rtld-audit - auditing API for the dynamic linker
7

SYNOPSIS

9       #define _GNU_SOURCE             /* See feature_test_macros(7) */
10       #include <link.h>
11

DESCRIPTION

13       The  GNU dynamic linker (run-time linker) provides an auditing API that
14       allows an application to  be  notified  when  various  dynamic  linking
15       events  occur.  This API is very similar to the auditing interface pro‐
16       vided by the Solaris run-time linker.  The necessary constants and pro‐
17       totypes are defined by including <link.h>.
18
19       To use this interface, the programmer creates a shared library that im‐
20       plements a standard set of function names.  Not all  of  the  functions
21       need  to be implemented: in most cases, if the programmer is not inter‐
22       ested in a particular class of auditing event, then  no  implementation
23       needs to be provided for the corresponding auditing function.
24
25       To  employ  the  auditing  interface, the environment variable LD_AUDIT
26       must be defined to contain a colon-separated list of shared  libraries,
27       each  of  which can implement (parts of) the auditing API.  When an au‐
28       ditable event occurs, the corresponding function is invoked in each li‐
29       brary, in the order that the libraries are listed.
30
31   la_version()
32
33       unsigned int la_version(unsigned int version);
34
35       This  is the only function that must be defined by an auditing library:
36       it performs the initial handshake between the dynamic  linker  and  the
37       auditing  library.   When  invoking  this  function, the dynamic linker
38       passes, in version, the highest version of the auditing interface  that
39       the linker supports.
40
41       A  typical  implementation of this function simply returns the constant
42       LAV_CURRENT, which indicates the version of <link.h> that was  used  to
43       build  the  audit  module.  If the dynamic linker does not support this
44       version of the audit interface, it will refuse to activate  this  audit
45       module.  If the function returns zero, the dynamic linker also does not
46       activate this audit module.
47
48       In order to enable backwards compatibility with older dynamic  linkers,
49       an  audit module can examine the version argument and return an earlier
50       version than LAV_CURRENT, assuming the module can adjust its  implemen‐
51       tation  to  match the requirements of the previous version of the audit
52       interface.  The la_version function should not return the value of ver‐
53       sion without further checks because it could correspond to an interface
54       that does not match the <link.h> definitions used to  build  the  audit
55       module.
56
57   la_objsearch()
58
59       char *la_objsearch(const char *name, uintptr_t *cookie,
60                          unsigned int flag);
61
62       The dynamic linker invokes this function to inform the auditing library
63       that it is about to search for a shared object.  The name  argument  is
64       the filename or pathname that is to be searched for.  cookie identifies
65       the shared object that initiated the search.  flag is set to one of the
66       following values:
67
68       LA_SER_ORIG      This  is the original name that is being searched for.
69                        Typically, this name comes from an ELF  DT_NEEDED  en‐
70                        try, or is the filename argument given to dlopen(3).
71
72       LA_SER_LIBPATH   name was created using a directory specified in LD_LI‐
73                        BRARY_PATH.
74
75       LA_SER_RUNPATH   name was created using a directory specified in an ELF
76                        DT_RPATH or DT_RUNPATH list.
77
78       LA_SER_CONFIG    name    was    found   via   the   ldconfig(8)   cache
79                        (/etc/ld.so.cache).
80
81       LA_SER_DEFAULT   name was found via a search of one of the default  di‐
82                        rectories.
83
84       LA_SER_SECURE    name is specific to a secure object (unused on Linux).
85
86       As  its  function  result, la_objsearch() returns the pathname that the
87       dynamic linker should use for further processing.  If NULL is returned,
88       then  this  pathname  is ignored for further processing.  If this audit
89       library simply intends to monitor search paths, then name should be re‐
90       turned.
91
92   la_activity()
93
94       void la_activity( uintptr_t *cookie, unsigned int flag);
95
96       The  dynamic  linker calls this function to inform the auditing library
97       that link-map activity is occurring.  cookie identifies the  object  at
98       the  head  of the link map.  When the dynamic linker invokes this func‐
99       tion, flag is set to one of the following values:
100
101       LA_ACT_ADD         New objects are being added to the link map.
102
103       LA_ACT_DELETE      Objects are being removed from the link map.
104
105       LA_ACT_CONSISTENT  Link-map activity has been  completed:  the  map  is
106                          once again consistent.
107
108   la_objopen()
109
110       unsigned int la_objopen(struct link_map *map, Lmid_t lmid,
111                               uintptr_t *cookie);
112
113       The  dynamic  linker  calls  this  function when a new shared object is
114       loaded.  The map argument is a pointer to a link-map structure that de‐
115       scribes the object.  The lmid field has one of the following values
116
117       LM_ID_BASE       Link map is part of the initial namespace.
118
119       LM_ID_NEWLM      Link  map is part of a new namespace requested via dl‐
120                        mopen(3).
121
122       cookie is a pointer to an identifier for this object.   The  identifier
123       is  provided to later calls to functions in the auditing library in or‐
124       der to identify this object.  This identifier is initialized  to  point
125       to  object's  link map, but the audit library can change the identifier
126       to some other value that it may prefer to use to identify the object.
127
128       As its return value, la_objopen() returns a bit mask created  by  ORing
129       zero  or  more of the following constants, which allow the auditing li‐
130       brary to select the objects to be monitored by la_symbind*():
131
132       LA_FLG_BINDTO    Audit symbol bindings to this object.
133
134       LA_FLG_BINDFROM  Audit symbol bindings from this object.
135
136       A return value of 0 from la_objopen() indicates that no symbol bindings
137       should be audited for this object.
138
139   la_objclose()
140
141       unsigned int la_objclose(uintptr_t *cookie);
142
143       The  dynamic  linker  invokes this function after any finalization code
144       for the object has been executed, before the object is  unloaded.   The
145       cookie  argument  is the identifier obtained from a previous invocation
146       of la_objopen().
147
148       In the current implementation, the value returned by  la_objclose()  is
149       ignored.
150
151   la_preinit()
152
153       void la_preinit(uintptr_t *cookie);
154
155       The  dynamic linker invokes this function after all shared objects have
156       been loaded, before control is passed to the application (i.e.,  before
157       calling main()).  Note that main() may still later dynamically load ob‐
158       jects using dlopen(3).
159
160   la_symbind*()
161
162       uintptr_t la_symbind32(Elf32_Sym *sym, unsigned int ndx,
163                              uintptr_t *refcook, uintptr_t *defcook,
164                              unsigned int *flags, const char *symname);
165       uintptr_t la_symbind64(Elf64_Sym *sym, unsigned int ndx,
166                              uintptr_t *refcook, uintptr_t *defcook,
167                              unsigned int *flags, const char *symname);
168
169       The dynamic linker invokes one of these functions when a symbol binding
170       occurs  between  two  shared objects that have been marked for auditing
171       notification by la_objopen().  The la_symbind32() function is  employed
172       on  32-bit platforms; the la_symbind64() function is employed on 64-bit
173       platforms.
174
175       The sym argument is a pointer to a structure that provides  information
176       about  the  symbol  being  bound.  The structure definition is shown in
177       <elf.h>.  Among the fields of this structure,  st_value  indicates  the
178       address to which the symbol is bound.
179
180       The  ndx  argument gives the index of the symbol in the symbol table of
181       the bound shared object.
182
183       The refcook argument identifies the shared object that  is  making  the
184       symbol  reference;  this is the same identifier that is provided to the
185       la_objopen() function that returned LA_FLG_BINDFROM.  The defcook argu‐
186       ment  identifies  the shared object that defines the referenced symbol;
187       this is the same identifier that is provided to the la_objopen()  func‐
188       tion that returned LA_FLG_BINDTO.
189
190       The symname argument points a string containing the name of the symbol.
191
192       The  flags  argument is a bit mask that both provides information about
193       the symbol and can be used to modify further auditing of this PLT (Pro‐
194       cedure Linkage Table) entry.  The dynamic linker may supply the follow‐
195       ing bit values in this argument:
196
197       LA_SYMB_DLSYM         The binding resulted from a call to dlsym(3).
198
199       LA_SYMB_ALTVALUE      A previous la_symbind*() call returned an  alter‐
200                             nate value for this symbol.
201
202       By default, if the auditing library implements la_pltenter() and la_pl‐
203       texit() functions (see below), then these functions are invoked,  after
204       la_symbind(), for PLT entries, each time the symbol is referenced.  The
205       following flags can be ORed into *flags to change this  default  behav‐
206       ior:
207
208       LA_SYMB_NOPLTENTER    Don't call la_pltenter() for this symbol.
209
210       LA_SYMB_NOPLTEXIT     Don't call la_pltexit() for this symbol.
211
212       The return value of la_symbind32() and la_symbind64() is the address to
213       which control should be passed after the function returns.  If the  au‐
214       diting library is simply monitoring symbol bindings, then it should re‐
215       turn sym->st_value.  A different value may be returned if  the  library
216       wishes to direct control to an alternate location.
217
218   la_pltenter()
219       The  precise  name  and  argument types for this function depend on the
220       hardware  platform.   (The  appropriate  definition  is   supplied   by
221       <link.h>.)  Here is the definition for x86-32:
222
223       Elf32_Addr la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
224                        uintptr_t *refcook, uintptr_t *defcook,
225                        La_i86_regs *regs, unsigned int *flags,
226                        const char *symname, long *framesizep);
227
228       This function is invoked just before a PLT entry is called, between two
229       shared objects that have been marked for binding notification.
230
231       The sym, ndx, refcook, defcook, and symname are as for la_symbind*().
232
233       The regs argument points to a structure (defined in <link.h>)  contain‐
234       ing the values of registers to be used for the call to this PLT entry.
235
236       The flags argument points to a bit mask that conveys information about,
237       and can be used to modify subsequent auditing of, this  PLT  entry,  as
238       for la_symbind*().
239
240       The framesizep argument points to a long int buffer that can be used to
241       explicitly set the frame size used for the call to this PLT entry.   If
242       different  la_pltenter()  invocations  for this symbol return different
243       values, then the maximum returned  value  is  used.   The  la_pltexit()
244       function  is called only if this buffer is explicitly set to a suitable
245       value.
246
247       The return value of la_pltenter() is as for la_symbind*().
248
249   la_pltexit()
250       The precise name and argument types for this  function  depend  on  the
251       hardware   platform.    (The  appropriate  definition  is  supplied  by
252       <link.h>.)  Here is the definition for x86-32:
253
254       unsigned int la_i86_gnu_pltexit(Elf32_Sym *sym, unsigned int ndx,
255                        uintptr_t *refcook, uintptr_t *defcook,
256                        const La_i86_regs *inregs, La_i86_retval *outregs,
257                        const char *symname);
258
259       This function is called when a PLT entry, made between two  shared  ob‐
260       jects  that  have  been  marked for binding notification, returns.  The
261       function is called just before control returns to the caller of the PLT
262       entry.
263
264       The sym, ndx, refcook, defcook, and symname are as for la_symbind*().
265
266       The  inregs  argument  points to a structure (defined in <link.h>) con‐
267       taining the values of registers used for the call to  this  PLT  entry.
268       The  outregs  argument points to a structure (defined in <link.h>) con‐
269       taining return values for the call to this PLT entry.  These values can
270       be  modified  by  the  caller,  and  the changes will be visible to the
271       caller of the PLT entry.
272
273       In the current GNU implementation, the return value of la_pltexit()  is
274       ignored.
275

VERSIONS

277       This  API  is  very similar to the Solaris API described in the Solaris
278       Linker and Libraries Guide, in the chapter Runtime Linker Auditing  In‐
279       terface.
280

STANDARDS

282       None.
283

NOTES

285       Note the following differences from the Solaris dynamic linker auditing
286       API:
287
288       •  The Solaris la_objfilter() interface is not supported by the GNU im‐
289          plementation.
290
291       •  The Solaris la_symbind32() and la_pltexit() functions do not provide
292          a symname argument.
293
294       •  The Solaris la_pltexit() function does not provide inregs  and  out‐
295          regs arguments (but does provide a retval argument with the function
296          return value).
297

BUGS

299       In glibc versions up to and include 2.9, specifying more than one audit
300       library  in  LD_AUDIT  results in a run-time crash.  This is reportedly
301       fixed in glibc 2.10.
302

EXAMPLES

304       #include <link.h>
305       #include <stdio.h>
306
307       unsigned int
308       la_version(unsigned int version)
309       {
310           printf("la_version(): version = %u; LAV_CURRENT = %u\n",
311                   version, LAV_CURRENT);
312
313           return LAV_CURRENT;
314       }
315
316       char *
317       la_objsearch(const char *name, uintptr_t *cookie, unsigned int flag)
318       {
319           printf("la_objsearch(): name = %s; cookie = %p", name, cookie);
320           printf("; flag = %s\n",
321                   (flag == LA_SER_ORIG) ?    "LA_SER_ORIG" :
322                   (flag == LA_SER_LIBPATH) ? "LA_SER_LIBPATH" :
323                   (flag == LA_SER_RUNPATH) ? "LA_SER_RUNPATH" :
324                   (flag == LA_SER_DEFAULT) ? "LA_SER_DEFAULT" :
325                   (flag == LA_SER_CONFIG) ?  "LA_SER_CONFIG" :
326                   (flag == LA_SER_SECURE) ?  "LA_SER_SECURE" :
327                   "???");
328
329           return name;
330       }
331
332       void
333       la_activity (uintptr_t *cookie, unsigned int flag)
334       {
335           printf("la_activity(): cookie = %p; flag = %s\n", cookie,
336                   (flag == LA_ACT_CONSISTENT) ? "LA_ACT_CONSISTENT" :
337                   (flag == LA_ACT_ADD) ?        "LA_ACT_ADD" :
338                   (flag == LA_ACT_DELETE) ?     "LA_ACT_DELETE" :
339                   "???");
340       }
341
342       unsigned int
343       la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
344       {
345           printf("la_objopen(): loading \"%s\"; lmid = %s; cookie=%p\n",
346                   map->l_name,
347                   (lmid == LM_ID_BASE) ?  "LM_ID_BASE" :
348                   (lmid == LM_ID_NEWLM) ? "LM_ID_NEWLM" :
349                   "???",
350                   cookie);
351
352           return LA_FLG_BINDTO | LA_FLG_BINDFROM;
353       }
354
355       unsigned int
356       la_objclose (uintptr_t *cookie)
357       {
358           printf("la_objclose(): %p\n", cookie);
359
360           return 0;
361       }
362
363       void
364       la_preinit(uintptr_t *cookie)
365       {
366           printf("la_preinit(): %p\n", cookie);
367       }
368
369       uintptr_t
370       la_symbind32(Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
371               uintptr_t *defcook, unsigned int *flags, const char *symname)
372       {
373           printf("la_symbind32(): symname = %s; sym->st_value = %p\n",
374                   symname, sym->st_value);
375           printf("        ndx = %u; flags = %#x", ndx, *flags);
376           printf("; refcook = %p; defcook = %p\n", refcook, defcook);
377
378           return sym->st_value;
379       }
380
381       uintptr_t
382       la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
383               uintptr_t *defcook, unsigned int *flags, const char *symname)
384       {
385           printf("la_symbind64(): symname = %s; sym->st_value = %p\n",
386                   symname, sym->st_value);
387           printf("        ndx = %u; flags = %#x", ndx, *flags);
388           printf("; refcook = %p; defcook = %p\n", refcook, defcook);
389
390           return sym->st_value;
391       }
392
393       Elf32_Addr
394       la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
395               uintptr_t *refcook, uintptr_t *defcook, La_i86_regs *regs,
396               unsigned int *flags, const char *symname, long *framesizep)
397       {
398           printf("la_i86_gnu_pltenter(): %s (%p)\n", symname, sym->st_value);
399
400           return sym->st_value;
401       }
402

SEE ALSO

404       ldd(1), dlopen(3), ld.so(8), ldconfig(8)
405
406
407
408Linux man-pages 6.04              2023-03-30                     RTLD-AUDIT(7)
Impressum