Provided by: manpages-fr-dev_4.19.0-7_all bug

NOM

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

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #include <linux/seccomp.h>  /* Définition des constantes SECCOMP_* */
       #include <linux/filter.h>   /* Définition de struct sock_fprog */
       #include <linux/audit.h>    /* Définition des constantes AUDIT_* */
       #include <linux/signal.h>   /* Définition des constantes SIG* */
       #include <sys/ptrace.h>     /* Définition des constantes PTRACE_* */
       #include <sys/syscall.h>    /* Définition des constantes SYS_* */
       #include <unistd.h>

       int syscall(SYS_seccomp, unsigned int opération, unsigned int flags,
                   void *args);

       Remarque :  la  glibc ne fournit pas d'enveloppe pour seccomp(), imposant l'utilisation de
       syscall(2).

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'opération 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  aboutissent  à  la fin du thread appelant ou à la fin du processus complet
              avec le signal SIGKILL quand il n'y a qu'un seul thread. 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.

              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  enfant  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_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_NEW_LISTENER (depuis Linux 5.0)
                     Après une installation réussie du programme de filtrage, renvoyer un nouveau
                     descripteur  de  fichier  de   notification   pour   l'espace   utilisateur.
                     (L'attribut  close-on-exec est défini pour le descripteur de fichier.) Quand
                     le filtre renvoie SECCOMP_RET_USER_NOTIF, une notification sera envoyée à ce
                     descripteur de fichier.

                     Pour  un  thread,  au maximum un seul filtre de seccomp utilisant l'attribut
                     SECCOMP_FILTER_FLAG_NEW_LISTENER peut être installé.

                     Consultez seccomp_unotify(2) pour plus de détails.

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

              SECCOMP_FILTER_FLAG_TSYNC
                     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 seccomp()
                     distincts génère différents filtres depuis cette perspective).

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

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

       SECCOMP_GET_NOTIF_SIZES (depuis Linux 5.O)
              Obtenir la taille  des  structures  de  notification  de  l'espace  utilisateur  de
              seccomp.  Comme  ces  structures  peuvent  évoluer  et croître avec le temps, cette
              commande peut être utilisée pour déterminer quelle quantité de mémoire allouer pour
              envoyer et recevoir des notifications.

              La  valeur  de  flags  doit  être de 0 et args doit être un pointeur vers un struct
              seccomp_notif_sizes de la forme suivante :

              struct seccomp_notif_sizes
                  __u16 seccomp_notif;      /* Taille de la structure de notification */
                  __u16 seccomp_notif_resp; /* Taille de la structure de réponse */
                  __u16 seccomp_data;       /* Taille de 'struct seccomp_data' */
              };

              Consultez seccomp_unotify(2) pour plus de détails.

   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  appelé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 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.

       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é  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 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_USER_NOTIF (depuis Linux 5.0)
              Faire  suivre  l'appel  système  à  un processus de superviseur attaché de l'espace
              utilisateur attaché pour permettre à ce processus de décider quoi faire de  l'appel
              système.  Si  il n'y a pas de superviseur attaché (soit parce que le filtre n'a pas
              été installé avec  l'attribut  SECCOMP_FILTER_FLAG_NEW_LISTENER  ou  parce  que  le
              descripteur de fichier était fermé), le filtre renvoie ENOSYS (c'est similaire à ce
              qui se produit quand un  filtre  renvoie  SECCOMP_RET_TRACE  et  qu'il  n'y  a  pas
              d'observateur). Consultez seccomp_unotify(2) pour plus de détails.

              Remarquez  que  le  processus de superviseur ne sera pas notifié si un autre filtre
              renvoie une valeur d'action ayant une priorité supérieure à SECCOMP_RET_USER_NOTIF.

       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  Linux 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 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  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 a été
       utilisé,  le  code  de  retour  est  l'identifiant  du thread à l'origine de l'échec de la
       synchronisation (cet identifiant est un identifiant de thread du noyau du type renvoyé par
       clone(2) et gettid(2)). Si une autre erreur arrive, -1 est renvoyé et errno est positionné
       pour indiquer 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.

       EBUSY  Pendant      l'installation       d'un       nouveau       filtre,       l'attribut
              SECCOMP_FILTER_FLAG_NEW_LISTENER a été indiqué, mais un filtre précédent a déjà été
              installé avec cet attribut.

       EFAULT args n'était pas une adresse valable.

       EINVAL L'opération 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'opération donnée.

       EINVAL L'opération  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'opération diffère du  paramétrage
              existant.

       EINVAL opération 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
              opération 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.

STANDARDS

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

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

       •  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és 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 <linux/audit.h>
       #include <linux/filter.h>
       #include <linux/seccomp.h>
       #include <stddef.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/prctl.h>
       #include <sys/syscall.h>
       #include <unistd.h>

       #define X32_SYSCALL_BIT 0x40000000
       #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

       static int
       install_filter(int syscall_nr, unsigned int t_arch, int f_errno)
       {
           unsigned int upper_nr_limit = 0xffffffff;

           /* On suppose que AUDIT_ARCH_X86_64 renvoie à l'ABI x86-64 normale
              (dans l'ABI x32, tous les appels système ont le bit 30 positionné
              dans le champ 'nr', donc 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 en arrière 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 depuis le 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] Reculer 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 (syscall(SYS_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),
                              strtoul(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),  seccomp_unotify(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

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>,  Jean-Philippe  MENGUAL
       <jpmengual@debian.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⟩.