]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/ioctl_ns.2
pipe.2: Note that 'pipefd' is left unchanged in the event of an error
[thirdparty/man-pages.git] / man2 / ioctl_ns.2
1 .\" Copyright (c) 2017 by Michael Kerrisk <mtk.manpages@gmail.com>
2 .\"
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
7 .\"
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
12 .\"
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
19 .\" professionally.
20 .\"
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" %%%LICENSE_END
24 .\"
25 .\"
26 .TH IOCTL_NS 2 2019-03-06 "Linux" "Linux Programmer's Manual"
27 .SH NAME
28 ioctl_ns \- ioctl() operations for Linux namespaces
29 .SH DESCRIPTION
30 .\" ============================================================
31 .\"
32 .SS Discovering namespace relationships
33 The following
34 .BR ioctl (2)
35 operations are provided to allow discovery of namespace relationships (see
36 .BR user_namespaces (7)
37 and
38 .BR pid_namespaces (7)).
39 The form of the calls is:
40 .PP
41 .in +4n
42 .EX
43 new_fd = ioctl(fd, request);
44 .EE
45 .in
46 .PP
47 In each case,
48 .I fd
49 refers to a
50 .IR /proc/[pid]/ns/*
51 file.
52 Both operations return a new file descriptor on success.
53 .TP
54 .BR NS_GET_USERNS " (since Linux 4.9)"
55 .\" commit bcac25a58bfc6bd79191ac5d7afb49bea96da8c9
56 .\" commit 6786741dbf99e44fb0c0ed85a37582b8a26f1c3b
57 Returns a file descriptor that refers to the owning user namespace
58 for the namespace referred to by
59 .IR fd .
60 .TP
61 .BR NS_GET_PARENT " (since Linux 4.9)"
62 .\" commit a7306ed8d94af729ecef8b6e37506a1c6fc14788
63 Returns a file descriptor that refers to the parent namespace of
64 the namespace referred to by
65 .IR fd .
66 This operation is valid only for hierarchical namespaces
67 (i.e., PID and user namespaces).
68 For user namespaces,
69 .BR NS_GET_PARENT
70 is synonymous with
71 .BR NS_GET_USERNS .
72 .PP
73 The new file descriptor returned by these operations is opened with the
74 .BR O_RDONLY
75 and
76 .BR O_CLOEXEC
77 (close-on-exec; see
78 .BR fcntl (2))
79 flags.
80 .PP
81 By applying
82 .BR fstat (2)
83 to the returned file descriptor, one obtains a
84 .I stat
85 structure whose
86 .I st_dev
87 (resident device) and
88 .I st_ino
89 (inode number) fields together identify the owning/parent namespace.
90 This inode number can be matched with the inode number of another
91 .IR /proc/[pid]/ns/{pid,user}
92 file to determine whether that is the owning/parent namespace.
93 .PP
94 Either of these
95 .BR ioctl (2)
96 operations can fail with the following errors:
97 .TP
98 .B EPERM
99 The requested namespace is outside of the caller's namespace scope.
100 This error can occur if, for example, the owning user namespace is an
101 ancestor of the caller's current user namespace.
102 It can also occur on attempts to obtain the parent of the initial
103 user or PID namespace.
104 .TP
105 .B ENOTTY
106 The operation is not supported by this kernel version.
107 .PP
108 Additionally, the
109 .B NS_GET_PARENT
110 operation can fail with the following error:
111 .TP
112 .B EINVAL
113 .I fd
114 refers to a nonhierarchical namespace.
115 .PP
116 See the EXAMPLE section for an example of the use of these operations.
117 .\" ============================================================
118 .\"
119 .SS Discovering the namespace type
120 The
121 .B NS_GET_NSTYPE
122 .\" commit e5ff5ce6e20ee22511398bb31fb912466cf82a36
123 operation (available since Linux 4.11) can be used to discover
124 the type of namespace referred to by the file descriptor
125 .IR fd :
126 .PP
127 .in +4n
128 .EX
129 nstype = ioctl(fd, NS_GET_NSTYPE);
130 .EE
131 .in
132 .PP
133 .I fd
134 refers to a
135 .IR /proc/[pid]/ns/*
136 file.
137 .PP
138 The return value is one of the
139 .BR CLONE_NEW*
140 values that can be specified to
141 .BR clone (2)
142 or
143 .BR unshare (2)
144 in order to create a namespace.
145 .\" ============================================================
146 .\"
147 .SS Discovering the owner of a user namespace
148 The
149 .B NS_GET_OWNER_UID
150 .\" commit 015bb305b8ebe8d601a238ab70ebdc394c7a19ba
151 operation (available since Linux 4.11) can be used to discover
152 the owner user ID of a user namespace (i.e., the effective user ID
153 of the process that created the user namespace).
154 The form of the call is:
155 .PP
156 .in +4n
157 .EX
158 uid_t uid;
159 ioctl(fd, NS_GET_OWNER_UID, &uid);
160 .EE
161 .in
162 .PP
163 .I fd
164 refers to a
165 .IR /proc/[pid]/ns/user
166 file.
167 .PP
168 The owner user ID is returned in the
169 .I uid_t
170 pointed to by the third argument.
171 .PP
172 This operation can fail with the following error:
173 .TP
174 .B EINVAL
175 .I fd
176 does not refer to a user namespace.
177 .SH ERRORS
178 Any of the above
179 .BR ioctl ()
180 operations can return the following errors:
181 .TP
182 .B ENOTTY
183 .I fd
184 does not refer to a
185 .I /proc/[pid]/ns/*
186 file.
187 .SH CONFORMING TO
188 Namespaces and the operations described on this page are a Linux-specific.
189 .SH EXAMPLE
190 The example shown below uses the
191 .BR ioctl (2)
192 operations described above to perform simple
193 discovery of namespace relationships.
194 The following shell sessions show various examples of the use
195 of this program.
196 .PP
197 Trying to get the parent of the initial user namespace fails,
198 since it has no parent:
199 .PP
200 .in +4n
201 .EX
202 $ \fB./ns_show /proc/self/ns/user p\fP
203 The parent namespace is outside your namespace scope
204 .EE
205 .in
206 .PP
207 Create a process running
208 .BR sleep (1)
209 that resides in new user and UTS namespaces,
210 and show that the new UTS namespace is associated with the new user namespace:
211 .PP
212 .in +4n
213 .EX
214 $ \fBunshare \-Uu sleep 1000 &\fP
215 [1] 23235
216 $ \fB./ns_show /proc/23235/ns/uts u\fP
217 Device/Inode of owning user namespace is: [0,3] / 4026532448
218 $ \fBreadlink /proc/23235/ns/user \fP
219 user:[4026532448]
220 .EE
221 .in
222 .PP
223 Then show that the parent of the new user namespace in the preceding
224 example is the initial user namespace:
225 .PP
226 .in +4n
227 .EX
228 $ \fBreadlink /proc/self/ns/user\fP
229 user:[4026531837]
230 $ \fB./ns_show /proc/23235/ns/user p\fP
231 Device/Inode of parent namespace is: [0,3] / 4026531837
232 .EE
233 .in
234 .PP
235 Start a shell in a new user namespace, and show that from within
236 this shell, the parent user namespace can't be discovered.
237 Similarly, the UTS namespace
238 (which is associated with the initial user namespace)
239 can't be discovered.
240 .PP
241 .in +4n
242 .EX
243 $ \fBPS1="sh2$ " unshare \-U bash\fP
244 sh2$ \fB./ns_show /proc/self/ns/user p\fP
245 The parent namespace is outside your namespace scope
246 sh2$ \fB./ns_show /proc/self/ns/uts u\fP
247 The owning user namespace is outside your namespace scope
248 .EE
249 .in
250 .SS Program source
251 \&
252 .EX
253 /* ns_show.c
254
255 Licensed under the GNU General Public License v2 or later.
256 */
257 #include <stdlib.h>
258 #include <unistd.h>
259 #include <stdio.h>
260 #include <fcntl.h>
261 #include <string.h>
262 #include <sys/stat.h>
263 #include <sys/ioctl.h>
264 #include <errno.h>
265 #include <sys/sysmacros.h>
266
267 #ifndef NS_GET_USERNS
268 #define NSIO 0xb7
269 #define NS_GET_USERNS _IO(NSIO, 0x1)
270 #define NS_GET_PARENT _IO(NSIO, 0x2)
271 #endif
272
273 int
274 main(int argc, char *argv[])
275 {
276 int fd, userns_fd, parent_fd;
277 struct stat sb;
278
279 if (argc < 2) {
280 fprintf(stderr, "Usage: %s /proc/[pid]/ns/[file] [p|u]\en",
281 argv[0]);
282 fprintf(stderr, "\enDisplay the result of one or both "
283 "of NS_GET_USERNS (u) or NS_GET_PARENT (p)\en"
284 "for the specified /proc/[pid]/ns/[file]. If neither "
285 "\(aqp\(aq nor \(aqu\(aq is specified,\en"
286 "NS_GET_USERNS is the default.\en");
287 exit(EXIT_FAILURE);
288 }
289
290 /* Obtain a file descriptor for the \(aqns\(aq file specified
291 in argv[1] */
292
293 fd = open(argv[1], O_RDONLY);
294 if (fd == \-1) {
295 perror("open");
296 exit(EXIT_FAILURE);
297 }
298
299 /* Obtain a file descriptor for the owning user namespace and
300 then obtain and display the inode number of that namespace */
301
302 if (argc < 3 || strchr(argv[2], \(aqu\(aq)) {
303 userns_fd = ioctl(fd, NS_GET_USERNS);
304
305 if (userns_fd == \-1) {
306 if (errno == EPERM)
307 printf("The owning user namespace is outside "
308 "your namespace scope\en");
309 else
310 perror("ioctl\-NS_GET_USERNS");
311 exit(EXIT_FAILURE);
312 }
313
314 if (fstat(userns_fd, &sb) == \-1) {
315 perror("fstat\-userns");
316 exit(EXIT_FAILURE);
317 }
318 printf("Device/Inode of owning user namespace is: "
319 "[%lx,%lx] / %ld\en",
320 (long) major(sb.st_dev), (long) minor(sb.st_dev),
321 (long) sb.st_ino);
322
323 close(userns_fd);
324 }
325
326 /* Obtain a file descriptor for the parent namespace and
327 then obtain and display the inode number of that namespace */
328
329 if (argc > 2 && strchr(argv[2], \(aqp\(aq)) {
330 parent_fd = ioctl(fd, NS_GET_PARENT);
331
332 if (parent_fd == \-1) {
333 if (errno == EINVAL)
334 printf("Can\(aq get parent namespace of a "
335 "nonhierarchical namespace\en");
336 else if (errno == EPERM)
337 printf("The parent namespace is outside "
338 "your namespace scope\en");
339 else
340 perror("ioctl\-NS_GET_PARENT");
341 exit(EXIT_FAILURE);
342 }
343
344 if (fstat(parent_fd, &sb) == \-1) {
345 perror("fstat\-parentns");
346 exit(EXIT_FAILURE);
347 }
348 printf("Device/Inode of parent namespace is: [%lx,%lx] / %ld\en",
349 (long) major(sb.st_dev), (long) minor(sb.st_dev),
350 (long) sb.st_ino);
351
352 close(parent_fd);
353 }
354
355 exit(EXIT_SUCCESS);
356 }
357 .EE
358 .SH SEE ALSO
359 .BR fstat (2),
360 .BR ioctl (2),
361 .BR proc (5),
362 .BR namespaces (7)