Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/seccomp: Test PTRACE_O_SUSPEND_SECCOMP without CAP_SYS_ADMIN

Add a test to check that PTRACE_O_SUSPEND_SECCOMP can't be set without
CAP_SYS_ADMIN through PTRACE_SEIZE or PTRACE_SETOPTIONS.

Signed-off-by: Jann Horn <jannh@google.com>
Co-developed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>

authored by

Jann Horn and committed by
Kees Cook
d250a3e4 2bfed7d2

+64
+1
tools/testing/selftests/seccomp/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 CFLAGS += -Wl,-no-as-needed -Wall -isystem ../../../../usr/include/ 3 3 LDFLAGS += -lpthread 4 + LDLIBS += -lcap 4 5 5 6 TEST_GEN_PROGS := seccomp_bpf seccomp_benchmark 6 7 include ../lib.mk
+63
tools/testing/selftests/seccomp/seccomp_bpf.c
··· 46 46 #include <sys/ioctl.h> 47 47 #include <linux/kcmp.h> 48 48 #include <sys/resource.h> 49 + #include <sys/capability.h> 49 50 50 51 #include <unistd.h> 51 52 #include <sys/syscall.h> ··· 4230 4229 EXPECT_EQ(0, WEXITSTATUS(status)); 4231 4230 4232 4231 close(memfd); 4232 + } 4233 + 4234 + /* Make sure PTRACE_O_SUSPEND_SECCOMP requires CAP_SYS_ADMIN. */ 4235 + FIXTURE(O_SUSPEND_SECCOMP) { 4236 + pid_t pid; 4237 + }; 4238 + 4239 + FIXTURE_SETUP(O_SUSPEND_SECCOMP) 4240 + { 4241 + ERRNO_FILTER(block_read, E2BIG); 4242 + cap_value_t cap_list[] = { CAP_SYS_ADMIN }; 4243 + cap_t caps; 4244 + 4245 + self->pid = 0; 4246 + 4247 + /* make sure we don't have CAP_SYS_ADMIN */ 4248 + caps = cap_get_proc(); 4249 + ASSERT_NE(NULL, caps); 4250 + ASSERT_EQ(0, cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_list, CAP_CLEAR)); 4251 + ASSERT_EQ(0, cap_set_proc(caps)); 4252 + cap_free(caps); 4253 + 4254 + ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); 4255 + ASSERT_EQ(0, prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog_block_read)); 4256 + 4257 + self->pid = fork(); 4258 + ASSERT_GE(self->pid, 0); 4259 + 4260 + if (self->pid == 0) { 4261 + while (1) 4262 + pause(); 4263 + _exit(127); 4264 + } 4265 + } 4266 + 4267 + FIXTURE_TEARDOWN(O_SUSPEND_SECCOMP) 4268 + { 4269 + if (self->pid) 4270 + kill(self->pid, SIGKILL); 4271 + } 4272 + 4273 + TEST_F(O_SUSPEND_SECCOMP, setoptions) 4274 + { 4275 + int wstatus; 4276 + 4277 + ASSERT_EQ(0, ptrace(PTRACE_ATTACH, self->pid, NULL, 0)); 4278 + ASSERT_EQ(self->pid, wait(&wstatus)); 4279 + ASSERT_EQ(-1, ptrace(PTRACE_SETOPTIONS, self->pid, NULL, PTRACE_O_SUSPEND_SECCOMP)); 4280 + if (errno == EINVAL) 4281 + SKIP(return, "Kernel does not support PTRACE_O_SUSPEND_SECCOMP (missing CONFIG_CHECKPOINT_RESTORE?)"); 4282 + ASSERT_EQ(EPERM, errno); 4283 + } 4284 + 4285 + TEST_F(O_SUSPEND_SECCOMP, seize) 4286 + { 4287 + int ret; 4288 + 4289 + ret = ptrace(PTRACE_SEIZE, self->pid, NULL, PTRACE_O_SUSPEND_SECCOMP); 4290 + ASSERT_EQ(-1, ret); 4291 + if (errno == EINVAL) 4292 + SKIP(return, "Kernel does not support PTRACE_O_SUSPEND_SECCOMP (missing CONFIG_CHECKPOINT_RESTORE?)"); 4293 + ASSERT_EQ(EPERM, errno); 4233 4294 } 4234 4295 4235 4296 /*