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

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