mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-31 19:45:21 +00:00
selftests/seccomp: Check for EPOLLHUP for user_notif
This verifies we're correctly notified when a seccomp filter becomes unused when a notifier is in use. Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com> Link: https://lore.kernel.org/r/20200531115031.391515-4-christian.brauner@ubuntu.com Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
99cdb8b9a5
commit
ad5682184a
1 changed files with 136 additions and 0 deletions
|
@ -51,6 +51,7 @@
|
|||
#include <poll.h>
|
||||
|
||||
#include "../kselftest_harness.h"
|
||||
#include "../clone3/clone3_selftests.h"
|
||||
|
||||
/* Attempt to de-conflict with the selftests tree. */
|
||||
#ifndef SKIP
|
||||
|
@ -3702,6 +3703,141 @@ skip:
|
|||
}
|
||||
}
|
||||
|
||||
TEST(user_notification_filter_empty)
|
||||
{
|
||||
pid_t pid;
|
||||
long ret;
|
||||
int status;
|
||||
struct pollfd pollfd;
|
||||
struct clone_args args = {
|
||||
.flags = CLONE_FILES,
|
||||
.exit_signal = SIGCHLD,
|
||||
};
|
||||
|
||||
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!");
|
||||
}
|
||||
|
||||
pid = sys_clone3(&args, sizeof(args));
|
||||
ASSERT_GE(pid, 0);
|
||||
|
||||
if (pid == 0) {
|
||||
int listener;
|
||||
|
||||
listener = user_trap_syscall(__NR_mknod, SECCOMP_FILTER_FLAG_NEW_LISTENER);
|
||||
if (listener < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (dup2(listener, 200) != 200)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
close(listener);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
EXPECT_EQ(waitpid(pid, &status, 0), pid);
|
||||
EXPECT_EQ(true, WIFEXITED(status));
|
||||
EXPECT_EQ(0, WEXITSTATUS(status));
|
||||
|
||||
/*
|
||||
* The seccomp filter has become unused so we should be notified once
|
||||
* the kernel gets around to cleaning up task struct.
|
||||
*/
|
||||
pollfd.fd = 200;
|
||||
pollfd.events = POLLHUP;
|
||||
|
||||
EXPECT_GT(poll(&pollfd, 1, 2000), 0);
|
||||
EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0);
|
||||
}
|
||||
|
||||
static void *do_thread(void *data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TEST(user_notification_filter_empty_threaded)
|
||||
{
|
||||
pid_t pid;
|
||||
long ret;
|
||||
int status;
|
||||
struct pollfd pollfd;
|
||||
struct clone_args args = {
|
||||
.flags = CLONE_FILES,
|
||||
.exit_signal = SIGCHLD,
|
||||
};
|
||||
|
||||
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!");
|
||||
}
|
||||
|
||||
pid = sys_clone3(&args, sizeof(args));
|
||||
ASSERT_GE(pid, 0);
|
||||
|
||||
if (pid == 0) {
|
||||
pid_t pid1, pid2;
|
||||
int listener, status;
|
||||
pthread_t thread;
|
||||
|
||||
listener = user_trap_syscall(__NR_dup, SECCOMP_FILTER_FLAG_NEW_LISTENER);
|
||||
if (listener < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (dup2(listener, 200) != 200)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
close(listener);
|
||||
|
||||
pid1 = fork();
|
||||
if (pid1 < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (pid1 == 0)
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
pid2 = fork();
|
||||
if (pid2 < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (pid2 == 0)
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
if (pthread_create(&thread, NULL, do_thread, NULL) ||
|
||||
pthread_join(thread, NULL))
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (pthread_create(&thread, NULL, do_thread, NULL) ||
|
||||
pthread_join(thread, NULL))
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (waitpid(pid1, &status, 0) != pid1 || !WIFEXITED(status) ||
|
||||
WEXITSTATUS(status))
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (waitpid(pid2, &status, 0) != pid2 || !WIFEXITED(status) ||
|
||||
WEXITSTATUS(status))
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
EXPECT_EQ(waitpid(pid, &status, 0), pid);
|
||||
EXPECT_EQ(true, WIFEXITED(status));
|
||||
EXPECT_EQ(0, WEXITSTATUS(status));
|
||||
|
||||
/*
|
||||
* The seccomp filter has become unused so we should be notified once
|
||||
* the kernel gets around to cleaning up task struct.
|
||||
*/
|
||||
pollfd.fd = 200;
|
||||
pollfd.events = POLLHUP;
|
||||
|
||||
EXPECT_GT(poll(&pollfd, 1, 2000), 0);
|
||||
EXPECT_GT((pollfd.revents & POLLHUP) ?: 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - add microbenchmarks
|
||||
|
|
Loading…
Add table
Reference in a new issue