selftests/pidfd: first test for multi-threaded exec polling

Add first test for premature thread-group leader exit.

Link: https://lore.kernel.org/r/20250320-work-pidfs-thread_group-v4-2-da678ce805bf@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2025-03-20 14:24:09 +01:00
parent 0fb482728b
commit db7ce91e22

View File

@@ -236,7 +236,7 @@ static void *pidfd_info_pause_thread(void *arg)
TEST_F(pidfd_info, thread_group)
{
pid_t pid_leader, pid_thread;
pid_t pid_leader, pid_poller, pid_thread;
pthread_t thread;
int nevents, pidfd_leader, pidfd_thread, pidfd_leader_thread, ret;
int ipc_sockets[2];
@@ -262,6 +262,35 @@ TEST_F(pidfd_info, thread_group)
syscall(__NR_exit, EXIT_SUCCESS);
}
/*
* Opening a PIDFD_THREAD aka thread-specific pidfd based on a
* thread-group leader must succeed.
*/
pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD);
ASSERT_GE(pidfd_leader_thread, 0);
pid_poller = fork();
ASSERT_GE(pid_poller, 0);
if (pid_poller == 0) {
/*
* We can't poll and wait for the old thread-group
* leader to exit using a thread-specific pidfd. The
* thread-group leader exited prematurely and
* notification is delayed until all subthreads have
* exited.
*/
fds.events = POLLIN;
fds.fd = pidfd_leader_thread;
nevents = poll(&fds, 1, 10000 /* wait 5 seconds */);
if (nevents != 0)
_exit(EXIT_FAILURE);
if (fds.revents & POLLIN)
_exit(EXIT_FAILURE);
if (fds.revents & POLLHUP)
_exit(EXIT_FAILURE);
_exit(EXIT_SUCCESS);
}
/* Retrieve the tid of the thread. */
EXPECT_EQ(close(ipc_sockets[1]), 0);
ASSERT_EQ(read_nointr(ipc_sockets[0], &pid_thread, sizeof(pid_thread)), sizeof(pid_thread));
@@ -275,12 +304,7 @@ TEST_F(pidfd_info, thread_group)
pidfd_thread = sys_pidfd_open(pid_thread, PIDFD_THREAD);
ASSERT_GE(pidfd_thread, 0);
/*
* Opening a PIDFD_THREAD aka thread-specific pidfd based on a
* thread-group leader must succeed.
*/
pidfd_leader_thread = sys_pidfd_open(pid_leader, PIDFD_THREAD);
ASSERT_GE(pidfd_leader_thread, 0);
ASSERT_EQ(wait_for_pid(pid_poller), 0);
/*
* Note that pidfd_leader is a thread-group pidfd, so polling on it