Provided by: manpages-fr-dev_4.21.0-2_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 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.

Pages du manuel de Linux 6.03                    5 février 2023                                  memfd_create(2)