Provided by: manpages-fr-dev_4.26.0-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.

       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

       Linux.

HISTORIQUE

       Linux 3.17, glibc 2.27.

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 <sys/types.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' peut contenir un des "
                       "caractères suivants :\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("Verrous existants :");
           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.9.1                    15 juin 2024                                   memfd_create(2)