pidfd_setns_test.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. // SPDX-License-Identifier: GPL-2.0
  2. #define _GNU_SOURCE
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <limits.h>
  6. #include <linux/types.h>
  7. #include <sched.h>
  8. #include <signal.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <syscall.h>
  13. #include <sys/prctl.h>
  14. #include <sys/wait.h>
  15. #include <unistd.h>
  16. #include <sys/socket.h>
  17. #include <sys/stat.h>
  18. #include <linux/ioctl.h>
  19. #include "pidfd.h"
  20. #include "../clone3/clone3_selftests.h"
  21. #include "../kselftest_harness.h"
  22. #ifndef PIDFS_IOCTL_MAGIC
  23. #define PIDFS_IOCTL_MAGIC 0xFF
  24. #endif
  25. #ifndef PIDFD_GET_CGROUP_NAMESPACE
  26. #define PIDFD_GET_CGROUP_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 1)
  27. #endif
  28. #ifndef PIDFD_GET_IPC_NAMESPACE
  29. #define PIDFD_GET_IPC_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 2)
  30. #endif
  31. #ifndef PIDFD_GET_MNT_NAMESPACE
  32. #define PIDFD_GET_MNT_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 3)
  33. #endif
  34. #ifndef PIDFD_GET_NET_NAMESPACE
  35. #define PIDFD_GET_NET_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 4)
  36. #endif
  37. #ifndef PIDFD_GET_PID_NAMESPACE
  38. #define PIDFD_GET_PID_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 5)
  39. #endif
  40. #ifndef PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE
  41. #define PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 6)
  42. #endif
  43. #ifndef PIDFD_GET_TIME_NAMESPACE
  44. #define PIDFD_GET_TIME_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 7)
  45. #endif
  46. #ifndef PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE
  47. #define PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 8)
  48. #endif
  49. #ifndef PIDFD_GET_USER_NAMESPACE
  50. #define PIDFD_GET_USER_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 9)
  51. #endif
  52. #ifndef PIDFD_GET_UTS_NAMESPACE
  53. #define PIDFD_GET_UTS_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 10)
  54. #endif
  55. enum {
  56. PIDFD_NS_USER,
  57. PIDFD_NS_MNT,
  58. PIDFD_NS_PID,
  59. PIDFD_NS_UTS,
  60. PIDFD_NS_IPC,
  61. PIDFD_NS_NET,
  62. PIDFD_NS_CGROUP,
  63. PIDFD_NS_PIDCLD,
  64. PIDFD_NS_TIME,
  65. PIDFD_NS_TIMECLD,
  66. PIDFD_NS_MAX
  67. };
  68. const struct ns_info {
  69. const char *name;
  70. int flag;
  71. unsigned int pidfd_ioctl;
  72. } ns_info[] = {
  73. [PIDFD_NS_USER] = { "user", CLONE_NEWUSER, PIDFD_GET_USER_NAMESPACE, },
  74. [PIDFD_NS_MNT] = { "mnt", CLONE_NEWNS, PIDFD_GET_MNT_NAMESPACE, },
  75. [PIDFD_NS_PID] = { "pid", CLONE_NEWPID, PIDFD_GET_PID_NAMESPACE, },
  76. [PIDFD_NS_UTS] = { "uts", CLONE_NEWUTS, PIDFD_GET_UTS_NAMESPACE, },
  77. [PIDFD_NS_IPC] = { "ipc", CLONE_NEWIPC, PIDFD_GET_IPC_NAMESPACE, },
  78. [PIDFD_NS_NET] = { "net", CLONE_NEWNET, PIDFD_GET_NET_NAMESPACE, },
  79. [PIDFD_NS_CGROUP] = { "cgroup", CLONE_NEWCGROUP, PIDFD_GET_CGROUP_NAMESPACE, },
  80. [PIDFD_NS_TIME] = { "time", CLONE_NEWTIME, PIDFD_GET_TIME_NAMESPACE, },
  81. [PIDFD_NS_PIDCLD] = { "pid_for_children", 0, PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE, },
  82. [PIDFD_NS_TIMECLD] = { "time_for_children", 0, PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE, },
  83. };
  84. FIXTURE(current_nsset)
  85. {
  86. pid_t pid;
  87. int pidfd;
  88. int nsfds[PIDFD_NS_MAX];
  89. int child_pidfd_derived_nsfds[PIDFD_NS_MAX];
  90. pid_t child_pid_exited;
  91. int child_pidfd_exited;
  92. pid_t child_pid1;
  93. int child_pidfd1;
  94. int child_nsfds1[PIDFD_NS_MAX];
  95. int child_pidfd_derived_nsfds1[PIDFD_NS_MAX];
  96. pid_t child_pid2;
  97. int child_pidfd2;
  98. int child_nsfds2[PIDFD_NS_MAX];
  99. int child_pidfd_derived_nsfds2[PIDFD_NS_MAX];
  100. };
  101. static int sys_waitid(int which, pid_t pid, int options)
  102. {
  103. return syscall(__NR_waitid, which, pid, NULL, options, NULL);
  104. }
  105. pid_t create_child(int *pidfd, unsigned flags)
  106. {
  107. struct __clone_args args = {
  108. .flags = CLONE_PIDFD | flags,
  109. .exit_signal = SIGCHLD,
  110. .pidfd = ptr_to_u64(pidfd),
  111. };
  112. return sys_clone3(&args, sizeof(struct clone_args));
  113. }
  114. static bool switch_timens(void)
  115. {
  116. int fd, ret;
  117. if (unshare(CLONE_NEWTIME))
  118. return false;
  119. fd = open("/proc/self/ns/time_for_children", O_RDONLY | O_CLOEXEC);
  120. if (fd < 0)
  121. return false;
  122. ret = setns(fd, CLONE_NEWTIME);
  123. close(fd);
  124. return ret == 0;
  125. }
  126. static ssize_t read_nointr(int fd, void *buf, size_t count)
  127. {
  128. ssize_t ret;
  129. do {
  130. ret = read(fd, buf, count);
  131. } while (ret < 0 && errno == EINTR);
  132. return ret;
  133. }
  134. static ssize_t write_nointr(int fd, const void *buf, size_t count)
  135. {
  136. ssize_t ret;
  137. do {
  138. ret = write(fd, buf, count);
  139. } while (ret < 0 && errno == EINTR);
  140. return ret;
  141. }
  142. FIXTURE_SETUP(current_nsset)
  143. {
  144. int i, proc_fd, ret;
  145. int ipc_sockets[2];
  146. char c;
  147. for (i = 0; i < PIDFD_NS_MAX; i++) {
  148. self->nsfds[i] = -EBADF;
  149. self->child_nsfds1[i] = -EBADF;
  150. self->child_nsfds2[i] = -EBADF;
  151. self->child_pidfd_derived_nsfds[i] = -EBADF;
  152. self->child_pidfd_derived_nsfds1[i] = -EBADF;
  153. self->child_pidfd_derived_nsfds2[i] = -EBADF;
  154. }
  155. proc_fd = open("/proc/self/ns", O_DIRECTORY | O_CLOEXEC);
  156. ASSERT_GE(proc_fd, 0) {
  157. TH_LOG("%m - Failed to open /proc/self/ns");
  158. }
  159. self->pid = getpid();
  160. self->pidfd = sys_pidfd_open(self->pid, 0);
  161. EXPECT_GT(self->pidfd, 0) {
  162. TH_LOG("%m - Failed to open pidfd for process %d", self->pid);
  163. }
  164. for (i = 0; i < PIDFD_NS_MAX; i++) {
  165. const struct ns_info *info = &ns_info[i];
  166. self->nsfds[i] = openat(proc_fd, info->name, O_RDONLY | O_CLOEXEC);
  167. if (self->nsfds[i] < 0) {
  168. EXPECT_EQ(errno, ENOENT) {
  169. TH_LOG("%m - Failed to open %s namespace for process %d",
  170. info->name, self->pid);
  171. }
  172. }
  173. self->child_pidfd_derived_nsfds[i] = ioctl(self->pidfd, info->pidfd_ioctl, 0);
  174. if (self->child_pidfd_derived_nsfds[i] < 0) {
  175. EXPECT_EQ(errno, EOPNOTSUPP) {
  176. TH_LOG("%m - Failed to derive %s namespace from pidfd of process %d",
  177. info->name, self->pid);
  178. }
  179. }
  180. }
  181. /* Create task that exits right away. */
  182. self->child_pid_exited = create_child(&self->child_pidfd_exited, 0);
  183. EXPECT_GE(self->child_pid_exited, 0);
  184. if (self->child_pid_exited == 0) {
  185. if (self->nsfds[PIDFD_NS_USER] >= 0 && unshare(CLONE_NEWUSER) < 0)
  186. _exit(EXIT_FAILURE);
  187. if (self->nsfds[PIDFD_NS_NET] >= 0 && unshare(CLONE_NEWNET) < 0)
  188. _exit(EXIT_FAILURE);
  189. _exit(EXIT_SUCCESS);
  190. }
  191. ASSERT_EQ(sys_waitid(P_PID, self->child_pid_exited, WEXITED | WNOWAIT), 0);
  192. self->pidfd = sys_pidfd_open(self->pid, 0);
  193. EXPECT_GE(self->pidfd, 0) {
  194. TH_LOG("%m - Failed to open pidfd for process %d", self->pid);
  195. }
  196. ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
  197. EXPECT_EQ(ret, 0);
  198. /* Create tasks that will be stopped. */
  199. if (self->nsfds[PIDFD_NS_USER] >= 0 && self->nsfds[PIDFD_NS_PID] >= 0)
  200. self->child_pid1 = create_child(&self->child_pidfd1, CLONE_NEWUSER | CLONE_NEWPID);
  201. else if (self->nsfds[PIDFD_NS_PID] >= 0)
  202. self->child_pid1 = create_child(&self->child_pidfd1, CLONE_NEWPID);
  203. else if (self->nsfds[PIDFD_NS_USER] >= 0)
  204. self->child_pid1 = create_child(&self->child_pidfd1, CLONE_NEWUSER);
  205. else
  206. self->child_pid1 = create_child(&self->child_pidfd1, 0);
  207. EXPECT_GE(self->child_pid1, 0);
  208. if (self->child_pid1 == 0) {
  209. close(ipc_sockets[0]);
  210. if (self->nsfds[PIDFD_NS_MNT] >= 0 && unshare(CLONE_NEWNS) < 0) {
  211. TH_LOG("%m - Failed to unshare mount namespace for process %d", self->pid);
  212. _exit(EXIT_FAILURE);
  213. }
  214. if (self->nsfds[PIDFD_NS_CGROUP] >= 0 && unshare(CLONE_NEWCGROUP) < 0) {
  215. TH_LOG("%m - Failed to unshare cgroup namespace for process %d", self->pid);
  216. _exit(EXIT_FAILURE);
  217. }
  218. if (self->nsfds[PIDFD_NS_IPC] >= 0 && unshare(CLONE_NEWIPC) < 0) {
  219. TH_LOG("%m - Failed to unshare ipc namespace for process %d", self->pid);
  220. _exit(EXIT_FAILURE);
  221. }
  222. if (self->nsfds[PIDFD_NS_UTS] >= 0 && unshare(CLONE_NEWUTS) < 0) {
  223. TH_LOG("%m - Failed to unshare uts namespace for process %d", self->pid);
  224. _exit(EXIT_FAILURE);
  225. }
  226. if (self->nsfds[PIDFD_NS_NET] >= 0 && unshare(CLONE_NEWNET) < 0) {
  227. TH_LOG("%m - Failed to unshare net namespace for process %d", self->pid);
  228. _exit(EXIT_FAILURE);
  229. }
  230. if (self->nsfds[PIDFD_NS_TIME] >= 0 && !switch_timens()) {
  231. TH_LOG("%m - Failed to unshare time namespace for process %d", self->pid);
  232. _exit(EXIT_FAILURE);
  233. }
  234. if (write_nointr(ipc_sockets[1], "1", 1) < 0)
  235. _exit(EXIT_FAILURE);
  236. close(ipc_sockets[1]);
  237. pause();
  238. _exit(EXIT_SUCCESS);
  239. }
  240. close(ipc_sockets[1]);
  241. ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
  242. close(ipc_sockets[0]);
  243. ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
  244. EXPECT_EQ(ret, 0);
  245. if (self->nsfds[PIDFD_NS_USER] >= 0 && self->nsfds[PIDFD_NS_PID] >= 0)
  246. self->child_pid2 = create_child(&self->child_pidfd2, CLONE_NEWUSER | CLONE_NEWPID);
  247. else if (self->nsfds[PIDFD_NS_PID] >= 0)
  248. self->child_pid2 = create_child(&self->child_pidfd2, CLONE_NEWPID);
  249. else if (self->nsfds[PIDFD_NS_USER] >= 0)
  250. self->child_pid2 = create_child(&self->child_pidfd2, CLONE_NEWUSER);
  251. else
  252. self->child_pid2 = create_child(&self->child_pidfd2, 0);
  253. EXPECT_GE(self->child_pid2, 0);
  254. if (self->child_pid2 == 0) {
  255. close(ipc_sockets[0]);
  256. if (self->nsfds[PIDFD_NS_MNT] >= 0 && unshare(CLONE_NEWNS) < 0) {
  257. TH_LOG("%m - Failed to unshare mount namespace for process %d", self->pid);
  258. _exit(EXIT_FAILURE);
  259. }
  260. if (self->nsfds[PIDFD_NS_CGROUP] >= 0 && unshare(CLONE_NEWCGROUP) < 0) {
  261. TH_LOG("%m - Failed to unshare cgroup namespace for process %d", self->pid);
  262. _exit(EXIT_FAILURE);
  263. }
  264. if (self->nsfds[PIDFD_NS_IPC] >= 0 && unshare(CLONE_NEWIPC) < 0) {
  265. TH_LOG("%m - Failed to unshare ipc namespace for process %d", self->pid);
  266. _exit(EXIT_FAILURE);
  267. }
  268. if (self->nsfds[PIDFD_NS_UTS] >= 0 && unshare(CLONE_NEWUTS) < 0) {
  269. TH_LOG("%m - Failed to unshare uts namespace for process %d", self->pid);
  270. _exit(EXIT_FAILURE);
  271. }
  272. if (self->nsfds[PIDFD_NS_NET] >= 0 && unshare(CLONE_NEWNET) < 0) {
  273. TH_LOG("%m - Failed to unshare net namespace for process %d", self->pid);
  274. _exit(EXIT_FAILURE);
  275. }
  276. if (self->nsfds[PIDFD_NS_TIME] >= 0 && !switch_timens()) {
  277. TH_LOG("%m - Failed to unshare time namespace for process %d", self->pid);
  278. _exit(EXIT_FAILURE);
  279. }
  280. if (write_nointr(ipc_sockets[1], "1", 1) < 0)
  281. _exit(EXIT_FAILURE);
  282. close(ipc_sockets[1]);
  283. pause();
  284. _exit(EXIT_SUCCESS);
  285. }
  286. close(ipc_sockets[1]);
  287. ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
  288. close(ipc_sockets[0]);
  289. for (i = 0; i < PIDFD_NS_MAX; i++) {
  290. char p[100];
  291. const struct ns_info *info = &ns_info[i];
  292. self->nsfds[i] = openat(proc_fd, info->name, O_RDONLY | O_CLOEXEC);
  293. if (self->nsfds[i] < 0) {
  294. EXPECT_EQ(errno, ENOENT) {
  295. TH_LOG("%m - Failed to open %s namespace for process %d",
  296. info->name, self->pid);
  297. }
  298. }
  299. ret = snprintf(p, sizeof(p), "/proc/%d/ns/%s",
  300. self->child_pid1, info->name);
  301. EXPECT_GT(ret, 0);
  302. EXPECT_LT(ret, sizeof(p));
  303. self->child_nsfds1[i] = open(p, O_RDONLY | O_CLOEXEC);
  304. if (self->child_nsfds1[i] < 0) {
  305. EXPECT_EQ(errno, ENOENT) {
  306. TH_LOG("%m - Failed to open %s namespace for process %d",
  307. info->name, self->child_pid1);
  308. }
  309. }
  310. ret = snprintf(p, sizeof(p), "/proc/%d/ns/%s",
  311. self->child_pid2, info->name);
  312. EXPECT_GT(ret, 0);
  313. EXPECT_LT(ret, sizeof(p));
  314. self->child_nsfds2[i] = open(p, O_RDONLY | O_CLOEXEC);
  315. if (self->child_nsfds2[i] < 0) {
  316. EXPECT_EQ(errno, ENOENT) {
  317. TH_LOG("%m - Failed to open %s namespace for process %d",
  318. info->name, self->child_pid1);
  319. }
  320. }
  321. self->child_pidfd_derived_nsfds1[i] = ioctl(self->child_pidfd1, info->pidfd_ioctl, 0);
  322. if (self->child_pidfd_derived_nsfds1[i] < 0) {
  323. EXPECT_EQ(errno, EOPNOTSUPP) {
  324. TH_LOG("%m - Failed to derive %s namespace from pidfd of process %d",
  325. info->name, self->child_pid1);
  326. }
  327. }
  328. self->child_pidfd_derived_nsfds2[i] = ioctl(self->child_pidfd2, info->pidfd_ioctl, 0);
  329. if (self->child_pidfd_derived_nsfds2[i] < 0) {
  330. EXPECT_EQ(errno, EOPNOTSUPP) {
  331. TH_LOG("%m - Failed to derive %s namespace from pidfd of process %d",
  332. info->name, self->child_pid2);
  333. }
  334. }
  335. }
  336. close(proc_fd);
  337. }
  338. FIXTURE_TEARDOWN(current_nsset)
  339. {
  340. int i;
  341. ASSERT_EQ(sys_pidfd_send_signal(self->child_pidfd1,
  342. SIGKILL, NULL, 0), 0);
  343. ASSERT_EQ(sys_pidfd_send_signal(self->child_pidfd2,
  344. SIGKILL, NULL, 0), 0);
  345. for (i = 0; i < PIDFD_NS_MAX; i++) {
  346. if (self->nsfds[i] >= 0)
  347. close(self->nsfds[i]);
  348. if (self->child_nsfds1[i] >= 0)
  349. close(self->child_nsfds1[i]);
  350. if (self->child_nsfds2[i] >= 0)
  351. close(self->child_nsfds2[i]);
  352. if (self->child_pidfd_derived_nsfds[i] >= 0)
  353. close(self->child_pidfd_derived_nsfds[i]);
  354. if (self->child_pidfd_derived_nsfds1[i] >= 0)
  355. close(self->child_pidfd_derived_nsfds1[i]);
  356. if (self->child_pidfd_derived_nsfds2[i] >= 0)
  357. close(self->child_pidfd_derived_nsfds2[i]);
  358. }
  359. if (self->child_pidfd1 >= 0)
  360. EXPECT_EQ(0, close(self->child_pidfd1));
  361. if (self->child_pidfd2 >= 0)
  362. EXPECT_EQ(0, close(self->child_pidfd2));
  363. ASSERT_EQ(sys_waitid(P_PID, self->child_pid_exited, WEXITED), 0);
  364. ASSERT_EQ(sys_waitid(P_PID, self->child_pid1, WEXITED), 0);
  365. ASSERT_EQ(sys_waitid(P_PID, self->child_pid2, WEXITED), 0);
  366. }
  367. static int preserve_ns(const int pid, const char *ns)
  368. {
  369. int ret;
  370. char path[50];
  371. ret = snprintf(path, sizeof(path), "/proc/%d/ns/%s", pid, ns);
  372. if (ret < 0 || (size_t)ret >= sizeof(path))
  373. return -EIO;
  374. return open(path, O_RDONLY | O_CLOEXEC);
  375. }
  376. static int in_same_namespace(int ns_fd1, pid_t pid2, const char *ns)
  377. {
  378. int ns_fd2 = -EBADF;
  379. int ret = -1;
  380. struct stat ns_st1, ns_st2;
  381. ret = fstat(ns_fd1, &ns_st1);
  382. if (ret < 0)
  383. return -1;
  384. ns_fd2 = preserve_ns(pid2, ns);
  385. if (ns_fd2 < 0)
  386. return -1;
  387. ret = fstat(ns_fd2, &ns_st2);
  388. close(ns_fd2);
  389. if (ret < 0)
  390. return -1;
  391. /* processes are in the same namespace */
  392. if ((ns_st1.st_dev == ns_st2.st_dev) &&
  393. (ns_st1.st_ino == ns_st2.st_ino))
  394. return 1;
  395. /* processes are in different namespaces */
  396. return 0;
  397. }
  398. /* Test that we can't pass garbage to the kernel. */
  399. TEST_F(current_nsset, invalid_flags)
  400. {
  401. ASSERT_NE(setns(self->pidfd, 0), 0);
  402. EXPECT_EQ(errno, EINVAL);
  403. ASSERT_NE(setns(self->pidfd, -1), 0);
  404. EXPECT_EQ(errno, EINVAL);
  405. ASSERT_NE(setns(self->pidfd, CLONE_VM), 0);
  406. EXPECT_EQ(errno, EINVAL);
  407. ASSERT_NE(setns(self->pidfd, CLONE_NEWUSER | CLONE_VM), 0);
  408. EXPECT_EQ(errno, EINVAL);
  409. }
  410. /* Test that we can't attach to a task that has already exited. */
  411. TEST_F(current_nsset, pidfd_exited_child)
  412. {
  413. int i;
  414. pid_t pid;
  415. ASSERT_NE(setns(self->child_pidfd_exited, CLONE_NEWUSER | CLONE_NEWNET),
  416. 0);
  417. EXPECT_EQ(errno, ESRCH);
  418. pid = getpid();
  419. for (i = 0; i < PIDFD_NS_MAX; i++) {
  420. const struct ns_info *info = &ns_info[i];
  421. /* Verify that we haven't changed any namespaces. */
  422. if (self->nsfds[i] >= 0)
  423. ASSERT_EQ(in_same_namespace(self->nsfds[i], pid, info->name), 1);
  424. }
  425. }
  426. TEST_F(current_nsset, pidfd_incremental_setns)
  427. {
  428. int i;
  429. pid_t pid;
  430. pid = getpid();
  431. for (i = 0; i < PIDFD_NS_MAX; i++) {
  432. const struct ns_info *info = &ns_info[i];
  433. int nsfd;
  434. if (self->child_nsfds1[i] < 0)
  435. continue;
  436. if (info->flag) {
  437. ASSERT_EQ(setns(self->child_pidfd1, info->flag), 0) {
  438. TH_LOG("%m - Failed to setns to %s namespace of %d via pidfd %d",
  439. info->name, self->child_pid1,
  440. self->child_pidfd1);
  441. }
  442. }
  443. /* Verify that we have changed to the correct namespaces. */
  444. if (info->flag == CLONE_NEWPID)
  445. nsfd = self->nsfds[i];
  446. else
  447. nsfd = self->child_nsfds1[i];
  448. ASSERT_EQ(in_same_namespace(nsfd, pid, info->name), 1) {
  449. TH_LOG("setns failed to place us correctly into %s namespace of %d via pidfd %d",
  450. info->name, self->child_pid1,
  451. self->child_pidfd1);
  452. }
  453. TH_LOG("Managed to correctly setns to %s namespace of %d via pidfd %d",
  454. info->name, self->child_pid1, self->child_pidfd1);
  455. }
  456. }
  457. TEST_F(current_nsset, nsfd_incremental_setns)
  458. {
  459. int i;
  460. pid_t pid;
  461. pid = getpid();
  462. for (i = 0; i < PIDFD_NS_MAX; i++) {
  463. const struct ns_info *info = &ns_info[i];
  464. int nsfd;
  465. if (self->child_nsfds1[i] < 0)
  466. continue;
  467. if (info->flag) {
  468. ASSERT_EQ(setns(self->child_nsfds1[i], info->flag), 0) {
  469. TH_LOG("%m - Failed to setns to %s namespace of %d via nsfd %d",
  470. info->name, self->child_pid1,
  471. self->child_nsfds1[i]);
  472. }
  473. }
  474. /* Verify that we have changed to the correct namespaces. */
  475. if (info->flag == CLONE_NEWPID)
  476. nsfd = self->nsfds[i];
  477. else
  478. nsfd = self->child_nsfds1[i];
  479. ASSERT_EQ(in_same_namespace(nsfd, pid, info->name), 1) {
  480. TH_LOG("setns failed to place us correctly into %s namespace of %d via nsfd %d",
  481. info->name, self->child_pid1,
  482. self->child_nsfds1[i]);
  483. }
  484. TH_LOG("Managed to correctly setns to %s namespace of %d via nsfd %d",
  485. info->name, self->child_pid1, self->child_nsfds1[i]);
  486. }
  487. }
  488. TEST_F(current_nsset, pidfd_derived_nsfd_incremental_setns)
  489. {
  490. int i;
  491. pid_t pid;
  492. pid = getpid();
  493. for (i = 0; i < PIDFD_NS_MAX; i++) {
  494. const struct ns_info *info = &ns_info[i];
  495. int nsfd;
  496. if (self->child_pidfd_derived_nsfds1[i] < 0)
  497. continue;
  498. if (info->flag) {
  499. ASSERT_EQ(setns(self->child_pidfd_derived_nsfds1[i], info->flag), 0) {
  500. TH_LOG("%m - Failed to setns to %s namespace of %d via nsfd %d",
  501. info->name, self->child_pid1,
  502. self->child_pidfd_derived_nsfds1[i]);
  503. }
  504. }
  505. /* Verify that we have changed to the correct namespaces. */
  506. if (info->flag == CLONE_NEWPID)
  507. nsfd = self->child_pidfd_derived_nsfds[i];
  508. else
  509. nsfd = self->child_pidfd_derived_nsfds1[i];
  510. ASSERT_EQ(in_same_namespace(nsfd, pid, info->name), 1) {
  511. TH_LOG("setns failed to place us correctly into %s namespace of %d via nsfd %d",
  512. info->name, self->child_pid1,
  513. self->child_pidfd_derived_nsfds1[i]);
  514. }
  515. TH_LOG("Managed to correctly setns to %s namespace of %d via nsfd %d",
  516. info->name, self->child_pid1, self->child_pidfd_derived_nsfds1[i]);
  517. }
  518. }
  519. TEST_F(current_nsset, pidfd_one_shot_setns)
  520. {
  521. unsigned flags = 0;
  522. int i;
  523. pid_t pid;
  524. for (i = 0; i < PIDFD_NS_MAX; i++) {
  525. const struct ns_info *info = &ns_info[i];
  526. if (self->child_nsfds1[i] < 0)
  527. continue;
  528. flags |= info->flag;
  529. TH_LOG("Adding %s namespace of %d to list of namespaces to attach to",
  530. info->name, self->child_pid1);
  531. }
  532. ASSERT_EQ(setns(self->child_pidfd1, flags), 0) {
  533. TH_LOG("%m - Failed to setns to namespaces of %d",
  534. self->child_pid1);
  535. }
  536. pid = getpid();
  537. for (i = 0; i < PIDFD_NS_MAX; i++) {
  538. const struct ns_info *info = &ns_info[i];
  539. int nsfd;
  540. if (self->child_nsfds1[i] < 0)
  541. continue;
  542. /* Verify that we have changed to the correct namespaces. */
  543. if (info->flag == CLONE_NEWPID)
  544. nsfd = self->nsfds[i];
  545. else
  546. nsfd = self->child_nsfds1[i];
  547. ASSERT_EQ(in_same_namespace(nsfd, pid, info->name), 1) {
  548. TH_LOG("setns failed to place us correctly into %s namespace of %d",
  549. info->name, self->child_pid1);
  550. }
  551. TH_LOG("Managed to correctly setns to %s namespace of %d",
  552. info->name, self->child_pid1);
  553. }
  554. }
  555. TEST_F(current_nsset, no_foul_play)
  556. {
  557. unsigned flags = 0;
  558. int i;
  559. for (i = 0; i < PIDFD_NS_MAX; i++) {
  560. const struct ns_info *info = &ns_info[i];
  561. if (self->child_nsfds1[i] < 0)
  562. continue;
  563. flags |= info->flag;
  564. if (info->flag) /* No use logging pid_for_children. */
  565. TH_LOG("Adding %s namespace of %d to list of namespaces to attach to",
  566. info->name, self->child_pid1);
  567. }
  568. ASSERT_EQ(setns(self->child_pidfd1, flags), 0) {
  569. TH_LOG("%m - Failed to setns to namespaces of %d vid pidfd %d",
  570. self->child_pid1, self->child_pidfd1);
  571. }
  572. /*
  573. * Can't setns to a user namespace outside of our hierarchy since we
  574. * don't have caps in there and didn't create it. That means that under
  575. * no circumstances should we be able to setns to any of the other
  576. * ones since they aren't owned by our user namespace.
  577. */
  578. for (i = 0; i < PIDFD_NS_MAX; i++) {
  579. const struct ns_info *info = &ns_info[i];
  580. if (self->child_nsfds2[i] < 0 || !info->flag)
  581. continue;
  582. ASSERT_NE(setns(self->child_pidfd2, info->flag), 0) {
  583. TH_LOG("Managed to setns to %s namespace of %d via pidfd %d",
  584. info->name, self->child_pid2,
  585. self->child_pidfd2);
  586. }
  587. TH_LOG("%m - Correctly failed to setns to %s namespace of %d via pidfd %d",
  588. info->name, self->child_pid2,
  589. self->child_pidfd2);
  590. ASSERT_NE(setns(self->child_nsfds2[i], info->flag), 0) {
  591. TH_LOG("Managed to setns to %s namespace of %d via nsfd %d",
  592. info->name, self->child_pid2,
  593. self->child_nsfds2[i]);
  594. }
  595. TH_LOG("%m - Correctly failed to setns to %s namespace of %d via nsfd %d",
  596. info->name, self->child_pid2,
  597. self->child_nsfds2[i]);
  598. }
  599. /*
  600. * Can't setns to a user namespace outside of our hierarchy since we
  601. * don't have caps in there and didn't create it. That means that under
  602. * no circumstances should we be able to setns to any of the other
  603. * ones since they aren't owned by our user namespace.
  604. */
  605. for (i = 0; i < PIDFD_NS_MAX; i++) {
  606. const struct ns_info *info = &ns_info[i];
  607. if (self->child_pidfd_derived_nsfds2[i] < 0 || !info->flag)
  608. continue;
  609. ASSERT_NE(setns(self->child_pidfd_derived_nsfds2[i], info->flag), 0) {
  610. TH_LOG("Managed to setns to %s namespace of %d via nsfd %d",
  611. info->name, self->child_pid2,
  612. self->child_pidfd_derived_nsfds2[i]);
  613. }
  614. TH_LOG("%m - Correctly failed to setns to %s namespace of %d via nsfd %d",
  615. info->name, self->child_pid2,
  616. self->child_pidfd_derived_nsfds2[i]);
  617. }
  618. }
  619. TEST(setns_einval)
  620. {
  621. int fd;
  622. fd = sys_memfd_create("rostock", 0);
  623. EXPECT_GT(fd, 0);
  624. ASSERT_NE(setns(fd, 0), 0);
  625. EXPECT_EQ(errno, EINVAL);
  626. close(fd);
  627. }
  628. TEST_HARNESS_MAIN