attributes(7)

NOM
attributes – Concepts de sécurité POSIX

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

  Fonctionnalités sûres sous condition
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.

  Autres remarques sur la sûreté
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.

VOIR AUSSI
pthreads(7), signal-safety(7)

TRADUCTION
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 (https://www.gnu.org/licenses/gpl-3.0.html) 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.