]> Git Repo - linux.git/blob - tools/testing/selftests/pidfd/pidfd_test.c
x86/kaslr: Expose and use the end of the physical memory address space
[linux.git] / tools / testing / selftests / pidfd / pidfd_test.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #define _GNU_SOURCE
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <linux/types.h>
7 #include <pthread.h>
8 #include <sched.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <syscall.h>
15 #include <sys/epoll.h>
16 #include <sys/mman.h>
17 #include <sys/mount.h>
18 #include <sys/wait.h>
19 #include <time.h>
20 #include <unistd.h>
21
22 #include "pidfd.h"
23 #include "../kselftest.h"
24
25 #define str(s) _str(s)
26 #define _str(s) #s
27 #define CHILD_THREAD_MIN_WAIT 3 /* seconds */
28
29 #define MAX_EVENTS 5
30
31 static bool have_pidfd_send_signal;
32
33 static pid_t pidfd_clone(int flags, int *pidfd, int (*fn)(void *))
34 {
35         size_t stack_size = 1024;
36         char *stack[1024] = { 0 };
37
38 #ifdef __ia64__
39         return __clone2(fn, stack, stack_size, flags | SIGCHLD, NULL, pidfd);
40 #else
41         return clone(fn, stack + stack_size, flags | SIGCHLD, NULL, pidfd);
42 #endif
43 }
44
45 static int signal_received;
46
47 static void set_signal_received_on_sigusr1(int sig)
48 {
49         if (sig == SIGUSR1)
50                 signal_received = 1;
51 }
52
53 /*
54  * Straightforward test to see whether pidfd_send_signal() works is to send
55  * a signal to ourself.
56  */
57 static int test_pidfd_send_signal_simple_success(void)
58 {
59         int pidfd, ret;
60         const char *test_name = "pidfd_send_signal send SIGUSR1";
61
62         if (!have_pidfd_send_signal) {
63                 ksft_test_result_skip(
64                         "%s test: pidfd_send_signal() syscall not supported\n",
65                         test_name);
66                 return 0;
67         }
68
69         pidfd = open("/proc/self", O_DIRECTORY | O_CLOEXEC);
70         if (pidfd < 0)
71                 ksft_exit_fail_msg(
72                         "%s test: Failed to open process file descriptor\n",
73                         test_name);
74
75         signal(SIGUSR1, set_signal_received_on_sigusr1);
76
77         ret = sys_pidfd_send_signal(pidfd, SIGUSR1, NULL, 0);
78         close(pidfd);
79         if (ret < 0)
80                 ksft_exit_fail_msg("%s test: Failed to send signal\n",
81                                    test_name);
82
83         if (signal_received != 1)
84                 ksft_exit_fail_msg("%s test: Failed to receive signal\n",
85                                    test_name);
86
87         signal_received = 0;
88         ksft_test_result_pass("%s test: Sent signal\n", test_name);
89         return 0;
90 }
91
92 static int test_pidfd_send_signal_exited_fail(void)
93 {
94         int pidfd, ret, saved_errno;
95         char buf[256];
96         pid_t pid;
97         const char *test_name = "pidfd_send_signal signal exited process";
98
99         if (!have_pidfd_send_signal) {
100                 ksft_test_result_skip(
101                         "%s test: pidfd_send_signal() syscall not supported\n",
102                         test_name);
103                 return 0;
104         }
105
106         pid = fork();
107         if (pid < 0)
108                 ksft_exit_fail_msg("%s test: Failed to create new process\n",
109                                    test_name);
110
111         if (pid == 0)
112                 _exit(EXIT_SUCCESS);
113
114         snprintf(buf, sizeof(buf), "/proc/%d", pid);
115
116         pidfd = open(buf, O_DIRECTORY | O_CLOEXEC);
117
118         ret = wait_for_pid(pid);
119         ksft_print_msg("waitpid WEXITSTATUS=%d\n", ret);
120
121         if (pidfd < 0)
122                 ksft_exit_fail_msg(
123                         "%s test: Failed to open process file descriptor\n",
124                         test_name);
125
126         ret = sys_pidfd_send_signal(pidfd, 0, NULL, 0);
127         saved_errno = errno;
128         close(pidfd);
129         if (ret == 0)
130                 ksft_exit_fail_msg(
131                         "%s test: Managed to send signal to process even though it should have failed\n",
132                         test_name);
133
134         if (saved_errno != ESRCH)
135                 ksft_exit_fail_msg(
136                         "%s test: Expected to receive ESRCH as errno value but received %d instead\n",
137                         test_name, saved_errno);
138
139         ksft_test_result_pass("%s test: Failed to send signal as expected\n",
140                               test_name);
141         return 0;
142 }
143
144 /*
145  * Maximum number of cycles we allow. This is equivalent to PID_MAX_DEFAULT.
146  * If users set a higher limit or we have cycled PIDFD_MAX_DEFAULT number of
147  * times then we skip the test to not go into an infinite loop or block for a
148  * long time.
149  */
150 #define PIDFD_MAX_DEFAULT 0x8000
151
152 static int test_pidfd_send_signal_recycled_pid_fail(void)
153 {
154         int i, ret;
155         pid_t pid1;
156         const char *test_name = "pidfd_send_signal signal recycled pid";
157
158         if (!have_pidfd_send_signal) {
159                 ksft_test_result_skip(
160                         "%s test: pidfd_send_signal() syscall not supported\n",
161                         test_name);
162                 return 0;
163         }
164
165         ret = unshare(CLONE_NEWPID);
166         if (ret < 0) {
167                 if (errno == EPERM) {
168                         ksft_test_result_skip("%s test: Unsharing pid namespace not permitted\n",
169                                               test_name);
170                         return 0;
171                 }
172                 ksft_exit_fail_msg("%s test: Failed to unshare pid namespace\n",
173                                    test_name);
174         }
175
176         ret = unshare(CLONE_NEWNS);
177         if (ret < 0) {
178                 if (errno == EPERM) {
179                         ksft_test_result_skip("%s test: Unsharing mount namespace not permitted\n",
180                                               test_name);
181                         return 0;
182                 }
183                 ksft_exit_fail_msg("%s test: Failed to unshare mount namespace\n",
184                                    test_name);
185         }
186
187         ret = mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0);
188         if (ret < 0)
189                 ksft_exit_fail_msg("%s test: Failed to remount / private\n",
190                                    test_name);
191
192         /* pid 1 in new pid namespace */
193         pid1 = fork();
194         if (pid1 < 0)
195                 ksft_exit_fail_msg("%s test: Failed to create new process\n",
196                                    test_name);
197
198         if (pid1 == 0) {
199                 char buf[256];
200                 pid_t pid2;
201                 int pidfd = -1;
202
203                 (void)umount2("/proc", MNT_DETACH);
204                 ret = mount("proc", "/proc", "proc", 0, NULL);
205                 if (ret < 0)
206                         _exit(PIDFD_ERROR);
207
208                 /* grab pid PID_RECYCLE */
209                 for (i = 0; i <= PIDFD_MAX_DEFAULT; i++) {
210                         pid2 = fork();
211                         if (pid2 < 0)
212                                 _exit(PIDFD_ERROR);
213
214                         if (pid2 == 0)
215                                 _exit(PIDFD_PASS);
216
217                         if (pid2 == PID_RECYCLE) {
218                                 snprintf(buf, sizeof(buf), "/proc/%d", pid2);
219                                 ksft_print_msg("pid to recycle is %d\n", pid2);
220                                 pidfd = open(buf, O_DIRECTORY | O_CLOEXEC);
221                         }
222
223                         if (wait_for_pid(pid2))
224                                 _exit(PIDFD_ERROR);
225
226                         if (pid2 >= PID_RECYCLE)
227                                 break;
228                 }
229
230                 /*
231                  * We want to be as predictable as we can so if we haven't been
232                  * able to grab pid PID_RECYCLE skip the test.
233                  */
234                 if (pid2 != PID_RECYCLE) {
235                         /* skip test */
236                         close(pidfd);
237                         _exit(PIDFD_SKIP);
238                 }
239
240                 if (pidfd < 0)
241                         _exit(PIDFD_ERROR);
242
243                 for (i = 0; i <= PIDFD_MAX_DEFAULT; i++) {
244                         char c;
245                         int pipe_fds[2];
246                         pid_t recycled_pid;
247                         int child_ret = PIDFD_PASS;
248
249                         ret = pipe2(pipe_fds, O_CLOEXEC);
250                         if (ret < 0)
251                                 _exit(PIDFD_ERROR);
252
253                         recycled_pid = fork();
254                         if (recycled_pid < 0)
255                                 _exit(PIDFD_ERROR);
256
257                         if (recycled_pid == 0) {
258                                 close(pipe_fds[1]);
259                                 (void)read(pipe_fds[0], &c, 1);
260                                 close(pipe_fds[0]);
261
262                                 _exit(PIDFD_PASS);
263                         }
264
265                         /*
266                          * Stop the child so we can inspect whether we have
267                          * recycled pid PID_RECYCLE.
268                          */
269                         close(pipe_fds[0]);
270                         ret = kill(recycled_pid, SIGSTOP);
271                         close(pipe_fds[1]);
272                         if (ret) {
273                                 (void)wait_for_pid(recycled_pid);
274                                 _exit(PIDFD_ERROR);
275                         }
276
277                         /*
278                          * We have recycled the pid. Try to signal it. This
279                          * needs to fail since this is a different process than
280                          * the one the pidfd refers to.
281                          */
282                         if (recycled_pid == PID_RECYCLE) {
283                                 ret = sys_pidfd_send_signal(pidfd, SIGCONT,
284                                                             NULL, 0);
285                                 if (ret && errno == ESRCH)
286                                         child_ret = PIDFD_XFAIL;
287                                 else
288                                         child_ret = PIDFD_FAIL;
289                         }
290
291                         /* let the process move on */
292                         ret = kill(recycled_pid, SIGCONT);
293                         if (ret)
294                                 (void)kill(recycled_pid, SIGKILL);
295
296                         if (wait_for_pid(recycled_pid))
297                                 _exit(PIDFD_ERROR);
298
299                         switch (child_ret) {
300                         case PIDFD_FAIL:
301                                 /* fallthrough */
302                         case PIDFD_XFAIL:
303                                 _exit(child_ret);
304                         case PIDFD_PASS:
305                                 break;
306                         default:
307                                 /* not reached */
308                                 _exit(PIDFD_ERROR);
309                         }
310
311                         /*
312                          * If the user set a custom pid_max limit we could be
313                          * in the millions.
314                          * Skip the test in this case.
315                          */
316                         if (recycled_pid > PIDFD_MAX_DEFAULT)
317                                 _exit(PIDFD_SKIP);
318                 }
319
320                 /* failed to recycle pid */
321                 _exit(PIDFD_SKIP);
322         }
323
324         ret = wait_for_pid(pid1);
325         switch (ret) {
326         case PIDFD_FAIL:
327                 ksft_exit_fail_msg(
328                         "%s test: Managed to signal recycled pid %d\n",
329                         test_name, PID_RECYCLE);
330         case PIDFD_PASS:
331                 ksft_exit_fail_msg("%s test: Failed to recycle pid %d\n",
332                                    test_name, PID_RECYCLE);
333         case PIDFD_SKIP:
334                 ksft_test_result_skip("%s test: Skipping test\n", test_name);
335                 ret = 0;
336                 break;
337         case PIDFD_XFAIL:
338                 ksft_test_result_pass(
339                         "%s test: Failed to signal recycled pid as expected\n",
340                         test_name);
341                 ret = 0;
342                 break;
343         default /* PIDFD_ERROR */:
344                 ksft_exit_fail_msg("%s test: Error while running tests\n",
345                                    test_name);
346         }
347
348         return ret;
349 }
350
351 static int test_pidfd_send_signal_syscall_support(void)
352 {
353         int pidfd, ret;
354         const char *test_name = "pidfd_send_signal check for support";
355
356         pidfd = open("/proc/self", O_DIRECTORY | O_CLOEXEC);
357         if (pidfd < 0)
358                 ksft_exit_fail_msg(
359                         "%s test: Failed to open process file descriptor\n",
360                         test_name);
361
362         ret = sys_pidfd_send_signal(pidfd, 0, NULL, 0);
363         if (ret < 0) {
364                 if (errno == ENOSYS) {
365                         ksft_test_result_skip(
366                                 "%s test: pidfd_send_signal() syscall not supported\n",
367                                 test_name);
368                         return 0;
369                 }
370                 ksft_exit_fail_msg("%s test: Failed to send signal\n",
371                                    test_name);
372         }
373
374         have_pidfd_send_signal = true;
375         close(pidfd);
376         ksft_test_result_pass(
377                 "%s test: pidfd_send_signal() syscall is supported. Tests can be executed\n",
378                 test_name);
379         return 0;
380 }
381
382 static void *test_pidfd_poll_exec_thread(void *priv)
383 {
384         ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n",
385                         getpid(), syscall(SYS_gettid));
386         ksft_print_msg("Child Thread: doing exec of sleep\n");
387
388         execl("/bin/sleep", "sleep", str(CHILD_THREAD_MIN_WAIT), (char *)NULL);
389
390         ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n",
391                         getpid(), syscall(SYS_gettid));
392         return NULL;
393 }
394
395 static void poll_pidfd(const char *test_name, int pidfd)
396 {
397         int c;
398         int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
399         struct epoll_event event, events[MAX_EVENTS];
400
401         if (epoll_fd == -1)
402                 ksft_exit_fail_msg("%s test: Failed to create epoll file descriptor "
403                                    "(errno %d)\n",
404                                    test_name, errno);
405
406         event.events = EPOLLIN;
407         event.data.fd = pidfd;
408
409         if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pidfd, &event)) {
410                 ksft_exit_fail_msg("%s test: Failed to add epoll file descriptor "
411                                    "(errno %d)\n",
412                                    test_name, errno);
413         }
414
415         c = epoll_wait(epoll_fd, events, MAX_EVENTS, 5000);
416         if (c != 1 || !(events[0].events & EPOLLIN))
417                 ksft_exit_fail_msg("%s test: Unexpected epoll_wait result (c=%d, events=%x) "
418                                    "(errno %d)\n",
419                                    test_name, c, events[0].events, errno);
420
421         close(epoll_fd);
422         return;
423
424 }
425
426 static int child_poll_exec_test(void *args)
427 {
428         pthread_t t1;
429
430         ksft_print_msg("Child (pidfd): starting. pid %d tid %ld\n", getpid(),
431                         syscall(SYS_gettid));
432         pthread_create(&t1, NULL, test_pidfd_poll_exec_thread, NULL);
433         /*
434          * Exec in the non-leader thread will destroy the leader immediately.
435          * If the wait in the parent returns too soon, the test fails.
436          */
437         while (1)
438                 sleep(1);
439
440         return 0;
441 }
442
443 static void test_pidfd_poll_exec(int use_waitpid)
444 {
445         int pid, pidfd = 0;
446         int status, ret;
447         time_t prog_start = time(NULL);
448         const char *test_name = "pidfd_poll check for premature notification on child thread exec";
449
450         ksft_print_msg("Parent: pid: %d\n", getpid());
451         pid = pidfd_clone(CLONE_PIDFD, &pidfd, child_poll_exec_test);
452         if (pid < 0)
453                 ksft_exit_fail_msg("%s test: pidfd_clone failed (ret %d, errno %d)\n",
454                                    test_name, pid, errno);
455
456         ksft_print_msg("Parent: Waiting for Child (%d) to complete.\n", pid);
457
458         if (use_waitpid) {
459                 ret = waitpid(pid, &status, 0);
460                 if (ret == -1)
461                         ksft_print_msg("Parent: error\n");
462
463                 if (ret == pid)
464                         ksft_print_msg("Parent: Child process waited for.\n");
465         } else {
466                 poll_pidfd(test_name, pidfd);
467         }
468
469         time_t prog_time = time(NULL) - prog_start;
470
471         ksft_print_msg("Time waited for child: %lu\n", prog_time);
472
473         close(pidfd);
474
475         if (prog_time < CHILD_THREAD_MIN_WAIT || prog_time > CHILD_THREAD_MIN_WAIT + 2)
476                 ksft_exit_fail_msg("%s test: Failed\n", test_name);
477         else
478                 ksft_test_result_pass("%s test: Passed\n", test_name);
479 }
480
481 static void *test_pidfd_poll_leader_exit_thread(void *priv)
482 {
483         ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n",
484                         getpid(), syscall(SYS_gettid));
485         sleep(CHILD_THREAD_MIN_WAIT);
486         ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n", getpid(), syscall(SYS_gettid));
487         return NULL;
488 }
489
490 static time_t *child_exit_secs;
491 static int child_poll_leader_exit_test(void *args)
492 {
493         pthread_t t1, t2;
494
495         ksft_print_msg("Child: starting. pid %d tid %ld\n", getpid(), syscall(SYS_gettid));
496         pthread_create(&t1, NULL, test_pidfd_poll_leader_exit_thread, NULL);
497         pthread_create(&t2, NULL, test_pidfd_poll_leader_exit_thread, NULL);
498
499         /*
500          * glibc exit calls exit_group syscall, so explicity call exit only
501          * so that only the group leader exits, leaving the threads alone.
502          */
503         *child_exit_secs = time(NULL);
504         syscall(SYS_exit, 0);
505         /* Never reached, but appeases compiler thinking we should return. */
506         exit(0);
507 }
508
509 static void test_pidfd_poll_leader_exit(int use_waitpid)
510 {
511         int pid, pidfd = 0;
512         int status, ret = 0;
513         const char *test_name = "pidfd_poll check for premature notification on non-empty"
514                                 "group leader exit";
515
516         child_exit_secs = mmap(NULL, sizeof *child_exit_secs, PROT_READ | PROT_WRITE,
517                         MAP_SHARED | MAP_ANONYMOUS, -1, 0);
518
519         if (child_exit_secs == MAP_FAILED)
520                 ksft_exit_fail_msg("%s test: mmap failed (errno %d)\n",
521                                    test_name, errno);
522
523         ksft_print_msg("Parent: pid: %d\n", getpid());
524         pid = pidfd_clone(CLONE_PIDFD, &pidfd, child_poll_leader_exit_test);
525         if (pid < 0)
526                 ksft_exit_fail_msg("%s test: pidfd_clone failed (ret %d, errno %d)\n",
527                                    test_name, pid, errno);
528
529         ksft_print_msg("Parent: Waiting for Child (%d) to complete.\n", pid);
530
531         if (use_waitpid) {
532                 ret = waitpid(pid, &status, 0);
533                 if (ret == -1)
534                         ksft_print_msg("Parent: error\n");
535         } else {
536                 /*
537                  * This sleep tests for the case where if the child exits, and is in
538                  * EXIT_ZOMBIE, but the thread group leader is non-empty, then the poll
539                  * doesn't prematurely return even though there are active threads
540                  */
541                 sleep(1);
542                 poll_pidfd(test_name, pidfd);
543         }
544
545         if (ret == pid)
546                 ksft_print_msg("Parent: Child process waited for.\n");
547
548         time_t since_child_exit = time(NULL) - *child_exit_secs;
549
550         ksft_print_msg("Time since child exit: %lu\n", since_child_exit);
551
552         close(pidfd);
553
554         if (since_child_exit < CHILD_THREAD_MIN_WAIT ||
555                         since_child_exit > CHILD_THREAD_MIN_WAIT + 2)
556                 ksft_exit_fail_msg("%s test: Failed\n", test_name);
557         else
558                 ksft_test_result_pass("%s test: Passed\n", test_name);
559 }
560
561 int main(int argc, char **argv)
562 {
563         ksft_print_header();
564         ksft_set_plan(8);
565
566         test_pidfd_poll_exec(0);
567         test_pidfd_poll_exec(1);
568         test_pidfd_poll_leader_exit(0);
569         test_pidfd_poll_leader_exit(1);
570         test_pidfd_send_signal_syscall_support();
571         test_pidfd_send_signal_simple_success();
572         test_pidfd_send_signal_exited_fail();
573         test_pidfd_send_signal_recycled_pid_fail();
574
575         ksft_exit_pass();
576 }
This page took 0.068438 seconds and 4 git commands to generate.