1setns(2)                      System Calls Manual                     setns(2)
2
3
4

NAME

6       setns - reassociate thread with a namespace
7

LIBRARY

9       Standard C library (libc, -lc)
10

SYNOPSIS

12       #define _GNU_SOURCE             /* See feature_test_macros(7) */
13       #include <sched.h>
14
15       int setns(int fd, int nstype);
16

DESCRIPTION

18       The  setns() system call allows the calling thread to move into differ‐
19       ent namespaces.  The fd argument is one of the following:
20
21       •  a file  descriptor  referring  to  one  of  the  magic  links  in  a
22          /proc/pid/ns/ directory (or a bind mount to such a link);
23
24       •  a PID file descriptor (see pidfd_open(2)).
25
26       The nstype argument is interpreted differently in each case.
27
28   fd refers to a /proc/pid/ns/ link
29       If  fd  refers  to  a /proc/pid/ns/ link, then setns() reassociates the
30       calling thread with the namespace associated with that link, subject to
31       any  constraints  imposed  by the nstype argument.  In this usage, each
32       call to setns() changes just one of the caller's namespace memberships.
33
34       The nstype argument specifies  which  type  of  namespace  the  calling
35       thread  may  be  reassociated  with.  This argument can have one of the
36       following values:
37
38       0      Allow any type of namespace to be joined.
39
40       CLONE_NEWCGROUP (since Linux 4.6)
41              fd must refer to a cgroup namespace.
42
43       CLONE_NEWIPC (since Linux 3.0)
44              fd must refer to an IPC namespace.
45
46       CLONE_NEWNET (since Linux 3.0)
47              fd must refer to a network namespace.
48
49       CLONE_NEWNS (since Linux 3.8)
50              fd must refer to a mount namespace.
51
52       CLONE_NEWPID (since Linux 3.8)
53              fd must refer to a descendant PID namespace.
54
55       CLONE_NEWTIME (since Linux 5.8)
56              fd must refer to a time namespace.
57
58       CLONE_NEWUSER (since Linux 3.8)
59              fd must refer to a user namespace.
60
61       CLONE_NEWUTS (since Linux 3.0)
62              fd must refer to a UTS namespace.
63
64       Specifying nstype as 0 suffices if the caller knows (or does not  care)
65       what  type  of  namespace  is  referred to by fd.  Specifying a nonzero
66       value for nstype is useful if the caller does not  know  what  type  of
67       namespace  is  referred to by fd and wants to ensure that the namespace
68       is of a particular type.  (The caller might not know the  type  of  the
69       namespace  referred  to  by fd if the file descriptor was opened by an‐
70       other process and, for example, passed to the caller via a UNIX  domain
71       socket.)
72
73   fd is a PID file descriptor
74       Since  Linux  5.8,  fd may refer to a PID file descriptor obtained from
75       pidfd_open(2) or clone(2).  In this usage, setns() atomically moves the
76       calling  thread  into  one or more of the same namespaces as the thread
77       referred to by fd.
78
79       The nstype argument is a bit mask specified by ORing  together  one  or
80       more of the CLONE_NEW* namespace constants listed above.  The caller is
81       moved into each of the target thread's namespaces that is specified  in
82       nstype;  the  caller's memberships in the remaining namespaces are left
83       unchanged.
84
85       For example, the following code would move the  caller  into  the  same
86       user,  network,  and  UTS  namespaces  as PID 1234, but would leave the
87       caller's other namespace memberships unchanged:
88
89           int fd = pidfd_open(1234, 0);
90           setns(fd, CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWUTS);
91
92   Details for specific namespace types
93       Note the following details and  restrictions  when  reassociating  with
94       specific namespace types:
95
96       User namespaces
97              A  process  reassociating itself with a user namespace must have
98              the CAP_SYS_ADMIN  capability  in  the  target  user  namespace.
99              (This necessarily implies that it is only possible to join a de‐
100              scendant user namespace.)   Upon  successfully  joining  a  user
101              namespace,  a  process is granted all capabilities in that name‐
102              space, regardless of its user and group IDs.
103
104              A multithreaded process  may  not  change  user  namespace  with
105              setns().
106
107              It  is not permitted to use setns() to reenter the caller's cur‐
108              rent user namespace.  This prevents a caller  that  has  dropped
109              capabilities  from  regaining  those  capabilities via a call to
110              setns().
111
112              For security reasons, a process can't join a new user  namespace
113              if  it  is sharing filesystem-related attributes (the attributes
114              whose sharing is controlled by the clone(2) CLONE_FS flag)  with
115              another process.
116
117              For further details on user namespaces, see user_namespaces(7).
118
119       Mount namespaces
120              Changing  the  mount  namespace requires that the caller possess
121              both CAP_SYS_CHROOT and CAP_SYS_ADMIN capabilities  in  its  own
122              user namespace and CAP_SYS_ADMIN in the user namespace that owns
123              the target mount namespace.
124
125              A process can't join a new mount  namespace  if  it  is  sharing
126              filesystem-related  attributes  (the attributes whose sharing is
127              controlled by the clone(2) CLONE_FS flag) with another process.
128
129              See user_namespaces(7) for details on the  interaction  of  user
130              namespaces and mount namespaces.
131
132       PID namespaces
133              In  order  to  reassociate  itself with a new PID namespace, the
134              caller must have the CAP_SYS_ADMIN capability both  in  its  own
135              user  namespace  and  in the user namespace that owns the target
136              PID namespace.
137
138              Reassociating the PID  namespace  has  somewhat  different  from
139              other  namespace types.  Reassociating the calling thread with a
140              PID namespace changes only the PID namespace  that  subsequently
141              created child processes of the caller will be placed in; it does
142              not change the PID namespace of the caller itself.
143
144              Reassociating with a PID namespace is allowed only if the target
145              PID  namespace is a descendant (child, grandchild, etc.)  of, or
146              is the same as, the current PID namespace of the caller.
147
148              For further details on PID namespaces, see pid_namespaces(7).
149
150       Cgroup namespaces
151              In order to reassociate itself with a new cgroup namespace,  the
152              caller  must  have  the CAP_SYS_ADMIN capability both in its own
153              user namespace and in the user namespace that  owns  the  target
154              cgroup namespace.
155
156              Using  setns()  to change the caller's cgroup namespace does not
157              change the caller's cgroup memberships.
158
159       Network, IPC, time, and UTS namespaces
160              In order to reassociate itself with a new network, IPC, time, or
161              UTS namespace, the caller must have the CAP_SYS_ADMIN capability
162              both in its own user namespace and in the  user  namespace  that
163              owns the target namespace.
164

RETURN VALUE

166       On success, setns() returns 0.  On failure, -1 is returned and errno is
167       set to indicate the error.
168

ERRORS

170       EBADF  fd is not a valid file descriptor.
171
172       EINVAL fd refers to a namespace whose type does not match  that  speci‐
173              fied in nstype.
174
175       EINVAL There  is  problem with reassociating the thread with the speci‐
176              fied namespace.
177
178       EINVAL The caller tried to join an ancestor (parent,  grandparent,  and
179              so on) PID namespace.
180
181       EINVAL The  caller  attempted to join the user namespace in which it is
182              already a member.
183
184       EINVAL The caller shares filesystem (CLONE_FS)  state  (in  particular,
185              the root directory) with other processes and tried to join a new
186              user namespace.
187
188       EINVAL The caller is multithreaded and tried to join a new  user  name‐
189              space.
190
191       EINVAL fd  is  a PID file descriptor and nstype is invalid (e.g., it is
192              0).
193
194       ENOMEM Cannot allocate sufficient memory to change the specified  name‐
195              space.
196
197       EPERM  The calling thread did not have the required capability for this
198              operation.
199
200       ESRCH  fd is a PID file descriptor but the  process  it  refers  to  no
201              longer exists (i.e., it has terminated and been waited on).
202

STANDARDS

204       Linux.
205

VERSIONS

207       Linux 3.0, glibc 2.14.
208

NOTES

210       For  further  information  on  the /proc/pid/ns/ magic links, see name‐
211       spaces(7).
212
213       Not all of the attributes that can be shared when a new thread is  cre‐
214       ated using clone(2) can be changed using setns().
215

EXAMPLES

217       The  program  below  takes  two  or more arguments.  The first argument
218       specifies the pathname of a namespace file in an existing /proc/pid/ns/
219       directory.   The  remaining  arguments  specify a command and its argu‐
220       ments.  The program opens the namespace file, joins that namespace  us‐
221       ing setns(), and executes the specified command inside that namespace.
222
223       The  following shell session demonstrates the use of this program (com‐
224       piled as a binary named ns_exec) in conjunction with  the  CLONE_NEWUTS
225       example  program  in  the clone(2) man page (complied as a binary named
226       newuts).
227
228       We begin by executing the example program  in  clone(2)  in  the  back‐
229       ground.  That program creates a child in a separate UTS namespace.  The
230       child changes the hostname in its namespace, and  then  both  processes
231       display  the hostnames in their UTS namespaces, so that we can see that
232       they are different.
233
234           $ su                   # Need privilege for namespace operations
235           Password:
236           # ./newuts bizarro &
237           [1] 3549
238           clone() returned 3550
239           uts.nodename in child:  bizarro
240           uts.nodename in parent: antero
241           # uname -n             # Verify hostname in the shell
242           antero
243
244       We then run the program shown below, using it to execute a shell.   In‐
245       side  that  shell,  we  verify  that the hostname is the one set by the
246       child created by the first program:
247
248           # ./ns_exec /proc/3550/ns/uts /bin/bash
249           # uname -n             # Executed in shell started by ns_exec
250           bizarro
251
252   Program source
253       #define _GNU_SOURCE
254       #include <err.h>
255       #include <fcntl.h>
256       #include <sched.h>
257       #include <stdio.h>
258       #include <stdlib.h>
259       #include <unistd.h>
260
261       int
262       main(int argc, char *argv[])
263       {
264           int fd;
265
266           if (argc < 3) {
267               fprintf(stderr, "%s /proc/PID/ns/FILE cmd args...\n", argv[0]);
268               exit(EXIT_FAILURE);
269           }
270
271           /* Get file descriptor for namespace; the file descriptor is opened
272              with O_CLOEXEC so as to ensure that it is not inherited by the
273              program that is later executed. */
274
275           fd = open(argv[1], O_RDONLY | O_CLOEXEC);
276           if (fd == -1)
277               err(EXIT_FAILURE, "open");
278
279           if (setns(fd, 0) == -1)       /* Join that namespace */
280               err(EXIT_FAILURE, "setns");
281
282           execvp(argv[2], &argv[2]);    /* Execute a command in namespace */
283           err(EXIT_FAILURE, "execvp");
284       }
285

SEE ALSO

287       nsenter(1), clone(2),  fork(2),  unshare(2),  vfork(2),  namespaces(7),
288       unix(7)
289
290
291
292Linux man-pages 6.04              2023-04-03                          setns(2)
Impressum