37.4.1 Audit Module Loading

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_AUDIT

The LD_AUDIT environment variable.

--audit

If the dynamic linker is invoked manually, it allows an --audit command line parameter followed by a list of auditors.

DT_AUDIT

If the main program has a DT_AUDIT dynamic tag, that tag specifies a list of auditors.

DT_DEPAUDIT

If 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.


Footnotes

(6)

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.