Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit f0c508f

Browse files
avaginkees
authored andcommitted
selftests/seccomp: check that a zombie leader doesn't affect others
Ensure that a dead thread leader doesn't prevent installing new filters with SECCOMP_FILTER_FLAG_TSYNC from other threads. Signed-off-by: Andrei Vagin <avagin@google.com> Link: https://lore.kernel.org/r/20240628021014.231976-5-avagin@google.com Reviewed-by: Tycho Andersen <tandersen@netflix.com> Signed-off-by: Kees Cook <kees@kernel.org>
1 parent 39a73b4 commit f0c508f

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

tools/testing/selftests/seccomp/seccomp_bpf.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4809,6 +4809,83 @@ TEST(user_notification_wait_killable_fatal)
48094809
EXPECT_EQ(SIGTERM, WTERMSIG(status));
48104810
}
48114811

4812+
struct tsync_vs_thread_leader_args {
4813+
pthread_t leader;
4814+
};
4815+
4816+
static void *tsync_vs_dead_thread_leader_sibling(void *_args)
4817+
{
4818+
struct sock_filter allow_filter[] = {
4819+
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
4820+
};
4821+
struct sock_fprog allow_prog = {
4822+
.len = (unsigned short)ARRAY_SIZE(allow_filter),
4823+
.filter = allow_filter,
4824+
};
4825+
struct tsync_vs_thread_leader_args *args = _args;
4826+
void *retval;
4827+
long ret;
4828+
4829+
ret = pthread_join(args->leader, &retval);
4830+
if (ret)
4831+
exit(1);
4832+
if (retval != _args)
4833+
exit(2);
4834+
ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, &allow_prog);
4835+
if (ret)
4836+
exit(3);
4837+
4838+
exit(0);
4839+
}
4840+
4841+
/*
4842+
* Ensure that a dead thread leader doesn't prevent installing new filters with
4843+
* SECCOMP_FILTER_FLAG_TSYNC from other threads.
4844+
*/
4845+
TEST(tsync_vs_dead_thread_leader)
4846+
{
4847+
int status;
4848+
pid_t pid;
4849+
long ret;
4850+
4851+
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
4852+
ASSERT_EQ(0, ret) {
4853+
TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
4854+
}
4855+
4856+
pid = fork();
4857+
ASSERT_GE(pid, 0);
4858+
4859+
if (pid == 0) {
4860+
struct sock_filter allow_filter[] = {
4861+
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
4862+
};
4863+
struct sock_fprog allow_prog = {
4864+
.len = (unsigned short)ARRAY_SIZE(allow_filter),
4865+
.filter = allow_filter,
4866+
};
4867+
struct tsync_vs_thread_leader_args *args;
4868+
pthread_t sibling;
4869+
4870+
args = malloc(sizeof(*args));
4871+
ASSERT_NE(NULL, args);
4872+
args->leader = pthread_self();
4873+
4874+
ret = pthread_create(&sibling, NULL,
4875+
tsync_vs_dead_thread_leader_sibling, args);
4876+
ASSERT_EQ(0, ret);
4877+
4878+
/* Install a new filter just to the leader thread. */
4879+
ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &allow_prog);
4880+
ASSERT_EQ(0, ret);
4881+
pthread_exit(args);
4882+
exit(1);
4883+
}
4884+
4885+
EXPECT_EQ(pid, waitpid(pid, &status, 0));
4886+
EXPECT_EQ(0, status);
4887+
}
4888+
48124889
/*
48134890
* TODO:
48144891
* - expand NNP testing

0 commit comments

Comments
 (0)