2 * Check decoding of NS_* commands of ioctl syscall.
4 * Copyright (c) 2017 Nikolay Marchuk <marchuk.nikolay.a@gmail.com>
5 * Copyright (c) 2017-2018 The strace developers.
8 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <sys/ioctl.h>
23 # define CLONE_NEWUSER 0x10000000
27 test_no_namespace(void)
29 ioctl(-1, NS_GET_USERNS);
30 printf("ioctl(-1, NS_GET_USERNS) = -1 EBADF (%m)\n");
31 ioctl(-1, NS_GET_PARENT);
32 printf("ioctl(-1, NS_GET_PARENT) = -1 EBADF (%m)\n");
33 ioctl(-1, NS_GET_NSTYPE);
34 printf("ioctl(-1, NS_GET_NSTYPE) = -1 EBADF (%m)\n");
35 ioctl(-1, NS_GET_OWNER_UID, NULL);
36 printf("ioctl(-1, NS_GET_OWNER_UID, NULL) = -1 EBADF (%m)\n");
42 char path[sizeof("/proc/%d/ns/user") + sizeof(int)*3];
43 snprintf(path, sizeof(path), "/proc/%d/ns/user", pid);
45 int ns_fd = open(path, O_RDONLY);
47 perror_msg_and_skip("open: %s", path);
49 int userns_fd = ioctl(ns_fd, NS_GET_USERNS);
50 printf("ioctl(%d, NS_GET_USERNS) = %s\n", ns_fd, sprintrc(userns_fd));
52 int parent_ns_fd = ioctl(userns_fd, NS_GET_PARENT);
53 printf("ioctl(%d, NS_GET_PARENT) = %s\n",
54 userns_fd, sprintrc(parent_ns_fd));
56 int nstype = ioctl(userns_fd, NS_GET_NSTYPE);
58 printf("ioctl(%d, NS_GET_NSTYPE) = %s\n",
59 userns_fd, sprintrc(nstype));
61 printf("ioctl(%d, NS_GET_NSTYPE) = %d (CLONE_NEWUSER)\n",
65 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, uid);
66 int rc = ioctl(userns_fd, NS_GET_OWNER_UID, uid);
68 printf("ioctl(%d, NS_GET_OWNER_UID, %p) = %s\n",
69 userns_fd, uid, sprintrc(rc));
71 printf("ioctl(%d, NS_GET_OWNER_UID, [%u]) = %d\n",
79 int *pipefd = (int *) arg;
81 /* Wait for EOF from pipe. */
82 if (read(pipefd[0], &pipefd[1], 1))
83 perror_msg_and_fail("read");
88 extern int __clone2(int (*)(void *), void *, size_t, int, void *, ...);
89 # define clone(fn, child_stack, flags, arg) \
90 __clone2(fn, child_stack, get_page_size() / 2, flags, arg)
94 test_user_namespace(void)
101 perror_msg_and_fail("pipe");
103 pid = clone(child, tail_alloc(get_page_size() / 2),
104 CLONE_NEWUSER | CLONE_UNTRACED | SIGCHLD, pipefd);
112 if (wait(&status) != pid) {
113 perror_msg_and_fail("wait");
114 } else if (status != 0) {
115 error_msg_and_fail("unexpected child exit status %d", status);
123 test_user_namespace();
124 puts("+++ exited with 0 +++");