memfd_create(2) System Calls Manual memfd_create(2) NOM memfd_create - Creer un fichier anonyme BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #define _GNU_SOURCE /* Consultez feature_test_macros(7) */ #include int memfd_create(const char *name, unsigned int flags); DESCRIPTION memfd_create() cree un fichier anonyme et renvoie un descripteur de fichier qui s'y rapporte. Le fichier se comporte comme un fichier normal, il peut donc etre modifie, tronque, projete en memoire, et ainsi de suite. Mais contrairement a un fichier normal, il reside dans la RAM et son stockage est volatile. Une fois que toutes les references au fichier ont disparu, il est automatiquement libere. La memoire anonyme est utilisee pour toutes les pages de sauvegarde du fichier. Les fichiers crees par memfd_create() ont donc la meme semantique que les autres allocations de memoire anonyme telles que celles qui utilisent mmap(2) avec l'attribut MAP_ANONYMOUS. La taille initiale du fichier est positionnee a 0. Apres l'appel, elle devrait etre definie en utilisant ftruncate(2) (ou le fichier peut etre rempli par des appels a write(2) ou equivalent). Le nom fourni dans name est utilise comme nom de fichier et sera affiche en tant que cible du lien symbolique correspondant dans le repertoire /proc/self/fd/. Le nom affiche a toujours un prefixe memfd: et il ne sert que pour le debogage. Les noms ne changent pas le comportement du descripteur de fichier et en tant que tels plusieurs fichiers peuvent avoir le meme nom sans effets de bord. Les valeurs suivantes peuvent subir une operation OU logique bit a 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 etre utile. MFD_ALLOW_SEALING Permettre des operations de verrouillage sur ce fichier. Voir le point sur les operations 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 defini, le positionnement initial des verrous sera F_SEAL_SEAL, ce qui veut dire qu'aucun autre verrou ne peut etre positionne sur le fichier. MFD_HUGETLB (depuis Linux 4.14) Le fichier anonyme sera cree sur le systeme 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 a la fois MFD_HUGETLB et MFD_ALLOW_SEALING dans flags est pris en charge depuis Linux 4.16. MFD_HUGE_2MB MFD_HUGE_1GB ... Utilise avec MFD_HUGETLB pour selectionner d'autres tailles de page hugetlb (respectivement 2 Mo, 1 Go, ...) sur les systemes qui gerent plusieurs tailles de page hugetlb. Les definitions des tailles de page immenses connues figurent dans le fichier d'entete . Pour des details sur l'encodage des tailles des pages immenses ne figurant pas dans le fichier d'entete, voir le point sur les constantes du meme nom dans mmap(2). Les bits inusitees dans flags doivent valoir 0. En code de retour, memfd_create() renvoie un nouveau descripteur de fichier qui peut etre utilise pour se referer au fichier. Ce descripteur de fichier est ouvert en lecture et en ecriture (O_RDWR) et O_LARGEFILE est positionne pour le descripteur de fichier. Par rapport a fork(2) et execve(2), la semantique habituelle s'applique au descripteur de fichier cree par memfd_create(). Une copie du descripteur de fichier est recuperee par l'enfant produit par fork(2) et elle se rapporte au meme fichier. Le descripteur de fichier est preserve pendant un execve(2), sauf si l'attribut close-on-exec a ete positionne. VALEUR RENVOYEE En cas de succes, memfd_create() renvoie un nouveau descripteur de fichier. En cas d'erreur, -1 est renvoye et errno est positionne pour indiquer l'erreur. ERREURS EFAULT L'adresse dans name pointe vers une memoire non valable. EINVAL flags comprend des bits inconnus. EINVAL name etait trop long (la limite de 249 octets, n'incluant pas l'octet NULL final). EINVAL MFD_HUGETLB et MFD_ALLOW_SEALING ont tous deux ete indiques dans flags. EMFILE La limite du nombre de descripteurs de fichiers par processus a ete atteinte. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENOMEM Memoire insuffisante pour creer un nouveau fichier anonyme. EPERM L'attribut MFD_HUGETLB a ete specifie, mais l'appelant n'est pas un utilisateur privilegie (il n'a pas la capacite 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 systeme memfd_create() offre une alternative simple au montage manuel d'un systeme de fichiers tmpfs(5) et a la creation et l'ouverture d'un fichier dans ce systeme de fichiers. Le premier objectif de memfd_create() est de creer des fichiers et leur descripteur associe, utilises avec les API de verrou de fichiers fournis par fcntl(2). L'appel systeme memfd_create() s'utilise egalement sans verrou de fichier (c'est pourquoi le verrouillage de fichier a ete desactive sauf demande explicite avec l'attribut MFD_ALLOW_SEALING). En particulier, il peut etre utilise comme alternative pour creer des fichiers dans tmp ou pour utiliser O_TMPFILE de open(2), si vous ne voulez pas rattacher le fichier resultant au systeme de fichiers. Verrou de fichiers En l'absence de verrou de fichier, les processus qui communiquent a travers la memoire partagee doivent soit se faire confiance entre eux, soit prendre des mesures pour gerer la possibilite qu'un pair non fiable manipule la region de memoire partagee de maniere problematique. Par exemple, un pair non fiable pourrait modifier le contenu de la memoire partagee n'importe quand ou retrecir la zone de memoire partagee. La premiere eventualite rend le processus local vulnerable aux conflits (race conditions) time-of-check-to-time-of-use (generalement geres en copiant les donnees de la zone de memoire partagee avant de les verifier et de les utiliser). La deuxieme eventualite rend le processus local vulnerable aux signaux SIGBUS quand on essaie d'acceder a un emplacement inexistant dans la zone de memoire partagee (gerer cette eventualite implique d'utiliser un gestionnaire pour le signal SIGBUS). La gestion de pairs non fiables impose une plus grande complexite du code qui utilise la memoire partagee. Les verrous memoire eliminent cette complexite, en permettant a un processus d'agir en toute securite en sachant que son pair ne peut pas modifier la memoire partagee de maniere non souhaitee. Voici un exemple d'utilisation du mecanisme de verrouillage : (1) Le premier processus cree un fichier tmpfs(5) en utilisant memfd_create(). L'appel donne un descripteur de fichier utilise dans les etapes ulterieures. (2) Le premier processus dimensionne le fichier cree a l'etape precedente en utilisant ftruncate(2), il le projette en utilisant mmap(2) et il remplit la memoire partagee avec les donnees desirees. (3) Le premier processus utilise l'operation F_ADD_SEALS de fcntl(2) pour poser un ou plusieurs verrous sur le fichier afin de restreindre des modifications ulterieures (si on pose un verrou F_SEAL_WRITE, il sera necessaire de desassocier la projection modifiable partagee creee a l'etape precedente. Sinon, on peut obtenir un comportement identique a F_SEAL_WRITE en utilisant F_SEAL_FUTURE_WRITE, qui empechera des ecritures ulterieures a l'aide de mmap(2) et de write(2), tout en conservant les projections modifiables partagees existantes). (4) Un deuxieme 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 appele memfd_create() a pu transferer le descripteur de fichier consecutif au deuxieme processus a l'aide d'un socket de domaine UNIX (voir unix(7) et cmsg(3)). Le deuxieme processus projette alors le fichier en utilisant mmap(2). - Le deuxieme processus est cree a l'aide de fork(2) et, ainsi, il recupere 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 meme identifiant utilisateur. Donc, un verrou de fichier n'est, en principe, pas necessaire). - Le deuxieme processus ouvre le fichier /proc/pid/fd/fd ou est l'identifiant de processus du premier processus (celui qui a appele memfd_create()) et est le numero du descripteur de fichier renvoye par l'appel a memfd_create dans ce processus. Le deuxieme processus projette ensuite le fichier en utilisant mmap(2). (5) Le deuxieme processus utilise l'operation F_GET_SEALS de fcntl(2) pour recuperer le masque de bits de verrous applique au fichier. Ce masque peut etre examine pour determiner le type de restrictions posees aux modifications du fichier. Si vous le souhaitez, le deuxieme processus peut appliquer des verrous supplementaires pour imposer d'autres restrictions (tant que le verrou F_SEAL_SEAL n'a pas encore ete applique). 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, cree un fichier tmpfs(5) en utilisant memfd_create(), donne une taille au fichier, le projette en memoire et, en option, pose des verrous sur le fichier. Le programme accepte jusqu'a trois parametres en ligne de commande, dont les deux premiers sont requis. Le premier parametre est le nom a donner au fichier, le deuxieme est la taille a lui donner, le troisieme, optionnel, est une chaine de caracteres qui indique les verrous a poser sur le fichier. Le deuxieme programme, t_get_seals.c, peut etre utilise pour ouvrir un fichier existant cree a l'aide de memfd_create() et examiner les verrous qui y sont poses. La session d'interpreteur suivant montre l'utilisation de ces programmes. Nous creons 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 A ce moment, le programme t_memfd_create continue a s'executer en tache de fond. A partir d'un autre programme, nous pouvons obtenir un descripteur de fichier pour le fichier cree 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 poses 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 #include #include #include #include #include #include #include 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 " "caracteres 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]; /* Creer 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 indiquee 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 donnees omises. */ /* Si un parametre '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'execution pour que le fichier cree par memfd_create() continue a exister. */ pause(); exit(EXIT_SUCCESS); } Source du programme : t_get_seals.c #define _GNU_SOURCE #include #include #include #include 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'acces au contenu de la projection resultante omise. */ exit(EXIT_SUCCESS); } VOIR AUSSI fcntl(2), ftruncate(2), memfd_secret(2), mmap(2), shmget(2), shm_open(3) TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 memfd_create(2)