diff options
-rw-r--r-- | include/linux/seccomp.h | 1 | ||||
-rw-r--r-- | kernel/fork.c | 17 | ||||
-rw-r--r-- | tools/testing/selftests/seccomp/seccomp_bpf.c | 6 |
3 files changed, 16 insertions, 8 deletions
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index d31d76be4982..175079552f68 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -27,6 +27,7 @@ struct seccomp_filter; * * @mode: indicates one of the valid values above for controlled * system calls available to a process. + * @filter_count: number of seccomp filters * @filter: must always point to a valid seccomp-filter or NULL as it is * accessed without locking during system call entry. * diff --git a/kernel/fork.c b/kernel/fork.c index 08969f5aa38d..844dfdc8c639 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -535,6 +535,9 @@ void put_task_stack(struct task_struct *tsk) void free_task(struct task_struct *tsk) { +#ifdef CONFIG_SECCOMP + WARN_ON_ONCE(tsk->seccomp.filter); +#endif release_user_cpus_ptr(tsk); scs_release(tsk); @@ -2406,12 +2409,6 @@ static __latent_entropy struct task_struct *copy_process( spin_lock(¤t->sighand->siglock); - /* - * Copy seccomp details explicitly here, in case they were changed - * before holding sighand lock. - */ - copy_seccomp(p); - rv_task_fork(p); rseq_fork(p, clone_flags); @@ -2428,6 +2425,14 @@ static __latent_entropy struct task_struct *copy_process( goto bad_fork_cancel_cgroup; } + /* No more failure paths after this point. */ + + /* + * Copy seccomp details explicitly here, in case they were changed + * before holding sighand lock. + */ + copy_seccomp(p); + init_task_pid_links(p); if (likely(p->pid)) { ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace); diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 4ae6c8991307..9c2f448bb3a9 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -392,6 +392,8 @@ TEST(mode_filter_without_nnp) .filter = filter, }; long ret; + cap_t cap = cap_get_proc(); + cap_flag_value_t is_cap_sys_admin = 0; ret = prctl(PR_GET_NO_NEW_PRIVS, 0, NULL, 0, 0); ASSERT_LE(0, ret) { @@ -400,8 +402,8 @@ TEST(mode_filter_without_nnp) errno = 0; ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0); /* Succeeds with CAP_SYS_ADMIN, fails without */ - /* TODO(wad) check caps not euid */ - if (geteuid()) { + cap_get_flag(cap, CAP_SYS_ADMIN, CAP_EFFECTIVE, &is_cap_sys_admin); + if (!is_cap_sys_admin) { EXPECT_EQ(-1, ret); EXPECT_EQ(EACCES, errno); } else { |