Commit f0ece18e authored by Tycho Andersen's avatar Tycho Andersen Committed by Christian Brauner

selftests: add ESRCH tests for pidfd_getfd()

Ensure that pidfd_getfd() reports -ESRCH if the task is already exiting.
Signed-off-by: default avatarTycho Andersen <tandersen@netflix.com>
Link: https://lore.kernel.org/r/20240206192357.81942-1-tycho@tycho.pizzaSigned-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 0c9bd6bc
......@@ -5,6 +5,7 @@
#include <fcntl.h>
#include <limits.h>
#include <linux/types.h>
#include <poll.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
......@@ -129,6 +130,7 @@ FIXTURE(child)
* When it is closed, the child will exit.
*/
int sk;
bool ignore_child_result;
};
FIXTURE_SETUP(child)
......@@ -165,10 +167,14 @@ FIXTURE_SETUP(child)
FIXTURE_TEARDOWN(child)
{
int ret;
EXPECT_EQ(0, close(self->pidfd));
EXPECT_EQ(0, close(self->sk));
EXPECT_EQ(0, wait_for_pid(self->pid));
ret = wait_for_pid(self->pid);
if (!self->ignore_child_result)
EXPECT_EQ(0, ret);
}
TEST_F(child, disable_ptrace)
......@@ -235,6 +241,29 @@ TEST(flags_set)
EXPECT_EQ(errno, EINVAL);
}
TEST_F(child, no_strange_EBADF)
{
struct pollfd fds;
self->ignore_child_result = true;
fds.fd = self->pidfd;
fds.events = POLLIN;
ASSERT_EQ(kill(self->pid, SIGKILL), 0);
ASSERT_EQ(poll(&fds, 1, 5000), 1);
/*
* It used to be that pidfd_getfd() could race with the exiting thread
* between exit_files() and release_task(), and get a non-null task
* with a NULL files struct, and you'd get EBADF, which was slightly
* confusing.
*/
errno = 0;
EXPECT_EQ(sys_pidfd_getfd(self->pidfd, self->remote_fd, 0), -1);
EXPECT_EQ(errno, ESRCH);
}
#if __NR_pidfd_getfd == -1
int main(void)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment