NOM
rtld-audit - API d’audit pour l’éditeur de liens dynamique
SYNOPSIS
#define _GNU_SOURCE
#include <link.h>
L’éditeur de liens dynamique GNU (l’éditeur de liens à l’exécution)
fournit une API d’audit qui permet à une application d’être notifiée
quand différent événement liés à l’édition de liens surviennent. Cette
API est très similaire à l’interface d’audit fournie par l’éditeur de
liens Solaris. Les constantes et prototypes nécessaires sont définis en
incluant <link.h>.
Pour utiliser cette interface, le programmeur crée une bibliothèque
partagée qui implémente un ensemble standard de noms de fonctions.
Toutes les fonctions n’ont pas à être implémentées : dans la plupart
des cas, si le programmeur n’est pas intéressé dans une certaine classe
d’événements d’audit, alors aucune implémentation n’a à être fournie
pour la fonction d’audit correspondante.
Pour utiliser l’interface d’audit, la variable d’environnement LD_AUDIT
doit être définie avec une liste de bibliothèques partagées, séparées
par des « deux-points », qui peuvent implémenter l’API (ou une partie)
d’audit. Quand un événement pouvant être surveillé survient, la
fonction correspondante est appelée dans chaque bibliothèque, dans
l’ordre où sont listées les bibliothèques.
la_version()
unsigned int la_version(unsigned int version);
Il s’agit de la seule fonction qui doit être définie par une
bibliothèque d’audit : elle effectue la présentation initiale entre
l’éditeur de liens et la bibliothèque d’audit. Lorsque cette fonction
est appelée, l’éditeur de liens passe, dans version, la version la plus
importante de l’interface d’audit qui soit prise en charge par
l’éditeur de liens. Si nécessaire, la bibliothèque d’audit peut
vérifier que cette version suffit à ses besoins.
En retours, cette fonction doit renvoyer la version de l’interface
d’audit que cette bibliothèque d’audit va utiliser (renvoyer version
est permis). Si la valeur de retour est 0 ou une version supérieure à
celle prise en charge par l’éditeur de liens, alors la bibliothèque
d’audit est ignorée.
la_objsearch()
char *la_objsearch(const char *name, uintptr_t *cookie,
unsigned int flag);
L’éditeur de liens appelle cette fonction pour informer la bibliothèque
d’audit qu’il va se mettre à la recherche d’un objet partagé. Le
paramètre name est le nom de fichier ou le chemin dans lequel
s’effectue la recherche. cookie identifie l’objet partagé qui a
déclenché la recherche. flag est l’une des valeur suivante :
LA_SER_ORIG Il s’agit du nom de départ de la recherche.
Généralement ce nom provient d’une entrée ELF
DT_NEEDED ou est le paramètre filename fourni à
dlopen(3).
LA_SER_LIBPATH name a été créé en utilisant un répertoire indiqué
dans LD_LIBRARY_PATH.
LA_SER_RUNPATH name a été créé en utilisant un répertoire indiqué
dans une liste ELF DT_RPATH ou DT_RUNPATH.
LA_SER_CONFIG name a été trouvé par le cache ldconfig(8)
(/etc/ld.so.cache).
LA_SER_DEFAULT name a été trouvé par une recherche dans un des
répertoires par défaut.
LA_SER_SECURE name est spécifique à un objet sûr (pas utilisé sous
Linux).
la_objsearch() renvoie comme valeur de retour le chemin que l’éditeur
de liens devrait utiliser pour les opérations suivantes. Si NULL est
renvoyé, alors le chemin est ignoré par la suite. Les bibliothèques qui
ne cherche qu’à observer les chemins de recherche devraient renvoyer
name.
la_activity()
void la_activity( uintptr_t *cookie, unsigned int flag);
L’éditeur de liens appelle cette fonction pour informer la bibliothèque
d’audit d’activités sur la table des liens. cookie identifie l’objet à
la tête de la table. Quand l’éditeur de liens appelle cette fonction,
flag vaut l’une des valeurs suivantes :
LA_ACT_ADD De nouveaux objets sont ajoutés à la table.
LA_ACT_DELETE Des objets sont retirés d ela table.
LA_ACT_CONSISTENT L’activité sur la table est terminée : la table est
de nouveau cohérente.
la_objopen()
unsigned int la_objopen(struct link_map *map, Lmid_t lmid,
uintptr_t *cookie);
L’éditeur de liens appelle cette fonction quand un nouvel objet partagé
est chargé. Le paramètre map est un pointeur vers la structure d’une
table de liens qui décrit l’objet. Le champ lmid prend une des valeurs
suivantes :
LM_ID_BASE La table fait partie de l’espace de noms de départ.
LM_ID_NEWLM La table fait partie d’un nouvel espace de noms
demandé avec dlmopen(3).
cookie est un pointeur vers un identifiant pour un objet. L’identifiant
est fourni aux appels suivants des fonctions de la bibliothèque d’audit
afin d’identifier l’objet. L’identifiant est initialisé pour pointer
vers la table de l’objet, mais la bibliothèque d’audit peut changer
l’identifiant pour une autre valeur qu’elle préférerait utiliser pour
identifier l’objet.
la_objopen() renvoie comme valeur de retour un masque de bits créé en
combinant zéro ou plusieurs constantes avec un OU binaire, ce qui
permet à la bibliothèque d’audit de sélectionner les objets à
surveiller avec les fonctions la_symbind*() :
LA_FLG_BINDTO Surveiller les associations de symboles à cet objet.
LA_FLG_BINDFROM Surveiller les associations de symboles provenant de
cet objet.
Une valeur de retour de 0 pour la_objopen() indique qu’aucune
association de symbole n’est à surveiller pour cet objet.
la_objclose()
unsigned int la_objclose(uintptr_t *cookie);
L’éditeur de liens appelle cette fonction après l’exécution du code de
finalisation pour l’objet (s’il y en a), et avant que l’objet soit
déchargé. Le paramètre cookie est l’identifiant obtenu par l’appel
précédent à la_objopen().
Dans l’implémentation actuelle, la valeur renvoyée par la_objclose()
est ignorée.
la_preinit()
void la_preinit(uintptr_t *cookie);
L’éditeur de liens appelle cette fonction après que tous les objets
partagés ont été chargé, avant que le contrôle soit donné à
l’application (c’est-à-dire avant l’appel à main()). Notez que main()
peut encore charger des objets dynamiquement en utilisant dlopen(3).
la_symbind*()
uintptr_t la_symbind32(Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname);
uintptr_t la_symbind64(Elf64_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname);
L’éditeur de liens appelle une de ces fonctions quand une association
de symbole survient entre deux objets partagés qui ont été marqué comme
étant surveillés par la_objopen(). La fonction la_symbind32() est
utilisée pour les plate-formes 32 bits ; la fonction la_symbind64() est
utilisée pour les plate-formes 64 bits.
Le paramètre sym est un pointeur vers une structure qui fournit des
informations sur le symbole en cours d’association. La définition de la
structure se trouve dans <elf.h>. Parmi les champs de la structure,
st_value indique l’adresse à laquelle le symbole est associé.
Le paramètre ndx fournit l’index du symbole dans la table des symboles
de l’objet partagé associé.
Le paramètre refcook identifie l’objet partagé qui crée la référence du
symbole ; il s’agit du même identifiant fourni à la fonction
la_objopen() qui a renvoyé LA_FLG_BINDFROM. Le paramètre defcook
identifie l’objet partagé qui défini le symbole référencé ; il s’agit
du même identifiant fourni à la fonction la_objopen() qui a renvoyé
LA_FLG_BINDTO.
Le paramètre symname pointe vers une chaîne contenant le nom du
symbole.
Le paramètre flags est un masque de bits qui peut à la fois fournir des
informations sur le symbole et être utilisé pour modifier encore plus
la surveillance de cette entrée de la PLT (Procedure Linkage Table).
L’éditeur de liens dynamique peut fournir les bits suivants dans ce
paramètre :
LA_SYMB_DLSYM L’association provient d’un appelle à dlsym(3).
LA_SYMB_ALTVALUE Un appel précédent à la_symbind*() a renvoyé une
autre valeur pour ce symbole.
Par défaut, si la bibliothèque d’audit implémente les fonctions
la_pltenter() et la_pltexit() (voir ci-dessous), alors ces fonctions
sont appelées, après la_symbind(), pour les entrées de la PLT, à chaque
fois que le symbole est référencé. Les drapeaux suivants peuvent être
fournis en les combinant avec un OU binaire dans *flags pour modifier
ce comportement par défaut :
LA_SYMB_NOPLTENTER Ne pas appeler la_pltenter() pour ce symbole.
LA_SYMB_NOPLTEXIT Ne pas appeler la_pltexit() pour ce symbole.
La valeur de retour de la_symbind32() et la_symbind64() est l’adresse à
laquelle le contrôle doit être donné après que la fonction se termine.
Si la bibliothèque d’audit ne fait qu’observer les associations de
symboles, elle devrait renvoyer sym->st_name. Une valeur différente
peut être renvoyée si la bibliothèque souhaite rediriger le contrôle à
un autre endroit.
la_pltenter()
Le nom et les types des paramètres de cette fonction dépendent de la
plate-forme matérielle. (la définition appropriée est fournie par
<link.h>.) Voici la définition pour la plate-forme x86-32 :
Elf32_Addr la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
La_i86_regs *regs, unsigned int *flags,
const char *symname, long int *framesizep);
Cette fonction est appelée juste avant l’appel d’une entrée de la PLT,
entre deux objets partagés ayant été marqués pour la notification des
associations.
Les paramètres sym, ndx, refcook, defcook et symname sont comme pour
la_symbind*().
Le paramètre regs pointe vers une structure (définie dans <link.h>) qui
contient les valeurs des registres à utiliser pour l’appel à cette
entrée de la PLT.
Le paramètre flags pointe vers une masque de bits qui, comme pour
la_symbind*(), fournit des informations pour cette entrée de la PLT et
peut être utilisé pour modifier la façon dont elle sera surveillée
ultérieurement.
Le paramètre framesizep pointe vers un long int qui peut être utilisé
pour définir explicitement la taille de la trame utilisée pour l’appel
à cette entrée de la PLT. Si différents appels à la_pltenter() pour ce
symbole renvoient différentes valeurs, alors la valeur maximale
renvoyée est utilisée. La fonction la_pltenter() n’est appelée que si
ce pointeur est explicitement définit avec une valeur convenable.
La valeur de retour de la_pltenter() est comme pour la_symbind*().
la_pltexit()
Le nom et les types des paramètres de cette fonction dépendent de la
plate-forme matérielle. (la définition appropriée est fournie par
<link.h>.) Voici la définition pour la plate-forme x86-32 :
unsigned int la_i86_gnu_pltexit(Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
const La_i86_regs *inregs, La_i86_retval *outregs,
const char *symname);
Cette fonction est appelée quand une entrée de la PLT, créée entre deux
objets partagés ayant été marqués pour la notification des
associations, se termine. La fonction est appelée juste avant que le
contrôle soit rendu à l’appelant de l’entrée de la PLT.
Les paramètres sym, ndx, refcook, defcook et symname sont comme pour
la_symbind*().
Le paramètre inregs pointe vers une structure (définie dans <link.h>)
qui contient les valeurs des registres utilisés pour l’appel à cette
entrée de la PLT. Le paramètre outregs pointe vers une structure
(définie dans <link.h>) qui contient les valeurs de retour de l’appel à
cette entrée de la PLT. Ces valeurs peuvent être modifiées par
l’appelant et les modifications seront visibles pour l’appelant de
l’entrée de la PLT.
Dans l’implémentation GNU actuelle, la valeur de retour de la_pltexit()
est ignorée.
CONFORMITÉ
Cette API n’est pas standard, mais est très proche de l’API Solaris,
décrite dans le guide Solaris Linker and Libraries Guide, au chapitre
Runtime Linker Auditing Interface.
NOTES
Notez les différences suivantes avec l’API d’audit de l’éditeur de
liens Solaris :
* L’interface Solaris la_objfilter() n’est pas prise en charge par
l’implémentation GNU.
* Les fonctions Solaris la_symbind32() et la_pltexit() ne fournissent
pas de paramètre symname.
* La fonction Solaris la_pltexit() ne forunit pas de paramètre inregs
ou outregs (mais fournit une paramètre retval avec la valeur de
retour de la fonction).
EXEMPLE
#include <link.h>
#include <stdio.h>
unsigned int
la_version(unsigned int version)
{
printf("la_version(): %d\n", version);
return version;
}
char *
la_objsearch(const char *name, uintptr_t *cookie, unsigned int flag)
{
printf("la_objsearch(): name = %s; cookie = %x", name, cookie);
printf("; flag = %s\n",
(flag == LA_SER_ORIG) ? "LA_SER_ORIG" :
(flag == LA_SER_LIBPATH) ? "LA_SER_LIBPATH" :
(flag == LA_SER_RUNPATH) ? "LA_SER_RUNPATH" :
(flag == LA_SER_DEFAULT) ? "LA_SER_DEFAULT" :
(flag == LA_SER_CONFIG) ? "LA_SER_CONFIG" :
(flag == LA_SER_SECURE) ? "LA_SER_SECURE" :
"???");
return name;
}
void
la_activity (uintptr_t *cookie, unsigned int flag)
{
printf("la_activity(): cookie = %x; flag = %s\n", cookie,
(flag == LA_ACT_CONSISTENT) ? "LA_ACT_CONSISTENT" :
(flag == LA_ACT_ADD) ? "LA_ACT_ADD" :
(flag == LA_ACT_DELETE) ? "LA_ACT_DELETE" :
"???");
}
unsigned int
la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
printf("la_objopen(): loading \"%s\"; lmid = %s; cookie=%x\n",
map->l_name,
(lmid == LM_ID_BASE) ? "LM_ID_BASE" :
(lmid == LM_ID_NEWLM) ? "LM_ID_NEWLM" :
"???",
cookie);
return LA_FLG_BINDTO | LA_FLG_BINDFROM;
}
unsigned int
la_objclose (uintptr_t *cookie)
{
printf("la_objclose(): %x\n", cookie);
return 0;
}
void
la_preinit(uintptr_t *cookie)
{
printf("la_preinit(): %x\n", cookie);
}
uintptr_t
la_symbind32(Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
{
printf("la_symbind32(): symname = %s; sym->st_value = %p\n",
symname, sym->st_value);
printf(" ndx = %d; flags = 0x%x", ndx, *flags);
printf("; refcook = %x; defcook = %x\n", refcook, defcook);
return sym->st_value;
}
uintptr_t
la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
{
printf("la_symbind64(): symname = %s; sym->st_value = %p\n",
symname, sym->st_value);
printf(" ndx = %d; flags = 0x%x", ndx, *flags);
printf("; refcook = %x; defcook = %x\n", refcook, defcook);
return sym->st_value;
}
Elf32_Addr
la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook, La_i86_regs *regs,
unsigned int *flags, const char *symname, long int *framesizep)
{
printf("la_i86_gnu_pltenter(): %s (%p)\n", symname, sym->st_value);
return sym->st_value;
}
BOGUES
Dans les version de la glibc jusqu’à la version 2.9 (inclue), fournit
plus d’une bibliothèque d’audit dans LD_AUDIT provoquait un crash à
l’exécution. Cela a été corrigé dans la version 2.10.
VOIR AUSSI
ldd(1), dlopen(3), ld.so(8), ldconfig(8)
COLOPHON
Cette page fait partie de la publication 3.23 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent être trouvées à l’adresse
http://www.kernel.org/doc/man-pages/.
TRADUCTION
Cette page de manuel a été traduite et est maintenue par Nicolas
François <nicolas.francois@centraliens.net> et l’équipe francophone de
traduction de Debian.
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document
en utilisant la commande « man -L C <section> <page_de_man> ».