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 /* 343 * pidfd_send_signal() will currently return ENOSYS when 344 * CONFIG_PROC_FS is not set. 345 */ 346 if (errno == ENOSYS) 347 ksft_exit_skip( 348 "%s test: pidfd_send_signal() syscall not supported (Ensure that CONFIG_PROC_FS=y is set)\n", 349 test_name); 350 351 ksft_exit_fail_msg("%s test: Failed to send signal\n", 352 test_name); 353 } 354 355 close(pidfd); 356 ksft_test_result_pass( 357 "%s test: pidfd_send_signal() syscall is supported. Tests can be executed\n", 358 test_name); 359 return 0; 360 } 361 362 static void *test_pidfd_poll_exec_thread(void *priv) 363 { 364 ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n", 365 getpid(), syscall(SYS_gettid)); 366 ksft_print_msg("Child Thread: doing exec of sleep\n"); 367 368 execl("/bin/sleep", "sleep", str(CHILD_THREAD_MIN_WAIT), (char *)NULL); 369 370 ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", 371 getpid(), syscall(SYS_gettid)); 372 return NULL; 373 } 374 375 static void poll_pidfd(const char *test_name, int pidfd) 376 { 377 int c; 378 int epoll_fd = epoll_create1(EPOLL_CLOEXEC); 379 struct epoll_event event, events[MAX_EVENTS]; 380 381 if (epoll_fd == -1) 382 ksft_exit_fail_msg("%s test: Failed to create epoll file descriptor " 383 "(errno %d)\n", 384 test_name, errno); 385 386 event.events = EPOLLIN; 387 event.data.fd = pidfd; 388 389 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pidfd, &event)) { 390 ksft_exit_fail_msg("%s test: Failed to add epoll file descriptor " 391 "(errno %d)\n", 392 test_name, errno); 393 } 394 395 c = epoll_wait(epoll_fd, events, MAX_EVENTS, 5000); 396 if (c != 1 || !(events[0].events & EPOLLIN)) 397 ksft_exit_fail_msg("%s test: Unexpected epoll_wait result (c=%d, events=%x) ", 398 "(errno %d)\n", 399 test_name, c, events[0].events, errno); 400 401 close(epoll_fd); 402 return; 403 404 } 405 406 static int child_poll_exec_test(void *args) 407 { 408 pthread_t t1; 409 410 ksft_print_msg("Child (pidfd): starting. pid %d tid %d\n", getpid(), 411 syscall(SYS_gettid)); 412 pthread_create(&t1, NULL, test_pidfd_poll_exec_thread, NULL); 413 /* 414 * Exec in the non-leader thread will destroy the leader immediately. 415 * If the wait in the parent returns too soon, the test fails. 416 */ 417 while (1) 418 sleep(1); 419 } 420 421 static void test_pidfd_poll_exec(int use_waitpid) 422 { 423 int pid, pidfd = 0; 424 int status, ret; 425 pthread_t t1; 426 time_t prog_start = time(NULL); 427 const char *test_name = "pidfd_poll check for premature notification on child thread exec"; 428 429 ksft_print_msg("Parent: pid: %d\n", getpid()); 430 pid = pidfd_clone(CLONE_PIDFD, &pidfd, child_poll_exec_test); 431 if (pid < 0) 432 ksft_exit_fail_msg("%s test: pidfd_clone failed (ret %d, errno %d)\n", 433 test_name, pid, errno); 434 435 ksft_print_msg("Parent: Waiting for Child (%d) to complete.\n", pid); 436 437 if (use_waitpid) { 438 ret = waitpid(pid, &status, 0); 439 if (ret == -1) 440 ksft_print_msg("Parent: error\n"); 441 442 if (ret == pid) 443 ksft_print_msg("Parent: Child process waited for.\n"); 444 } else { 445 poll_pidfd(test_name, pidfd); 446 } 447 448 time_t prog_time = time(NULL) - prog_start; 449 450 ksft_print_msg("Time waited for child: %lu\n", prog_time); 451 452 close(pidfd); 453 454 if (prog_time < CHILD_THREAD_MIN_WAIT || prog_time > CHILD_THREAD_MIN_WAIT + 2) 455 ksft_exit_fail_msg("%s test: Failed\n", test_name); 456 else 457 ksft_test_result_pass("%s test: Passed\n", test_name); 458 } 459 460 static void *test_pidfd_poll_leader_exit_thread(void *priv) 461 { 462 ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n", 463 getpid(), syscall(SYS_gettid)); 464 sleep(CHILD_THREAD_MIN_WAIT); 465 ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", getpid(), syscall(SYS_gettid)); 466 return NULL; 467 } 468 469 static time_t *child_exit_secs; 470 static int child_poll_leader_exit_test(void *args) 471 { 472 pthread_t t1, t2; 473 474 ksft_print_msg("Child: starting. pid %d tid %d\n", getpid(), syscall(SYS_gettid)); 475 pthread_create(&t1, NULL, test_pidfd_poll_leader_exit_thread, NULL); 476 pthread_create(&t2, NULL, test_pidfd_poll_leader_exit_thread, NULL); 477 478 /* 479 * glibc exit calls exit_group syscall, so explicity call exit only 480 * so that only the group leader exits, leaving the threads alone. 481 */ 482 *child_exit_secs = time(NULL); 483 syscall(SYS_exit, 0); 484 } 485 486 static void test_pidfd_poll_leader_exit(int use_waitpid) 487 { 488 int pid, pidfd = 0; 489 int status, ret; 490 time_t prog_start = time(NULL); 491 const char *test_name = "pidfd_poll check for premature notification on non-empty" 492 "group leader exit"; 493 494 child_exit_secs = mmap(NULL, sizeof *child_exit_secs, PROT_READ | PROT_WRITE, 495 MAP_SHARED | MAP_ANONYMOUS, -1, 0); 496 497 if (child_exit_secs == MAP_FAILED) 498 ksft_exit_fail_msg("%s test: mmap failed (errno %d)\n", 499 test_name, errno); 500 501 ksft_print_msg("Parent: pid: %d\n", getpid()); 502 pid = pidfd_clone(CLONE_PIDFD, &pidfd, child_poll_leader_exit_test); 503 if (pid < 0) 504 ksft_exit_fail_msg("%s test: pidfd_clone failed (ret %d, errno %d)\n", 505 test_name, pid, errno); 506 507 ksft_print_msg("Parent: Waiting for Child (%d) to complete.\n", pid); 508 509 if (use_waitpid) { 510 ret = waitpid(pid, &status, 0); 511 if (ret == -1) 512 ksft_print_msg("Parent: error\n"); 513 } else { 514 /* 515 * This sleep tests for the case where if the child exits, and is in 516 * EXIT_ZOMBIE, but the thread group leader is non-empty, then the poll 517 * doesn't prematurely return even though there are active threads 518 */ 519 sleep(1); 520 poll_pidfd(test_name, pidfd); 521 } 522 523 if (ret == pid) 524 ksft_print_msg("Parent: Child process waited for.\n"); 525 526 time_t since_child_exit = time(NULL) - *child_exit_secs; 527 528 ksft_print_msg("Time since child exit: %lu\n", since_child_exit); 529 530 close(pidfd); 531 532 if (since_child_exit < CHILD_THREAD_MIN_WAIT || 533 since_child_exit > CHILD_THREAD_MIN_WAIT + 2) 534 ksft_exit_fail_msg("%s test: Failed\n", test_name); 535 else 536 ksft_test_result_pass("%s test: Passed\n", test_name); 537 } 538 539 int main(int argc, char **argv) 540 { 541 ksft_print_header(); 542 ksft_set_plan(4); 543 544 test_pidfd_poll_exec(0); 545 test_pidfd_poll_exec(1); 546 test_pidfd_poll_leader_exit(0); 547 test_pidfd_poll_leader_exit(1); 548 test_pidfd_send_signal_syscall_support(); 549 test_pidfd_send_signal_simple_success(); 550 test_pidfd_send_signal_exited_fail(); 551 test_pidfd_send_signal_recycled_pid_fail(); 552 553 return ksft_exit_pass(); 554 } 555