From 0072e3624b463636c842ad8e261f1dc91deb8c78 Mon Sep 17 00:00:00 2001 From: Yafang Shao Date: Wed, 23 Aug 2023 02:07:03 +0000 Subject: [PATCH] selftests/bpf: Add selftest for allow_ptr_leaks - Without prev commit $ tools/testing/selftests/bpf/test_progs --name=tc_bpf #232/1 tc_bpf/tc_bpf_root:OK test_tc_bpf_non_root:PASS:set_cap_bpf_cap_net_admin 0 nsec test_tc_bpf_non_root:PASS:disable_cap_sys_admin 0 nsec 0: R1=ctx(off=0,imm=0) R10=fp0 ; if ((long)(iph + 1) > (long)skb->data_end) 0: (61) r2 = *(u32 *)(r1 +80) ; R1=ctx(off=0,imm=0) R2_w=pkt_end(off=0,imm=0) ; struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr); 1: (61) r1 = *(u32 *)(r1 +76) ; R1_w=pkt(off=0,r=0,imm=0) ; if ((long)(iph + 1) > (long)skb->data_end) 2: (07) r1 += 34 ; R1_w=pkt(off=34,r=0,imm=0) 3: (b4) w0 = 1 ; R0_w=1 4: (2d) if r1 > r2 goto pc+1 R2 pointer comparison prohibited processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0 test_tc_bpf_non_root:FAIL:test_tc_bpf__open_and_load unexpected error: -13 #233/2 tc_bpf_non_root:FAIL - With prev commit $ tools/testing/selftests/bpf/test_progs --name=tc_bpf #232/1 tc_bpf/tc_bpf_root:OK #232/2 tc_bpf/tc_bpf_non_root:OK #232 tc_bpf:OK Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Yafang Shao Link: https://lore.kernel.org/r/20230823020703.3790-3-laoar.shao@gmail.com Signed-off-by: Alexei Starovoitov --- .../testing/selftests/bpf/prog_tests/tc_bpf.c | 36 ++++++++++++++++++- .../testing/selftests/bpf/progs/test_tc_bpf.c | 13 +++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c index e873766276d1..48b55539331e 100644 --- a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c +++ b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c @@ -3,6 +3,7 @@ #include #include +#include "cap_helpers.h" #include "test_tc_bpf.skel.h" #define LO_IFINDEX 1 @@ -327,7 +328,7 @@ static int test_tc_bpf_api(struct bpf_tc_hook *hook, int fd) return 0; } -void test_tc_bpf(void) +void tc_bpf_root(void) { DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX, .attach_point = BPF_TC_INGRESS); @@ -393,3 +394,36 @@ void test_tc_bpf(void) } test_tc_bpf__destroy(skel); } + +void tc_bpf_non_root(void) +{ + struct test_tc_bpf *skel = NULL; + __u64 caps = 0; + int ret; + + /* In case CAP_BPF and CAP_PERFMON is not set */ + ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps); + if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin")) + return; + ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL); + if (!ASSERT_OK(ret, "disable_cap_sys_admin")) + goto restore_cap; + + skel = test_tc_bpf__open_and_load(); + if (!ASSERT_OK_PTR(skel, "test_tc_bpf__open_and_load")) + goto restore_cap; + + test_tc_bpf__destroy(skel); + +restore_cap: + if (caps) + cap_enable_effective(caps, NULL); +} + +void test_tc_bpf(void) +{ + if (test__start_subtest("tc_bpf_root")) + tc_bpf_root(); + if (test__start_subtest("tc_bpf_non_root")) + tc_bpf_non_root(); +} diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c index d28ca8d1f3d0..ef7da419632a 100644 --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c @@ -2,6 +2,8 @@ #include #include +#include +#include /* Dummy prog to test TC-BPF API */ @@ -10,3 +12,14 @@ int cls(struct __sk_buff *skb) { return 0; } + +/* Prog to verify tc-bpf without cap_sys_admin and cap_perfmon */ +SEC("tcx/ingress") +int pkt_ptr(struct __sk_buff *skb) +{ + struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr); + + if ((long)(iph + 1) > (long)skb->data_end) + return 1; + return 0; +}