diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index a8e7187..1ca118f 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -350,6 +350,12 @@ else SKIP=$((SKIP + 1)) fi +if require_guest_test "process-vm-deny-test"; then + expect_output "process-vm-deny-test" "PASS: process_vm_readv denied" \ + "$KBOX" image -S "$ROOTFS" --syscall-mode=seccomp \ + -- "/opt/tests/process-vm-deny-test" +fi + echo "" echo "--- Rewrite security ---" diff --git a/src/seccomp-bpf.c b/src/seccomp-bpf.c index 012af7c..ad86b1d 100644 --- a/src/seccomp-bpf.c +++ b/src/seccomp-bpf.c @@ -43,6 +43,7 @@ static const int deny_nrs[] = { /* Tracing: supervisor memory/process access attacks */ 101, /* ptrace */ + 310, /* process_vm_readv */ 311, /* process_vm_writev */ 440, /* process_madvise */ 448, /* process_mrelease */ @@ -148,6 +149,7 @@ static const int deny_nrs[] = { /* Tracing */ 117, /* ptrace */ + 270, /* process_vm_readv */ 271, /* process_vm_writev */ 440, /* process_madvise */ 448, /* process_mrelease */ diff --git a/tests/guest/process-vm-deny-test.c b/tests/guest/process-vm-deny-test.c new file mode 100644 index 0000000..ff6419b --- /dev/null +++ b/tests/guest/process-vm-deny-test.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: MIT */ +/* Guest test: verify process_vm_readv is blocked by the seccomp BPF deny list. + * + * The guest has no legitimate need to read another process's address space. + * kbox itself uses process_vm_readv in the supervisor -> child direction only. + * The guest-side syscall must therefore fail with EPERM before reaching the + * seccomp-unotify supervisor path. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHECK(cond, msg) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "FAIL: %s (%s)\n", msg, #cond); \ + exit(1); \ + } \ + } while (0) + +int main(void) +{ + uint32_t src = 0x12345678u; + uint32_t dst = 0; + struct iovec local = {.iov_base = &dst, .iov_len = sizeof(dst)}; + struct iovec remote = {.iov_base = &src, .iov_len = sizeof(src)}; + long rc; + + errno = 0; + rc = syscall(__NR_process_vm_readv, getpid(), &local, 1, &remote, 1, 0); + CHECK(rc < 0, "process_vm_readv should fail"); + CHECK(errno == EPERM, "process_vm_readv errno should be EPERM"); + printf("PASS: process_vm_readv denied\n"); + return 0; +}