Provided by: manpages-fr-dev_4.13-4_all bug

NOM

       seccomp – Agir sur l'état de calcul sécurisé (Secure Computing State) du processus

SYNOPSIS

       #include <linux/seccomp.h>
       #include <linux/filter.h>
       #include <linux/audit.h>
       #include <linux/signal.h>
       #include <sys/ptrace.h>

       int seccomp(unsigned int operation, unsigned int flags, void *args);

DESCRIPTION

       L'appel  système  seccomp()  agit  sur  l'état  de  calcul sécurisé (seccomp) du processus
       appelant.

       Actuellement, Linux gère les valeurs d'operation suivantes :

       SECCOMP_SET_MODE_STRICT
              Les seuls appels système que le thread appelant est autorisé à faire sont  read(2),
              write(2),  _exit(2)  (mais  pas  exit_group(2))  et sigreturn(2). Les autres appels
              système envoient un signal SIGKILL. Le mode de calcul  sécurisé  strict  est  utile
              pour  les  applications  fonctionnant  à coups de chiffres qui peuvent avoir besoin
              d'exécuter un code à octets non fiable, obtenu peut-être en lisant un  tube  ou  un
              socket.

              Remarquez  que  si  le thread appelant ne peut plus appeler sigprocmask(2), il peut
              utiliser sigreturn(2) pour bloquer tous les signaux, sauf ceux provenant de SIGKILL
              et  de  SIGSTOP. Cela veut dire que alarm(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, SIGKILL doit être utilisé. On peut le faire en utilisant timer_create(2)
              avec SIGEV_SIGNAL et sigev_signo positionné à SIGKILL ou en utilisant  setrlimit(2)
              pour positionner la limite ferme de RLIMIT_CPU.

              Cette   opération   n'est   disponible  que  si  le  noyau  a  été  configuré  avec
              CONFIG_SECCOMP.

              La valeur de flags doit être de 0 et args doit être NULL.

              Cette opération est fonctionnellement identique à l'appel :

                  prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);

       SECCOMP_SET_MODE_FILTER
              Les appels système autorisés sont définis par un pointeur vers un  filtre  Berkeley
              Packet  (BPF)  fourni  à  l'aide  de  args.  Ce  paramètre est un pointeur vers une
              struct sock_fprog ; 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,
              seccomp() échoue en renvoyant EINVAL dans errno.

              Si fork(2) ou clone(2) est autorisé par le filtre,  les  processus  enfants  seront
              contraints  par les mêmes filtres d'appel système que leur parent. Si execve(2) est
              autorisé, les filtres existants seront préservés lors d'un appel à execve(2).

              Pour utiliser l'opération SECCOMP_SET_MODE_FILTER, soit  le  thread  appelant  doit
              avoir  la  capacité CAP_SYS_ADMIN dans son espace de noms utilisateur, soit il doit
              avoir déjà le bit no_new_privs défini. Si ce bit n'a pas déjà été positionné par un
              ascendant du thread, le thread doit effectuer l'appel suivant :

                  prctl(PR_SET_NO_NEW_PRIVS, 1);

              Sinon,  l'opération  SECCOMP_SET_MODE_FILTER  échoue  et renvoie EACCES dans errno.
              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 execve(2), compromettant ainsi le programme (un tel filtre malveillant
              pourrait,  par  exemple,  conduire  setuid(2) à essayer de définir les identifiants
              utilisateur de l'appelant à des valeurs non nulles  pour  renvoyer  plutôt  0  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).

              Si  prctl(2)  ou  seccomp()  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.

              L'opération  SECCOMP_SET_MODE_FILTER  n'est  disponible  que  si  le  noyau  a  été
              configuré avec CONFIG_SECCOMP_FILTER.

              Quand flags vaut 0, cette opération est fonctionnellement identique à l'appel :

                  prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, args);

              Les paramètres reconnus de flags sont :

              SECCOMP_FILTER_FLAG_TSYNC
                     Lors de l'ajout  d'un  filtre,  synchroniser  tous  les  autres  threads  du
                     processus  appelant  sur  la  même  arborescence  de  filtres  seccomp.  Une
                     « arborescence de filtres » est une liste ordonnée de filtres rattachés à un
                     thread  (le  rattachement  de  filtres  identiques dans des appels seccomp()
                     distincts génère différents filtres depuis cette perspective).

                     Si un 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
                     SECCOMP_MODE_STRICT ou  si  des  filtres  seccomp  lui  sont  rattachés,  en
                     décalage par rapport à l'arborescence de filtres du thread appelant.

              SECCOMP_FILTER_FLAG_LOG (depuis Linux 4.14)
                     Toutes  les  actions  de renvoi des filtres, sauf SECCOMP_RET_ALLOW, 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
                     /proc/sys/kernel/seccomp/actions_logged.

              SECCOMP_FILTER_FLAG_SPEC_ALLOW (depuis Linux 4.17)
                     Désactiver la mitigation Speculative Store Bypass.

       SECCOMP_GET_ACTION_AVAIL (depuis Linux 4.14)
              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
              SECCOMP_RET_KILL_PROCESS.

              La  valeur de flags doit être de 0 et args doit être un pointeur vers une action de
              renvoi de filtre 32 bits non signé.

   Filtres
       Lors de l'ajout d'un filtre à l'aide  de  SECCOMP_SET_MODE_FILTER,  args  pointe  vers  un
       programme de filtrage :

           struct sock_fprog {
               unsigned short      len;    /* Nombre d'instructions BPF */
               struct sock_filter *filter; /* Pointeur vers le tableau
                                              d'instructions BPF */
           };

       Chaque programme doit contenir une ou plusieurs instructions BPF :

           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 */
           };

       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 BPF_ABS) en tant que tampon (en lecture seule) ayant la forme suivante :

           struct seccomp_data {
               int   nr;                   /* Numéro de l'appel système */
               __u32 arch;                 /* Valeur AUDIT_ARCH_*
                                              (voir <linux/audit.h>) */
               __u64 instruction_pointer;  /* pointeur vers l'instruction du processeur */
               __u64 args[6];              /* Jusqu'à 6 paramètres de l'appel système */
           };

       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 execve(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 arch.

       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 Mises en garde
       ci-dessous.

       Le  champ  arch n'est pas unique pour toutes les conventions d'appelant. Les ABI x86-64 et
       x32 utilisent AUDIT_ARCH_X86_64 en tant que arch  et  elles  fonctionnent  sur  les  mêmes
       processeurs.  Au  contraire, le masque __X32_SYSCALL_BIT est utilisé sur le numéro d'appel
       système pour parler indépendamment aux deux ABI.

       Cela veut dire  qu'une  politique  peut  soit  interdire  tous  les  appels  système  avec
       __X32_SYSCALL_BIT,  soit  elle  doit  les  reconnaître  avec  le  positionnement ou pas de
       __X32_SYSCALL_BIT. Une liste des appels système à interdire qui s'appuie sur nr et qui  ne
       contient pas de valeurs nr__X32_SYSCALL_BIT est positionné peut être contournée par un
       programme malveillant qui positionne __X32_SYSCALL_BIT.

       En outre, les noyaux précédant Linux 5.4 autorisaient  à  tort  nr  dans  les  intervalles
       512–547  ainsi  que  les  appels système non x32 correspondants reliés (opération OU) avec
       __X32_SYSCALL_BIT. Par exemple, nr == 521 et nr ==  (101 |  __X32_SYSCALL_BIT)  créeraient
       des  appels  ptrace(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
       ENOSYS sans rien faire.

       Le  champ  instruction_pointer fournit l'adresse de l'instruction en langage machine qui a
       effectué l'appel système. Cela pourrait être utile avec  /proc/[pid]/maps  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  mmap(2)  et
       mprotect(2) pour empêcher le programme de contourner de telles vérifications).

       Lors  de  la  vérification  des  valeurs  de  args, 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  int, 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.

       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  SECCOMP_RET_ACTION_FULL),
       contient une des valeurs « action » listée ci-dessous ; la moins significative, de 16 bits
       (définie par la constante SECCOMP_RET_DATA), contient des « data » à associer à ce code de
       retour.

       Si plusieurs filtres existent, ils  sont  tous  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  appellés renvoie SECCOMP_RET_KILL. 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 particulier). 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.

       Dans  l'ordre décroissant de priorité, les valeurs d'action qui peuvent être renvoyées par
       un filtre seccomp sont :

       SECCOMP_RET_KILL_PROCESS (depuis Linux 4.14)
              Cette valeur aboutit à la fin immédiate  du  processus,  avec  un  vidage  mémoire.
              L'appel   système   n'est  pas  exécuté.  Contrairement  à  SECCOMP_RET_KILL_THREAD
              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 CLONE_THREAD de clone(2)).

              Le  processus  se  termine  parce que il a été tué par un signal SIGSYS. Même si un
              gestionnaire de signal a été enregistré pour SIGSYS, le  gestionnaire  sera  ignoré
              dans  ce cas et le processus se termine toujours. Le processus parent qui attend ce
              processus (en utilisant waitpid(2) ou équivalent) reçoit wstatus  qui  indique  que
              son enfant s'est terminé suite à un signal SIGSYS.

       SECCOMP_RET_KILL_THREAD (ou SECCOMP_RET_KILL)
              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.

              Le    thread    s'est    terminé   comme   tué   par   un   signal   SIGSYS.   Voir
              SECCOMP_RET_KILL_PROCESS ci-dessus.

              Avant Linux 4.11, tout processus qui se terminait de cette manière ne générait  pas
              de  vidage  mémoire (bien que SIGSYS soit documenté dans signal(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.

              Avec      l'apparition     de     SECCOMP_RET_KILL_PROCESS     dans     Linux 4.14,
              SECCOMP_RET_KILL_THREAD a été ajouté comme synonyme de  SECCOMP_RET_KILL,  afin  de
              distinguer plus clairement les deux actions.

              Remarque : l'utilisation de SECCOMP_RET_KILL_THREAD 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.

       SECCOMP_RET_TRAP
              Cette  valeur  fait  envoyer  par  le  noyau  un  signal  SIGSYS  adressé au thread
              déclencheur (l'appel système n'est pas exécuté). Divers champs  seront  positionnés
              dans la structure siginfo_t (voir sigaction(2)) associée au signal :

              –  si_signo contiendra SIGSYS.

              –  si_call_addr affichera l'adresse de l'instruction de l'appel système.

              –  si_syscall et si_arch indiqueront l'appel système qui a été essayé.

              –  si_code contiendra SYS_SECCOMP.

              –  si_errno contiendra la partie SECCOMP_RET_DATA du code de retour du filtre.

              Le  compteur  du programme sera arrêté sitôt l'appel système 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
              ENOSYS écraserait des informations utiles).

       SECCOMP_RET_ERRNO
              Cette valeur fait passer la partie SECCOMP_RET_DATA du code de retour du  filtre  à
              l'espace utilisateur en tant que valeur errno sans exécuter l'appel système.

       SECCOMP_RET_TRACE
              Quand  cette  valeur  est  renvoyée, le noyau essaiera de notifier à un observateur
              basé sur ptrace(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
              errno sur ENOSYS.

              Un  observateur  sera  notifié  s'il  demande  PTRACE_O_TRACESECCOMP  en  utilisant
              ptrace(PTRACE_SETOPTIONS).  Il  sera notifié d'un PTRACE_EVENT_SECCOMP et la partie
              SECCOMP_RET_DATA du code de  retour  du  filtre  sera  mise  à  la  disposition  de
              l'observateur à l'aide de PTRACE_GETEVENTMSG.

              L'observateur  peut  ignorer  l'appel  système  en  modifiant  le numéro de l'appel
              système à -1. 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.

              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  ne  doivent  pas  autoriser  l'utilisation de
              ptrace(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).

              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 à SECCOMP_RET_TRACE.

       SECCOMP_RET_LOG (depuis Linux 4.14)
              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 /proc/sys/kernel/seccomp/actions_logged.

       SECCOMP_RET_ALLOW
              Cette valeur provoque l'exécution de l'appel système.

       Si on indique un code d'action différent de ceux ci-dessus, l'action de filtre est traitée
       soit    comme   un   SECCOMP_RET_KILL_PROCESS   (depuis   Linux 4.14),   soit   comme   un
       SECCOMP_RET_KILL_THREAD (dans Linux 4.13 et antérieurs).

   Interfaces /proc
       Les fichiers du  répertoire  /proc/sys/kernel/seccomp  offrent  des  informations  et  des
       configurations seccomp supplémentaires :

       actions_avail (depuis Linux 4.14)
              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.

       actions_logged (depuis Linux 4.14)
              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
              actions_avail.

              Il  est  important  de  remarquer  que  la  valeur  de actions_logged n'empêche pas
              certaines actions de renvoi  de  filtre  de  s'enregistrer  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 actions_logged, 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 SECCOMP_RET_ALLOW.

              La chaîne « allow » n'est pas acceptée dans le fichier actions_logged car il  n'est
              pas   possible   d'enregistrer  les  actions  SECCOMP_RET_ALLOW.  Essayer  d'écrire
              « allow » dans le fichier échouera avec l'erreur EINVAL.

   Enregistrement d'audit des actions seccomp
       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 actions_logged et  de
       l'activation  de l'audit du noyau (par exemple avec l'option d'amorçage du noyau audit=1).
       Les règles sont les suivantes :

       –  Si l'action est SECCOMP_RET_ALLOW, l'action n'est pas enregistrée.

       –  Sinon, si l'action est SECCOMP_RET_KILL_PROCESS ou SECCOMP_RET_KILL_THREAD et  si  elle
          apparaît dans le fichier actions_logged, l'action est enregistrée.

       –  Sinon,  si le filtre a demandé l'enregistrement (l'attribut SECCOMP_FILTER_FLAG_LOG) et
          si elle apparaît dans le fichier actions_logged, l'action est enregistrée.

       –  Sinon, si l'audit du noyau est activé et si le processus doit être audité (autrace(8)),
          l'action est enregistrée.

       –  Sinon, l'action n'est pas enregistrée.

VALEUR RENVOYÉE

       En cas de succès, seccomp() renvoie 0. En cas d'erreur, si SECCOMP_FILTER_FLAG_TSYNC é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
       clone(2) et gettid(2)). Si d'autres erreurs se produisent, -1 est  renvoyé  et  errno  est
       positionné pour indiquer la cause de l'erreur.

ERREURS

       seccomp() peut échouer pour les raisons suivantes :

       EACCES L'appelant   n'avait  pas  la  capacité  CAP_SYS_ADMIN  dans  son  espace  de  noms
              utilisateur   ou   n'avait   pas   positionné   no_new_privs    avant    d'utiliser
              SECCOMP_SET_MODE_FILTER.

       EFAULT args n'était pas une adresse valable.

       EINVAL L'operation  est  inconnue  ou n'est pas prise en charge par cette version ou cette
              configuration du noyau.

       EINVAL Les flags spécifiés ne sont pas valables pour l'operation donnée.

       EINVAL L'operation comprenait BPF_ABS, mais la position indiquée n'était pas  alignée  sur
              une limite 32 bits ou elle dépassait sizeof(struct seccomp_data).

       EINVAL Un  mode de calcul sécurisé a déjà été défini et l'operation diffère du paramétrage
              existant.

       EINVAL operation indiquait SECCOMP_SET_MODE_FILTER mais le programme de filtre vers lequel
              pointait  args  n'était  pas  valable  ou  sa  longueur  était de zéro ou dépassait
              BPF_MAXINSNS instructions (4096).

       ENOMEM Plus assez de mémoire.

       ENOMEM La taille totale de tous les programmes de  filtre  rattachés  au  thread  appelant
              dépasserait  MAX_INSNS_PER_PATH 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 4 instructions.

       EOPNOTSUPP
              operation  indiquait SECCOMP_GET_ACTION_AVAIL mais le noyau ne gère pas l'action de
              renvoi de filtre indiquée par args.

       ESRCH  Un  autre  thread  a  provoqué  un  échec  pendant  la  synchronisation,  mais  son
              identifiant n'a pas pu être déterminé.

VERSIONS

       L'appel système seccomp() est apparu pour la première fois dans Linux 3.17.

CONFORMITÉ

       L'appel système seccomp() est une extension Linux non standard.

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 libseccomp qui fournit  une  interface  de
       génération de filtres seccomp.

       Le  champ Seccomp du fichier /proc/[pid]/status offre une méthode de visualisation du mode
       seccomp du processus ; voir proc(5).

       seccomp() fournit un sur-ensemble de  fonctionnalités  de  l'opération  PR_SET_SECCOMP  de
       prctl(2) (qui ne prend pas en charge les flags).

       Depuis  Linux 4.4,  l'opération  PTRACE_SECCOMP_GET_FILTER de ptrace(2) peut être utilisée
       pour obtenir un fichier des filtres seccomp d'un processus.

   Gestion d'architecture pour le BPF seccomp
       La gestion d'architecture  pour  le  filtrage  de  BPF  seccomp  est  disponible  sur  les
       architectures suivantes :

       –  x86-64, i386, x32 (depuis Linux 3.5)
       –  ARM (depuis Linux 3.8)
       –  s390 (depuis Linux 3.8)
       –  MIPS (depuis Linux 3.16)
       –  ARM-64 (depuis Linux 3.19)
       –  PowerPC (depuis Linux 4.3)
       –  Tile (depuis Linux 4.3)
       –  PA-RISC (depuis Linux 4.6)

   Mises en garde
       Il y a beaucoup de subtilités à prendre en compte lorsqu'on applique des filtres seccomp à
       un programme, notamment :

       –  Certains appels système traditionnels ont des implémentations dans l'espace utilisateur
          dans  le  vdso(7)  de  nombreuses  architectures.  Parmi  les exemples remarquables, se
          trouvent clock_gettime(2), gettimeofday(2) et time(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 vdso(7) se rabattent sur le véritable appel système, alors les  filtres
          seccomp verraient l'appel système).

       –  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 :

            •
             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 exit(2) utilise en  fait  l'appel  système  exit_group(2)  et  la
             fonction fork(2) utilise en réalité les appels clone(2).

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

            •
             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
             open(2)  appelait  l'appel  système  du  même  nom,  mais  à  partir   de   la 2.26,
             l'implémentation est passée à l'appel openat(2) sur toutes les architectures.

       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  Différences  entre  le  noyau  et   la
       bibliothèque C.

       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.

   Détails BPF spécifiques à seccomp
       Remarquez que les détails BPF suivants sont spécifiques aux filtres seccomp :

       –  Les  modificateurs  de  taille  BPF_H  et BPF_B ne sont pas pris en charge : toutes les
          opérations doivent charger et stocker des mots (4 octets) (BPF_W).

       –  Pour accéder au contenu du  tampon  seccomp_data,  utilisez  le  modificateur  du  mode
          d'adressage BPF_ABS.

       –  Le  modificateur  du mode d'adressage BPF_LEN produit un opérande de mode immédiatement
          dont la valeur est la taille du tampon seccomp_data.

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 :

       [1] Si  le programme ne tourne pas sur l'architecture indiquée, le filtre BPF fait échouer
           les appels système avec l'erreur ENOSYS.

       [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 errno sur le numéro d'erreur indiqué.

       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
       execv(3)  (une  fonction  de bibliothèque qui utilise l'appel système execve(2)). Certains
       exemples d’exécution du programme sont présentées ci-dessous.

       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 :

           $ uname -m
           x86_64
           $ syscall_nr() {
               cat /usr/src/linux/arch/x86/syscalls/syscall_64.tbl | \
               awk '$2 != "x32" && $3 == "'$1'" { print $1 }'
           }

       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 :

           $ errno 99
           EADDRNOTAVAIL 99 Ne peut pas affecter l'adresse demandée

       Dans  l'exemple  suivant,  on  essaie d'exécuter la commande whoami(1), mais le filtre BPF
       rejette l'appel système execve(2), donc la commande n'est même pas exécutée :

           $ syscall_nr execve
           59
           $ ./a.out
           Utilisation : ./a.out <syscall_nr> <arch> <errno> <prog> [<args>]
           Astuce pour <arch> : AUDIT_ARCH_I386: 0x40000003
                            AUDIT_ARCH_X86_64 : 0xC000003E
           $ ./a.out 59 0xC000003E 99 /bin/whoami
           execv : Ne peut pas affecter l'adresse demandée

       Dans le prochain exemple, le filtre BPF rejette l'appel système write(2) pour que, même si
       elle a pu démarrer, la commande whoami(1) ne puisse pas écrire de sortie :

           $ syscall_nr write
           1
           $ ./a.out 1 0xC000003E 99 /bin/whoami

       Dans  le dernier exemple, le filtre BPF rejette un appel système qui n'est pas utilisé par
       la commande whoami(1), elle peut donc s'exécuter et produire une sortie :

           $ syscall_nr preadv
           295
           $ ./a.out 295 0xC000003E 99 /bin/whoami
           cecilia

   Source du programme
       #include <errno.h>
       #include <stddef.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <linux/audit.h>
       #include <linux/filter.h>
       #include <linux/seccomp.h>
       #include <sys/prctl.h>

       #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 'nr', 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
                      'seccomp_data' 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 à 't_arch' */
               BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, t_arch, 0, 5),

               /* [2] Charger le numéro d'appel système à partir du tampon
                      'seccomp_data' 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 à 'syscall_nr' */
               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 'f_errno' dans 'errno' */
               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 <syscall_nr> <arch> <errno> <prog> [<args>]\n"
                       "Astuce pour <arch>: AUDIT_ARCH_I386: 0x%X\n"
                       "                 AUDIT_ARCH_X86_64: 0x%X\n"
                       "\n", 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);
       }

VOIR AUSSI

       bpfc(1),  strace(1),  bpf(2),  prctl(2),  ptrace(2),  sigaction(2),  proc(5),   signal(7),
       socket(7)

       Plusieurs    pages   de   la   bibliothèque   libseccomp,   dont :   scmp_sys_resolver(1),
       seccomp_export_bpf(3), seccomp_init(3), seccomp_load(3) et seccomp_rule_add(3).

       Les              fichiers              Documentation/networking/filter.txt              et
       Documentation/userspace-api/seccomp_filter.rst     des     sources     du     noyau    (ou
       Documentation/prctl/seccomp_filter.txt avant Linux 4.13).

       McCanne, S. et Jacobson, V. (1992)  The BSD Packet Filter : une nouvelle  architecture  de
       captation  de  paquets  au  niveau utilisateur, colloque de la conférence USENIX à l'hiver
       1993 ⟨http://www.tcpdump.org/papers/bpf-usenix93.pdf

COLOPHON

       Cette page fait partie de la publication 5.10 du projet man-pages 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/.

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-Philippe MENGUAL
       <jpmengual@debian.org>

       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 ⟨⟩.