PageRenderTime 27ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/testing/selftests/pidfd/pidfd_test.c

http://github.com/torvalds/linux
C | 536 lines | 390 code | 97 blank | 49 comment | 78 complexity | 34a0a4163a8d3f291e2aa19ae521cc38 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #define _GNU_SOURCE
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <linux/types.h>
  6. #include <pthread.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/epoll.h>
  14. #include <sys/mman.h>
  15. #include <sys/mount.h>
  16. #include <sys/wait.h>
  17. #include <time.h>
  18. #include <unistd.h>
  19. #include "pidfd.h"
  20. #include "../kselftest.h"
  21. #define str(s) _str(s)
  22. #define _str(s) #s
  23. #define CHILD_THREAD_MIN_WAIT 3 /* seconds */
  24. #define MAX_EVENTS 5
  25. static pid_t pidfd_clone(int flags, int *pidfd, int (*fn)(void *))
  26. {
  27. size_t stack_size = 1024;
  28. char *stack[1024] = { 0 };
  29. #ifdef __ia64__
  30. return __clone2(fn, stack, stack_size, flags | SIGCHLD, NULL, pidfd);
  31. #else
  32. return clone(fn, stack + stack_size, flags | SIGCHLD, NULL, pidfd);
  33. #endif
  34. }
  35. static int signal_received;
  36. static void set_signal_received_on_sigusr1(int sig)
  37. {
  38. if (sig == SIGUSR1)
  39. signal_received = 1;
  40. }
  41. /*
  42. * Straightforward test to see whether pidfd_send_signal() works is to send
  43. * a signal to ourself.
  44. */
  45. static int test_pidfd_send_signal_simple_success(void)
  46. {
  47. int pidfd, ret;
  48. const char *test_name = "pidfd_send_signal send SIGUSR1";
  49. pidfd = open("/proc/self", O_DIRECTORY | O_CLOEXEC);
  50. if (pidfd < 0)
  51. ksft_exit_fail_msg(
  52. "%s test: Failed to open process file descriptor\n",
  53. test_name);
  54. signal(SIGUSR1, set_signal_received_on_sigusr1);
  55. ret = sys_pidfd_send_signal(pidfd, SIGUSR1, NULL, 0);
  56. close(pidfd);
  57. if (ret < 0)
  58. ksft_exit_fail_msg("%s test: Failed to send signal\n",
  59. test_name);
  60. if (signal_received != 1)
  61. ksft_exit_fail_msg("%s test: Failed to receive signal\n",
  62. test_name);
  63. signal_received = 0;
  64. ksft_test_result_pass("%s test: Sent signal\n", test_name);
  65. return 0;
  66. }
  67. static int test_pidfd_send_signal_exited_fail(void)
  68. {
  69. int pidfd, ret, saved_errno;
  70. char buf[256];
  71. pid_t pid;
  72. const char *test_name = "pidfd_send_signal signal exited process";
  73. pid = fork();
  74. if (pid < 0)
  75. ksft_exit_fail_msg("%s test: Failed to create new process\n",
  76. test_name);
  77. if (pid == 0)
  78. _exit(EXIT_SUCCESS);
  79. snprintf(buf, sizeof(buf), "/proc/%d", pid);
  80. pidfd = open(buf, O_DIRECTORY | O_CLOEXEC);
  81. (void)wait_for_pid(pid);
  82. if (pidfd < 0)
  83. ksft_exit_fail_msg(
  84. "%s test: Failed to open process file descriptor\n",
  85. test_name);
  86. ret = sys_pidfd_send_signal(pidfd, 0, NULL, 0);
  87. saved_errno = errno;
  88. close(pidfd);
  89. if (ret == 0)
  90. ksft_exit_fail_msg(
  91. "%s test: Managed to send signal to process even though it should have failed\n",
  92. test_name);
  93. if (saved_errno != ESRCH)
  94. ksft_exit_fail_msg(
  95. "%s test: Expected to receive ESRCH as errno value but received %d instead\n",
  96. test_name, saved_errno);
  97. ksft_test_result_pass("%s test: Failed to send signal as expected\n",
  98. test_name);
  99. return 0;
  100. }
  101. /*
  102. * Maximum number of cycles we allow. This is equivalent to PID_MAX_DEFAULT.
  103. * If users set a higher limit or we have cycled PIDFD_MAX_DEFAULT number of
  104. * times then we skip the test to not go into an infinite loop or block for a
  105. * long time.
  106. */
  107. #define PIDFD_MAX_DEFAULT 0x8000
  108. static int test_pidfd_send_signal_recycled_pid_fail(void)
  109. {
  110. int i, ret;
  111. pid_t pid1;
  112. const char *test_name = "pidfd_send_signal signal recycled pid";
  113. ret = unshare(CLONE_NEWPID);
  114. if (ret < 0)
  115. ksft_exit_fail_msg("%s test: Failed to unshare pid namespace\n",
  116. test_name);
  117. ret = unshare(CLONE_NEWNS);
  118. if (ret < 0)
  119. ksft_exit_fail_msg(
  120. "%s test: Failed to unshare mount namespace\n",
  121. test_name);
  122. ret = mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0);
  123. if (ret < 0)
  124. ksft_exit_fail_msg("%s test: Failed to remount / private\n",
  125. test_name);
  126. /* pid 1 in new pid namespace */
  127. pid1 = fork();
  128. if (pid1 < 0)
  129. ksft_exit_fail_msg("%s test: Failed to create new process\n",
  130. test_name);
  131. if (pid1 == 0) {
  132. char buf[256];
  133. pid_t pid2;
  134. int pidfd = -1;
  135. (void)umount2("/proc", MNT_DETACH);
  136. ret = mount("proc", "/proc", "proc", 0, NULL);
  137. if (ret < 0)
  138. _exit(PIDFD_ERROR);
  139. /* grab pid PID_RECYCLE */
  140. for (i = 0; i <= PIDFD_MAX_DEFAULT; i++) {
  141. pid2 = fork();
  142. if (pid2 < 0)
  143. _exit(PIDFD_ERROR);
  144. if (pid2 == 0)
  145. _exit(PIDFD_PASS);
  146. if (pid2 == PID_RECYCLE) {
  147. snprintf(buf, sizeof(buf), "/proc/%d", pid2);
  148. ksft_print_msg("pid to recycle is %d\n", pid2);
  149. pidfd = open(buf, O_DIRECTORY | O_CLOEXEC);
  150. }
  151. if (wait_for_pid(pid2))
  152. _exit(PIDFD_ERROR);
  153. if (pid2 >= PID_RECYCLE)
  154. break;
  155. }
  156. /*
  157. * We want to be as predictable as we can so if we haven't been
  158. * able to grab pid PID_RECYCLE skip the test.
  159. */
  160. if (pid2 != PID_RECYCLE) {
  161. /* skip test */
  162. close(pidfd);
  163. _exit(PIDFD_SKIP);
  164. }
  165. if (pidfd < 0)
  166. _exit(PIDFD_ERROR);
  167. for (i = 0; i <= PIDFD_MAX_DEFAULT; i++) {
  168. char c;
  169. int pipe_fds[2];
  170. pid_t recycled_pid;
  171. int child_ret = PIDFD_PASS;
  172. ret = pipe2(pipe_fds, O_CLOEXEC);
  173. if (ret < 0)
  174. _exit(PIDFD_ERROR);
  175. recycled_pid = fork();
  176. if (recycled_pid < 0)
  177. _exit(PIDFD_ERROR);
  178. if (recycled_pid == 0) {
  179. close(pipe_fds[1]);
  180. (void)read(pipe_fds[0], &c, 1);
  181. close(pipe_fds[0]);
  182. _exit(PIDFD_PASS);
  183. }
  184. /*
  185. * Stop the child so we can inspect whether we have
  186. * recycled pid PID_RECYCLE.
  187. */
  188. close(pipe_fds[0]);
  189. ret = kill(recycled_pid, SIGSTOP);
  190. close(pipe_fds[1]);
  191. if (ret) {
  192. (void)wait_for_pid(recycled_pid);
  193. _exit(PIDFD_ERROR);
  194. }
  195. /*
  196. * We have recycled the pid. Try to signal it. This
  197. * needs to fail since this is a different process than
  198. * the one the pidfd refers to.
  199. */
  200. if (recycled_pid == PID_RECYCLE) {
  201. ret = sys_pidfd_send_signal(pidfd, SIGCONT,
  202. NULL, 0);
  203. if (ret && errno == ESRCH)
  204. child_ret = PIDFD_XFAIL;
  205. else
  206. child_ret = PIDFD_FAIL;
  207. }
  208. /* let the process move on */
  209. ret = kill(recycled_pid, SIGCONT);
  210. if (ret)
  211. (void)kill(recycled_pid, SIGKILL);
  212. if (wait_for_pid(recycled_pid))
  213. _exit(PIDFD_ERROR);
  214. switch (child_ret) {
  215. case PIDFD_FAIL:
  216. /* fallthrough */
  217. case PIDFD_XFAIL:
  218. _exit(child_ret);
  219. case PIDFD_PASS:
  220. break;
  221. default:
  222. /* not reached */
  223. _exit(PIDFD_ERROR);
  224. }
  225. /*
  226. * If the user set a custom pid_max limit we could be
  227. * in the millions.
  228. * Skip the test in this case.
  229. */
  230. if (recycled_pid > PIDFD_MAX_DEFAULT)
  231. _exit(PIDFD_SKIP);
  232. }
  233. /* failed to recycle pid */
  234. _exit(PIDFD_SKIP);
  235. }
  236. ret = wait_for_pid(pid1);
  237. switch (ret) {
  238. case PIDFD_FAIL:
  239. ksft_exit_fail_msg(
  240. "%s test: Managed to signal recycled pid %d\n",
  241. test_name, PID_RECYCLE);
  242. case PIDFD_PASS:
  243. ksft_exit_fail_msg("%s test: Failed to recycle pid %d\n",
  244. test_name, PID_RECYCLE);
  245. case PIDFD_SKIP:
  246. ksft_print_msg("%s test: Skipping test\n", test_name);
  247. ret = 0;
  248. break;
  249. case PIDFD_XFAIL:
  250. ksft_test_result_pass(
  251. "%s test: Failed to signal recycled pid as expected\n",
  252. test_name);
  253. ret = 0;
  254. break;
  255. default /* PIDFD_ERROR */:
  256. ksft_exit_fail_msg("%s test: Error while running tests\n",
  257. test_name);
  258. }
  259. return ret;
  260. }
  261. static int test_pidfd_send_signal_syscall_support(void)
  262. {
  263. int pidfd, ret;
  264. const char *test_name = "pidfd_send_signal check for support";
  265. pidfd = open("/proc/self", O_DIRECTORY | O_CLOEXEC);
  266. if (pidfd < 0)
  267. ksft_exit_fail_msg(
  268. "%s test: Failed to open process file descriptor\n",
  269. test_name);
  270. ret = sys_pidfd_send_signal(pidfd, 0, NULL, 0);
  271. if (ret < 0) {
  272. if (errno == ENOSYS)
  273. ksft_exit_skip(
  274. "%s test: pidfd_send_signal() syscall not supported\n",
  275. test_name);
  276. ksft_exit_fail_msg("%s test: Failed to send signal\n",
  277. test_name);
  278. }
  279. close(pidfd);
  280. ksft_test_result_pass(
  281. "%s test: pidfd_send_signal() syscall is supported. Tests can be executed\n",
  282. test_name);
  283. return 0;
  284. }
  285. static void *test_pidfd_poll_exec_thread(void *priv)
  286. {
  287. ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n",
  288. getpid(), syscall(SYS_gettid));
  289. ksft_print_msg("Child Thread: doing exec of sleep\n");
  290. execl("/bin/sleep", "sleep", str(CHILD_THREAD_MIN_WAIT), (char *)NULL);
  291. ksft_print_msg("Child Thread: DONE. pid %d tid %d\n",
  292. getpid(), syscall(SYS_gettid));
  293. return NULL;
  294. }
  295. static void poll_pidfd(const char *test_name, int pidfd)
  296. {
  297. int c;
  298. int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
  299. struct epoll_event event, events[MAX_EVENTS];
  300. if (epoll_fd == -1)
  301. ksft_exit_fail_msg("%s test: Failed to create epoll file descriptor "
  302. "(errno %d)\n",
  303. test_name, errno);
  304. event.events = EPOLLIN;
  305. event.data.fd = pidfd;
  306. if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pidfd, &event)) {
  307. ksft_exit_fail_msg("%s test: Failed to add epoll file descriptor "
  308. "(errno %d)\n",
  309. test_name, errno);
  310. }
  311. c = epoll_wait(epoll_fd, events, MAX_EVENTS, 5000);
  312. if (c != 1 || !(events[0].events & EPOLLIN))
  313. ksft_exit_fail_msg("%s test: Unexpected epoll_wait result (c=%d, events=%x) ",
  314. "(errno %d)\n",
  315. test_name, c, events[0].events, errno);
  316. close(epoll_fd);
  317. return;
  318. }
  319. static int child_poll_exec_test(void *args)
  320. {
  321. pthread_t t1;
  322. ksft_print_msg("Child (pidfd): starting. pid %d tid %d\n", getpid(),
  323. syscall(SYS_gettid));
  324. pthread_create(&t1, NULL, test_pidfd_poll_exec_thread, NULL);
  325. /*
  326. * Exec in the non-leader thread will destroy the leader immediately.
  327. * If the wait in the parent returns too soon, the test fails.
  328. */
  329. while (1)
  330. sleep(1);
  331. }
  332. static void test_pidfd_poll_exec(int use_waitpid)
  333. {
  334. int pid, pidfd = 0;
  335. int status, ret;
  336. pthread_t t1;
  337. time_t prog_start = time(NULL);
  338. const char *test_name = "pidfd_poll check for premature notification on child thread exec";
  339. ksft_print_msg("Parent: pid: %d\n", getpid());
  340. pid = pidfd_clone(CLONE_PIDFD, &pidfd, child_poll_exec_test);
  341. if (pid < 0)
  342. ksft_exit_fail_msg("%s test: pidfd_clone failed (ret %d, errno %d)\n",
  343. test_name, pid, errno);
  344. ksft_print_msg("Parent: Waiting for Child (%d) to complete.\n", pid);
  345. if (use_waitpid) {
  346. ret = waitpid(pid, &status, 0);
  347. if (ret == -1)
  348. ksft_print_msg("Parent: error\n");
  349. if (ret == pid)
  350. ksft_print_msg("Parent: Child process waited for.\n");
  351. } else {
  352. poll_pidfd(test_name, pidfd);
  353. }
  354. time_t prog_time = time(NULL) - prog_start;
  355. ksft_print_msg("Time waited for child: %lu\n", prog_time);
  356. close(pidfd);
  357. if (prog_time < CHILD_THREAD_MIN_WAIT || prog_time > CHILD_THREAD_MIN_WAIT + 2)
  358. ksft_exit_fail_msg("%s test: Failed\n", test_name);
  359. else
  360. ksft_test_result_pass("%s test: Passed\n", test_name);
  361. }
  362. static void *test_pidfd_poll_leader_exit_thread(void *priv)
  363. {
  364. ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n",
  365. getpid(), syscall(SYS_gettid));
  366. sleep(CHILD_THREAD_MIN_WAIT);
  367. ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", getpid(), syscall(SYS_gettid));
  368. return NULL;
  369. }
  370. static time_t *child_exit_secs;
  371. static int child_poll_leader_exit_test(void *args)
  372. {
  373. pthread_t t1, t2;
  374. ksft_print_msg("Child: starting. pid %d tid %d\n", getpid(), syscall(SYS_gettid));
  375. pthread_create(&t1, NULL, test_pidfd_poll_leader_exit_thread, NULL);
  376. pthread_create(&t2, NULL, test_pidfd_poll_leader_exit_thread, NULL);
  377. /*
  378. * glibc exit calls exit_group syscall, so explicity call exit only
  379. * so that only the group leader exits, leaving the threads alone.
  380. */
  381. *child_exit_secs = time(NULL);
  382. syscall(SYS_exit, 0);
  383. }
  384. static void test_pidfd_poll_leader_exit(int use_waitpid)
  385. {
  386. int pid, pidfd = 0;
  387. int status, ret;
  388. time_t prog_start = time(NULL);
  389. const char *test_name = "pidfd_poll check for premature notification on non-empty"
  390. "group leader exit";
  391. child_exit_secs = mmap(NULL, sizeof *child_exit_secs, PROT_READ | PROT_WRITE,
  392. MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  393. if (child_exit_secs == MAP_FAILED)
  394. ksft_exit_fail_msg("%s test: mmap failed (errno %d)\n",
  395. test_name, errno);
  396. ksft_print_msg("Parent: pid: %d\n", getpid());
  397. pid = pidfd_clone(CLONE_PIDFD, &pidfd, child_poll_leader_exit_test);
  398. if (pid < 0)
  399. ksft_exit_fail_msg("%s test: pidfd_clone failed (ret %d, errno %d)\n",
  400. test_name, pid, errno);
  401. ksft_print_msg("Parent: Waiting for Child (%d) to complete.\n", pid);
  402. if (use_waitpid) {
  403. ret = waitpid(pid, &status, 0);
  404. if (ret == -1)
  405. ksft_print_msg("Parent: error\n");
  406. } else {
  407. /*
  408. * This sleep tests for the case where if the child exits, and is in
  409. * EXIT_ZOMBIE, but the thread group leader is non-empty, then the poll
  410. * doesn't prematurely return even though there are active threads
  411. */
  412. sleep(1);
  413. poll_pidfd(test_name, pidfd);
  414. }
  415. if (ret == pid)
  416. ksft_print_msg("Parent: Child process waited for.\n");
  417. time_t since_child_exit = time(NULL) - *child_exit_secs;
  418. ksft_print_msg("Time since child exit: %lu\n", since_child_exit);
  419. close(pidfd);
  420. if (since_child_exit < CHILD_THREAD_MIN_WAIT ||
  421. since_child_exit > CHILD_THREAD_MIN_WAIT + 2)
  422. ksft_exit_fail_msg("%s test: Failed\n", test_name);
  423. else
  424. ksft_test_result_pass("%s test: Passed\n", test_name);
  425. }
  426. int main(int argc, char **argv)
  427. {
  428. ksft_print_header();
  429. ksft_set_plan(4);
  430. test_pidfd_poll_exec(0);
  431. test_pidfd_poll_exec(1);
  432. test_pidfd_poll_leader_exit(0);
  433. test_pidfd_poll_leader_exit(1);
  434. test_pidfd_send_signal_syscall_support();
  435. test_pidfd_send_signal_simple_success();
  436. test_pidfd_send_signal_exited_fail();
  437. test_pidfd_send_signal_recycled_pid_fail();
  438. return ksft_exit_pass();
  439. }