1RTLD-AUDIT(7) Miscellaneous Information Manual RTLD-AUDIT(7)
2
3
4
6 rtld-audit - auditing API for the dynamic linker
7
9 #define _GNU_SOURCE /* See feature_test_macros(7) */
10 #include <link.h>
11
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
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
282 None.
283
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
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
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
404 ldd(1), dlopen(3), ld.so(8), ldconfig(8)
405
406
407
408Linux man-pages 6.05 2023-05-03 RTLD-AUDIT(7)