Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: add ESRCH tests for pidfd_getfd()

Ensure that pidfd_getfd() reports -ESRCH if the task is already exiting.

Signed-off-by: Tycho Andersen <tandersen@netflix.com>
Link: https://lore.kernel.org/r/20240206192357.81942-1-tycho@tycho.pizza
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Tycho Andersen and committed by
Christian Brauner
f0ece18e 0c9bd6bc

+30 -1
+30 -1
tools/testing/selftests/pidfd/pidfd_getfd_test.c
··· 5 5 #include <fcntl.h> 6 6 #include <limits.h> 7 7 #include <linux/types.h> 8 + #include <poll.h> 8 9 #include <sched.h> 9 10 #include <signal.h> 10 11 #include <stdio.h> ··· 130 129 * When it is closed, the child will exit. 131 130 */ 132 131 int sk; 132 + bool ignore_child_result; 133 133 }; 134 134 135 135 FIXTURE_SETUP(child) ··· 167 165 168 166 FIXTURE_TEARDOWN(child) 169 167 { 168 + int ret; 169 + 170 170 EXPECT_EQ(0, close(self->pidfd)); 171 171 EXPECT_EQ(0, close(self->sk)); 172 172 173 - EXPECT_EQ(0, wait_for_pid(self->pid)); 173 + ret = wait_for_pid(self->pid); 174 + if (!self->ignore_child_result) 175 + EXPECT_EQ(0, ret); 174 176 } 175 177 176 178 TEST_F(child, disable_ptrace) ··· 239 233 { 240 234 ASSERT_EQ(-1, sys_pidfd_getfd(0, 0, 1)); 241 235 EXPECT_EQ(errno, EINVAL); 236 + } 237 + 238 + TEST_F(child, no_strange_EBADF) 239 + { 240 + struct pollfd fds; 241 + 242 + self->ignore_child_result = true; 243 + 244 + fds.fd = self->pidfd; 245 + fds.events = POLLIN; 246 + 247 + ASSERT_EQ(kill(self->pid, SIGKILL), 0); 248 + ASSERT_EQ(poll(&fds, 1, 5000), 1); 249 + 250 + /* 251 + * It used to be that pidfd_getfd() could race with the exiting thread 252 + * between exit_files() and release_task(), and get a non-null task 253 + * with a NULL files struct, and you'd get EBADF, which was slightly 254 + * confusing. 255 + */ 256 + errno = 0; 257 + EXPECT_EQ(sys_pidfd_getfd(self->pidfd, self->remote_fd, 0), -1); 258 + EXPECT_EQ(errno, ESRCH); 242 259 } 243 260 244 261 #if __NR_pidfd_getfd == -1