An audit module (auditor) is a shared object (plus its
DT_NEEDED dependencies) that is loaded very early in the
dynamic loading process in its own link namespace. An auditor can load
a set of support libraries into its link namespace and the symbols
that these libraries define will be invisible to the main executable
and its dependencies. For example, each auditor may load its own
libstdc++, which may be incompatible with those used by the main
executable and/or other auditors, and will have its own copy of glibc
itself (separate malloc, heap, stdio, etc.). Despite the fact that an
auditor in its own link namespace is somewhat isolated from the main
executable and other auditors, auditors and the main executable share
ld.so and process state, including Linux namespaces (distinct
from link namespaces), process ID, and file descriptors.
Once an auditor is loaded, the dynamic loader will call functions in the auditor to report key actions in the load process—associated with itself, other auditors, the executable, and any shared objects. Example actions include opening a shared object, binding a symbol, or completion of changes to the link map. While an auditor receives notifications of all dynamic linker actions on behalf of the main executable and its shared objects, as explained later, an auditor only receives limited notifications about its own actions or those of other auditors.
Auditors are specified by four methods, each of which specifies a colon-separated list of auditors:
LD_AUDITThe LD_AUDIT environment variable.
--auditIf the dynamic linker is invoked manually, it allows an --audit
command line parameter followed by a list of auditors.
DT_AUDITIf the main program has a DT_AUDIT dynamic tag, that tag
specifies a list of auditors.
DT_DEPAUDITIf the main program has a DT_DEPAUDIT dynamic tag, that tag is
a separate tag for auditors that are requested not by the main object,
but by one of the shared objects it was linked against.
Auditors are loaded in the order of the table above: first those from
LD_AUDIT, then those from --audit, DT_AUDIT, and
DT_DEPAUDIT. For each callback the dynamic loader calls, the
modules will be called in the order in which they were loaded.
Note that --audit may occur multiple times. The limit on the
number of colon-separated lists is currently 16. The limit on the
number of auditors currently defaults to 12 due to limits on remaining
namespaces (see Dynamic Linking Tunables). The program will fail
to start if too many auditors are requested. Every auditor named
counts towards that limit, including ones that cannot be loaded or
that la_version rejects, because the names are counted before
any auditor is loaded. An auditor that cannot be loaded is reported
with an error message, and the program runs without it.
As each auditor is loaded, its la_version callback is called to
ensure the module supports the API version the dynamic loader is
using. Auditors which do not are unloaded. Once an auditor is
loaded, it may audit the loading of further auditors6. Each auditor is loaded into its own
namespace, that is, any symbols exported by the auditor will not be
visible to the main program or other auditors.
If the program running is AT_SECURE (for example, set-user-id
programs), auditors are limited to secure auditors—auditor names
must not include ‘/’ characters and will only be searched for in
standard directories (ignoring ld.so.cache). Additionally,
such auditors must themselves be set-user-id, and have names less than
255 characters long.
The current implementation sends events for the searching and loading, but nothing significant after that. This may be intentional or it may be a bug, and auditors should assume auditing auditors is unsupported but plan for such events.