1 // SPDX-License-Identifier: GPL-2.0 2 3 #define _GNU_SOURCE 4 #include <errno.h> 5 #include <fcntl.h> 6 #include <limits.h> 7 #include <linux/types.h> 8 #include <poll.h> 9 #include <pthread.h> 10 #include <sched.h> 11 #include <signal.h> 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <syscall.h> 16 #include <sys/prctl.h> 17 #include <sys/wait.h> 18 #include <unistd.h> 19 #include <sys/socket.h> 20 #include <linux/kcmp.h> 21 #include <sys/stat.h> 22 23 #include "pidfd.h" 24 #include "../kselftest_harness.h" 25 26 FIXTURE(pidfd_info) 27 { 28 pid_t child_pid1; 29 int child_pidfd1; 30 31 pid_t child_pid2; 32 int child_pidfd2; 33 34 pid_t child_pid3; 35 int child_pidfd3; 36 37 pid_t child_pid4; 38 int child_pidfd4; 39 }; 40 41 FIXTURE_SETUP(pidfd_info) 42 { 43 int ret; 44 int ipc_sockets[2]; 45 char c; 46 47 ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); 48 EXPECT_EQ(ret, 0); 49 50 self->child_pid1 = create_child(&self->child_pidfd1, 0); 51 EXPECT_GE(self->child_pid1, 0); 52 53 if (self->child_pid1 == 0) { 54 close(ipc_sockets[0]); 55 56 if (write_nointr(ipc_sockets[1], "1", 1) < 0) 57 _exit(EXIT_FAILURE); 58 59 close(ipc_sockets[1]); 60 61 pause(); 62 _exit(EXIT_SUCCESS); 63 } 64 65 EXPECT_EQ(close(ipc_sockets[1]), 0); 66 ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1); 67 EXPECT_EQ(close(ipc_sockets[0]), 0); 68 69 /* SIGKILL but don't reap. */ 70 EXPECT_EQ(sys_pidfd_send_signal(self->child_pidfd1, SIGKILL, NULL, 0), 0); 71 72 ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); 73 EXPECT_EQ(ret, 0); 74 75 self->child_pid2 = create_child(&self->child_pidfd2, 0); 76 EXPECT_GE(self->child_pid2, 0); 77 78 if (self->child_pid2 == 0) { 79 close(ipc_sockets[0]); 80 81 if (write_nointr(ipc_sockets[1], "1", 1) < 0) 82 _exit(EXIT_FAILURE); 83 84 close(ipc_sockets[1]); 85 86 pause(); 87 _exit(EXIT_SUCCESS); 88 } 89 90 EXPECT_EQ(close(ipc_sockets[1]), 0); 91 ASSERT_EQ(read_nointr(ipc_sockets[0], &c, 1), 1); 92 EXPECT_EQ(close(ipc_sockets[0]), 0); 93 94 /* SIGKILL and reap. */ 95 EXPECT_EQ(sys_pidfd_send_signal(self->child_pidfd2, SIGKILL, NULL, 0), 0); 96 EXPECT_EQ(sys_waitid(P_PID, self->child_pid2, NULL, WEXITED), 0); 97 98 self->child_pid3 = create_child(&self->child_pidfd3, CLONE_NEWUSER | CLONE_NEWPID); 99 EXPECT_GE(self->child_pid3, 0); 100 101 if (self->child_pid3 == 0) 102 _exit(EXIT_SUCCESS); 103 104 self->child_pid4 = create_child(&self->child_pidfd4, CLONE_NEWUSER | CLONE_NEWPID); 105 EXPECT_GE(self->child_pid4, 0); 106 107 if (self->child_pid4 == 0) 108 _exit(EXIT_SUCCESS); 109 110 EXPECT_EQ(sys_waitid(P_PID, self->child_pid4, NULL, WEXITED), 0); 111 } 112 113 FIXTURE_TEARDOWN(pidfd_info) 114 { 115 sys_pidfd_send_signal(self->child_pidfd1, SIGKILL, NULL, 0); 116 if (self->child_pidfd1 >= 0) 117 EXPECT_EQ(0, close(self->child_pidfd1)); 118 119 sys_waitid(P_PID, self->child_pid1, NULL, WEXITED); 120 121 sys_pidfd_send_signal(self->child_pidfd2, SIGKILL, NULL, 0); 122 if (self->child_pidfd2 >= 0) 123 EXPECT_EQ(0, close(self->child_pidfd2)); 124 125 sys_waitid(P_PID, self->child_pid2, NULL, WEXITED); 126 sys_waitid(P_PID, self->child_pid3, NULL, WEXITED); 127 sys_waitid(P_PID, self->child_pid4, NULL, WEXITED); 128 } 129 130 TEST_F(pidfd_info, sigkill_exit) 131 { 132 struct pidfd_info info = { 133 .mask = PIDFD_INFO_CGROUPID, 134 }; 135 136 /* Process has exited but not been reaped so this must work. */ 137 ASSERT_EQ(ioctl(self->child_pidfd1, PIDFD_GET_INFO, &info), 0); 138 139 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 140 ASSERT_EQ(ioctl(self->child_pidfd1, PIDFD_GET_INFO, &info), 0); 141 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS)); 142 /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */ 143 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT)); 144 } 145 146 TEST_F(pidfd_info, sigkill_reaped) 147 { 148 struct pidfd_info info = { 149 .mask = PIDFD_INFO_CGROUPID, 150 }; 151 152 /* Process has already been reaped and PIDFD_INFO_EXIT hasn't been set. */ 153 ASSERT_NE(ioctl(self->child_pidfd2, PIDFD_GET_INFO, &info), 0); 154 ASSERT_EQ(errno, ESRCH); 155 156 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 157 ASSERT_EQ(ioctl(self->child_pidfd2, PIDFD_GET_INFO, &info), 0); 158 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 159 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 160 ASSERT_TRUE(WIFSIGNALED(info.exit_code)); 161 ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL); 162 } 163 164 TEST_F(pidfd_info, success_exit) 165 { 166 struct pidfd_info info = { 167 .mask = PIDFD_INFO_CGROUPID, 168 }; 169 170 /* Process has exited but not been reaped so this must work. */ 171 ASSERT_EQ(ioctl(self->child_pidfd3, PIDFD_GET_INFO, &info), 0); 172 173 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 174 ASSERT_EQ(ioctl(self->child_pidfd3, PIDFD_GET_INFO, &info), 0); 175 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS)); 176 /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */ 177 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT)); 178 } 179 180 TEST_F(pidfd_info, success_reaped) 181 { 182 struct pidfd_info info = { 183 .mask = PIDFD_INFO_CGROUPID, 184 }; 185 186 /* Process has already been reaped and PIDFD_INFO_EXIT hasn't been set. */ 187 ASSERT_NE(ioctl(self->child_pidfd4, PIDFD_GET_INFO, &info), 0); 188 ASSERT_EQ(errno, ESRCH); 189 190 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 191 ASSERT_EQ(ioctl(self->child_pidfd4, PIDFD_GET_INFO, &info), 0); 192 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 193 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 194 ASSERT_TRUE(WIFEXITED(info.exit_code)); 195 ASSERT_EQ(WEXITSTATUS(info.exit_code), 0); 196 } 197 198 TEST_F(pidfd_info, success_reaped_poll) 199 { 200 struct pidfd_info info = { 201 .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT, 202 }; 203 struct pollfd fds = {}; 204 int nevents; 205 206 fds.events = POLLIN; 207 fds.fd = self->child_pidfd2; 208 209 nevents = poll(&fds, 1, -1); 210 ASSERT_EQ(nevents, 1); 211 ASSERT_TRUE(!!(fds.revents & POLLIN)); 212 ASSERT_TRUE(!!(fds.revents & POLLHUP)); 213 214 ASSERT_EQ(ioctl(self->child_pidfd2, PIDFD_GET_INFO, &info), 0); 215 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 216 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 217 ASSERT_TRUE(WIFSIGNALED(info.exit_code)); 218 ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL); 219 } 220 221 static void *pidfd_info_pause_thread(void *arg) 222 { 223 pid_t pid_thread = gettid(); 224 int ipc_socket = *(int *)arg; 225 226 /* Inform the grand-parent what the tid of this thread is. */ 227 if (write_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread)) 228 return NULL; 229 230 close(ipc_socket); 231 232 /* Sleep untill we're killed. */ 233 pause(); 234 return NULL; 235 } 236 237 TEST_F(pidfd_info, thread_group) 238 { 239 pid_t pid_leader, pid_poller, pid_thread; 240 pthread_t thread; 241 int nevents, pidfd_leader, pidfd_thread, pidfd_leader_thread, ret; 242 int ipc_sockets[2]; 243 struct pollfd fds = {}; 244 struct pidfd_info info = { 245 .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT, 246 }, info2; 247 248 ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); 249 EXPECT_EQ(ret, 0); 250 251 pid_leader = create_child(&pidfd_leader, 0); 252 EXPECT_GE(pid_leader, 0); 253 254 if (pid_leader == 0) { 255 close(ipc_sockets[0]); 256 257 /* The thread will outlive the thread-group leader. */ 258 if (pthread_create(&thread, NULL, pidfd_info_pause_thread, &ipc_sockets[1])) 259 syscall(__NR_exit, EXIT_FAILURE); 260 261 /* Make the thread-group leader exit prematurely. */ 262 syscall(__NR_exit, EXIT_SUCCESS); 263 } 264 265 /* 266 * Opening a PIDFD_THREAD aka thread-specific pidfd based on a 267 * thread-group leader must succeed. 268 */ 269 pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD); 270 ASSERT_GE(pidfd_leader_thread, 0); 271 272 pid_poller = fork(); 273 ASSERT_GE(pid_poller, 0); 274 if (pid_poller == 0) { 275 /* 276 * We can't poll and wait for the old thread-group 277 * leader to exit using a thread-specific pidfd. The 278 * thread-group leader exited prematurely and 279 * notification is delayed until all subthreads have 280 * exited. 281 */ 282 fds.events = POLLIN; 283 fds.fd = pidfd_leader_thread; 284 nevents = poll(&fds, 1, 10000 /* wait 5 seconds */); 285 if (nevents != 0) 286 _exit(EXIT_FAILURE); 287 if (fds.revents & POLLIN) 288 _exit(EXIT_FAILURE); 289 if (fds.revents & POLLHUP) 290 _exit(EXIT_FAILURE); 291 _exit(EXIT_SUCCESS); 292 } 293 294 /* Retrieve the tid of the thread. */ 295 EXPECT_EQ(close(ipc_sockets[1]), 0); 296 ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread)); 297 EXPECT_EQ(close(ipc_sockets[0]), 0); 298 299 /* Opening a thread as a thread-group leader must fail. */ 300 pidfd_thread = sys_pidfd_open(pid_thread, 0); 301 ASSERT_LT(pidfd_thread, 0); 302 ASSERT_EQ(errno, ENOENT); 303 304 /* Opening a thread as a PIDFD_THREAD must succeed. */ 305 pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD); 306 ASSERT_GE(pidfd_thread, 0); 307 308 ASSERT_EQ(wait_for_pid(pid_poller), 0); 309 310 /* 311 * Note that pidfd_leader is a thread-group pidfd, so polling on it 312 * would only notify us once all thread in the thread-group have 313 * exited. So we can't poll before we have taken down the whole 314 * thread-group. 315 */ 316 317 /* Get PIDFD_GET_INFO using the thread-group leader pidfd. */ 318 ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0); 319 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS)); 320 /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */ 321 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT)); 322 ASSERT_EQ(info.pid, pid_leader); 323 324 /* 325 * Now retrieve the same info using the thread specific pidfd 326 * for the thread-group leader. 327 */ 328 info2.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 329 ASSERT_EQ(ioctl(pidfd_leader_thread, PIDFD_GET_INFO, &info2), 0); 330 ASSERT_TRUE(!!(info2.mask & PIDFD_INFO_CREDS)); 331 /* Process has exited but not been reaped, so no PIDFD_INFO_EXIT information yet. */ 332 ASSERT_FALSE(!!(info2.mask & PIDFD_INFO_EXIT)); 333 ASSERT_EQ(info2.pid, pid_leader); 334 335 /* Now try the thread-specific pidfd. */ 336 ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0); 337 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS)); 338 /* The thread hasn't exited, so no PIDFD_INFO_EXIT information yet. */ 339 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT)); 340 ASSERT_EQ(info.pid, pid_thread); 341 342 /* 343 * Take down the whole thread-group. The thread-group leader 344 * exited successfully but the thread will now be SIGKILLed. 345 * This must be reflected in the recorded exit information. 346 */ 347 EXPECT_EQ(sys_pidfd_send_signal(pidfd_leader, SIGKILL, NULL, 0), 0); 348 EXPECT_EQ(sys_waitid(P_PIDFD, pidfd_leader, NULL, WEXITED), 0); 349 350 fds.events = POLLIN; 351 fds.fd = pidfd_leader; 352 nevents = poll(&fds, 1, -1); 353 ASSERT_EQ(nevents, 1); 354 ASSERT_TRUE(!!(fds.revents & POLLIN)); 355 /* The thread-group leader has been reaped. */ 356 ASSERT_TRUE(!!(fds.revents & POLLHUP)); 357 358 /* 359 * Retrieve exit information for the thread-group leader via the 360 * thread-group leader pidfd. 361 */ 362 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 363 ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0); 364 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 365 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 366 /* Even though the thread-group exited successfully it will still report the group exit code. */ 367 ASSERT_TRUE(WIFSIGNALED(info.exit_code)); 368 ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL); 369 370 /* 371 * Retrieve exit information for the thread-group leader via the 372 * thread-specific pidfd. 373 */ 374 info2.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 375 ASSERT_EQ(ioctl(pidfd_leader_thread, PIDFD_GET_INFO, &info2), 0); 376 ASSERT_FALSE(!!(info2.mask & PIDFD_INFO_CREDS)); 377 ASSERT_TRUE(!!(info2.mask & PIDFD_INFO_EXIT)); 378 379 /* Even though the thread-group exited successfully it will still report the group exit code. */ 380 ASSERT_TRUE(WIFSIGNALED(info2.exit_code)); 381 ASSERT_EQ(WTERMSIG(info2.exit_code), SIGKILL); 382 383 /* Retrieve exit information for the thread. */ 384 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 385 ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0); 386 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 387 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 388 389 /* The thread got SIGKILLed. */ 390 ASSERT_TRUE(WIFSIGNALED(info.exit_code)); 391 ASSERT_EQ(WTERMSIG(info.exit_code), SIGKILL); 392 393 EXPECT_EQ(close(pidfd_leader), 0); 394 EXPECT_EQ(close(pidfd_thread), 0); 395 } 396 397 static void *pidfd_info_thread_exec(void *arg) 398 { 399 pid_t pid_thread = gettid(); 400 int ipc_socket = *(int *)arg; 401 402 /* Inform the grand-parent what the tid of this thread is. */ 403 if (write_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread)) 404 return NULL; 405 406 if (read_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread)) 407 return NULL; 408 409 close(ipc_socket); 410 411 sys_execveat(AT_FDCWD, "pidfd_exec_helper", NULL, NULL, 0); 412 return NULL; 413 } 414 415 TEST_F(pidfd_info, thread_group_exec) 416 { 417 pid_t pid_leader, pid_poller, pid_thread; 418 pthread_t thread; 419 int nevents, pidfd_leader, pidfd_leader_thread, pidfd_thread, ret; 420 int ipc_sockets[2]; 421 struct pollfd fds = {}; 422 struct pidfd_info info = { 423 .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT, 424 }; 425 426 ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); 427 EXPECT_EQ(ret, 0); 428 429 pid_leader = create_child(&pidfd_leader, 0); 430 EXPECT_GE(pid_leader, 0); 431 432 if (pid_leader == 0) { 433 close(ipc_sockets[0]); 434 435 /* The thread will outlive the thread-group leader. */ 436 if (pthread_create(&thread, NULL, pidfd_info_thread_exec, &ipc_sockets[1])) 437 syscall(__NR_exit, EXIT_FAILURE); 438 439 /* Make the thread-group leader exit prematurely. */ 440 syscall(__NR_exit, EXIT_SUCCESS); 441 } 442 443 /* Open a thread-specific pidfd for the thread-group leader. */ 444 pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD); 445 ASSERT_GE(pidfd_leader_thread, 0); 446 447 pid_poller = fork(); 448 ASSERT_GE(pid_poller, 0); 449 if (pid_poller == 0) { 450 /* 451 * We can't poll and wait for the old thread-group 452 * leader to exit using a thread-specific pidfd. The 453 * thread-group leader exited prematurely and 454 * notification is delayed until all subthreads have 455 * exited. 456 * 457 * When the thread has execed it will taken over the old 458 * thread-group leaders struct pid. Calling poll after 459 * the thread execed will thus block again because a new 460 * thread-group has started. 461 */ 462 fds.events = POLLIN; 463 fds.fd = pidfd_leader_thread; 464 nevents = poll(&fds, 1, 10000 /* wait 5 seconds */); 465 if (nevents != 0) 466 _exit(EXIT_FAILURE); 467 if (fds.revents & POLLIN) 468 _exit(EXIT_FAILURE); 469 if (fds.revents & POLLHUP) 470 _exit(EXIT_FAILURE); 471 _exit(EXIT_SUCCESS); 472 } 473 474 /* Retrieve the tid of the thread. */ 475 EXPECT_EQ(close(ipc_sockets[1]), 0); 476 ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread)); 477 478 /* Opening a thread as a PIDFD_THREAD must succeed. */ 479 pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD); 480 ASSERT_GE(pidfd_thread, 0); 481 482 /* Now that we've opened a thread-specific pidfd the thread can exec. */ 483 ASSERT_EQ(write_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread)); 484 EXPECT_EQ(close(ipc_sockets[0]), 0); 485 486 ASSERT_EQ(wait_for_pid(pid_poller), 0); 487 488 /* Wait until the kernel has SIGKILLed the thread. */ 489 fds.events = POLLHUP; 490 fds.fd = pidfd_thread; 491 nevents = poll(&fds, 1, -1); 492 ASSERT_EQ(nevents, 1); 493 /* The thread has been reaped. */ 494 ASSERT_TRUE(!!(fds.revents & POLLHUP)); 495 496 /* Retrieve thread-specific exit info from pidfd. */ 497 ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0); 498 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 499 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 500 /* 501 * While the kernel will have SIGKILLed the whole thread-group 502 * during exec it will cause the individual threads to exit 503 * cleanly. 504 */ 505 ASSERT_TRUE(WIFEXITED(info.exit_code)); 506 ASSERT_EQ(WEXITSTATUS(info.exit_code), 0); 507 508 /* 509 * The thread-group leader is still alive, the thread has taken 510 * over its struct pid and thus its pid number. 511 */ 512 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 513 ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0); 514 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS)); 515 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT)); 516 ASSERT_EQ(info.pid, pid_leader); 517 518 /* Take down the thread-group leader. */ 519 EXPECT_EQ(sys_pidfd_send_signal(pidfd_leader, SIGKILL, NULL, 0), 0); 520 521 /* 522 * Afte the exec we're dealing with an empty thread-group so now 523 * we must see an exit notification on the thread-specific pidfd 524 * for the thread-group leader as there's no subthread that can 525 * revive the struct pid. 526 */ 527 fds.events = POLLIN; 528 fds.fd = pidfd_leader_thread; 529 nevents = poll(&fds, 1, -1); 530 ASSERT_EQ(nevents, 1); 531 ASSERT_TRUE(!!(fds.revents & POLLIN)); 532 ASSERT_FALSE(!!(fds.revents & POLLHUP)); 533 534 EXPECT_EQ(sys_waitid(P_PIDFD, pidfd_leader, NULL, WEXITED), 0); 535 536 /* Retrieve exit information for the thread-group leader. */ 537 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 538 ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0); 539 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 540 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 541 542 EXPECT_EQ(close(pidfd_leader), 0); 543 EXPECT_EQ(close(pidfd_thread), 0); 544 } 545 546 static void *pidfd_info_thread_exec_sane(void *arg) 547 { 548 pid_t pid_thread = gettid(); 549 int ipc_socket = *(int *)arg; 550 551 /* Inform the grand-parent what the tid of this thread is. */ 552 if (write_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread)) 553 return NULL; 554 555 if (read_nointr(ipc_socket, &pid_thread, sizeof(pid_thread)) != sizeof(pid_thread)) 556 return NULL; 557 558 close(ipc_socket); 559 560 sys_execveat(AT_FDCWD, "pidfd_exec_helper", NULL, NULL, 0); 561 return NULL; 562 } 563 564 TEST_F(pidfd_info, thread_group_exec_thread) 565 { 566 pid_t pid_leader, pid_poller, pid_thread; 567 pthread_t thread; 568 int nevents, pidfd_leader, pidfd_leader_thread, pidfd_thread, ret; 569 int ipc_sockets[2]; 570 struct pollfd fds = {}; 571 struct pidfd_info info = { 572 .mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT, 573 }; 574 575 ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); 576 EXPECT_EQ(ret, 0); 577 578 pid_leader = create_child(&pidfd_leader, 0); 579 EXPECT_GE(pid_leader, 0); 580 581 if (pid_leader == 0) { 582 close(ipc_sockets[0]); 583 584 /* The thread will outlive the thread-group leader. */ 585 if (pthread_create(&thread, NULL, pidfd_info_thread_exec_sane, &ipc_sockets[1])) 586 syscall(__NR_exit, EXIT_FAILURE); 587 588 /* 589 * Pause the thread-group leader. It will be killed once 590 * the subthread execs. 591 */ 592 pause(); 593 syscall(__NR_exit, EXIT_SUCCESS); 594 } 595 596 /* Retrieve the tid of the thread. */ 597 EXPECT_EQ(close(ipc_sockets[1]), 0); 598 ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread)); 599 600 /* Opening a thread as a PIDFD_THREAD must succeed. */ 601 pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD); 602 ASSERT_GE(pidfd_thread, 0); 603 604 /* Open a thread-specific pidfd for the thread-group leader. */ 605 pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD); 606 ASSERT_GE(pidfd_leader_thread, 0); 607 608 pid_poller = fork(); 609 ASSERT_GE(pid_poller, 0); 610 if (pid_poller == 0) { 611 /* 612 * The subthread will now exec. The struct pid of the old 613 * thread-group leader will be assumed by the subthread which 614 * becomes the new thread-group leader. So no exit notification 615 * must be generated. Wait for 5 seconds and call it a success 616 * if no notification has been received. 617 */ 618 fds.events = POLLIN; 619 fds.fd = pidfd_leader_thread; 620 nevents = poll(&fds, 1, 10000 /* wait 5 seconds */); 621 if (nevents != 0) 622 _exit(EXIT_FAILURE); 623 if (fds.revents & POLLIN) 624 _exit(EXIT_FAILURE); 625 if (fds.revents & POLLHUP) 626 _exit(EXIT_FAILURE); 627 _exit(EXIT_SUCCESS); 628 } 629 630 /* Now that we've opened a thread-specific pidfd the thread can exec. */ 631 ASSERT_EQ(write_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread)); 632 EXPECT_EQ(close(ipc_sockets[0]), 0); 633 ASSERT_EQ(wait_for_pid(pid_poller), 0); 634 635 /* Wait until the kernel has SIGKILLed the thread. */ 636 fds.events = POLLHUP; 637 fds.fd = pidfd_thread; 638 nevents = poll(&fds, 1, -1); 639 ASSERT_EQ(nevents, 1); 640 /* The thread has been reaped. */ 641 ASSERT_TRUE(!!(fds.revents & POLLHUP)); 642 643 /* Retrieve thread-specific exit info from pidfd. */ 644 ASSERT_EQ(ioctl(pidfd_thread, PIDFD_GET_INFO, &info), 0); 645 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 646 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 647 /* 648 * While the kernel will have SIGKILLed the whole thread-group 649 * during exec it will cause the individual threads to exit 650 * cleanly. 651 */ 652 ASSERT_TRUE(WIFEXITED(info.exit_code)); 653 ASSERT_EQ(WEXITSTATUS(info.exit_code), 0); 654 655 /* 656 * The thread-group leader is still alive, the thread has taken 657 * over its struct pid and thus its pid number. 658 */ 659 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 660 ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0); 661 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_CREDS)); 662 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_EXIT)); 663 ASSERT_EQ(info.pid, pid_leader); 664 665 /* Take down the thread-group leader. */ 666 EXPECT_EQ(sys_pidfd_send_signal(pidfd_leader, SIGKILL, NULL, 0), 0); 667 668 /* 669 * Afte the exec we're dealing with an empty thread-group so now 670 * we must see an exit notification on the thread-specific pidfd 671 * for the thread-group leader as there's no subthread that can 672 * revive the struct pid. 673 */ 674 fds.events = POLLIN; 675 fds.fd = pidfd_leader_thread; 676 nevents = poll(&fds, 1, -1); 677 ASSERT_EQ(nevents, 1); 678 ASSERT_TRUE(!!(fds.revents & POLLIN)); 679 ASSERT_FALSE(!!(fds.revents & POLLHUP)); 680 681 EXPECT_EQ(sys_waitid(P_PIDFD, pidfd_leader, NULL, WEXITED), 0); 682 683 /* Retrieve exit information for the thread-group leader. */ 684 info.mask = PIDFD_INFO_CGROUPID | PIDFD_INFO_EXIT; 685 ASSERT_EQ(ioctl(pidfd_leader, PIDFD_GET_INFO, &info), 0); 686 ASSERT_FALSE(!!(info.mask & PIDFD_INFO_CREDS)); 687 ASSERT_TRUE(!!(info.mask & PIDFD_INFO_EXIT)); 688 689 EXPECT_EQ(close(pidfd_leader), 0); 690 EXPECT_EQ(close(pidfd_thread), 0); 691 } 692 693 TEST_HARNESS_MAIN 694