diff mbox series

[bpf-next,5/6] selftests/bpf: Add seccomp verifier tests

Message ID 20231031012407.51371-6-hengqi.chen@gmail.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series bpf: Add seccomp program type | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/cc_maintainers warning 12 maintainers not CCed: sdf@google.com jolsa@kernel.org john.fastabend@gmail.com eddyz87@gmail.com kpsingh@kernel.org mykolal@fb.com song@kernel.org shuah@kernel.org linux-kselftest@vger.kernel.org yonghong.song@linux.dev haoluo@google.com martin.lau@linux.dev
netdev/build_clang success Errors and warnings before: 9 this patch: 9
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 9 this patch: 9
netdev/checkpatch warning WARNING: Avoid line continuations in quoted strings WARNING: Avoid unnecessary line continuations WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? WARNING: line length of 82 exceeds 80 columns WARNING: line length of 83 exceeds 80 columns WARNING: line length of 85 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 95 exceeds 80 columns WARNING: line length of 96 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-8 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-3 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-9 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-17 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-llvm-16 / build / build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-llvm-16 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-llvm-16 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-llvm-16 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-16 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-16 / veristat
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc

Commit Message

Hengqi Chen Oct. 31, 2023, 1:24 a.m. UTC
This tests seccomp context access and helper call
restriction.

  # ./test_progs -t verifier_seccomp
  #375/1   verifier_seccomp/seccomp no helper call:OK
  #375/2   verifier_seccomp/seccomp invalid ctx access, write:OK
  #375/3   verifier_seccomp/seccomp invalid ctx access, out of range:OK
  #375/4   verifier_seccomp/seccomp invalid ctx access, size too short:OK
  #375/5   verifier_seccomp/seccomp invalid ctx access, size too short:OK
  #375/6   verifier_seccomp/seccomp invalid ctx access, size too short:OK
  #375/7   verifier_seccomp/seccomp invalid ctx access, size too short:OK
  #375/8   verifier_seccomp/seccomp invalid ctx access, size too large:OK
  #375/9   verifier_seccomp/seccomp ctx access, valid:OK
  #375     verifier_seccomp:OK
  Summary: 1/9 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
---
 .../selftests/bpf/prog_tests/verifier.c       |   2 +
 .../selftests/bpf/progs/verifier_seccomp.c    | 154 ++++++++++++++++++
 2 files changed, 156 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/verifier_seccomp.c
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
index e3e68c97b40c..dfb40a11939e 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
@@ -57,6 +57,7 @@ 
 #include "verifier_scalar_ids.skel.h"
 #include "verifier_sdiv.skel.h"
 #include "verifier_search_pruning.skel.h"
+#include "verifier_seccomp.skel.h"
 #include "verifier_sock.skel.h"
 #include "verifier_spill_fill.skel.h"
 #include "verifier_spin_lock.skel.h"
@@ -164,6 +165,7 @@  void test_verifier_runtime_jit(void)          { RUN(verifier_runtime_jit); }
 void test_verifier_scalar_ids(void)           { RUN(verifier_scalar_ids); }
 void test_verifier_sdiv(void)                 { RUN(verifier_sdiv); }
 void test_verifier_search_pruning(void)       { RUN(verifier_search_pruning); }
+void test_verifier_seccomp(void)              { RUN(verifier_seccomp); }
 void test_verifier_sock(void)                 { RUN(verifier_sock); }
 void test_verifier_spill_fill(void)           { RUN(verifier_spill_fill); }
 void test_verifier_spin_lock(void)            { RUN(verifier_spin_lock); }
diff --git a/tools/testing/selftests/bpf/progs/verifier_seccomp.c b/tools/testing/selftests/bpf/progs/verifier_seccomp.c
new file mode 100644
index 000000000000..d3984a0cdae0
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/verifier_seccomp.c
@@ -0,0 +1,154 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2023 Hengqi Chen */
+
+#include "vmlinux.h"
+#include "bpf_misc.h"
+
+#include <bpf/bpf_endian.h>
+#include <bpf/bpf_tracing.h>
+#include <bpf/bpf_helpers.h>
+
+SEC("seccomp")
+__description("seccomp no helper call")
+__failure __msg("unknown func bpf_get_prandom_u32")
+__naked void seccomp_no_helper_call(void)
+{
+	asm volatile ("					\
+	call %[bpf_get_prandom_u32];			\
+	r0 = 0;						\
+	exit;"						\
+	:
+	: __imm(bpf_get_prandom_u32)
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp invalid ctx access, write")
+__failure __msg("invalid bpf_context access")
+__naked void seccomp_ctx_write(void)
+{
+	asm volatile ("					\
+	r2 = r1;					\
+	*(u64*)(r2 + 8) = r1;				\
+	r0 = 0;						\
+	exit;"						\
+	:
+	:
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp invalid ctx access, out of range")
+__failure __msg("invalid bpf_context access")
+__naked void seccomp_ctx_read_out_of_range(void)
+{
+	asm volatile ("					\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_size]);	\
+	r0 = 0;						\
+	exit;"						\
+	:
+	: __imm_const(__bpf_seccomp_ctx_size, sizeof(struct seccomp_data))
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp invalid ctx access, size too short")
+__failure __msg("invalid bpf_context access")
+__naked void seccomp_ctx_read_too_short1(void)
+{
+	asm volatile ("					\
+	r2 = *(u8*)(r1 + %[__bpf_seccomp_ctx_nr]);	\
+	r0 = 0;						\
+	exit;"						\
+	:
+	: __imm_const(__bpf_seccomp_ctx_nr, offsetof(struct seccomp_data, nr))
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp invalid ctx access, size too short")
+__failure __msg("invalid bpf_context access")
+__naked void seccomp_ctx_read_too_short2(void)
+{
+	asm volatile ("					\
+	r2 = *(u16*)(r1 + %[__bpf_seccomp_ctx_arch]);	\
+	r0 = 0;						\
+	exit;"						\
+	:
+	: __imm_const(__bpf_seccomp_ctx_arch, offsetof(struct seccomp_data, arch))
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp invalid ctx access, size too short")
+__failure __msg("invalid bpf_context access")
+__naked void seccomp_ctx_read_too_short3(void)
+{
+	asm volatile ("					\
+	r2 = *(u32*)(r1 + %[__bpf_seccomp_ctx_ip]);	\
+	r0 = 0;						\
+	exit;"						\
+	:
+	: __imm_const(__bpf_seccomp_ctx_ip, offsetof(struct seccomp_data, instruction_pointer))
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp invalid ctx access, size too short")
+__failure __msg("invalid bpf_context access")
+__naked void seccomp_ctx_read_too_short4(void)
+{
+	asm volatile ("					\
+	r2 = *(u32*)(r1 + %[__bpf_seccomp_ctx_arg1]);	\
+	r0 = 0;						\
+	exit;"						\
+	:
+	: __imm_const(__bpf_seccomp_ctx_arg1, offsetof(struct seccomp_data, args[1]))
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp invalid ctx access, size too large")
+__failure __msg("invalid bpf_context access")
+__naked void seccomp_ctx_read_too_large(void)
+{
+	asm volatile ("					\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_nr]);	\
+	r0 = 0;						\
+	exit;"						\
+	:
+	: __imm_const(__bpf_seccomp_ctx_nr, offsetof(struct seccomp_data, nr))
+	: __clobber_all);
+}
+
+SEC("seccomp")
+__description("seccomp ctx access, valid")
+__success __retval(0x5ecc0779)
+__naked void seccomp_ctx_read_ok(void)
+{
+	asm volatile ("					\
+	r2 = *(u32*)(r1 + %[__bpf_seccomp_ctx_nr]);	\
+	r2 = *(u32*)(r1 + %[__bpf_seccomp_ctx_arch]);	\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_ip]);	\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_arg0]);	\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_arg1]);	\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_arg2]);	\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_arg3]);	\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_arg4]);	\
+	r2 = *(u64*)(r1 + %[__bpf_seccomp_ctx_arg5]);	\
+	r0 = 0x5ecc0779;				\
+	exit;"						\
+	:
+	: __imm_const(__bpf_seccomp_ctx_nr, offsetof(struct seccomp_data, nr)),
+	  __imm_const(__bpf_seccomp_ctx_arch, offsetof(struct seccomp_data, arch)),
+	  __imm_const(__bpf_seccomp_ctx_ip, offsetof(struct seccomp_data, instruction_pointer)),
+	  __imm_const(__bpf_seccomp_ctx_arg0, offsetof(struct seccomp_data, args[0])),
+	  __imm_const(__bpf_seccomp_ctx_arg1, offsetof(struct seccomp_data, args[1])),
+	  __imm_const(__bpf_seccomp_ctx_arg2, offsetof(struct seccomp_data, args[2])),
+	  __imm_const(__bpf_seccomp_ctx_arg3, offsetof(struct seccomp_data, args[3])),
+	  __imm_const(__bpf_seccomp_ctx_arg4, offsetof(struct seccomp_data, args[4])),
+	  __imm_const(__bpf_seccomp_ctx_arg5, offsetof(struct seccomp_data, args[5]))
+	: __clobber_all);
+}
+
+char _license[] SEC("license") = "GPL";