attributes – Concepts de sécurité POSIX
Note : le texte de cette page de manuel est
basée sur des éléments pris dans la section
« POSIX Safety Concepts » du manuel de la
bibliothèque GNU C. Plus de détails sur les sujets
décrits ici peuvent être trouvés dans ce manuel.
Diverses pages de manuel de fonctions comportent une section
ATTRIBUTES qui décrit la sécurité de l'appel d'une
fonction dans divers contextes. Cette section annote les fonctions avec les
balises de sécurité suivantes :
- MT-Safe
- Les fonctions MT-Safe ou Thread-Safe sont sûres
à appeler en présence d'autres threads. MT, dans MT-Safe,
signifie « multithread ».
- L'état MT-Safe n'implique pas qu'une fonction est atomique, ni
qu'elle utilise un des mécanismes de synchronisation de
mémoire que POSIX expose aux utilisateurs. Il est même
possible que l'appel de plusieurs fonctions MT-Safe à la suite ne
produise pas une combinaison MT-Safe. Par exemple, le fait qu'un thread
appelle deux fonctions MT-Safe l'une immédiatement après
l'autre ne garantit pas un comportement équivalent à
l'exécution atomique de la combinaison des deux fonctions, dans la
mesure où des appels concomitants dans d'autres threads peuvent
interférer de manière destructive.
- Les optimisations à l'échelle du programme qui peuvent
intégrer des fonctions à travers les interfaces des
bibliothèques peuvent exposer à des réorganisations
non sûres, aussi il n'est pas recommandé de réaliser
des intégrations au moyen des interfaces de la bibliothèque
GNU C. L'état documenté MT-Safety n'est pas garanti.
Néanmoins, les fonctions définies dans les en-têtes
visibles par l'utilisateur sont conçues pour être
sûres pour l'intégration.
- MT-Unsafe
- Les fonctions MT-Unsafe ne sont pas sûres pour des appels
dans des programmes multithreadés.
D'autres mots-clefs qui apparaissent dans des notes de
sûreté sont définis dans les sections suivantes.
Pour certaines fonctionnalités qui rendent non sûre
l'appel de certaines fonctions dans certains contextes, il existe des moyens
connus pour éviter un problème autres que de s'abstenir
complètement d'appeler la fonction. Les mots-clés qui suivent
font référence à ces fonctionnalités et chacune
des définitions indique comment le programme dans son ensemble doit
être contraint de manière à supprimer le
problème de sûreté indiqué par le
mot-clé. C'est seulement lorsque toutes les raisons qui rendent une
fonction non sûre ont été observées et
traitées, en appliquant les contraintes documentées, que
l'appel d'une fonction devient sûr dans un contexte.
- init
- Les fonctions marquées init en tant que
fonctionnalité MT-Unsafe réalisent une initialisation
MT-Unsafe quand elles sont appelées en premier.
- L'appel d'une fonction de ce type au moins une fois en mode monothread
supprime cette raison spécifique qui fait considérer la
fonction comme MT-Unsafe. S'il ne reste pas d'autre raison, la
fonction peut alors être appelée de façon sûre
après le démarrage d'autres threads.
- race
- Les fonctions marquées race en tant que problème
d'état MT-Safe opèrent sur des objets d'une
façon qui peut provoquer des situations de concurrences de
données ou des formes similaires d'interférences
destructives provoquées par une exécution concurrente. Dans
certains cas, les objets sont passés aux fonctions par les
utilisateurs ; dans d'autres, ils sont utilisés par les
fonctions pour renvoyer des valeurs aux utilisateurs ; dans
d'autres encore, ils ne sont même pas exposés aux
utilisateurs.
- const
- Les fonctions marquées const en tant que problème
d'état MT-Safe modifient de façon non-atomique les objets
internes qui sont plutôt à considérer comme
constants, parce qu'une partie importante de la bibliothèque
GNU C y accède sans synchronisation. À la
différence de race qui fait qu'à la fois lecteurs et
écrivains d'objets internes sont considérés comme
MT-Unsafe, cette marque ne s'applique qu'aux écrivains. Leur
appel demeure MT-Unsafe, mais le caractère constant alors
obligatoire des objets qu'ils modifient permet de considérer les
lecteurs comme MT-safe (aussi longtemps qu'il n'y a pas d'autre
raison pour qu'ils soient non sûrs), dans la mesure où
l'absence de synchronisation n'est pas un problème quand les objets
sont effectivement constants.
- L'identifiant qui suit la marque const apparaîtra
lui-même conne une note de sûreté dans les lecteurs.
Les programmes qui souhaitent contourner ce problème de
sûreté, afin d'appeler les écrivains, peuvent
utiliser un verrou en lecture et écriture non récursif
associé à l'identifiant et garder la totalité
des appels à des fonctions marquées const suivies de
l'identifiant avec un verrou en écriture et la
totalité des appels à des fonctions marquées
par l'identifiant lui-même avec un verrou en lecture.
- sig
- Les fonctions marquées sig en tant que problème
d'état MT-Safe peuvent installer de façon temporaire un
gestionnaire de signal à des fins internes qui peut
interférer avec d'autres usages du signal, identifié
après deux-points.
- Le problème de sûreté peut être
contourné en s'assurant qu'aucun autre usage du signal
n'interviendra pendant la durée de l'appel. Il est
recommandé de maintenir un mutex non récursif pendant
l'appel de toutes les fonctions qui utilisent le même signal
temporaire, de bloquer ce signal avant l'appel et de réinitialiser
son gestionnaire après.
- term
- Les fonctions marquées term en tant que problème
d'état MT-Safe peuvent modifier la configuration du terminal de la
façon recommandée, c'est-à-dire : appel de
tcgetattr(3), modification de certains attributs puis appel de
tcsetattr(3), cela crée une fenêtre dans laquelle les
modifications effectuées par d'autres threads sont perdues. Donc,
les fonctions marquées term sont MT-Unsafe.
- Il est donc recommandé d'éviter, pour les applications
utilisant le terminal, des interactions simultanées et
réentrantes avec lui en nel'utilisant pas dans les gestionnaires de
signal ou les signaux bloquants qui pourraient l'utiliser
également, et de maintenir un verrou pendant l'utilisation de ces
fonctions et l'interaction avec le terminal. Ce verrou devrait
également être utilisé pour l'exclusion mutuelle avec
les fonctions marquées race:tcattr(fd) où fd
est un descripteur de fichier pour le terminal de contrôle.
L'appelant peut utiliser un mutex unique pour simplifier ou utiliser un
mutex par terminal même s'ils sont référencés
par des descripteurs de fichier différents.
Des mots clefs supplémentaires peuvent être
ajoutés aux fonctions, indiquant des fonctionnalités qui ne
rendent pas la fonction non sûre à appeler, mais il peut
être nécessaire d'en tenir compte dans certaines classes de
programmes.
- locale
- Les fonctions marquées locale en tant que problème
d'état MT-Safe lisent à partir de l'objet locale sans aucune
forme de synchronisation. Ces fonctions appelées en même
temps que des modifications de locale peuvent se comporter d'une
manière qui ne correspond à aucune des locales
actives pendant leur exécution mais à un mélange
imprévisible de celles-ci.
- Nous ne marquons pas ces fonctions comme MT-Unsafe
néanmoins, car les fonctions qui modifient l'objet locale
sont marquées const:locale et considérées
comme non sûres. Étant non sûres, ces
dernières ne doivent pas être appelées quand
plusieurs threads sont en exécution ou lorsque les signaux
asynchrones sont activés, et ainsi la locale peut
être considérée comme effectivement constante dans
ces contextes, ce qui rend les premières fonctions
sûres.
- env
- Les fonctions marquées env en tant que problème
d'état MT-Safe accèdent à l'environnement avec
getenv(3) ou une commande similaire sans aucune protection pour
garantir la sûreté en présence de modifications
simultanées.
- Nous ne marquons pas ces fonctions comme MT-Unsafe
néanmoins, car les fonctions qui modifient l'environnement sont
toutes marquées const:env et considérées comme
non sûres. Étant non sûres, ces dernières ne
doivent pas être appelées quand plusieurs threads sont en
exécution ou lorsque les signaux asynchrones sont activés,
et ainsi l'environnement peut être considéré comme
effectivement constant dans ces contextes, ce qui rend les
premières fonctions sûres.
- hostid
- Les fonctions marquées hostid en tant que problème
d'état MT-Safe lisent à partir des structures de
données communes à tout le système qui contiennent
« l'ID d'hôte » de la machine. Ces
structures de données ne peuvent pas en général
être modifiées automatiquement. Dans la mesure où il
est attendu que normalement « l'ID
d'hôte » ne change pas, la fonction qui lit à
partir d'elle (gethostid(3)) est considérée comme
sûre, tandis que la fonction qui la modifie (sethostid(3))
est marquée const:hostid, indiquant qu'elle requiert une
attention particulière si elle doit être appelée.
Dans ce cas particulier, cette attention particulière
équivaut à une coordination à l'échelle de
l'ensemble du système (pas seulement à l'intérieur du
processus).
- sigintr
- Les fonctions marquées sigintr en tant que problème
d'état MT-Safe accèdent à la structure de
données interne _sigintr de la bibliothèque
GNU C sans aucune protection pour garantir la sûreté
en présence de modifications simultanées.
- Nous ne marquons pas ces fonctions comme MT-Unsafe
néanmoins, car les fonctions qui modifient cette structure de
données sont toutes marquées const:sigintr et
considérées comme non sûres. Étant non
sûres, ces dernières ne doivent pas être
appelées quand plusieurs threads sont en exécution ou
lorsque les signaux asynchrones sont activés, et ainsi
l'environnement peut être considéré comme
effectivement constant dans ces contextes, ce qui rend les
premières fonctions sûres.
- cwd
- Les fonctions marquées cwd en tant que problème
d'état MT-Safe peuvent changer temporairement le répertoire
actif actuel durant leur exécution ce qui fait que les noms de
chemin relatifs peuvent être résolus de façon
inattendue dans les autres threads ou dans les gestionnaires de signal ou
d'annulation asynchrones.
- Ce n'est pas une raison suffisante pour marquer comme MT-Unsafe les
fonctions ainsi marquées, mais quand ce comportement est optionnel
(par exemple, nftw(3) avec FTW_CHDIR), éviter
l'option peut être une bonne alternative à l'utilisation des
noms de chemin complets ou d'appels système relatifs au descripteur
de fichier (par exemple, openat(2)).
- :identifiant
- Les annotations peuvent parfois être suivies par des identifiants
destinés à regrouper plusieurs fonctions qui, par exemple
accèdent aux structures de données de façon non
sûre, comme dans race et const, ou pour fournir des
informations plus spécifiques, comme le nom d'un signal dans une
fonction marquée sig. Il est envisagé que cela
pourrait aussi être appliqué à l'avenir à
lock et corrupt.
- Dans la plupart des cas, l'identifiant désignera un ensemble de
fonctions, mais il peut désigner des objets globaux ou des
paramètres de fonction, des propriétés identifiables
ou des composants logiques qui leur sont associés, avec une
notation du type, par exemple, :buf(param) pour désigner un
tampon associé au paramètre param, ou
:tcattr(fd) pour désigner les attributs de terminal d'un
descripteur de fichier fd.
- L'utilisation la plus courante des identifiants est de fournir des groupes
logiques de fonctions et de paramètres qui nécessitent
d'être protégés par la même primitive de
synchronisation afin d'assurer une opération sûre dans un
contexte donné.
- /condition
- Certaines annotations de sûreté peuvent être
conditionnelles, dans le sens qu'elles ne s'appliquent que si une
expression booléenne comprenant des paramètres, des
variables globales ou même le noyau sous-jacent est
évaluée vraie. Par exemple, /!ps et
/one_per_line indiquent que le marqueur qui précède
ne s'applique que si l'argument ps est NULL ou la variable globale
one_per_line est différente de zéro.'
- Quand toutes les marques qui rendent non sûre une fonction sont
agrémentées de conditions de ce type, et qu'aucune des
conditions nommées ne tient, alors, la fonction peut être
considérée comme sûre.
pthreads(7), signal-safety(7)
La traduction française de cette page de manuel a
été créée par Christophe Blaess
<https://www.blaess.fr/christophe/>, Stéphan Rafin
<stephan.rafin@laposte.net>, Thierry Vignaud
<tvignaud@mandriva.com>, François Micaux, Alain Portal
<aportal@univ-montp2.fr>, Jean-Philippe Guérard
<fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh)
<jean-luc.coulon@wanadoo.fr>, Julien Cristau
<jcristau@debian.org>, Thomas Huriaux
<thomas.huriaux@gmail.com>, Nicolas François
<nicolas.francois@centraliens.net>, Florentin Duneau
<fduneau@gmail.com>, Simon Paillard
<simon.paillard@resel.enst-bretagne.fr>, Denis Barbier
<barbier@debian.org>, David Prévot <david@tilapin.org> et
Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>
Cette traduction est une documentation libre ; veuillez
vous reporter à la
GNU General
Public License version 3 concernant les conditions de copie et de
distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page
de manuel, veuillez envoyer un message à
debian-l10n-french@lists.debian.org.