Man page - memfd_create(2)

Packages contains this manual

Available languages:

en fr ja ru

Manual

memfd_create

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
VALEUR RENVOYÉE
ERREURS
STANDARDS
HISTORIQUE
NOTES
Verrou de fichiers
EXEMPLES
Source du programme : t_memfd_create.c
Source du programme : t_get_seals.c
VOIR AUSSI
TRADUCTION

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 .