summaryrefslogtreecommitdiffstats
path: root/man/man2/ioctl_ns.2
diff options
context:
space:
mode:
Diffstat (limited to 'man/man2/ioctl_ns.2')
-rw-r--r--man/man2/ioctl_ns.2342
1 files changed, 342 insertions, 0 deletions
diff --git a/man/man2/ioctl_ns.2 b/man/man2/ioctl_ns.2
new file mode 100644
index 000000000..958a686b0
--- /dev/null
+++ b/man/man2/ioctl_ns.2
@@ -0,0 +1,342 @@
+.\" Copyright (c) 2017 by Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.\"
+.TH ioctl_ns 2 (date) "Linux man-pages (unreleased)"
+.SH NAME
+ioctl_ns \- ioctl() operations for Linux namespaces
+.SH DESCRIPTION
+.\" ============================================================
+.\"
+.SS Discovering namespace relationships
+The following
+.BR ioctl (2)
+operations are provided to allow discovery of namespace relationships (see
+.BR user_namespaces (7)
+and
+.BR pid_namespaces (7)).
+The form of the calls is:
+.P
+.in +4n
+.EX
+new_fd = ioctl(fd, op);
+.EE
+.in
+.P
+In each case,
+.I fd
+refers to a
+.IR /proc/ pid /ns/*
+file.
+Both operations return a new file descriptor on success.
+.TP
+.BR NS_GET_USERNS " (since Linux 4.9)"
+.\" commit bcac25a58bfc6bd79191ac5d7afb49bea96da8c9
+.\" commit 6786741dbf99e44fb0c0ed85a37582b8a26f1c3b
+Returns a file descriptor that refers to the owning user namespace
+for the namespace referred to by
+.IR fd .
+.TP
+.BR NS_GET_PARENT " (since Linux 4.9)"
+.\" commit a7306ed8d94af729ecef8b6e37506a1c6fc14788
+Returns a file descriptor that refers to the parent namespace of
+the namespace referred to by
+.IR fd .
+This operation is valid only for hierarchical namespaces
+(i.e., PID and user namespaces).
+For user namespaces,
+.B NS_GET_PARENT
+is synonymous with
+.BR NS_GET_USERNS .
+.P
+The new file descriptor returned by these operations is opened with the
+.B O_RDONLY
+and
+.B O_CLOEXEC
+(close-on-exec; see
+.BR fcntl (2))
+flags.
+.P
+By applying
+.BR fstat (2)
+to the returned file descriptor, one obtains a
+.I stat
+structure whose
+.I st_dev
+(resident device) and
+.I st_ino
+(inode number) fields together identify the owning/parent namespace.
+This inode number can be matched with the inode number of another
+.IR /proc/ pid /ns/ { pid , user }
+file to determine whether that is the owning/parent namespace.
+.P
+Either of these
+.BR ioctl (2)
+operations can fail with the following errors:
+.TP
+.B EPERM
+The requested namespace is outside of the caller's namespace scope.
+This error can occur if, for example, the owning user namespace is an
+ancestor of the caller's current user namespace.
+It can also occur on attempts to obtain the parent of the initial
+user or PID namespace.
+.TP
+.B ENOTTY
+The operation is not supported by this kernel version.
+.P
+Additionally, the
+.B NS_GET_PARENT
+operation can fail with the following error:
+.TP
+.B EINVAL
+.I fd
+refers to a nonhierarchical namespace.
+.P
+See the EXAMPLES section for an example of the use of these operations.
+.\" ============================================================
+.\"
+.SS Discovering the namespace type
+The
+.B NS_GET_NSTYPE
+.\" commit e5ff5ce6e20ee22511398bb31fb912466cf82a36
+operation (available since Linux 4.11) can be used to discover
+the type of namespace referred to by the file descriptor
+.IR fd :
+.P
+.in +4n
+.EX
+nstype = ioctl(fd, NS_GET_NSTYPE);
+.EE
+.in
+.P
+.I fd
+refers to a
+.IR /proc/ pid /ns/*
+file.
+.P
+The return value is one of the
+.B CLONE_NEW*
+values that can be specified to
+.BR clone (2)
+or
+.BR unshare (2)
+in order to create a namespace.
+.\" ============================================================
+.\"
+.SS Discovering the owner of a user namespace
+The
+.B NS_GET_OWNER_UID
+.\" commit 015bb305b8ebe8d601a238ab70ebdc394c7a19ba
+operation (available since Linux 4.11) can be used to discover
+the owner user ID of a user namespace (i.e., the effective user ID
+of the process that created the user namespace).
+The form of the call is:
+.P
+.in +4n
+.EX
+uid_t uid;
+ioctl(fd, NS_GET_OWNER_UID, &uid);
+.EE
+.in
+.P
+.I fd
+refers to a
+.IR /proc/ pid /ns/user
+file.
+.P
+The owner user ID is returned in the
+.I uid_t
+pointed to by the third argument.
+.P
+This operation can fail with the following error:
+.TP
+.B EINVAL
+.I fd
+does not refer to a user namespace.
+.SH ERRORS
+Any of the above
+.BR ioctl ()
+operations can return the following errors:
+.TP
+.B ENOTTY
+.I fd
+does not refer to a
+.IR /proc/ pid /ns/ *
+file.
+.SH STANDARDS
+Linux.
+.SH EXAMPLES
+The example shown below uses the
+.BR ioctl (2)
+operations described above to perform simple
+discovery of namespace relationships.
+The following shell sessions show various examples of the use
+of this program.
+.P
+Trying to get the parent of the initial user namespace fails,
+since it has no parent:
+.P
+.in +4n
+.EX
+$ \fB./ns_show /proc/self/ns/user p\fP
+The parent namespace is outside your namespace scope
+.EE
+.in
+.P
+Create a process running
+.BR sleep (1)
+that resides in new user and UTS namespaces,
+and show that the new UTS namespace is associated with the new user namespace:
+.P
+.in +4n
+.EX
+$ \fBunshare \-Uu sleep 1000 &\fP
+[1] 23235
+$ \fB./ns_show /proc/23235/ns/uts u\fP
+Device/Inode of owning user namespace is: [0,3] / 4026532448
+$ \fBreadlink /proc/23235/ns/user\fP
+user:[4026532448]
+.EE
+.in
+.P
+Then show that the parent of the new user namespace in the preceding
+example is the initial user namespace:
+.P
+.in +4n
+.EX
+$ \fBreadlink /proc/self/ns/user\fP
+user:[4026531837]
+$ \fB./ns_show /proc/23235/ns/user p\fP
+Device/Inode of parent namespace is: [0,3] / 4026531837
+.EE
+.in
+.P
+Start a shell in a new user namespace, and show that from within
+this shell, the parent user namespace can't be discovered.
+Similarly, the UTS namespace
+(which is associated with the initial user namespace)
+can't be discovered.
+.P
+.in +4n
+.EX
+$ \fBPS1="sh2$ " unshare \-U bash\fP
+sh2$ \fB./ns_show /proc/self/ns/user p\fP
+The parent namespace is outside your namespace scope
+sh2$ \fB./ns_show /proc/self/ns/uts u\fP
+The owning user namespace is outside your namespace scope
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (ns_show.c)
+.EX
+/* ns_show.c
+\&
+ Licensed under the GNU General Public License v2 or later.
+*/
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/nsfs.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <unistd.h>
+\&
+int
+main(int argc, char *argv[])
+{
+ int fd, userns_fd, parent_fd;
+ struct stat sb;
+\&
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s /proc/[pid]/ns/[file] [p|u]\en",
+ argv[0]);
+ fprintf(stderr, "\enDisplay the result of one or both "
+ "of NS_GET_USERNS (u) or NS_GET_PARENT (p)\en"
+ "for the specified /proc/[pid]/ns/[file]. If neither "
+ "\[aq]p\[aq] nor \[aq]u\[aq] is specified,\en"
+ "NS_GET_USERNS is the default.\en");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Obtain a file descriptor for the \[aq]ns\[aq] file specified
+ in argv[1]. */
+\&
+ fd = open(argv[1], O_RDONLY);
+ if (fd == \-1) {
+ perror("open");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Obtain a file descriptor for the owning user namespace and
+ then obtain and display the inode number of that namespace. */
+\&
+ if (argc < 3 || strchr(argv[2], \[aq]u\[aq])) {
+ userns_fd = ioctl(fd, NS_GET_USERNS);
+\&
+ if (userns_fd == \-1) {
+ if (errno == EPERM)
+ printf("The owning user namespace is outside "
+ "your namespace scope\en");
+ else
+ perror("ioctl\-NS_GET_USERNS");
+ exit(EXIT_FAILURE);
+ }
+\&
+ if (fstat(userns_fd, &sb) == \-1) {
+ perror("fstat\-userns");
+ exit(EXIT_FAILURE);
+ }
+ printf("Device/Inode of owning user namespace is: "
+ "[%x,%x] / %ju\en",
+ major(sb.st_dev),
+ minor(sb.st_dev),
+ (uintmax_t) sb.st_ino);
+\&
+ close(userns_fd);
+ }
+\&
+ /* Obtain a file descriptor for the parent namespace and
+ then obtain and display the inode number of that namespace. */
+\&
+ if (argc > 2 && strchr(argv[2], \[aq]p\[aq])) {
+ parent_fd = ioctl(fd, NS_GET_PARENT);
+\&
+ if (parent_fd == \-1) {
+ if (errno == EINVAL)
+ printf("Can\[aq] get parent namespace of a "
+ "nonhierarchical namespace\en");
+ else if (errno == EPERM)
+ printf("The parent namespace is outside "
+ "your namespace scope\en");
+ else
+ perror("ioctl\-NS_GET_PARENT");
+ exit(EXIT_FAILURE);
+ }
+\&
+ if (fstat(parent_fd, &sb) == \-1) {
+ perror("fstat\-parentns");
+ exit(EXIT_FAILURE);
+ }
+ printf("Device/Inode of parent namespace is: [%x,%x] / %ju\en",
+ major(sb.st_dev),
+ minor(sb.st_dev),
+ (uintmax_t) sb.st_ino);
+\&
+ close(parent_fd);
+ }
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR fstat (2),
+.BR ioctl (2),
+.BR proc (5),
+.BR namespaces (7)