unshare - Désassocier certaines parties du contexte
d'exécution
Bibliothèque C standard (libc, -lc)
#define _GNU_SOURCE
#include <sched.h>
int unshare(int flags);
unshare() permet à un processus (ou à un
thread) de désassocier certaines parties de son contexte
d'exécution qui sont actuellement partagées avec d'autres
processus (ou d'autres threads). Une partie du contexte d'exécution,
comme l'espace de noms de montage, est implicitement partagée quand
un processus est créé avec fork(2) ou vfork(2),
alors que d'autres parties, comme la mémoire virtuelle, peuvent
être partagées en faisant explicitement la demande lors de la
création d'un processus ou d'un thread avec clone(2).
L'intérêt principal de unshare() est de
permettre à un processus de contrôler son contexte
d'exécution partagé sans avoir à créer un
nouveau processus.
L'argument flags est un masque de bits qui indique quelles
parties du contexte d'exécution doivent être
désassociées. Cet argument est construit comme un OU binaire
entre les constantes suivantes :
- CLONE_FILES
- A l'effet inverse de l'attribut CLONE_FILES de clone(2).
Supprimer le partage de la table des descripteurs de fichier, afin que le
processus appelant ne partage plus ses descripteurs de fichier avec
d'autres processus.
- CLONE_FS
- Annuler l'effet de l'attribut CLONE_FS de clone(2).
Supprimer le partage des attributs de système de fichiers, afin que
le processus appelant ne partage plus son répertoire racine
(chroot(2)), son répertoire courant (chdir(2)) et sa
valeur d'umask (umask(2)) avec d'autres processus.
- CLONE_NEWCGROUP
(depuis Linux 4.6)
- Cet attribut a le même effet que l'attribut CLONE_NEWCGROUP
de clone(2). Départager l'espace de noms cgroup.
L'utilisation de CLONE_NEWCGROUP nécessite la
capacité CAP_SYS_ADMIN.
- CLONE_NEWIPC
(depuis Linux 2.6.19)
- Cet attribut a le même effet que l'attribut CLONE_NEWIPC de
clone(2). Supprimer le partage de l'espace de noms IPC, afin que le
processus appelant ait une copie privée de l'espace de noms IPC qui
ne soit pas partagée avec d'autres processus. L'utilisation de cet
attribut implique automatiquement aussi CLONE_SYSVSEM.
L'utilisation de CLONE_NEWIPC nécessite la capacité
CAP_SYS_ADMIN.
- CLONE_NEWNET
(depuis Linux 2.6.24)
- Cet attribut a le même effet que l'attribut CLONE_NEWNET de
clone(2). Supprimer le partage de l'espace de noms de
réseau, afin que le processus appelant soit déplacé
dans un nouvel espace de noms de réseau qui n'est pas
partagé avec d'autres processus. CLONE_NEWNET
nécessite la capacité CAP_SYS_ADMIN.
- CLONE_NEWNS
- Cet attribut a le même effet que l'attribut CLONE_NEWNS de
clone(2). Supprimer le partage de l'espace de noms de montage, afin
que le processus appelant ait une copie privée de son espace de
noms qui ne soit pas partagée avec d'autres processus.
L'utilisation de cet attribut implique automatiquement aussi
CLONE_FS. L'utilisation de CLONE_NEWNS nécessite la
capacité CAP_SYS_ADMIN. Pour plus d'informations, consultez
mount_namespaces(7).
- CLONE_NEWPID
(depuis Linux 3.8)
- Cet attribut a le même effet que l'attribut CLONE_NEWNS de
clone(2). Supprimr le partage l'espace de noms PID, afin que le
processus génère un nouvel espace de noms PID qui ne soit
pas partagé avec d'autres processus antérieurs et qui sera
celui de ses enfants. Le processus appelant ne change pas d'espace
de noms. Le premier enfant créé par le processus appelant
aura l'identifiant 1 et sera init(1) dans le nouvel espace de noms.
CLONE_NEWPID implique automatiquement CLONE_THREAD.
L'utilisation de CLONE_NEWPID nécessite de disposer de la
capacité CAP_SYS_ADMIN. Pour plus d'informations, consultez
pid_namespaces(7).
- CLONE_NEWTIME
(depuis Linux 5.6)
- Supprimer le partage de l'espace de noms temps, afin que le processus
appelant ait une copie privée de son espace de noms qui ne soit pas
partagée avec d'autres processus. Le processus appelant n'est
pas déplacé dans le nouvel espace de noms. L'utilisation
de CLONE_NEWTIME nécessite la capacité
CAP_SYS_ADMIN. Pour plus d'informations, consultez
time_namespaces(7).
- CLONE_NEWUSER
(depuis Linux 3.8)
- Cet attribut a le même effet que l'attribut CLONE_NEWUSER de
clone(2). Supprimer le partage de l'espace de noms utilisateur,
afin que le processus appelant soit déplacé dans un nouvel
espace de noms utilisateur qui n'est pas partagé avec d'autres
processus. Comme pour les enfants créés par clone(2)
avec l'attribut CLONE_NEWUSER, l'appelant obtient un ensemble
complet de capacités dans le nouvel espace de noms.
- CLONE_NEWUSER nécessite que le processus appelant ne soit
pas multi-threadé ; si CLONE_NEWUSER est
spécifié, CLONE_THREAD l'est automatiquement.
À partir de Linux 3.9, CLONE_NEWUSER implique
également automatiquement CLONE_FS. CLONE_NEWUSER
nécessite que les identifiants utilisateur et groupe du processus
appelant correspondent aux identifiants utilisateur et groupe dans
l'espace de noms utilisateur du processus appelant au moment de
l'appel.
- Pour obtenir plus d'informations sur les espaces de noms utilisateur,
consultez user_namespaces(7).
- CLONE_NEWUTS
(depuis Linux 2.6.19)
- Cet attribut a le même effet que l'attribut CLONE_NEWUTS de
clone(2). Départager l'espace de noms IPC UTS, afin que le
processus appelant ait une copie privée de l'espace de noms UTS qui
ne soit pas partagée avec d'autres processus. L'utilisation de
CLONE_NEWUTS nécessite la capacité
CAP_SYS_ADMIN.
- CLONE_SYSVSEM
(depuis Linux 2.6.26)
- Cet attribut inverse l'effet de l'attribut CLONE_SYSVSEM de
clone(2). Supprimer le partage des valeurs d'ajustement des
sémaphores System V (semadj), afin que le processus
appelant ait une nouvelle liste semadj vide qui ne soit
partagée avec aucun autre processus. S'il s'agit du dernier
processus ayant une référence à la liste
(semadj) du processus courant, alors les ajustements de cette liste
sont appliqués aux sémaphores correspondants, tels que
décrit dans semop(2).
De plus, CLONE_THREAD, CLONE_SIGHAND et
CLONE_VM peuvent être invoqués dans flags si
l'appelant est mono-threadé (c'est-à-dire s'il ne partage pas
son espace d'adressage avec un autre processus ou un autre thread). Dans ce
cas, ces attributs sont sans effet. Notez également que
spécifier CLONE_THREAD implique automatiquement
CLONE_VM, et que spécifier CLONE_VM implique
automatiquement CLONE_SIGHAND. Si le processus est
multi-threadé, al’utilisation de ces attributs mène
à une erreur.
Si flags vaut zéro, unshare() n'a aucun
effet : le contexte d'exécution du processus appelant n'est
pas modifié.
S'il réussit l'appel renvoie zéro, sinon il renvoie
-1 et errno est défini pour indiquer l'erreur.
- EINVAL
- Un attribut non autorisé est indiqué dans flags.
- EINVAL
- CLONE_THREAD, CLONE_SIGHAND ou CLONE_VM figurait dans
flags, et l'appelant était multi-threadé.
- EINVAL
- CLONE_NEWIPC a été spécifié dans
flags, mais le noyau n'a pas été configuré
avec les options CONFIG_SYSVIPC et CONFIG_IPC_NS.
- EINVAL
- CLONE_NEWNET a été spécifié dans
flags, mais le noyau n'a pas été configuré
avec l'option CONFIG_NET_NS.
- EINVAL
- CLONE_NEWPID a été spécifié dans le
flags, mais le noyau n'a pas été configuré
avec l'option CONFIG_PID_NS.
- EINVAL
- CLONE_NEWUSER a été spécifié dans
flags, mais le noyau n'a pas été configuré
avec l'option CONFIG_USER_NS.
- EINVAL
- CLONE_NEWUTS a été spécifié dans
flags, mais le noyau n'a pas été configuré
avec l'option CONFIG_UTS_NS.
- EINVAL
- CLONE_NEWPID a été spécifié dans
flags, mais le processus a appelé auparavant
unshare() avec l'attribut CLONE_NEWPID.
- ENOMEM
- Impossible d'allouer suffisamment de mémoire pour copier les
parties du contexte de l'appelant qui doivent être rendues
privées.
- ENOSPC (depuis
Linux 3.7)
- CLONE_NEWPID a été spécifié dans les
attributs et l'appel provoquerait un dépassement de la limite du
nombre maximal d'espaces de noms utilisateur imbriqués. Consultez
pid_namespaces(7).
- ENOSPC (depuis
Linux 4.9 ; auparavant EUSERS)
- CLONE_NEWUSER a été spécifié dans
flags et l'appel provoquerait un dépassement de la limite du
nombre maximal d'espaces de noms utilisateur imbriqués. Consultez
user_namespaces(7).
- De Linux 3.11 à Linux 4.8, l'erreur indiquée dans ce cas
était EUSERS.
- ENOSPC (depuis
Linux 4.9)
- Une des valeurs dans flags indiquait de créer un nouvel
espace de noms utilisateur, mais cela aurait provoqué un
dépassement de la limite définie par le fichier
correspondant dans /proc/sys/user. Pour plus de détails,
voir namespaces(7).
- EPERM
- Le processus appelant n'avait pas les privilèges appropriés
pour effectuer cette opération.
- EPERM
- CLONE_NEWUSER a été spécifié dans
flags, mais l'identifiant utilisateur effectif ou l'identifiant de
groupe effectif de l'appelant n'a pas de correspondance dans l'espace de
noms parent (consultez user_namespaces(7)).
- EPERM (depuis
Linux 3.9)
- CLONE_NEWUSER a été spécifié dans
flags et l'appelant se trouve dans un environnement chroot
(c'est-à-dire que le répertoire racine de l'appelant ne
correspond pas au répertoire racine de l'espace de noms de montage
dans lequel il se trouve).
- EUSERS (de Linux
3.11 à Linux 4.8)
- CLONE_NEWUSER a été spécifié dans
flags, et l'appel provoquerait un dépassement de la limite
du nombre maximal d'espaces de noms utilisateur imbriqués. Voir le
point sur l'erreur ENOSPC ci-dessus.
L'appel système unshare() est apparu dans
Linux 2.6.16.
L'appel système unshare() est spécifique
à Linux.
Tous les attributs de processus qui peuvent être
partagés lorsqu'un processus est créé avec
clone(2) ne peuvent pas être rendus privés avec
unshare(). En particulier, dans le noyau 3.8, unshare()
n'implémente pas de drapeaux inversant les effets de
CLONE_SIGHAND, CLONE_THREAD ou CLONE_VM. Cette
fonctionnalité pourra être ajoutée plus tard si
nécessaire.
La création de tout type d'espace de noms, à
l'exception des noms des espaces de noms utilisateur, requiert la
capacité CAP_SYS_ADMIN. Cependant, dans la mesure où la
création d'un espace de noms utilisateur confère un ensemble
complet de capacités, créer à la fois un espace de noms
utilisateur et un espace de noms de n'importe quel type dans le même
appel de unshare() ne nécessite pas la capacité
CAP_SYS_ADMIN dans l'espace de nom d'origine.
Le programme ci-dessous est une implémentation simple de la
commande unshare(1) qui supprime le partage d'un ou plusieurs espaces
de noms et exécute la commande fournie en argument. Voici un exemple
d'utilisation du programme qui exécute un shell dans un nouvel espace
de noms de montage, puis vérifie que le shell initial et le nouveau
shell sont bien dans des espaces de noms de montage
séparés :
$ readlink /proc/$$/ns/mnt
mnt:[4026531840]
$ sudo ./unshare -m /bin/bash
# readlink /proc/$$/ns/mnt
mnt:[4026532325]
Les deux chaînes renvoyées par readlink(1)
sont différentes, ce qui montre que les deux shells se trouvent dans
des espaces de noms de montage différents.
/* unshare.c
Une implémentation simple de la commande unshare(1): supprimer
le partage des espaces de noms et exécuter une commande.
*/
#define _GNU_SOURCE
#include <err.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void
usage(char *pname)
{
fprintf(stderr, "utilisation : %s [options] program [arg...]\n",
pname);
fprintf(stderr, "Les options sont :\n");
fprintf(stderr, " -C supprime le partage de l'espace de noms
cgroup\n");
fprintf(stderr, " -i supprime le partage de l'espace de noms
IPC\n");
fprintf(stderr, " -m supprime le partage de l'espace de noms de
montage\n");
fprintf(stderr, " -n supprime le partage de l'espace de noms
réseau\n");
fprintf(stderr, " -p supprime le partage de l'espace de noms
PID\n");
fprintf(stderr, " -t supprime le partage de l'espace de noms
temps\n");
fprintf(stderr, " -u supprime le partage de l'espace de noms
UTS\n");
fprintf(stderr, " -U supprime le partage de l'espace de noms
utilisateur\n");
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
int flags, opt;
flags = 0;
while ((opt = getopt(argc, argv, "CimnptuU")) != -1) {
switch (opt) {
case 'C': flags |= CLONE_NEWCGROUP; break;
case 'i': flags |= CLONE_NEWIPC; break;
case 'm': flags |= CLONE_NEWNS; break;
case 'n': flags |= CLONE_NEWNET; break;
case 'p': flags |= CLONE_NEWPID; break;
case 't': flags |= CLONE_NEWTIME; break;
case 'u': flags |= CLONE_NEWUTS; break;
case 'U': flags |= CLONE_NEWUSER; break;
default: usage(argv[0]);
}
}
if (optind >= argc)
usage(argv[0]);
if (unshare(flags) == -1)
err(EXIT_FAILURE, "unshare");
execvp(argv[optind], &argv[optind]);
err(EXIT_FAILURE, "execvp");
}
unshare(1), clone(2), fork(2),
kcmp(2), setns(2), vfork(2), namespaces(7)
Documentation/userspace-api/unshare.rst dans les sources du
noyau Linux (ou Documentation/unshare.txt avant Linux
4.12).
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>,
Cédric Boutillier <cedric.boutillier@gmail.com>,
Frédéric Hantrais <fhantrais@gmail.com> et Jean-Pierre
Giraud <jean-pierregiraud@neuf.fr>
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.