selftests/seccomp: add test for NOTIF_RECV and unused filters
Add a new test case to check that SECCOMP_IOCTL_NOTIF_RECV returns when all tasks have gone. Signed-off-by: Andrei Vagin <avagin@google.com> Link: https://lore.kernel.org/r/20240628021014.231976-4-avagin@google.com Reviewed-by: Tycho Andersen <tandersen@netflix.com> Signed-off-by: Kees Cook <kees@kernel.org>
This commit is contained in:
@@ -3954,6 +3954,60 @@ TEST(user_notification_filter_empty)
|
||||
EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0);
|
||||
}
|
||||
|
||||
TEST(user_ioctl_notification_filter_empty)
|
||||
{
|
||||
pid_t pid;
|
||||
long ret;
|
||||
int status, p[2];
|
||||
struct __clone_args args = {
|
||||
.flags = CLONE_FILES,
|
||||
.exit_signal = SIGCHLD,
|
||||
};
|
||||
struct seccomp_notif req = {};
|
||||
|
||||
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
|
||||
ASSERT_EQ(0, ret) {
|
||||
TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
|
||||
}
|
||||
|
||||
if (__NR_clone3 < 0)
|
||||
SKIP(return, "Test not built with clone3 support");
|
||||
|
||||
ASSERT_EQ(0, pipe(p));
|
||||
|
||||
pid = sys_clone3(&args, sizeof(args));
|
||||
ASSERT_GE(pid, 0);
|
||||
|
||||
if (pid == 0) {
|
||||
int listener;
|
||||
|
||||
listener = user_notif_syscall(__NR_mknodat, SECCOMP_FILTER_FLAG_NEW_LISTENER);
|
||||
if (listener < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (dup2(listener, 200) != 200)
|
||||
_exit(EXIT_FAILURE);
|
||||
close(p[1]);
|
||||
close(listener);
|
||||
sleep(1);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (read(p[0], &status, 1) != 0)
|
||||
_exit(EXIT_SUCCESS);
|
||||
close(p[0]);
|
||||
/*
|
||||
* The seccomp filter has become unused so we should be notified once
|
||||
* the kernel gets around to cleaning up task struct.
|
||||
*/
|
||||
EXPECT_EQ(ioctl(200, SECCOMP_IOCTL_NOTIF_RECV, &req), -1);
|
||||
EXPECT_EQ(errno, ENOENT);
|
||||
|
||||
EXPECT_EQ(waitpid(pid, &status, 0), pid);
|
||||
EXPECT_EQ(true, WIFEXITED(status));
|
||||
EXPECT_EQ(0, WEXITSTATUS(status));
|
||||
}
|
||||
|
||||
static void *do_thread(void *data)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user