NOM¶
rtld-audit - API d'audit pour l'éditeur de liens dynamique
SYNOPSIS¶
#define _GNU_SOURCE /* Consultez
feature_test_macros(7) */
#include <link.h>
DESCRIPTION¶
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érents événements 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 retour, 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
valeurs suivantes :
- 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és, 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és 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_value. 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.
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 fournit 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 versions 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.44 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¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
<
http://po4a.alioth.debian.org/> par l'équipe de traduction
francophone au sein du projet perkamon
<
http://perkamon.alioth.debian.org/>.
Nicolas François et l'équipe francophone de traduction de
Debian (2006-2009).
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> ».