1RTLD-AUDIT(7) Linux Programmer's 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
20 implements 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
28 auditable event occurs, the corresponding function is invoked in each
29 library, 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. If necessary, the auditing library can check that
40 this version is sufficient for its requirements.
41
42 As its function result, this function should return the version of the
43 auditing interface that this auditing library expects to use (returning
44 version is acceptable). If the returned value is 0, or a version that
45 is greater than that supported by the dynamic linker, then the audit
46 library is ignored.
47
48 la_objsearch()
49
50 char *la_objsearch(const char *name, uintptr_t *cookie,
51 unsigned int flag);
52
53 The dynamic linker invokes this function to inform the auditing library
54 that it is about to search for a shared object. The name argument is
55 the filename or pathname that is to be searched for. cookie identifies
56 the shared object that initiated the search. flag is set to one of the
57 following values:
58
59 LA_SER_ORIG This is the original name that is being searched for.
60 Typically, this name comes from an ELF DT_NEEDED
61 entry, or is the filename argument given to dlopen(3).
62
63 LA_SER_LIBPATH name was created using a directory specified in
64 LD_LIBRARY_PATH.
65
66 LA_SER_RUNPATH name was created using a directory specified in an ELF
67 DT_RPATH or DT_RUNPATH list.
68
69 LA_SER_CONFIG name was found via the ldconfig(8) cache
70 (/etc/ld.so.cache).
71
72 LA_SER_DEFAULT name was found via a search of one of the default
73 directories.
74
75 LA_SER_SECURE name is specific to a secure object (unused on Linux).
76
77 As its function result, la_objsearch() returns the pathname that the
78 dynamic linker should use for further processing. If NULL is returned,
79 then this pathname is ignored for further processing. If this audit
80 library simply intends to monitor search paths, then name should be
81 returned.
82
83 la_activity()
84
85 void la_activity( uintptr_t *cookie, unsigned int flag);
86
87 The dynamic linker calls this function to inform the auditing library
88 that link-map activity is occurring. cookie identifies the object at
89 the head of the link map. When the dynamic linker invokes this func‐
90 tion, flag is set to one of the following values:
91
92 LA_ACT_ADD New objects are being added to the link map.
93
94 LA_ACT_DELETE Objects are being removed from the link map.
95
96 LA_ACT_CONSISTENT Link-map activity has been completed: the map is
97 once again consistent.
98
99 la_objopen()
100
101 unsigned int la_objopen(struct link_map *map, Lmid_t lmid,
102 uintptr_t *cookie);
103
104 The dynamic linker calls this function when a new shared object is
105 loaded. The map argument is a pointer to a link-map structure that
106 describes the object. The lmid field has one of the following values
107
108 LM_ID_BASE Link map is part of the initial namespace.
109
110 LM_ID_NEWLM Link map is part of a new namespace requested via
111 dlmopen(3).
112
113 cookie is a pointer to an identifier for this object. The identifier
114 is provided to later calls to functions in the auditing library in
115 order to identify this object. This identifier is initialized to point
116 to object's link map, but the audit library can change the identifier
117 to some other value that it may prefer to use to identify the object.
118
119 As its return value, la_objopen() returns a bit mask created by ORing
120 zero or more of the following constants, which allow the auditing
121 library to select the objects to be monitored by la_symbind*():
122
123 LA_FLG_BINDTO Audit symbol bindings to this object.
124
125 LA_FLG_BINDFROM Audit symbol bindings from this object.
126
127 A return value of 0 from la_objopen() indicates that no symbol bindings
128 should be audited for this object.
129
130 la_objclose()
131
132 unsigned int la_objclose(uintptr_t *cookie);
133
134 The dynamic linker invokes this function after any finalization code
135 for the object has been executed, before the object is unloaded. The
136 cookie argument is the identifier obtained from a previous invocation
137 of la_objopen().
138
139 In the current implementation, the value returned by la_objclose() is
140 ignored.
141
142 la_preinit()
143
144 void la_preinit(uintptr_t *cookie);
145
146 The dynamic linker invokes this function after all shared objects have
147 been loaded, before control is passed to the application (i.e., before
148 calling main()). Note that main() may still later dynamically load
149 objects using dlopen(3).
150
151 la_symbind*()
152
153 uintptr_t la_symbind32(Elf32_Sym *sym, unsigned int ndx,
154 uintptr_t *refcook, uintptr_t *defcook,
155 unsigned int *flags, const char *symname);
156 uintptr_t la_symbind64(Elf64_Sym *sym, unsigned int ndx,
157 uintptr_t *refcook, uintptr_t *defcook,
158 unsigned int *flags, const char *symname);
159
160 The dynamic linker invokes one of these functions when a symbol binding
161 occurs between two shared objects that have been marked for auditing
162 notification by la_objopen(). The la_symbind32() function is employed
163 on 32-bit platforms; the la_symbind64() function is employed on 64-bit
164 platforms.
165
166 The sym argument is a pointer to a structure that provides information
167 about the symbol being bound. The structure definition is shown in
168 <elf.h>. Among the fields of this structure, st_value indicates the
169 address to which the symbol is bound.
170
171 The ndx argument gives the index of the symbol in the symbol table of
172 the bound shared object.
173
174 The refcook argument identifies the shared object that is making the
175 symbol reference; this is the same identifier that is provided to the
176 la_objopen() function that returned LA_FLG_BINDFROM. The defcook argu‐
177 ment identifies the shared object that defines the referenced symbol;
178 this is the same identifier that is provided to the la_objopen() func‐
179 tion that returned LA_FLG_BINDTO.
180
181 The symname argument points a string containing the name of the symbol.
182
183 The flags argument is a bit mask that both provides information about
184 the symbol and can be used to modify further auditing of this PLT (Pro‐
185 cedure Linkage Table) entry. The dynamic linker may supply the follow‐
186 ing bit values in this argument:
187
188 LA_SYMB_DLSYM The binding resulted from a call to dlsym(3).
189
190 LA_SYMB_ALTVALUE A previous la_symbind*() call returned an alter‐
191 nate value for this symbol.
192
193 By default, if the auditing library implements la_pltenter() and
194 la_pltexit() functions (see below), then these functions are invoked,
195 after la_symbind(), for PLT entries, each time the symbol is refer‐
196 enced. The following flags can be ORed into *flags to change this
197 default behavior:
198
199 LA_SYMB_NOPLTENTER Don't call la_pltenter() for this symbol.
200
201 LA_SYMB_NOPLTEXIT Don't call la_pltexit() for this symbol.
202
203 The return value of la_symbind32() and la_symbind64() is the address to
204 which control should be passed after the function returns. If the
205 auditing library is simply monitoring symbol bindings, then it should
206 return sym->st_value. A different value may be returned if the library
207 wishes to direct control to an alternate location.
208
209 la_pltenter()
210 The precise name and argument types for this function depend on the
211 hardware platform. (The appropriate definition is supplied by
212 <link.h>.) Here is the definition for x86-32:
213
214 Elf32_Addr la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
215 uintptr_t *refcook, uintptr_t *defcook,
216 La_i86_regs *regs, unsigned int *flags,
217 const char *symname, long int *framesizep);
218
219 This function is invoked just before a PLT entry is called, between two
220 shared objects that have been marked for binding notification.
221
222 The sym, ndx, refcook, defcook, and symname are as for la_symbind*().
223
224 The regs argument points to a structure (defined in <link.h>) contain‐
225 ing the values of registers to be used for the call to this PLT entry.
226
227 The flags argument points to a bit mask that conveys information about,
228 and can be used to modify subsequent auditing of, this PLT entry, as
229 for la_symbind*().
230
231 The framesizep argument points to a long int buffer that can be used to
232 explicitly set the frame size used for the call to this PLT entry. If
233 different la_pltenter() invocations for this symbol return different
234 values, then the maximum returned value is used. The la_pltexit()
235 function is called only if this buffer is explicitly set to a suitable
236 value.
237
238 The return value of la_pltenter() is as for la_symbind*().
239
240 la_pltexit()
241 The precise name and argument types for this function depend on the
242 hardware platform. (The appropriate definition is supplied by
243 <link.h>.) Here is the definition for x86-32:
244
245 unsigned int la_i86_gnu_pltexit(Elf32_Sym *sym, unsigned int ndx,
246 uintptr_t *refcook, uintptr_t *defcook,
247 const La_i86_regs *inregs, La_i86_retval *outregs,
248 const char *symname);
249
250 This function is called when a PLT entry, made between two shared
251 objects that have been marked for binding notification, returns. The
252 function is called just before control returns to the caller of the PLT
253 entry.
254
255 The sym, ndx, refcook, defcook, and symname are as for la_symbind*().
256
257 The inregs argument points to a structure (defined in <link.h>) con‐
258 taining the values of registers used for the call to this PLT entry.
259 The outregs argument points to a structure (defined in <link.h>) con‐
260 taining return values for the call to this PLT entry. These values can
261 be modified by the caller, and the changes will be visible to the call‐
262 er of the PLT entry.
263
264 In the current GNU implementation, the return value of la_pltexit() is
265 ignored.
266
268 This API is nonstandard, but very similar to the Solaris API, described
269 in the Solaris Linker and Libraries Guide, in the chapter Runtime
270 Linker Auditing Interface.
271
273 Note the following differences from the Solaris dynamic linker auditing
274 API:
275
276 * The Solaris la_objfilter() interface is not supported by the GNU
277 implementation.
278
279 * The Solaris la_symbind32() and la_pltexit() functions do not provide
280 a symname argument.
281
282 * The Solaris la_pltexit() function does not provide inregs and out‐
283 regs arguments (but does provide a retval argument with the function
284 return value).
285
287 In glibc versions up to and include 2.9, specifying more than one audit
288 library in LD_AUDIT results in a run-time crash. This is reportedly
289 fixed in glibc 2.10.
290
292 #include <link.h>
293 #include <stdio.h>
294
295 unsigned int
296 la_version(unsigned int version)
297 {
298 printf("la_version(): %d\n", version);
299
300 return version;
301 }
302
303 char *
304 la_objsearch(const char *name, uintptr_t *cookie, unsigned int flag)
305 {
306 printf("la_objsearch(): name = %s; cookie = %p", name, cookie);
307 printf("; flag = %s\n",
308 (flag == LA_SER_ORIG) ? "LA_SER_ORIG" :
309 (flag == LA_SER_LIBPATH) ? "LA_SER_LIBPATH" :
310 (flag == LA_SER_RUNPATH) ? "LA_SER_RUNPATH" :
311 (flag == LA_SER_DEFAULT) ? "LA_SER_DEFAULT" :
312 (flag == LA_SER_CONFIG) ? "LA_SER_CONFIG" :
313 (flag == LA_SER_SECURE) ? "LA_SER_SECURE" :
314 "???");
315
316 return name;
317 }
318
319 void
320 la_activity (uintptr_t *cookie, unsigned int flag)
321 {
322 printf("la_activity(): cookie = %p; flag = %s\n", cookie,
323 (flag == LA_ACT_CONSISTENT) ? "LA_ACT_CONSISTENT" :
324 (flag == LA_ACT_ADD) ? "LA_ACT_ADD" :
325 (flag == LA_ACT_DELETE) ? "LA_ACT_DELETE" :
326 "???");
327 }
328
329 unsigned int
330 la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
331 {
332 printf("la_objopen(): loading \"%s\"; lmid = %s; cookie=%p\n",
333 map->l_name,
334 (lmid == LM_ID_BASE) ? "LM_ID_BASE" :
335 (lmid == LM_ID_NEWLM) ? "LM_ID_NEWLM" :
336 "???",
337 cookie);
338
339 return LA_FLG_BINDTO | LA_FLG_BINDFROM;
340 }
341
342 unsigned int
343 la_objclose (uintptr_t *cookie)
344 {
345 printf("la_objclose(): %p\n", cookie);
346
347 return 0;
348 }
349
350 void
351 la_preinit(uintptr_t *cookie)
352 {
353 printf("la_preinit(): %p\n", cookie);
354 }
355
356 uintptr_t
357 la_symbind32(Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
358 uintptr_t *defcook, unsigned int *flags, const char *symname)
359 {
360 printf("la_symbind32(): symname = %s; sym->st_value = %p\n",
361 symname, sym->st_value);
362 printf(" ndx = %d; flags = 0x%x", ndx, *flags);
363 printf("; refcook = %p; defcook = %p\n", refcook, defcook);
364
365 return sym->st_value;
366 }
367
368 uintptr_t
369 la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
370 uintptr_t *defcook, unsigned int *flags, const char *symname)
371 {
372 printf("la_symbind64(): symname = %s; sym->st_value = %p\n",
373 symname, sym->st_value);
374 printf(" ndx = %d; flags = 0x%x", ndx, *flags);
375 printf("; refcook = %p; defcook = %p\n", refcook, defcook);
376
377 return sym->st_value;
378 }
379
380 Elf32_Addr
381 la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
382 uintptr_t *refcook, uintptr_t *defcook, La_i86_regs *regs,
383 unsigned int *flags, const char *symname, long int *framesizep)
384 {
385 printf("la_i86_gnu_pltenter(): %s (%p)\n", symname, sym->st_value);
386
387 return sym->st_value;
388 }
389
391 ldd(1), dlopen(3), ld.so(8), ldconfig(8)
392
394 This page is part of release 5.07 of the Linux man-pages project. A
395 description of the project, information about reporting bugs, and the
396 latest version of this page, can be found at
397 https://www.kernel.org/doc/man-pages/.
398
399
400
401Linux 2020-06-09 RTLD-AUDIT(7)