Provided by: manpages-fr-dev_4.18.1-1_all bug

NOM

       memfd_create - Créer un fichier anonyme

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #define _GNU_SOURCE         /* Consultez feature_test_macros(7) */
       #include <sys/mman.h>

       int memfd_create(const char *name, unsigned int flags);

DESCRIPTION

       memfd_create()  crée  un  fichier  anonyme  et  renvoie  un descripteur de fichier qui s'y
       rapporte. Le fichier se comporte comme un fichier  normal,  il  peut  donc  être  modifié,
       tronqué, projeté en mémoire, et ainsi de suite. Mais contrairement à un fichier normal, il
       réside dans la RAM et son stockage est volatile. Une fois que  toutes  les  références  au
       fichier  ont  disparu, il est automatiquement libéré. La mémoire anonyme est utilisée pour
       toutes les pages de sauvegarde du fichier. Les fichiers créés par memfd_create() ont  donc
       la  même  sémantique  que  les autres allocations de mémoire anonyme telles que celles qui
       utilisent mmap(2) avec l'attribut MAP_ANONYMOUS.

       La taille initiale du fichier est positionnée  à  0.  Après  l'appel,  elle  devrait  être
       définie  en  utilisant  ftruncate(2)  (ou  le  fichier  peut  être rempli par des appels à
       write(2) ou équivalent).

       Le nom fourni dans name est utilisé comme nom de fichier et sera affiché en tant que cible
       du  lien  symbolique  correspondant  dans  le  répertoire /proc/self/fd/. Le nom affiché a
       toujours un préfixe memfd: et il ne sert que pour le débogage. Les noms ne changent pas le
       comportement  du  descripteur  de  fichier  et en tant que tels plusieurs fichiers peuvent
       avoir le même nom sans effets de bord.

       Les valeurs suivantes peuvent subir une opération OU logique bit à  bit  dans  flags  pour
       modifier le comportement de memfd_create() :

       MFD_CLOEXEC
              Placer  l'attribut  « close-on-exec »  (FD_CLOEXEC)  sur  le nouveau descripteur de
              fichier. Consultez la description de l'attribut O_CLOEXEC dans open(2) pour  savoir
              pourquoi cela peut être utile.

       MFD_ALLOW_SEALING
              Permettre  des  opérations  de  verrouillage  sur ce fichier. Voir le point sur les
              opérations  F_ADD_SEALS  et  F_GET_SEALS  dans  fcntl(2),  ainsi  que   les   NOTES
              ci-dessous.  Le  positionnement initial des verrous est vide. Si cet attribut n'est
              pas défini, le positionnement initial des verrous sera  F_SEAL_SEAL,  ce  qui  veut
              dire qu'aucun autre verrou ne peut être positionné sur le fichier.

       MFD_HUGETLB (depuis Linux 4.14)
              Le  fichier  anonyme  sera  créé  sur le système de fichiers hugetlbfs en utilisant
              d'immenses pages. Voir le fichier Documentation/admin-guide/mm/hugetlbpage.rst  des
              sources du noyau Linux pour plus d'informations sur hugetlbfs. Le fait d'indiquer à
              la fois MFD_HUGETLB et MFD_ALLOW_SEALING dans flags est pris en charge depuis Linux
              4.16.

       MFD_HUGE_2MB, MFD_HUGE_1GB, ...
              Utilisé  avec  MFD_HUGETLB  pour  sélectionner  d'autres  tailles  de  page hugetlb
              (respectivement 2 Mo, 1 Go, ...) sur les systèmes qui gèrent plusieurs  tailles  de
              page hugetlb. Les définitions des tailles de page immenses connues figurent dans le
              fichier d'entête <linux/memfd.h>.

              Pour des détails sur l'encodage des tailles des pages immenses ne figurant pas dans
              le fichier d'entête, voir le point sur les constantes du même nom dans mmap(2).

       Les bits inusitées dans flags doivent valoir 0.

       En  code de retour, memfd_create() renvoie un nouveau descripteur de fichier qui peut être
       utilisé pour se référer au fichier. Ce descripteur de fichier est ouvert en lecture et  en
       écriture (O_RDWR)  et O_LARGEFILE est positionné pour le descripteur de fichier.

       Par  rapport à fork(2) et execve(2), la sémantique habituelle s'applique au descripteur de
       fichier créé par memfd_create(). Une copie du descripteur de  fichier  est  récupérée  par
       l'enfant  produit  par  fork(2)  et  elle  se  rapporte au même fichier. Le descripteur de
       fichier est préservé  pendant  un  execve(2),  sauf  si  l'attribut  close-on-exec  a  été
       positionné.

VALEUR RENVOYÉE

       En  cas  de  succès,  memfd_create()  renvoie  un  nouveau  descripteur de fichier. En cas
       d'erreur, -1 est renvoyé et errno est positionné pour indiquer l'erreur.

ERREURS

       EFAULT L'adresse dans name pointe vers une mémoire non valable.

       EINVAL flags comprend des bits inconnus.

       EINVAL name était trop long (la limite de 249 octets, n'incluant pas l'octet NULL final).

       EINVAL MFD_HUGETLB et MFD_ALLOW_SEALING ont tous deux été indiqués dans flags.

       EMFILE La limite du nombre de descripteurs de fichiers par processus a été atteinte.

       ENFILE La limite du nombre total  de  fichiers  ouverts  pour  le  système  entier  a  été
              atteinte.

       ENOMEM Mémoire insuffisante pour créer un nouveau fichier anonyme.

VERSIONS

       L'appel système memfd_create() est apparu dans Linux 3.17 ; la prise en charge de la glibc
       a été ajouté dans la glibc 2.27.

       EPERM  L'attribut MFD_HUGETLB a été spécifié, mais l'appelant  n'est  pas  un  utilisateur
              privilégié  (il  n'a pas la capacité CAP_IPC_LOCK) et il n'est pas membre du groupe
              sysctl_hugetlb_shm_group ;        consultez        la        description         de
              /proc/sys/vm/sysctl_hugetlb_shm_group dans proc(5).

STANDARDS

       L'appel système memfd_create() est spécifique à Linux.

NOTES

       L'appel système memfd_create() offre une alternative simple au montage manuel d'un système
       de fichiers tmpfs(5) et à la création et l'ouverture  d'un  fichier  dans  ce  système  de
       fichiers.  Le  premier  objectif  de  memfd_create()  est  de  créer  des fichiers et leur
       descripteur associé, utilisés avec les API de verrou de fichiers fournis par fcntl(2).

       L'appel système memfd_create() s'utilise également sans verrou de fichier (c'est  pourquoi
       le  verrouillage  de  fichier  a  été  désactivé  sauf  demande  explicite avec l'attribut
       MFD_ALLOW_SEALING). En particulier, il peut être utilisé comme alternative pour créer  des
       fichiers  dans  tmp ou pour utiliser O_TMPFILE de open(2), si vous ne voulez pas rattacher
       le fichier résultant au système de fichiers.

   Verrou de fichiers
       En l'absence de verrou de fichier, les processus qui communiquent  à  travers  la  mémoire
       partagée doivent soit se faire confiance entre eux, soit prendre des mesures pour gérer la
       possibilité qu'un pair non fiable manipule  la  région  de  mémoire  partagée  de  manière
       problématique.  Par exemple, un pair non fiable pourrait modifier le contenu de la mémoire
       partagée n'importe quand ou rétrécir la zone de mémoire partagée. La première  éventualité
       rend     le    processus    local    vulnérable    aux    conflits    (race    conditions)
       time-of-check-to-time-of-use (généralement gérés en copiant les  données  de  la  zone  de
       mémoire  partagée  avant de les vérifier et de les utiliser). La deuxième éventualité rend
       le processus  local  vulnérable  aux  signaux  SIGBUS  quand  on  essaie  d'accéder  à  un
       emplacement  inexistant dans la zone de mémoire partagée (gérer cette éventualité implique
       d'utiliser un gestionnaire pour le signal SIGBUS).

       La gestion de pairs non fiables impose une plus grande complexité du code qui  utilise  la
       mémoire  partagée.  Les  verrous  mémoire  éliminent  cette complexité, en permettant à un
       processus d'agir en toute sécurité en sachant que son pair ne peut pas modifier la mémoire
       partagée de manière non souhaitée.

       Voici un exemple d'utilisation du mécanisme de verrouillage :

       (1)  Le  premier  processus  crée un fichier tmpfs(5) en utilisant memfd_create(). L'appel
            donne un descripteur de fichier utilisé dans les étapes ultérieures.

       (2)  Le premier processus dimensionne le fichier créé à l'étape  précédente  en  utilisant
            ftruncate(2),  il  le projette en utilisant mmap(2) et il remplit la mémoire partagée
            avec les données désirées.

       (3)  Le premier processus utilise l'opération F_ADD_SEALS de fcntl(2)  pour  poser  un  ou
            plusieurs  verrous  sur  le fichier afin de restreindre des modifications ultérieures
            (si on pose un verrou F_SEAL_WRITE, il sera nécessaire de désassocier  la  projection
            modifiable   partagée   créée  à  l'étape  précédente.  Sinon,  on  peut  obtenir  un
            comportement identique à F_SEAL_WRITE en utilisant F_SEAL_FUTURE_WRITE, qui empêchera
            des  écritures ultérieures à l'aide de mmap(2) et de write(2), tout en conservant les
            projections modifiables partagées existantes).

       (4)  Un deuxième processus obtient un descripteur de fichier pour le fichier  tmpfs(5)  et
            le projette. Parmi les origines possibles de cela, vous trouverez :

            •  Le processus qui a appelé memfd_create() a pu transférer le descripteur de fichier
               consécutif au deuxième processus à  l'aide  d'un  socket  de  domaine  UNIX  (voir
               unix(7)  et cmsg(3)). Le deuxième processus projette alors le fichier en utilisant
               mmap(2).

            •  Le deuxième processus est  créé  à  l'aide  de  fork(2)  et,  ainsi,  il  récupère
               automatiquement  le descripteur de fichier et sa projection (remarquez que dans ce
               cas et dans le prochain, il existe une relation de confiance naturelle  entre  les
               deux  processus puisqu'ils tournent sous le même identifiant utilisateur. Donc, un
               verrou de fichier n'est, en principe, pas nécessaire).

            •  Le  deuxième  processus  ouvre  le  fichier  /proc/<pid>/fd/<fd>,  où  <pid>   est
               l'identifiant   de   processus   du   premier   processus   (celui  qui  a  appelé
               memfd_create()) et <fd> est le  numéro  du  descripteur  de  fichier  renvoyé  par
               l'appel  à  memfd_create dans ce processus. Le deuxième processus projette ensuite
               le fichier en utilisant mmap(2).

       (5)  Le deuxième processus utilise l'opération F_GET_SEALS de fcntl(2) pour  récupérer  le
            masque  de  bits  de  verrous  appliqué  au fichier. Ce masque peut être examiné pour
            déterminer le type de restrictions posées aux modifications du fichier.  Si  vous  le
            souhaitez,  le  deuxième  processus  peut  appliquer des verrous supplémentaires pour
            imposer d'autres restrictions (tant que le verrou  F_SEAL_SEAL  n'a  pas  encore  été
            appliqué).

EXEMPLES

       Voici  deux  exemples de programme montrant l'utilisation de memfd_create() et de l'API de
       verrou de fichier.

       Le  premier  programme,  t_memfd_create.c,  crée  un   fichier   tmpfs(5)   en   utilisant
       memfd_create(),  donne  une  taille au fichier, le projette en mémoire et, en option, pose
       des verrous sur le fichier. Le programme accepte jusqu'à  trois  paramètres  en  ligne  de
       commande,  dont les deux premiers sont requis. Le premier paramètre est le nom à donner au
       fichier, le deuxième est la taille à lui donner, le troisième, optionnel, est  une  chaîne
       de caractères qui indique les verrous à poser sur le fichier.

       Le  deuxième  programme,  t_get_seals.c, peut être utilisé pour ouvrir un fichier existant
       créé à l'aide de memfd_create() et examiner les verrous qui y sont posés.

       La session d'interpréteur suivant montre l'utilisation  de  ces  programmes.  Nous  créons
       d'abord un fichier tmpfs(5) et nous posons des verrous dessus :

           $ ./t_memfd_create my_memfd_file 4096 sw &
           [1] 11775
           PID: 11775; fd: 3; /proc/11775/fd/3

       À  ce moment, le programme t_memfd_create continue à s'exécuter en tâche de fond. À partir
       d'un autre programme, nous pouvons obtenir un descripteur de fichier pour le fichier  créé
       par memfd_create() en ouvrant /proc/pid/fd qui correspond au descripteur de fichier ouvert
       par memfd_create(). En utilisant ce chemin, nous examinons le contenu du  lien  symbolique
       /proc/pid/fd et nous utilisons notre programme t_get_seals pour voir les verrous posés sur
       le fichier :

           $ readlink /proc/11775/fd/3
           /memfd:my_memfd_file (deleted)
           $ ./t_get_seals /proc/11775/fd/3
           Verrous existants : WRITE SHRINK

   Source du programme : t_memfd_create.c

       #define _GNU_SOURCE
       #include <err.h>
       #include <fcntl.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/mman.h>
       #include <unistd.h>

       int
       main(int argc, char *argv[])
       {
           int           fd;
           char          *name, *seals_arg;
           ssize_t       len;
           unsigned int  seals;

           if (argc < 3) {
               fprintf(stderr, "%s name size [seals]\n", argv[0]);
               fprintf(stderr, "\t'seals' can contain any of the "
                       "following characters:\n");
               fprintf(stderr, "\t\tg - F_SEAL_GROW\n");
               fprintf(stderr, "\t\ts - F_SEAL_SHRINK\n");
               fprintf(stderr, "\t\tw - F_SEAL_WRITE\n");
               fprintf(stderr, "\t\tW - F_SEAL_FUTURE_WRITE\n");
               fprintf(stderr, "\t\tS - F_SEAL_SEAL\n");
               exit(EXIT_FAILURE);
           }

           name = argv[1];
           len = atoi(argv[2]);
           seals_arg = argv[3];

           /* Créer un fichier anonyme dans tmpfs ; permet de poser
               des verrous sur le fichier. */

           fd = memfd_create(name, MFD_ALLOW_SEALING);
           if (fd == -1)
               err(EXIT_FAILURE, "memfd_create");

           /* Taille du fichier indiquée sur la ligne de commande. */

           if (ftruncate(fd, len) == -1)
               err(EXIT_FAILURE, "truncate");

           printf("PID: %jd; fd: %d; /proc/%jd/fd/%d\n",
                  (intmax_t) getpid(), fd, (intmax_t) getpid(), fd);

           /* Code pour projeter le fichier et remplir la projection
              avec des données omises. */

           /* Si un paramètre 'seals' de la ligne de commande est fourni,
              poser des verrous sur le fichier. */

           if (seals_arg != NULL) {
               seals = 0;

               if (strchr(seals_arg, 'g') != NULL)
                   seals |= F_SEAL_GROW;
               if (strchr(seals_arg, 's') != NULL)
                   seals |= F_SEAL_SHRINK;
               if (strchr(seals_arg, 'w') != NULL)
                   seals |= F_SEAL_WRITE;
               if (strchr(seals_arg, 'W') != NULL)
                   seals |= F_SEAL_FUTURE_WRITE;
               if (strchr(seals_arg, 'S') != NULL)
                   seals |= F_SEAL_SEAL;

               if (fcntl(fd, F_ADD_SEALS, seals) == -1)
                   err(EXIT_FAILURE, "fcntl");
           }

           /* Continuer l’exécution pour que le fichier créé par
              memfd_create() continue à exister. */

           pause();

           exit(EXIT_SUCCESS);
       }

   Source du programme : t_get_seals.c

       #define _GNU_SOURCE
       #include <err.h>
       #include <fcntl.h>
       #include <stdio.h>
       #include <stdlib.h>

       int
       main(int argc, char *argv[])
       {
           int           fd;
           unsigned int  seals;

           if (argc != 2) {
               fprintf(stderr, "%s /proc/PID/fd/FD\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fd = open(argv[1], O_RDWR);
           if (fd == -1)
               err(EXIT_FAILURE, "open");

           seals = fcntl(fd, F_GET_SEALS);
           if (seals == -1)
               err(EXIT_FAILURE, "fcntl");

           printf("Existing seals:");
           if (seals & F_SEAL_SEAL)
               printf(" SEAL");
           if (seals & F_SEAL_GROW)
               printf(" GROW");
           if (seals & F_SEAL_WRITE)
               printf(" WRITE");
           if (seals & F_SEAL_FUTURE_WRITE)
               printf(" FUTURE_WRITE");
           if (seals & F_SEAL_SHRINK)
               printf(" SHRINK");
           printf("\n");

           /* Code pour associer le fichier et l'accès au contenu de la
              projection résultante omise. */

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       fcntl(2), ftruncate(2), memfd_secret(2), mmap(2), shmget(2), shm_open(3)

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