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