pidfd_info_test.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  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 <poll.h>
  8. #include <pthread.h>
  9. #include <sched.h>
  10. #include <signal.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <syscall.h>
  15. #include <sys/prctl.h>
  16. #include <sys/wait.h>
  17. #include <unistd.h>
  18. #include <sys/socket.h>
  19. #include <linux/kcmp.h>
  20. #include <sys/stat.h>
  21. #include "pidfd.h"
  22. #include "kselftest_harness.h"
  23. FIXTURE(pidfd_info)
  24. {
  25. pid_t child_pid1;
  26. int child_pidfd1;
  27. pid_t child_pid2;
  28. int child_pidfd2;
  29. pid_t child_pid3;
  30. int child_pidfd3;
  31. pid_t child_pid4;
  32. int child_pidfd4;
  33. };
  34. FIXTURE_SETUP(pidfd_info)
  35. {
  36. int ret;
  37. int ipc_sockets[2];
  38. char c;
  39. ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
  40. EXPECT_EQ(ret, 0);
  41. self->child_pid1 = create_child(&self->child_pidfd1, 0);
  42. EXPECT_GE(self->child_pid1, 0);
  43. if (self->child_pid1 == 0) {
  44. close(ipc_sockets[0]);
  45. if (write_nointr(ipc_sockets[1], "1", 1) < 0)
  46. _exit(EXIT_FAILURE);
  47. close(ipc_sockets[1]);
  48. pause();
  49. _exit(EXIT_SUCCESS);
  50. }
  51. EXPECT_EQ(close(ipc_sockets[1]), 0);
  52. ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
  53. EXPECT_EQ(close(ipc_sockets[0]), 0);
  54. /* SIGKILL but don't reap. */
  55. EXPECT_EQ(sys_pidfd_send_signal(self->child_pidfd1, SIGKILL, NULL, 0), 0);
  56. ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
  57. EXPECT_EQ(ret, 0);
  58. self->child_pid2 = create_child(&self->child_pidfd2, 0);
  59. EXPECT_GE(self->child_pid2, 0);
  60. if (self->child_pid2 == 0) {
  61. close(ipc_sockets[0]);
  62. if (write_nointr(ipc_sockets[1], "1", 1) < 0)
  63. _exit(EXIT_FAILURE);
  64. close(ipc_sockets[1]);
  65. pause();
  66. _exit(EXIT_SUCCESS);
  67. }
  68. EXPECT_EQ(close(ipc_sockets[1]), 0);
  69. ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1);
  70. EXPECT_EQ(close(ipc_sockets[0]), 0);
  71. /* SIGKILL and reap. */
  72. EXPECT_EQ(sys_pidfd_send_signal(self->child_pidfd2, SIGKILL, NULL, 0), 0);
  73. EXPECT_EQ(sys_waitid(P_PID, self->child_pid2, NULL, WEXITED), 0);
  74. self->child_pid3 = create_child(&self->child_pidfd3, CLONE_NEWUSER | CLONE_NEWPID);
  75. EXPECT_GE(self->child_pid3, 0);
  76. if (self->child_pid3 == 0)
  77. _exit(EXIT_SUCCESS);
  78. self->child_pid4 = create_child(&self->child_pidfd4, CLONE_NEWUSER | CLONE_NEWPID);
  79. EXPECT_GE(self->child_pid4, 0);
  80. if (self->child_pid4 == 0)
  81. _exit(EXIT_SUCCESS);
  82. EXPECT_EQ(sys_waitid(P_PID, self->child_pid4, NULL, WEXITED), 0);
  83. }
  84. FIXTURE_TEARDOWN(pidfd_info)
  85. {
  86. sys_pidfd_send_signal(self->child_pidfd1, SIGKILL, NULL, 0);
  87. if (self->child_pidfd1 >= 0)
  88. EXPECT_EQ(0, close(self->child_pidfd1));
  89. sys_waitid(P_PID, self->child_pid1, NULL, WEXITED);
  90. sys_pidfd_send_signal(self->child_pidfd2, SIGKILL, NULL, 0);
  91. if (self->child_pidfd2 >= 0)
  92. EXPECT_EQ(0, close(self->child_pidfd2));
  93. sys_waitid(P_PID, self->child_pid2, NULL, WEXITED);
  94. sys_waitid(P_PID, self->child_pid3, NULL, WEXITED);
  95. sys_waitid(P_PID, self->child_pid4, NULL, WEXITED);
  96. }
  97. TEST_F(pidfd_info, sigkill_exit)
  98. {
  99. struct pidfd_info info = {
  100. .mask = PIDFD_INFO_CGROUPID,
  101. };
  102. /* Process has exited but not been reaped so this must work. */
  103. ASSERT_EQ(ioctl(self->child_pidfd1, PIDFD_GET_INFO, &info), 0);
  104. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  105. ASSERT_EQ(ioctl(self->child_pidfd1, PIDFD_GET_INFO, &info), 0);
  106. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS));
  107. /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */
  108. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT));
  109. }
  110. TEST_F(pidfd_info, sigkill_reaped)
  111. {
  112. struct pidfd_info info = {
  113. .mask = PIDFD_INFO_CGROUPID,
  114. };
  115. /* Process has already been reaped and PIDFD_INFO_EXIT hasn't been set. */
  116. ASSERT_NE(ioctl(self->child_pidfd2, PIDFD_GET_INFO, &info), 0);
  117. ASSERT_EQ(errno, ESRCH);
  118. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  119. ASSERT_EQ(ioctl(self->child_pidfd2, PIDFD_GET_INFO, &info), 0);
  120. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  121. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  122. ASSERT_TRUE(WIFSIGNALED(info.exit_code));
  123. ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL);
  124. }
  125. TEST_F(pidfd_info, success_exit)
  126. {
  127. struct pidfd_info info = {
  128. .mask = PIDFD_INFO_CGROUPID,
  129. };
  130. /* Process has exited but not been reaped so this must work. */
  131. ASSERT_EQ(ioctl(self->child_pidfd3, PIDFD_GET_INFO, &info), 0);
  132. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  133. ASSERT_EQ(ioctl(self->child_pidfd3, PIDFD_GET_INFO, &info), 0);
  134. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS));
  135. /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */
  136. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT));
  137. }
  138. TEST_F(pidfd_info, success_reaped)
  139. {
  140. struct pidfd_info info = {
  141. .mask = PIDFD_INFO_CGROUPID,
  142. };
  143. /* Process has already been reaped and PIDFD_INFO_EXIT hasn't been set. */
  144. ASSERT_NE(ioctl(self->child_pidfd4, PIDFD_GET_INFO, &info), 0);
  145. ASSERT_EQ(errno, ESRCH);
  146. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  147. ASSERT_EQ(ioctl(self->child_pidfd4, PIDFD_GET_INFO, &info), 0);
  148. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  149. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  150. ASSERT_TRUE(WIFEXITED(info.exit_code));
  151. ASSERT_EQ(WEXITSTATUS(info.exit_code), 0);
  152. }
  153. TEST_F(pidfd_info, success_reaped_poll)
  154. {
  155. struct pidfd_info info = {
  156. .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT,
  157. };
  158. struct pollfd fds = {};
  159. int nevents;
  160. fds.events = POLLIN;
  161. fds.fd = self->child_pidfd2;
  162. nevents = poll(&fds, 1, -1);
  163. ASSERT_EQ(nevents, 1);
  164. ASSERT_TRUE(!!(fds.revents & POLLIN));
  165. ASSERT_TRUE(!!(fds.revents & POLLHUP));
  166. ASSERT_EQ(ioctl(self->child_pidfd2, PIDFD_GET_INFO, &info), 0);
  167. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  168. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  169. ASSERT_TRUE(WIFSIGNALED(info.exit_code));
  170. ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL);
  171. }
  172. static void *pidfd_info_pause_thread(void *arg)
  173. {
  174. pid_t pid_thread = gettid();
  175. int ipc_socket = *(int *)arg;
  176. /* Inform the grand-parent what the tid of this thread is. */
  177. if (write_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread))
  178. return NULL;
  179. close(ipc_socket);
  180. /* Sleep until we're killed. */
  181. pause();
  182. return NULL;
  183. }
  184. TEST_F(pidfd_info, thread_group)
  185. {
  186. pid_t pid_leader, pid_poller, pid_thread;
  187. pthread_t thread;
  188. int nevents, pidfd_leader, pidfd_thread, pidfd_leader_thread, ret;
  189. int ipc_sockets[2];
  190. struct pollfd fds = {};
  191. struct pidfd_info info = {
  192. .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT,
  193. }, info2;
  194. ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
  195. EXPECT_EQ(ret, 0);
  196. pid_leader = create_child(&pidfd_leader, 0);
  197. EXPECT_GE(pid_leader, 0);
  198. if (pid_leader == 0) {
  199. close(ipc_sockets[0]);
  200. /* The thread will outlive the thread-group leader. */
  201. if (pthread_create(&thread, NULL, pidfd_info_pause_thread, &ipc_sockets[1]))
  202. syscall(__NR_exit, EXIT_FAILURE);
  203. /* Make the thread-group leader exit prematurely. */
  204. syscall(__NR_exit, EXIT_SUCCESS);
  205. }
  206. /*
  207. * Opening a PIDFD_THREAD aka thread-specific pidfd based on a
  208. * thread-group leader must succeed.
  209. */
  210. pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD);
  211. ASSERT_GE(pidfd_leader_thread, 0);
  212. pid_poller = fork();
  213. ASSERT_GE(pid_poller, 0);
  214. if (pid_poller == 0) {
  215. /*
  216. * We can't poll and wait for the old thread-group
  217. * leader to exit using a thread-specific pidfd. The
  218. * thread-group leader exited prematurely and
  219. * notification is delayed until all subthreads have
  220. * exited.
  221. */
  222. fds.events = POLLIN;
  223. fds.fd = pidfd_leader_thread;
  224. nevents = poll(&fds, 1, 10000 /* wait 5 seconds */);
  225. if (nevents != 0)
  226. _exit(EXIT_FAILURE);
  227. if (fds.revents & POLLIN)
  228. _exit(EXIT_FAILURE);
  229. if (fds.revents & POLLHUP)
  230. _exit(EXIT_FAILURE);
  231. _exit(EXIT_SUCCESS);
  232. }
  233. /* Retrieve the tid of the thread. */
  234. EXPECT_EQ(close(ipc_sockets[1]), 0);
  235. ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread));
  236. EXPECT_EQ(close(ipc_sockets[0]), 0);
  237. /* Opening a thread as a thread-group leader must fail. */
  238. pidfd_thread = sys_pidfd_open(pid_thread, 0);
  239. ASSERT_LT(pidfd_thread, 0);
  240. ASSERT_EQ(errno, ENOENT);
  241. /* Opening a thread as a PIDFD_THREAD must succeed. */
  242. pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD);
  243. ASSERT_GE(pidfd_thread, 0);
  244. ASSERT_EQ(wait_for_pid(pid_poller), 0);
  245. /*
  246. * Note that pidfd_leader is a thread-group pidfd, so polling on it
  247. * would only notify us once all thread in the thread-group have
  248. * exited. So we can't poll before we have taken down the whole
  249. * thread-group.
  250. */
  251. /* Get PIDFD_GET_INFO using the thread-group leader pidfd. */
  252. ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0);
  253. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS));
  254. /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */
  255. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT));
  256. ASSERT_EQ(info.pid, pid_leader);
  257. /*
  258. * Now retrieve the same info using the thread specific pidfd
  259. * for the thread-group leader.
  260. */
  261. info2.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  262. ASSERT_EQ(ioctl(pidfd_leader_thread, PIDFD_GET_INFO, &info2), 0);
  263. ASSERT_TRUE(!!(info2.mask & PIDFD_INFO_CREDS));
  264. /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */
  265. ASSERT_FALSE(!!(info2.mask & PIDFD_INFO_EXIT));
  266. ASSERT_EQ(info2.pid, pid_leader);
  267. /* Now try the thread-specific pidfd. */
  268. ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0);
  269. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS));
  270. /* The thread hasn't exited, so no PIDFD_INFO_EXIT information yet. */
  271. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT));
  272. ASSERT_EQ(info.pid, pid_thread);
  273. /*
  274. * Take down the whole thread-group. The thread-group leader
  275. * exited successfully but the thread will now be SIGKILLed.
  276. * This must be reflected in the recorded exit information.
  277. */
  278. EXPECT_EQ(sys_pidfd_send_signal(pidfd_leader, SIGKILL, NULL, 0), 0);
  279. EXPECT_EQ(sys_waitid(P_PIDFD, pidfd_leader, NULL, WEXITED), 0);
  280. fds.events = POLLIN;
  281. fds.fd = pidfd_leader;
  282. nevents = poll(&fds, 1, -1);
  283. ASSERT_EQ(nevents, 1);
  284. ASSERT_TRUE(!!(fds.revents & POLLIN));
  285. /* The thread-group leader has been reaped. */
  286. ASSERT_TRUE(!!(fds.revents & POLLHUP));
  287. /*
  288. * Retrieve exit information for the thread-group leader via the
  289. * thread-group leader pidfd.
  290. */
  291. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  292. ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0);
  293. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  294. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  295. /* Even though the thread-group exited successfully it will still report the group exit code. */
  296. ASSERT_TRUE(WIFSIGNALED(info.exit_code));
  297. ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL);
  298. /*
  299. * Retrieve exit information for the thread-group leader via the
  300. * thread-specific pidfd.
  301. */
  302. info2.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  303. ASSERT_EQ(ioctl(pidfd_leader_thread, PIDFD_GET_INFO, &info2), 0);
  304. ASSERT_FALSE(!!(info2.mask & PIDFD_INFO_CREDS));
  305. ASSERT_TRUE(!!(info2.mask & PIDFD_INFO_EXIT));
  306. /* Even though the thread-group exited successfully it will still report the group exit code. */
  307. ASSERT_TRUE(WIFSIGNALED(info2.exit_code));
  308. ASSERT_EQ(WTERMSIG(info2.exit_code), SIGKILL);
  309. /* Retrieve exit information for the thread. */
  310. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  311. ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0);
  312. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  313. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  314. /* The thread got SIGKILLed. */
  315. ASSERT_TRUE(WIFSIGNALED(info.exit_code));
  316. ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL);
  317. EXPECT_EQ(close(pidfd_leader), 0);
  318. EXPECT_EQ(close(pidfd_thread), 0);
  319. }
  320. static void *pidfd_info_thread_exec(void *arg)
  321. {
  322. pid_t pid_thread = gettid();
  323. int ipc_socket = *(int *)arg;
  324. /* Inform the grand-parent what the tid of this thread is. */
  325. if (write_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread))
  326. return NULL;
  327. if (read_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread))
  328. return NULL;
  329. close(ipc_socket);
  330. sys_execveat(AT_FDCWD, "pidfd_exec_helper", NULL, NULL, 0);
  331. return NULL;
  332. }
  333. TEST_F(pidfd_info, thread_group_exec)
  334. {
  335. pid_t pid_leader, pid_poller, pid_thread;
  336. pthread_t thread;
  337. int nevents, pidfd_leader, pidfd_leader_thread, pidfd_thread, ret;
  338. int ipc_sockets[2];
  339. struct pollfd fds = {};
  340. struct pidfd_info info = {
  341. .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT,
  342. };
  343. ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
  344. EXPECT_EQ(ret, 0);
  345. pid_leader = create_child(&pidfd_leader, 0);
  346. EXPECT_GE(pid_leader, 0);
  347. if (pid_leader == 0) {
  348. close(ipc_sockets[0]);
  349. /* The thread will outlive the thread-group leader. */
  350. if (pthread_create(&thread, NULL, pidfd_info_thread_exec, &ipc_sockets[1]))
  351. syscall(__NR_exit, EXIT_FAILURE);
  352. /* Make the thread-group leader exit prematurely. */
  353. syscall(__NR_exit, EXIT_SUCCESS);
  354. }
  355. /* Open a thread-specific pidfd for the thread-group leader. */
  356. pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD);
  357. ASSERT_GE(pidfd_leader_thread, 0);
  358. pid_poller = fork();
  359. ASSERT_GE(pid_poller, 0);
  360. if (pid_poller == 0) {
  361. /*
  362. * We can't poll and wait for the old thread-group
  363. * leader to exit using a thread-specific pidfd. The
  364. * thread-group leader exited prematurely and
  365. * notification is delayed until all subthreads have
  366. * exited.
  367. *
  368. * When the thread has execed it will taken over the old
  369. * thread-group leaders struct pid. Calling poll after
  370. * the thread execed will thus block again because a new
  371. * thread-group has started.
  372. */
  373. fds.events = POLLIN;
  374. fds.fd = pidfd_leader_thread;
  375. nevents = poll(&fds, 1, 10000 /* wait 5 seconds */);
  376. if (nevents != 0)
  377. _exit(EXIT_FAILURE);
  378. if (fds.revents & POLLIN)
  379. _exit(EXIT_FAILURE);
  380. if (fds.revents & POLLHUP)
  381. _exit(EXIT_FAILURE);
  382. _exit(EXIT_SUCCESS);
  383. }
  384. /* Retrieve the tid of the thread. */
  385. EXPECT_EQ(close(ipc_sockets[1]), 0);
  386. ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread));
  387. /* Opening a thread as a PIDFD_THREAD must succeed. */
  388. pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD);
  389. ASSERT_GE(pidfd_thread, 0);
  390. /* Now that we've opened a thread-specific pidfd the thread can exec. */
  391. ASSERT_EQ(write_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread));
  392. EXPECT_EQ(close(ipc_sockets[0]), 0);
  393. ASSERT_EQ(wait_for_pid(pid_poller), 0);
  394. /* Wait until the kernel has SIGKILLed the thread. */
  395. fds.events = POLLHUP;
  396. fds.fd = pidfd_thread;
  397. nevents = poll(&fds, 1, -1);
  398. ASSERT_EQ(nevents, 1);
  399. /* The thread has been reaped. */
  400. ASSERT_TRUE(!!(fds.revents & POLLHUP));
  401. /* Retrieve thread-specific exit info from pidfd. */
  402. ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0);
  403. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  404. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  405. /*
  406. * While the kernel will have SIGKILLed the whole thread-group
  407. * during exec it will cause the individual threads to exit
  408. * cleanly.
  409. */
  410. ASSERT_TRUE(WIFEXITED(info.exit_code));
  411. ASSERT_EQ(WEXITSTATUS(info.exit_code), 0);
  412. /*
  413. * The thread-group leader is still alive, the thread has taken
  414. * over its struct pid and thus its pid number.
  415. */
  416. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  417. ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0);
  418. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS));
  419. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT));
  420. ASSERT_EQ(info.pid, pid_leader);
  421. /* Take down the thread-group leader. */
  422. EXPECT_EQ(sys_pidfd_send_signal(pidfd_leader, SIGKILL, NULL, 0), 0);
  423. /*
  424. * Afte the exec we're dealing with an empty thread-group so now
  425. * we must see an exit notification on the thread-specific pidfd
  426. * for the thread-group leader as there's no subthread that can
  427. * revive the struct pid.
  428. */
  429. fds.events = POLLIN;
  430. fds.fd = pidfd_leader_thread;
  431. nevents = poll(&fds, 1, -1);
  432. ASSERT_EQ(nevents, 1);
  433. ASSERT_TRUE(!!(fds.revents & POLLIN));
  434. ASSERT_FALSE(!!(fds.revents & POLLHUP));
  435. EXPECT_EQ(sys_waitid(P_PIDFD, pidfd_leader, NULL, WEXITED), 0);
  436. /* Retrieve exit information for the thread-group leader. */
  437. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  438. ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0);
  439. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  440. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  441. EXPECT_EQ(close(pidfd_leader), 0);
  442. EXPECT_EQ(close(pidfd_thread), 0);
  443. }
  444. static void *pidfd_info_thread_exec_sane(void *arg)
  445. {
  446. pid_t pid_thread = gettid();
  447. int ipc_socket = *(int *)arg;
  448. /* Inform the grand-parent what the tid of this thread is. */
  449. if (write_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread))
  450. return NULL;
  451. if (read_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread))
  452. return NULL;
  453. close(ipc_socket);
  454. sys_execveat(AT_FDCWD, "pidfd_exec_helper", NULL, NULL, 0);
  455. return NULL;
  456. }
  457. TEST_F(pidfd_info, thread_group_exec_thread)
  458. {
  459. pid_t pid_leader, pid_poller, pid_thread;
  460. pthread_t thread;
  461. int nevents, pidfd_leader, pidfd_leader_thread, pidfd_thread, ret;
  462. int ipc_sockets[2];
  463. struct pollfd fds = {};
  464. struct pidfd_info info = {
  465. .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT,
  466. };
  467. ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
  468. EXPECT_EQ(ret, 0);
  469. pid_leader = create_child(&pidfd_leader, 0);
  470. EXPECT_GE(pid_leader, 0);
  471. if (pid_leader == 0) {
  472. close(ipc_sockets[0]);
  473. /* The thread will outlive the thread-group leader. */
  474. if (pthread_create(&thread, NULL, pidfd_info_thread_exec_sane, &ipc_sockets[1]))
  475. syscall(__NR_exit, EXIT_FAILURE);
  476. /*
  477. * Pause the thread-group leader. It will be killed once
  478. * the subthread execs.
  479. */
  480. pause();
  481. syscall(__NR_exit, EXIT_SUCCESS);
  482. }
  483. /* Retrieve the tid of the thread. */
  484. EXPECT_EQ(close(ipc_sockets[1]), 0);
  485. ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread));
  486. /* Opening a thread as a PIDFD_THREAD must succeed. */
  487. pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD);
  488. ASSERT_GE(pidfd_thread, 0);
  489. /* Open a thread-specific pidfd for the thread-group leader. */
  490. pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD);
  491. ASSERT_GE(pidfd_leader_thread, 0);
  492. pid_poller = fork();
  493. ASSERT_GE(pid_poller, 0);
  494. if (pid_poller == 0) {
  495. /*
  496. * The subthread will now exec. The struct pid of the old
  497. * thread-group leader will be assumed by the subthread which
  498. * becomes the new thread-group leader. So no exit notification
  499. * must be generated. Wait for 5 seconds and call it a success
  500. * if no notification has been received.
  501. */
  502. fds.events = POLLIN;
  503. fds.fd = pidfd_leader_thread;
  504. nevents = poll(&fds, 1, 10000 /* wait 5 seconds */);
  505. if (nevents != 0)
  506. _exit(EXIT_FAILURE);
  507. if (fds.revents & POLLIN)
  508. _exit(EXIT_FAILURE);
  509. if (fds.revents & POLLHUP)
  510. _exit(EXIT_FAILURE);
  511. _exit(EXIT_SUCCESS);
  512. }
  513. /* Now that we've opened a thread-specific pidfd the thread can exec. */
  514. ASSERT_EQ(write_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread));
  515. EXPECT_EQ(close(ipc_sockets[0]), 0);
  516. ASSERT_EQ(wait_for_pid(pid_poller), 0);
  517. /* Wait until the kernel has SIGKILLed the thread. */
  518. fds.events = POLLHUP;
  519. fds.fd = pidfd_thread;
  520. nevents = poll(&fds, 1, -1);
  521. ASSERT_EQ(nevents, 1);
  522. /* The thread has been reaped. */
  523. ASSERT_TRUE(!!(fds.revents & POLLHUP));
  524. /* Retrieve thread-specific exit info from pidfd. */
  525. ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0);
  526. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  527. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  528. /*
  529. * While the kernel will have SIGKILLed the whole thread-group
  530. * during exec it will cause the individual threads to exit
  531. * cleanly.
  532. */
  533. ASSERT_TRUE(WIFEXITED(info.exit_code));
  534. ASSERT_EQ(WEXITSTATUS(info.exit_code), 0);
  535. /*
  536. * The thread-group leader is still alive, the thread has taken
  537. * over its struct pid and thus its pid number.
  538. */
  539. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  540. ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0);
  541. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS));
  542. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT));
  543. ASSERT_EQ(info.pid, pid_leader);
  544. /* Take down the thread-group leader. */
  545. EXPECT_EQ(sys_pidfd_send_signal(pidfd_leader, SIGKILL, NULL, 0), 0);
  546. /*
  547. * Afte the exec we're dealing with an empty thread-group so now
  548. * we must see an exit notification on the thread-specific pidfd
  549. * for the thread-group leader as there's no subthread that can
  550. * revive the struct pid.
  551. */
  552. fds.events = POLLIN;
  553. fds.fd = pidfd_leader_thread;
  554. nevents = poll(&fds, 1, -1);
  555. ASSERT_EQ(nevents, 1);
  556. ASSERT_TRUE(!!(fds.revents & POLLIN));
  557. ASSERT_FALSE(!!(fds.revents & POLLHUP));
  558. EXPECT_EQ(sys_waitid(P_PIDFD, pidfd_leader, NULL, WEXITED), 0);
  559. /* Retrieve exit information for the thread-group leader. */
  560. info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT;
  561. ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0);
  562. ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS));
  563. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT));
  564. EXPECT_EQ(close(pidfd_leader), 0);
  565. EXPECT_EQ(close(pidfd_thread), 0);
  566. }
  567. /*
  568. * Test: PIDFD_INFO_SUPPORTED_MASK field
  569. *
  570. * Verify that when PIDFD_INFO_SUPPORTED_MASK is requested, the kernel
  571. * returns the supported_mask field indicating which flags the kernel supports.
  572. */
  573. TEST(supported_mask_field)
  574. {
  575. struct pidfd_info info = {
  576. .mask = PIDFD_INFO_SUPPORTED_MASK,
  577. };
  578. int pidfd;
  579. pid_t pid;
  580. pid = create_child(&pidfd, 0);
  581. ASSERT_GE(pid, 0);
  582. if (pid == 0)
  583. pause();
  584. /* Request supported_mask field */
  585. ASSERT_EQ(ioctl(pidfd, PIDFD_GET_INFO, &info), 0);
  586. /* Verify PIDFD_INFO_SUPPORTED_MASK is set in the reply */
  587. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_SUPPORTED_MASK));
  588. /* Verify supported_mask contains expected flags */
  589. ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_PID));
  590. ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_CREDS));
  591. ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_CGROUPID));
  592. ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_EXIT));
  593. ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_COREDUMP));
  594. ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_SUPPORTED_MASK));
  595. ASSERT_TRUE(!!(info.supported_mask & PIDFD_INFO_COREDUMP_SIGNAL));
  596. /* Clean up */
  597. sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0);
  598. sys_waitid(P_PIDFD, pidfd, NULL, WEXITED);
  599. close(pidfd);
  600. }
  601. /*
  602. * Test: PIDFD_INFO_SUPPORTED_MASK always available
  603. *
  604. * Verify that supported_mask is returned even when other fields are requested.
  605. */
  606. TEST(supported_mask_with_other_fields)
  607. {
  608. struct pidfd_info info = {
  609. .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_SUPPORTED_MASK,
  610. };
  611. int pidfd;
  612. pid_t pid;
  613. pid = create_child(&pidfd, 0);
  614. ASSERT_GE(pid, 0);
  615. if (pid == 0)
  616. pause();
  617. ASSERT_EQ(ioctl(pidfd, PIDFD_GET_INFO, &info), 0);
  618. /* Both fields should be present */
  619. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CGROUPID));
  620. ASSERT_TRUE(!!(info.mask & PIDFD_INFO_SUPPORTED_MASK));
  621. ASSERT_NE(info.supported_mask, 0);
  622. /* Clean up */
  623. sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0);
  624. sys_waitid(P_PIDFD, pidfd, NULL, WEXITED);
  625. close(pidfd);
  626. }
  627. TEST_HARNESS_MAIN