.\" -*- coding: UTF-8 -*- .\" Copyright (C) 2014 Kees Cook .\" and Copyright (C) 2012 Will Drewry .\" and Copyright (C) 2008, 2014,2017 Michael Kerrisk .\" and Copyright (C) 2017 Tyler Hicks .\" .\" %%%LICENSE_START(VERBATIM) .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the Linux kernel and libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" %%%LICENSE_END .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH SECCOMP 2 "1 novembre 2020" Linux "Manuel du programmeur Linux" .SH NOM seccomp \- Agir sur l'état de calcul sécurisé (Secure Computing State) du processus .SH SYNOPSIS .nf .\" Kees Cook noted: Anything that uses SECCOMP_RET_TRACE returns will .\" need \fB#include \fP \fB#include \fP \fB#include \fP \fB#include \fP \fB#include \fP .PP \fBint seccomp(unsigned int \fP\fIopération\fP\fB, unsigned int \fP\fIflags\fP\fB, void *\fP\fIargs\fP\fB);\fP .fi .SH DESCRIPTION L'appel système \fBseccomp\fP() agit sur l'état de calcul sécurisé (seccomp) du processus appelant. .PP Actuellement, Linux gère les valeurs d'\fIopération\fP suivantes\ : .TP \fBSECCOMP_SET_MODE_STRICT\fP Les seuls appels système que le thread appelant est autorisé à faire sont \fBread\fP(2), \fBwrite\fP(2), \fB_exit\fP(2) (mais pas \fBexit_group\fP(2)) et \fBsigreturn\fP(2). Les autres appels système envoient un signal \fBSIGKILL\fP. Le mode de calcul sécurisé strict est utile pour les applications de traitement de nombres qui peuvent avoir besoin d'exécuter un code à octets non fiable, obtenu peut\-être en lisant un tube ou un socket. .IP Remarquez que si le thread appelant ne peut plus appeler \fBsigprocmask\fP(2), il peut utiliser \fBsigreturn\fP(2) pour bloquer tous les signaux, sauf ceux provenant de \fBSIGKILL\fP et de \fBSIGSTOP\fP. Cela veut dire que \fBalarm\fP(2) (par exemple) n'est pas suffisant pour restreindre la durée d'exécution d'un processus. Pour terminer de manière fiable un processus, \fBSIGKILL\fP doit être utilisé. On peut le faire en utilisant \fBtimer_create\fP(2) avec \fBSIGEV_SIGNAL\fP et \fIsigev_signo\fP positionné à \fBSIGKILL\fP ou en utilisant \fBsetrlimit\fP(2) pour positionner la limite ferme de \fBRLIMIT_CPU\fP. .IP Cette opération n'est disponible que si le noyau a été configuré avec \fBCONFIG_SECCOMP\fP. .IP La valeur de \fIflags\fP doit être de \fB0\fP et \fIargs\fP doit être NULL. .IP Cette opération est fonctionnellement identique à l'appel\ : .IP .in +4n .EX prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT); .EE .in .TP \fBSECCOMP_SET_MODE_FILTER\fP Les appels système autorisés sont définis par un pointeur vers un filtre Berkeley Packet (BPF) fourni à l'aide de \fIargs\fP. Ce paramètre est un pointeur vers une \fIstruct\ sock_fprog\fP\ ; il peut être conçu pour filtrer des appels système de votre choix ainsi que des paramètres d'appel système. Si le filtre n'est pas valable, \fBseccomp\fP() échoue en renvoyant \fBEINVAL\fP dans \fIerrno\fP. .IP Si \fBfork\fP(2) ou \fBclone\fP(2) est autorisé par le filtre, les processus enfant seront contraints par les mêmes filtres d'appel système que leur parent. Si \fBexecve\fP(2) est autorisé, les filtres existants seront préservés lors d'un appel à \fBexecve\fP(2). .IP Pour utiliser l'opération \fBSECCOMP_SET_MODE_FILTER\fP, soit le thread appelant doit avoir la capacité \fBCAP_SYS_ADMIN\fP dans son espace de noms utilisateur, soit il doit avoir déjà le bit \fIno_new_privs\fP défini. Si ce bit n'a pas déjà été positionné par un ascendant du thread, le thread doit effectuer l'appel suivant\ : .IP .in +4n .EX prctl(PR_SET_NO_NEW_PRIVS, 1); .EE .in .IP Sinon, l'opération \fBSECCOMP_SET_MODE_FILTER\fP échoue et renvoie \fBEACCES\fP dans \fIerrno\fP. Cette exigence garantit qu'un processus non privilégié ne peut pas appliquer un filtre malveillant et appeler un programme set\-user\-ID ou avec d'autres privilèges en utilisant \fBexecve\fP(2), compromettant ainsi le programme (un tel filtre malveillant pourrait, par exemple, conduire \fBsetuid\fP(2) à essayer de définir les identifiants utilisateur de l'appelant à des valeurs non nulles pour renvoyer plutôt \fB0\fP sans faire d'appel système. Ainsi, le programme pourrait être bidouillé pour garder les privilèges du super\-utilisateur à des moments où il est possible de l'influencer pour faire des choses dangereuses vu qu'il n'a pas abandonné ses privilèges). .IP Si \fBprctl\fP(2) ou \fBseccomp\fP() est autorisé par le filtre rattaché, d'autres filtres peuvent être ajoutés. Cela augmentera le temps d'évaluation mais permet d'autres réductions de la surface d'attaque lors de l'exécution d'un thread. .IP L'opération \fBSECCOMP_SET_MODE_FILTER\fP n'est disponible que si le noyau a été configuré avec \fBCONFIG_SECCOMP_FILTER\fP. .IP Quand \fIflags\fP vaut \fB0\fP, cette opération est fonctionnellement identique à l'appel\ : .IP .in +4n .EX prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, args); .EE .in .IP Les paramètres reconnus de \fIflags\fP sont\ : .RS .TP \fBSECCOMP_FILTER_FLAG_TSYNC\fP Lors de l'ajout d'un filtre, synchroniser tous les autres threads du processus appelant avec la même arborescence de filtres seccomp. Une «\ arborescence de filtres\ » est une liste ordonnée de filtres rattachée à un thread (le rattachement de filtres identiques dans des appels \fBseccomp\fP() distincts génère différents filtres depuis cette perspective). .IP Si aucun thread ne peut pas se synchroniser avec l'arborescence de filtres, l'appel ne rattachera pas le nouveau filtre seccomp et échouera en renvoyant le premier identifiant de thread qui n'a pas pu se synchroniser. La synchronisation échouera si un autre thread du même processus est en \fBSECCOMP_MODE_STRICT\fP ou si des nouveaux filtres seccomp lui sont rattachés en propre, en décalage par rapport à l'arborescence de filtres du thread appelant. .TP \fBSECCOMP_FILTER_FLAG_LOG\fP (depuis Linux 4.14) .\" commit e66a39977985b1e69e17c4042cb290768eca9b02 Toutes les actions de renvoi des filtres, sauf \fBSECCOMP_RET_ALLOW\fP, doivent être journalisées. Un administrateur peut outrepasser cet attribut de filtre en empêchant des actions spécifiques d'être journalisées à l'aide du fichier \fI/proc/sys/kernel/seccomp/actions_logged\fP. .TP \fBSECCOMP_FILTER_FLAG_SPEC_ALLOW\fP (depuis Linux\ 4.17) .\" commit 00a02d0c502a06d15e07b857f8ff921e3e402675 Désactiver la mitigation Speculative Store Bypass. .RE .TP \fBSECCOMP_GET_ACTION_AVAIL\fP (depuis Linux\ 4.14) .\" commit d612b1fd8010d0d67b5287fe146b8b55bcbb8655 Tester pour savoir si une action est prise en charge par le noyau. Cette opération peut aider à confirmer que le noyau connaît l'action de renvoi d'un filtre récemment ajouté puisque le noyau traite toutes les actions inconnues comme des \fBSECCOMP_RET_KILL_PROCESS\fP. .IP La valeur de \fIflags\fP doit être de \fB0\fP et \fIargs\fP doit être un pointeur vers une action de renvoi de filtre 32\ bits non signé. .SS Filtres Lors de l'ajout d'un filtre à l'aide de \fBSECCOMP_SET_MODE_FILTER\fP, \fIargs\fP pointe vers un programme de filtrage\ : .PP .in +4n .EX struct sock_fprog { unsigned short len; /* Nombre d'instructions BPF */ struct sock_filter *filter; /* Pointeur vers le tableau d'instructions BPF */ }; .EE .in .PP Chaque programme doit contenir une ou plusieurs instructions BPF\ : .PP .in +4n .EX struct sock_filter { /* Filter block */ __u16 code; /* Code du filtre réel */ __u8 jt; /* Jump true (sauter le vrai) */ __u8 jf; /* Jump false (sauter le faux) */ __u32 k; /* Champ générique multiusages */ }; .EE .in .PP .\" Quoting Kees Cook: .\" If BPF even allows changing the data, it's not copied back to .\" the syscall when it runs. Anything wanting to do things like .\" that would need to use ptrace to catch the call and directly .\" modify the registers before continuing with the call. Lors de l'exécution des instructions, le programme BPF agit sur les informations de l'appel système qui sont rendues disponibles (c'est\-à\-dire qu'il utilise le mode d'adressage \fBBPF_ABS\fP) en tant que tampon (en lecture seule) ayant la forme suivante\ : .PP .in +4n .EX struct seccomp_data { int nr; /* Numéro de l'appel système */ __u32 arch; /* Valeur AUDIT_ARCH_* (voir ) */ __u64 instruction_pointer; /* pointeur vers l'instruction du processeur */ __u64 args[6]; /* Jusqu'à 6 paramètres de l'appel système */ }; .EE .in .PP Comme la numérotation des appels système varie entre les architectures et comme certaines (comme x86\-64) autorisent du code de l'espace utilisateur à utiliser les conventions de l'appelant d'autres architectures (et comme cette convention peut varier pendant la vie d'un processus qui utilise \fBexecve\fP(2) pour exécuter des binaires qui utilisent différentes conventions), il est généralement nécessaire de vérifier la valeur du champ \fIarch\fP. .PP Il est fortement recommandé d'utiliser une approche par liste d'autorisations autant que possible, parce qu'une telle approche est plus robuste et plus simple. Une liste d'interdictions devra être mise à jour à chaque fois qu'un appel système dangereux sera ajouté (ou un attribut ou une option si elles font partie de la liste des interdictions) et il est souvent possible de modifier la représentation d'une valeur sans changer sa signification, conduisant à contourner la liste d'interdictions. Voir aussi \fIMises en garde\fP ci\-dessous. .PP .\" As noted by Dave Drysdale in a note at the end of .\" https://lwn.net/Articles/604515/ .\" One additional detail to point out for the x32 ABI case: .\" the syscall number gets a high bit set (__X32_SYSCALL_BIT), .\" to mark it as an x32 call. .\" .\" If x32 support is included in the kernel, then __SYSCALL_MASK .\" will have a value that is not all-ones, and this will trigger .\" an extra instruction in system_call to mask off the extra bit, .\" so that the syscall table indexing still works. Le champ \fIarch\fP n'est pas unique pour toutes les conventions d'appelant. Les ABI x86\-64 et x32 utilisent \fBAUDIT_ARCH_X86_64\fP en tant que \fIarch\fP et elles fonctionnent sur les mêmes processeurs. Au contraire, le masque \fB__X32_SYSCALL_BIT\fP est utilisé sur le numéro d'appel système pour parler indépendamment aux deux ABI. .PP Cela veut dire qu'une politique peut soit interdire tous les appels système avec \fB__X32_SYSCALL_BIT\fP, soit elle doit les reconnaître avec le positionnement ou pas de \fB__X32_SYSCALL_BIT\fP. Une liste des appels système à interdire qui s'appuie sur \fInr\fP et qui ne contient pas de valeurs \fInr\fP où \fB__X32_SYSCALL_BIT\fP est positionné peut être contournée par un programme malveillant qui positionne \fB__X32_SYSCALL_BIT\fP. .PP .\" commit 6365b842aae4490ebfafadfc6bb27a6d3cc54757 En outre, les noyaux précédant Linux\ 5.4 autorisaient à tort \fInr\fP dans les intervalles 512–547 ainsi que les appels système non x32 correspondants reliés (opération OU) avec \fB__X32_SYSCALL_BIT\fP. Par exemple, \fInr\fP == 521 et \fInr\fP == (101\ | \fB__X32_SYSCALL_BIT\fP) créeraient des appels \fBptrace\fP(2) avec une sémantique potentiellement confondue entre x32 et x86_64 dans le noyau. Les politiques prévues pour fonctionner sur des noyaux antérieurs à Linux\ 5.4 doivent garantir qu'elles interdisent ou qu'elles gèrent correctement ces appels système. Sur Linux\ 5.4 et plus récents, de tels appels système échoueront avec une erreur \fBENOSYS\fP sans rien faire. .PP Le champ \fIinstruction_pointer\fP fournit l'adresse de l'instruction en langage machine qui a effectué l'appel système. Cela pourrait être utile avec \fI/proc/[pid]/maps\fP pour effectuer des vérifications à partir de la région (projection) du programme qui a fait l'appel système (il est probablement raisonnable de verrouiller les appels système \fBmmap\fP(2) et \fBmprotect\fP(2) pour empêcher le programme de contourner de telles vérifications). .PP Lors de la vérification des valeurs de \fIargs\fP, gardez en tête que les paramètres sont souvent tronqués silencieusement avant d'être traités mais après la vérification seccomp. Cela arrive par exemple si l'ABI i386 est utilisée sur un noyau x86\-64\ : bien que le noyau n'ira normalement pas regarder au\-delà des 32\ bits les plus faibles des paramètres, les valeurs des registres 64 bits complets seront présentes dans les données de seccomp. Un exemple moins surprenant est que si l'ABI x86\-64 est utilisée pour effectuer un appel système prenant un paramètre de type \fIint\fP, la moitié du registre du paramètre la plus significative est ignorée par l'appel système mais visible dans les données de seccomp. .PP Un filtre seccomp renvoie une valeur 32\ bits en deux parties\ : la plus significative, de 16\ bits (correspondant au masque défini par la constante \fBSECCOMP_RET_ACTION_FULL\fP), contient une des valeurs «\ action\ » listée ci\-dessous\ ; la moins significative, de 16\ bits (définie par la constante \fBSECCOMP_RET_DATA\fP), contient des «\ data\ » à associer à ce code de retour. .PP .\" From an Aug 2015 conversation with Kees Cook where I asked why *all* .\" filters are applied even if one of the early filters returns .\" SECCOMP_RET_KILL: .\" .\" It's just because it would be an optimization that would only speed up .\" the RET_KILL case, but it's the uncommon one and the one that doesn't .\" benefit meaningfully from such a change (you need to kill the process .\" really quickly?). We would speed up killing a program at the (albeit .\" tiny) expense to all other filtered programs. Best to keep the filter .\" execution logic clear, simple, and as fast as possible for all .\" filters. Si plusieurs filtres existent, ils sont \fItous\fP exécutés dans l'ordre inverse de leur apparition dans l'arbre des filtres –\ si bien que le filtre le plus récemment installé est exécuté en premier) (remarquez que tous les filtres seront appelés même si l'un des premiers appelés renvoie \fBSECCOMP_RET_KILL\fP, cela pour simplifier le code du noyau et pour fournir une petite accélération d’exécution d’ensembles de filtres en évitant la vérification de ce cas rare). La valeur renvoyée de l'évaluation d'un appel système donné est la première valeur vue de l'action de plus haute priorité (ainsi que ses données associées) renvoyée par l'exécution de tous les filtres. .PP Dans l'ordre décroissant de priorité, les valeurs d'action qui peuvent être renvoyées par un filtre seccomp sont\ : .TP \fBSECCOMP_RET_KILL_PROCESS\fP (depuis Linux 4.14) .\" commit 4d3b0b05aae9ee9ce0970dc4cc0fb3fad5e85945 .\" commit 0466bdb99e8744bc9befa8d62a317f0fd7fd7421 Cette valeur aboutit à la fin immédiate du processus, avec un vidage mémoire. L'appel système n'est pas exécuté. Contrairement à \fBSECCOMP_RET_KILL_THREAD\fP ci\-dessous, tous les threads du groupe de threads sont terminés (pour un point sur les groupes de thread, voir la description de l'attribut \fBCLONE_THREAD\fP de \fBclone\fP(2)). .IP Le processus se termine \fIparce que\fP il a été tué par un signal \fBSIGSYS\fP. Même si un gestionnaire de signal a été enregistré pour \fBSIGSYS\fP, le gestionnaire sera ignoré dans ce cas et le processus se termine toujours. Le processus parent qui attend ce processus (en utilisant \fBwaitpid\fP(2) ou équivalent) reçoit \fIwstatus\fP qui indique que son enfant s'est terminé suite à un signal \fBSIGSYS\fP. .TP \fBSECCOMP_RET_KILL_THREAD\fP (ou \fBSECCOMP_RET_KILL\fP) Cette valeur provoque la fin immédiate du thread qui a effectué l'appel système. L'appel système n'est pas exécuté. Les autres threads du même groupe de threads continueront à s'exécuter. .IP Le thread s'est terminé \fIcomme\fP tué par un signal \fBSIGSYS\fP. Voir \fBSECCOMP_RET_KILL_PROCESS\fP ci\-dessus. .IP .\" See these commits: .\" seccomp: dump core when using SECCOMP_RET_KILL .\" (b25e67161c295c98acda92123b2dd1e7d8642901) .\" seccomp: Only dump core when single-threaded .\" (d7276e321ff8a53106a59c85ca46d03e34288893) Avant Linux\ 4.11, tout processus qui se terminait de cette manière ne générait pas de vidage mémoire (bien que \fBSIGSYS\fP soit documenté dans \fBsignal\fP(7) pour avoir comme action par défaut celle de terminer avec un vidage mémoire). Depuis Linux\ 4.11, un processus d'un seul thread créera un vidage mémoire s'il se termine dans ce cadre. .IP Avec l'apparition de \fBSECCOMP_RET_KILL_PROCESS\fP dans Linux\ 4.14, \fBSECCOMP_RET_KILL_THREAD\fP a été ajouté comme synonyme de \fBSECCOMP_RET_KILL\fP, afin de distinguer plus clairement les deux actions. .IP \fBRemarque\ :\fP l'utilisation de \fBSECCOMP_RET_KILL_THREAD\fP pour tuer un thread unique d'un processus de plusieurs threads va probablement mettre le processus dans un état incohérent et corrompre pour toujours son état. .TP \fBSECCOMP_RET_TRAP\fP Cette valeur fait envoyer par le noyau un signal \fBSIGSYS\fP adressé au thread déclencheur (l'appel système n'est pas exécuté). Divers champs seront positionnés dans la structure \fIsiginfo_t\fP (voir \fBsigaction\fP(2)) associée au signal\ : .RS .IP * 3 \fIsi_signo\fP contiendra \fBSIGSYS\fP. .IP * \fIsi_call_addr\fP affichera l'adresse de l'instruction de l'appel système. .IP * \fIsi_syscall\fP et \fIsi_arch\fP indiqueront l'appel système qui a été essayé. .IP * \fIsi_code\fP contiendra \fBSYS_SECCOMP\fP. .IP * \fIsi_errno\fP contiendra la partie \fBSECCOMP_RET_DATA\fP du code de retour du filtre. .RE .IP Le compteur du programme sera arrêté comme si l'appel système a été fait (c'est\-à\-dire que le compteur du programme ne pointera pas vers l'instruction de l'appel système). Le registre du code de retour contiendra une valeur dépendante de l'architecture\ ; en cas de relance de l'exécution, positionnez\-la sur quelque chose adapté à l'appel système (la dépendance de l'architecture provient du fait que son remplacement par \fBENOSYS\fP écraserait des informations utiles). .TP \fBSECCOMP_RET_ERRNO\fP Cette valeur fait passer la partie \fBSECCOMP_RET_DATA\fP du code de retour du filtre à l'espace utilisateur en tant que valeur \fIerrno\fP sans exécuter l'appel système. .TP \fBSECCOMP_RET_TRACE\fP Quand cette valeur est renvoyée, le noyau essaiera de notifier à un observateur basé sur \fBptrace\fP(2) avant d'exécuter l'appel système. Si aucun observateur n'est présent, l'appel système n'est pas exécuté et renvoie un échec en positionnant \fIerrno\fP sur \fBENOSYS\fP. .IP Un observateur sera notifié s'il demande \fBPTRACE_O_TRACESECCOMP\fP en utilisant \fIptrace(PTRACE_SETOPTIONS)\fP. Il sera notifié d'un \fBPTRACE_EVENT_SECCOMP\fP et la partie \fBSECCOMP_RET_DATA\fP du code de retour du filtre sera mise à la disposition de l'observateur à l'aide de \fBPTRACE_GETEVENTMSG\fP. .IP L'observateur peut ignorer l'appel système en modifiant le numéro de l'appel système à \fB\-1\fP. Autrement, l'observateur peut modifier l'appel système demandé en le passant à un numéro d'appel système valable. Si l'observateur demande à ignorer l'appel système, ce dernier renverra la valeur que l'observateur place dans le registre du code de retour. .IP .\" This was changed in ce6526e8afa4. .\" A related hole, using PTRACE_SYSCALL instead of SECCOMP_RET_TRACE, was .\" changed in arch-specific commits, e.g. 93e35efb8de4 for X86 and .\" 0f3912fd934c for ARM. Avant le noyau\ 4.8, la vérification seccomp ne sera pas refaite après que l'observateur ait reçu une notification (cela signifie que sur les anciens noyaux, les conteneurs basés sur seccomp \fBne doivent pas\fP autoriser l'utilisation de \fBptrace\fP(2) –\ même sur d'autres processus encapsulés\ – sans une prudence extrême\ ; les ptracers peuvent utiliser ce mécanisme pour sortir d'un conteneur seccomp). .IP Remarquez que le processus d'un observateur ne sera pas notifié si un autre filtre renvoie une valeur d'action ayant une priorité supérieure à \fBSECCOMP_RET_TRACE\fP. .TP \fBSECCOMP_RET_LOG\fP (depuis Linux\ 4.14) .\" commit 59f5cf44a38284eb9e76270c786fb6cc62ef8ac4 Cette valeur fait exécuter l'appel système après l'enregistrement de l'action de retour du filtre. Un administrateur peut supplanter la journalisation de cette action à l'aide du fichier \fI/proc/sys/kernel/seccomp/actions_logged\fP. .TP \fBSECCOMP_RET_ALLOW\fP Cette valeur provoque l'exécution de l'appel système. .PP .\" commit 4d3b0b05aae9ee9ce0970dc4cc0fb3fad5e85945 .\" Si on indique un code d'action différent de ceux ci\-dessus, l'action de filtre est traitée soit comme un \fBSECCOMP_RET_KILL_PROCESS\fP (depuis Linux\ 4.14), soit comme un \fBSECCOMP_RET_KILL_THREAD\fP (dans Linux\ 4.13 et antérieurs). .SS "Interfaces /proc" Les fichiers du répertoire \fI/proc/sys/kernel/seccomp\fP offrent des informations et des configurations seccomp supplémentaires\ : .TP \fIactions_avail\fP (depuis Linux 4.14) .\" commit 8e5f1ad116df6b0de65eac458d5e7c318d1c05af Une liste ordonnée en lecture seule d'actions de renvoi de filtre seccomp sous la forme d'une chaîne. L'ordre, de gauche à droite, est décroissant pour la priorité. La liste représente l'ensemble des actions de renvoi de filtre seccomp gérées par le noyau. .TP \fIactions_logged\fP (depuis Linux 4.14) .\" commit 0ddec0fc8900201c0897b87b762b7c420436662f Une liste ordonnée en lecture\-écriture d'actions de renvoi de filtre seccomp autorisées pour la journalisation. Les écritures dans le fichier n'ont pas besoin d'être ordonnées, mais les lectures se feront dans le même ordre que pour \fIactions_avail\fP. .IP Il est important de remarquer que la valeur de \fIactions_logged\fP n'empêche pas certaines actions de renvoi de filtre d'être enregistrées quand le sous\-système d'audit est configuré pour auditer une tâche. Si l'action n'est pas retrouvée dans le fichier \fIactions_logged\fP, la décision finale d'auditer l'action de cette tâche revient au sous\-système d'audit pour toutes les actions de renvoi de filtre autres que \fBSECCOMP_RET_ALLOW\fP. .IP .\" La chaîne «\ allow\ » n'est pas acceptée dans le fichier \fIactions_logged\fP car il n'est pas possible d'enregistrer les actions \fBSECCOMP_RET_ALLOW\fP. Essayer d'écrire «\ allow\ » dans le fichier échouera avec l'erreur \fBEINVAL\fP. .SS "Enregistrement d'audit des actions seccomp" .\" commit 59f5cf44a38284eb9e76270c786fb6cc62ef8ac4 .\" or auditing could be enabled via the netlink API (AUDIT_SET) Depuis Linux\ 4.14, le noyau offre la possibilité d'enregistrer les actions renvoyées par des filtres seccomp dans le compte\-rendu d'audit. Le noyau prend la décision d'enregistrer une action à partir du type d'action, de sa présence dans le fichier \fIactions_logged\fP et de l'activation de l'audit du noyau (par exemple avec l'option d'amorçage du noyau \fIaudit=1\fP). Les règles sont les suivantes\ : .IP * 3 Si l'action est \fBSECCOMP_RET_ALLOW\fP, l'action n'est pas enregistrée. .IP * Sinon, si l'action est \fBSECCOMP_RET_KILL_PROCESS\fP ou \fBSECCOMP_RET_KILL_THREAD\fP et si elle apparaît dans le fichier \fIactions_logged\fP, l'action est enregistrée. .IP * Sinon, si le filtre a demandé l'enregistrement (l'attribut \fBSECCOMP_FILTER_FLAG_LOG\fP) et si elle apparaît dans le fichier \fIactions_logged\fP, l'action est enregistrée. .IP * Sinon, si l'audit du noyau est activé et si le processus doit être audité (\fBautrace\fP(8)), l'action est enregistrée. .IP * Sinon, l'action n'est pas enregistrée. .SH "VALEUR RENVOYÉE" En cas de succès, \fBseccomp\fP() renvoie \fB0\fP. En cas d'erreur, si \fBSECCOMP_FILTER_FLAG_TSYNC\fP était utilisé, le code de retour est l'identifiant du thread qui a fait échouer la synchronisation (il s'agit d'un identifiant de thread du noyau du type renvoyé par \fBclone\fP(2) et \fBgettid\fP(2)). Si d'autres erreurs se produisent, \fB\-1\fP est renvoyé et \fIerrno\fP est positionné pour indiquer la cause de l'erreur. .SH ERREURS \fBseccomp\fP() peut échouer pour les raisons suivantes\ : .TP \fBEACCES\fP L'appelant n'avait pas la capacité \fBCAP_SYS_ADMIN\fP dans son espace de noms utilisateur ou n'avait pas positionné \fIno_new_privs\fP avant d'utiliser \fBSECCOMP_SET_MODE_FILTER\fP. .TP \fBEFAULT\fP \fIargs\fP n'était pas une adresse valable. .TP \fBEINVAL\fP L'\fIopération\fP est inconnue ou n'est pas prise en charge par cette version ou cette configuration du noyau. .TP \fBEINVAL\fP Les \fIflags\fP spécifiés ne sont pas valables pour l'\fIopération\fP donnée. .TP \fBEINVAL\fP L'\fIopération\fP comprenait \fBBPF_ABS\fP, mais la position indiquée n'était pas alignée sur une limite 32\ bits ou elle dépassait \fIsizeof(struct\ seccomp_data)\fP. .TP \fBEINVAL\fP .\" See kernel/seccomp.c::seccomp_may_assign_mode() in 3.18 sources Un mode de calcul sécurisé a déjà été défini et l'\fIopération\fP diffère du paramétrage existant. .TP \fBEINVAL\fP \fIopération\fP indiquait \fBSECCOMP_SET_MODE_FILTER\fP mais le programme de filtre vers lequel pointait \fIargs\fP n'était pas valable ou sa longueur était de zéro ou dépassait \fBBPF_MAXINSNS\fP instructions (4096). .TP \fBENOMEM\fP Plus assez de mémoire. .TP \fBENOMEM\fP .\" ENOMEM in kernel/seccomp.c::seccomp_attach_filter() in 3.18 sources La taille totale de tous les programmes de filtre rattachés au thread appelant dépasserait \fBMAX_INSNS_PER_PATH\fP instructions (32768). Remarquez qu'afin de calculer cette limite, chaque programme de filtre déjà existant intègre une pénalité de dépassement de \fB4\fP instructions. .TP \fBEOPNOTSUPP\fP \fIopération\fP indiquait \fBSECCOMP_GET_ACTION_AVAIL\fP mais le noyau ne gère pas l'action de renvoi de filtre indiquée par \fIargs\fP. .TP \fBESRCH\fP Un autre thread a provoqué un échec pendant la synchronisation, mais son identifiant n'a pas pu être déterminé. .SH VERSIONS .\" FIXME . Add glibc version L'appel système \fBseccomp\fP() est apparu pour la première fois dans Linux 3.17. .SH CONFORMITÉ L'appel système \fBseccomp\fP() est une extension Linux non standard. .SH NOTES Au lieu de coder à la main des filtres seccomp comme démontré dans l'exemple ci\-dessous, vous pourriez préférer utiliser la bibliothèque \fIlibseccomp\fP qui fournit une interface de génération de filtres seccomp. .PP Le champ \fISeccomp\fP du fichier \fI/proc/[pid]/status\fP offre une méthode de visualisation du mode seccomp du processus\ ; voir \fBproc\fP(5). .PP \fBseccomp\fP() fournit un sur\-ensemble de fonctionnalités de l'opération \fBPR_SET_SECCOMP\fP de \fBprctl\fP(2) (qui ne prend pas en charge les \fIflags\fP). .PP .\" Depuis Linux\ 4.4, l'opération \fBPTRACE_SECCOMP_GET_FILTER\fP de \fBptrace\fP(2) peut être utilisée pour obtenir les filtres seccomp d'un processus. .SS "Gestion d'architecture pour le BPF seccomp" .\" Check by grepping for HAVE_ARCH_SECCOMP_FILTER in Kconfig files in .\" kernel source. Last checked in Linux 4.16-rc source. La gestion d'architecture pour le filtrage de BPF seccomp est disponible sur les architectures suivantes\ : .IP * 3 x86\-64, i386, x32 (depuis Linux\ 3.5) .PD 0 .IP * ARM (depuis Linux\ 3.8) .IP * s390 (depuis Linux\ 3.8) .IP * MIPS (depuis Linux\ 3.16) .IP * ARM\-64 (depuis Linux\ 3.19) .IP * PowerPC (depuis Linux\ 4.3) .IP * Tile (depuis Linux\ 4.3) .IP * .\" User mode Linux since Linux 4.6 PA\-RISC (depuis Linux\ 4.6) .PD .\" .SS "Mises en garde" Il y a beaucoup de subtilités à prendre en compte lorsqu'on applique des filtres seccomp à un programme, notamment\ : .IP * 3 Certains appels système traditionnels ont des implémentations dans l'espace utilisateur dans le \fBvdso\fP(7) de nombreuses architectures. Parmi les exemples remarquables, se trouvent \fBclock_gettime\fP(2), \fBgettimeofday\fP(2) et \fBtime\fP(2). Sur de telles architectures, le filtrage seccomp de ces appels système sera sans effet (il y a cependant des cas où les implémentations \fBvdso\fP(7) se rabattent sur le véritable appel système, alors les filtres seccomp verraient l'appel système). .IP * Le filtrage seccomp s'appuie sur les numéros d'appel système. Cependant, les applications n'appellent généralement pas directement les appels système, mais plutôt les fonctions enveloppe de la bibliothèque\ C qui appellent à leur tour les appels système. Par conséquent, vous devez garder en tête ce qui suit\ : .RS .IP \(bu 3 Les enveloppes de la glibc pour certains appels système traditionnels peuvent utiliser des appels système ayant des noms différents dans le noyau. Par exemple, la fonction enveloppe \fBexit\fP(2) utilise en fait l'appel système \fBexit_group\fP(2) et la fonction \fBfork\fP(2) utilise en réalité les appels \fBclone\fP(2). .IP \(bu Le comportement des fonctions enveloppe peut changer en fonction des architectures, selon la plage d'appels système fournie sur ces architectures. Autrement dit, la même fonction enveloppe peut appeler différents appels système selon les architectures. .IP \(bu Enfin, le comportement des fonctions enveloppe peut changer selon les versions de la glibc. Par exemple, dans d'anciennes versions, la fonction enveloppe de la glibc de \fBopen\fP(2) appelait l'appel système du même nom, mais à partir de la\ 2.26, l'implémentation est passée à l'appel \fBopenat\fP(2) sur toutes les architectures. .RE .PP La conséquence des points ci\-dessus est qu'il pourrait être nécessaire de filtrer un appel système autre que celui prévu. Plusieurs pages de manuel de la section\ 2 donnent des détails utiles sur les différences entre les fonctions enveloppe et les appels système sous\-jacents dans les sous\-sections intitulées \fIDifférences entre le noyau et la bibliothèque\ C\fP. .PP .\" En outre, remarquez que l'application de filtres seccomp risque même de provoquer des bogues dans une application, quand les filtres provoquent des échecs inattendus d'opérations légitimes que l'application a besoin d'effectuer. De tels bogues pourraient ne pas être facilement identifiés lors d'un test des filtres seccomp s'ils se produisent à des endroits du code rarement utilisés. .SS "Détails BPF spécifiques à seccomp" Remarquez que les détails BPF suivants sont spécifiques aux filtres seccomp\ : .IP * 3 Les modificateurs de taille \fBBPF_H\fP et \fBBPF_B\fP ne sont pas pris en charge\ : toutes les opérations doivent charger et stocker des mots (4\ octets) (\fBBPF_W\fP). .IP * Pour accéder au contenu du tampon \fIseccomp_data\fP, utilisez le modificateur du mode d'adressage \fBBPF_ABS\fP. .IP * Le modificateur du mode d'adressage \fBBPF_LEN\fP produit un opérande de mode immédiatement dont la valeur est la taille du tampon \fIseccomp_data\fP. .SH EXEMPLES Le programme ci\-dessous accepte quatre paramètres ou plus. Les trois premiers sont un numéro d'appel système, un identifiant numérique d'architecture et un numéro d'erreur. Le programme utilise ces valeurs pour construire un filtre BPF utilisé lors de l'exécution pour effectuer les vérifications suivantes\ : .IP [1] 4 Si le programme ne tourne pas sur l'architecture indiquée, le filtre BPF fait échouer les appels système avec l'erreur \fBENOSYS\fP. .IP [2] Si le programme essaie d'exécuter l'appel système ayant le numéro indiqué, le filtre BPF fait échouer l'appel système en positionnant \fIerrno\fP sur le numéro d'erreur indiqué. .PP Les autres paramètres de la ligne de commande indiquent le chemin et les paramètres supplémentaires d'un programme que notre exemple doit essayer d'exécuter en utilisant \fBexecv\fP(3) (une fonction de bibliothèque qui utilise l'appel système \fBexecve\fP(2)). Certains exemples d’exécution du programme sont présentés ci\-dessous. .PP Tout d'abord, on affiche l'architecture sur laquelle on est (x86\-64) puis on construit une fonction d’interpréteur qui cherche les numéros d'appels système sur cette architecture\ : .PP .in +4n .EX $ \fBuname \-m\fP x86_64 $ \fBsyscall_nr() { cat /usr/src/linux/arch/x86/syscalls/syscall_64.tbl | \e awk \(aq$2 != "x32" && $3 == "\(aq$1\(aq" { print $1 }\(aq }\fP .EE .in .PP Quand le filtre BPF rejette un appel système (cas n°\ 2 ci\-dessus), il fait échouer l'appel système avec le numéro d'erreur indiqué sur la ligne de commande. Dans les exemples présentés ici, nous utiliserons le numéro d'erreur 99\ : .PP .in +4n .EX $ \fBerrno 99\fP EADDRNOTAVAIL 99 Ne peut pas affecter l'adresse demandée .EE .in .PP Dans l'exemple suivant, on essaie d'exécuter la commande \fBwhoami\fP(1), mais le filtre BPF rejette l'appel système \fBexecve\fP(2), donc la commande n'est même pas exécutée\ : .PP .in +4n .EX $ \fBsyscall_nr execve\fP 59 $ \fB./a.out\fP Utilisation\ : ./a.out [] Astuce pour \ : AUDIT_ARCH_I386: 0x40000003 AUDIT_ARCH_X86_64\ : 0xC000003E $ \fB./a.out 59 0xC000003E 99 /bin/whoami\fP execv\ : Ne peut pas affecter l'adresse demandée .EE .in .PP Dans le prochain exemple, le filtre BPF rejette l'appel système \fBwrite\fP(2) pour que, même si elle a pu démarrer, la commande \fBwhoami\fP(1) ne puisse pas écrire de sortie\ : .PP .in +4n .EX $ \fBsyscall_nr write\fP 1 $ \fB./a.out 1 0xC000003E 99 /bin/whoami\fP .EE .in .PP Dans le dernier exemple, le filtre BPF rejette un appel système qui n'est pas utilisé par la commande \fBwhoami\fP(1), elle peut donc s'exécuter et produire une sortie\ : .PP .in +4n .EX $ \fBsyscall_nr preadv\fP 295 $ \fB./a.out 295 0xC000003E 99 /bin/whoami\fP cecilia .EE .in .SS "Source du programme" .EX #include #include #include #include #include #include #include #include #include #define X32_SYSCALL_BIT 0x40000000 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) static int install_filter(int syscall_nr, int t_arch, int f_errno) { unsigned int upper_nr_limit = 0xffffffff; /* Supposer qu'AUDIT_ARCH_X86_64 signifie l'ABI x86\-64 normale (dans l'ABI x32, tous les appels système ont 30 bits positionnés dans le champ \(aqnr\(aq, ce qui veut dire que les numéros sont >= X32_SYSCALL_BIT) */ if (t_arch == AUDIT_ARCH_X86_64) upper_nr_limit = X32_SYSCALL_BIT \- 1; struct sock_filter filter[] = { /* [0] Charger l'architecture depuis le tampon \(aqseccomp_data\(aq dans l'accumulateur */ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, arch))), /* [1] Revenir de 5 instructions si l'architecture ne correspond pas à \(aqt_arch\(aq */ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, t_arch, 0, 5), /* [2] Charger le numéro d'appel système à partir du tampon \(aqseccomp_data\(aq dans l'accumulateur */ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), /* [3] Vérifier l'ABI \- nécessaire seulement pour x86\-64 si on utilise une liste d'interdictions. Utiliser BPF_JGT au lieu de vérifier par rapport au masque de bits pour ne pas devoir recharger le numéro d'appel système. */ BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, upper_nr_limit, 3, 0), /* [4] Revenir d'une instruction si le numéro d'appel système ne correspond pas à \(aqsyscall_nr\(aq */ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall_nr, 0, 1), /* [5] Architecture et appel système correspondants\ : ne pas exécuter l'appel système et renvoyer \(aqf_errno\(aq dans \(aqerrno\(aq */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (f_errno & SECCOMP_RET_DATA)), /* [6] Cible du numéro d'appel système inadéquate\ : autoriser d'autres appels système */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), /* [7] Cible de l'architecture inadéquate\ : tuer le processus */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS), }; struct sock_fprog prog = { .len = ARRAY_SIZE(filter), .filter = filter, }; if (seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog)) { perror("seccomp"); return 1; } return 0; } int main(int argc, char **argv) { if (argc < 5) { fprintf(stderr, "Utilisation\ : " "%s []\en" "Astuce pour : AUDIT_ARCH_I386: 0x%X\en" " AUDIT_ARCH_X86_64: 0x%X\en" "\en", argv[0], AUDIT_ARCH_I386, AUDIT_ARCH_X86_64); exit(EXIT_FAILURE); } if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("prctl"); exit(EXIT_FAILURE); } if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0), strtol(argv[3], NULL, 0))) exit(EXIT_FAILURE); execv(argv[4], &argv[4]); perror("execv"); exit(EXIT_FAILURE); } .EE .SH "VOIR AUSSI" \fBbpfc\fP(1), \fBstrace\fP(1), \fBbpf\fP(2), \fBprctl\fP(2), \fBptrace\fP(2), \fBsigaction\fP(2), \fBproc\fP(5), \fBsignal\fP(7), \fBsocket\fP(7) .PP Plusieurs pages de la bibliothèque \fIlibseccomp\fP, dont\ : \fBscmp_sys_resolver\fP(1), \fBseccomp_export_bpf\fP(3), \fBseccomp_init\fP(3), \fBseccomp_load\fP(3) et \fBseccomp_rule_add\fP(3). .PP .\" commit c061f33f35be0ccc80f4b8e0aea5dfd2ed7e01a3 Les fichiers \fIDocumentation/networking/filter.txt\fP et \fIDocumentation/userspace\-api/seccomp_filter.rst\fP des sources du noyau (ou \fIDocumentation/prctl/seccomp_filter.txt\fP avant Linux\ 4.13). .PP McCanne, S.\& et Jacobson, V.\& (1992) \fIThe BSD Packet Filter\ : une nouvelle architecture de captation de paquets au niveau utilisateur\fP, colloque de la conférence USENIX à l'hiver 1993 .UR http://www.tcpdump.org/papers/bpf\-usenix93.pdf .UE .SH COLOPHON Cette page fait partie de la publication\ 5.10 du projet \fIman\-pages\fP Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse \%https://www.kernel.org/doc/man\-pages/. .PP .SH TRADUCTION La traduction française de cette page de manuel a été créée par Christophe Blaess , Stéphan Rafin , Thierry Vignaud , François Micaux, Alain Portal , Jean-Philippe Guérard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas François , Florentin Duneau , Simon Paillard , Denis Barbier , David Prévot , Jean-Philippe MENGUAL et Jean-Pierre Giraud . .PP Cette traduction est une documentation libre ; veuillez vous reporter à la .UR https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3 .UE concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. .PP Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à .MT debian-l10n-french@lists.debian.org .ME .