1setns(2) System Calls Manual setns(2)
2
3
4
6 setns - reassociate thread with a namespace
7
9 Standard C library (libc, -lc)
10
12 #define _GNU_SOURCE /* See feature_test_macros(7) */
13 #include <sched.h>
14
15 int setns(int fd, int nstype);
16
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
166 On success, setns() returns 0. On failure, -1 is returned and errno is
167 set to indicate the error.
168
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
204 Linux.
205
207 Linux 3.0, glibc 2.14.
208
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
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
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)