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