From 6016df8fe874e1cf36f6357d71438b384198ce06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Date: Wed, 18 Nov 2020 08:16:38 +0100 Subject: [PATCH 1/3] selftests/bpf: Fix broken riscv build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The selftests/bpf Makefile includes system include directories from the host, when building BPF programs. On RISC-V glibc requires that __riscv_xlen is defined. This is not the case for "clang -target bpf", which messes up __WORDSIZE (errno.h -> ... -> wordsize.h) and breaks the build. By explicitly defining __risc_xlen correctly for riscv, we can workaround this. Fixes: 167381f3eac0 ("selftests/bpf: Makefile fix "missing" headers on build with -idirafter") Signed-off-by: Björn Töpel Signed-off-by: Andrii Nakryiko Acked-by: Luke Nelson Link: https://lore.kernel.org/bpf/20201118071640.83773-2-bjorn.topel@gmail.com --- tools/testing/selftests/bpf/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index c1708ffa6b1c..3d5940cd110d 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -219,7 +219,8 @@ $(RESOLVE_BTFIDS): $(BPFOBJ) | $(BUILD_DIR)/resolve_btfids \ # build would have failed anyways. define get_sys_includes $(shell $(1) -v -E - &1 \ - | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') + | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \ +$(shell $(1) -dM -E - Date: Wed, 18 Nov 2020 08:16:39 +0100 Subject: [PATCH 2/3] selftests/bpf: Avoid running unprivileged tests with alignment requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some architectures have strict alignment requirements. In that case, the BPF verifier detects if a program has unaligned accesses and rejects them. A user can pass BPF_F_ANY_ALIGNMENT to a program to override this check. That, however, will only work when a privileged user loads a program. An unprivileged user loading a program with this flag will be rejected prior entering the verifier. Hence, it does not make sense to load unprivileged programs without strict alignment when testing the verifier. This patch avoids exactly that. Signed-off-by: Björn Töpel Signed-off-by: Andrii Nakryiko Acked-by: Luke Nelson Link: https://lore.kernel.org/bpf/20201118071640.83773-3-bjorn.topel@gmail.com --- tools/testing/selftests/bpf/test_verifier.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 9be395d9dc64..4bfe3aa2cfc4 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -1152,6 +1152,19 @@ static void get_unpriv_disabled() static bool test_as_unpriv(struct bpf_test *test) { +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS + /* Some architectures have strict alignment requirements. In + * that case, the BPF verifier detects if a program has + * unaligned accesses and rejects them. A user can pass + * BPF_F_ANY_ALIGNMENT to a program to override this + * check. That, however, will only work when a privileged user + * loads a program. An unprivileged user loading a program + * with this flag will be rejected prior entering the + * verifier. + */ + if (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) + return false; +#endif return !test->prog_type || test->prog_type == BPF_PROG_TYPE_SOCKET_FILTER || test->prog_type == BPF_PROG_TYPE_CGROUP_SKB; From 6007b23cc7555df882be870433dc589841d4eb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Date: Wed, 18 Nov 2020 08:16:40 +0100 Subject: [PATCH 3/3] selftests/bpf: Mark tests that require unaligned memory access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A lot of tests require unaligned memory access to work. Mark the tests as such, so that they can be avoided on unsupported architectures such as RISC-V. Signed-off-by: Björn Töpel Signed-off-by: Andrii Nakryiko Acked-by: Luke Nelson Link: https://lore.kernel.org/bpf/20201118071640.83773-4-bjorn.topel@gmail.com --- .../selftests/bpf/verifier/ctx_sk_lookup.c | 7 +++ .../bpf/verifier/direct_value_access.c | 3 ++ .../testing/selftests/bpf/verifier/map_ptr.c | 1 + .../selftests/bpf/verifier/raw_tp_writable.c | 1 + .../selftests/bpf/verifier/ref_tracking.c | 4 ++ .../testing/selftests/bpf/verifier/regalloc.c | 8 ++++ .../selftests/bpf/verifier/wide_access.c | 46 +++++++++++-------- 7 files changed, 52 insertions(+), 18 deletions(-) diff --git a/tools/testing/selftests/bpf/verifier/ctx_sk_lookup.c b/tools/testing/selftests/bpf/verifier/ctx_sk_lookup.c index 2ad5f974451c..fb13ca2d5606 100644 --- a/tools/testing/selftests/bpf/verifier/ctx_sk_lookup.c +++ b/tools/testing/selftests/bpf/verifier/ctx_sk_lookup.c @@ -266,6 +266,7 @@ .result = REJECT, .prog_type = BPF_PROG_TYPE_SK_LOOKUP, .expected_attach_type = BPF_SK_LOOKUP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "invalid 8-byte read from bpf_sk_lookup remote_ip4 field", @@ -292,6 +293,7 @@ .result = REJECT, .prog_type = BPF_PROG_TYPE_SK_LOOKUP, .expected_attach_type = BPF_SK_LOOKUP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "invalid 8-byte read from bpf_sk_lookup remote_port field", @@ -305,6 +307,7 @@ .result = REJECT, .prog_type = BPF_PROG_TYPE_SK_LOOKUP, .expected_attach_type = BPF_SK_LOOKUP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "invalid 8-byte read from bpf_sk_lookup local_ip4 field", @@ -331,6 +334,7 @@ .result = REJECT, .prog_type = BPF_PROG_TYPE_SK_LOOKUP, .expected_attach_type = BPF_SK_LOOKUP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "invalid 8-byte read from bpf_sk_lookup local_port field", @@ -344,6 +348,7 @@ .result = REJECT, .prog_type = BPF_PROG_TYPE_SK_LOOKUP, .expected_attach_type = BPF_SK_LOOKUP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, /* invalid 1,2,4-byte reads from 8-byte fields in bpf_sk_lookup */ { @@ -410,6 +415,7 @@ .result = REJECT, .prog_type = BPF_PROG_TYPE_SK_LOOKUP, .expected_attach_type = BPF_SK_LOOKUP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "invalid 4-byte unaligned read from bpf_sk_lookup at even offset", @@ -422,6 +428,7 @@ .result = REJECT, .prog_type = BPF_PROG_TYPE_SK_LOOKUP, .expected_attach_type = BPF_SK_LOOKUP, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, /* in-bound and out-of-bound writes to bpf_sk_lookup */ { diff --git a/tools/testing/selftests/bpf/verifier/direct_value_access.c b/tools/testing/selftests/bpf/verifier/direct_value_access.c index 988f46a1a4c7..c0648dc009b5 100644 --- a/tools/testing/selftests/bpf/verifier/direct_value_access.c +++ b/tools/testing/selftests/bpf/verifier/direct_value_access.c @@ -69,6 +69,7 @@ .fixup_map_array_48b = { 1 }, .result = REJECT, .errstr = "R1 min value is outside of the allowed memory range", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "direct map access, write test 7", @@ -195,6 +196,7 @@ .fixup_map_array_48b = { 1, 3 }, .result = REJECT, .errstr = "invalid access to map value, value_size=48 off=47 size=2", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "direct map access, write test 17", @@ -209,6 +211,7 @@ .fixup_map_array_48b = { 1, 3 }, .result = REJECT, .errstr = "invalid access to map value, value_size=48 off=47 size=2", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "direct map access, write test 18", diff --git a/tools/testing/selftests/bpf/verifier/map_ptr.c b/tools/testing/selftests/bpf/verifier/map_ptr.c index 637f9293bda8..b117bdd3806d 100644 --- a/tools/testing/selftests/bpf/verifier/map_ptr.c +++ b/tools/testing/selftests/bpf/verifier/map_ptr.c @@ -44,6 +44,7 @@ .errstr_unpriv = "bpf_array access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN", .result = REJECT, .errstr = "cannot access ptr member ops with moff 0 in struct bpf_map with off 1 size 4", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "bpf_map_ptr: read ops field accepted", diff --git a/tools/testing/selftests/bpf/verifier/raw_tp_writable.c b/tools/testing/selftests/bpf/verifier/raw_tp_writable.c index 95b5d70a1dc1..2978fb5a769d 100644 --- a/tools/testing/selftests/bpf/verifier/raw_tp_writable.c +++ b/tools/testing/selftests/bpf/verifier/raw_tp_writable.c @@ -31,4 +31,5 @@ .fixup_map_hash_8b = { 1, }, .prog_type = BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, .errstr = "R6 invalid variable buffer offset: off=0, var_off=(0x0; 0xffffffff)", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, diff --git a/tools/testing/selftests/bpf/verifier/ref_tracking.c b/tools/testing/selftests/bpf/verifier/ref_tracking.c index 006b5bd99c08..3b6ee009c00b 100644 --- a/tools/testing/selftests/bpf/verifier/ref_tracking.c +++ b/tools/testing/selftests/bpf/verifier/ref_tracking.c @@ -675,6 +675,7 @@ .prog_type = BPF_PROG_TYPE_SCHED_CLS, .result = REJECT, .errstr = "invalid mem access", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "reference tracking: use ptr from bpf_sk_fullsock() after release", @@ -698,6 +699,7 @@ .prog_type = BPF_PROG_TYPE_SCHED_CLS, .result = REJECT, .errstr = "invalid mem access", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "reference tracking: use ptr from bpf_sk_fullsock(tp) after release", @@ -725,6 +727,7 @@ .prog_type = BPF_PROG_TYPE_SCHED_CLS, .result = REJECT, .errstr = "invalid mem access", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "reference tracking: use sk after bpf_sk_release(tp)", @@ -747,6 +750,7 @@ .prog_type = BPF_PROG_TYPE_SCHED_CLS, .result = REJECT, .errstr = "invalid mem access", + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "reference tracking: use ptr from bpf_get_listener_sock() after bpf_sk_release(sk)", diff --git a/tools/testing/selftests/bpf/verifier/regalloc.c b/tools/testing/selftests/bpf/verifier/regalloc.c index 4ad7e05de706..bb0dd89dd212 100644 --- a/tools/testing/selftests/bpf/verifier/regalloc.c +++ b/tools/testing/selftests/bpf/verifier/regalloc.c @@ -21,6 +21,7 @@ .fixup_map_hash_48b = { 4 }, .result = ACCEPT, .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc negative", @@ -71,6 +72,7 @@ .fixup_map_hash_48b = { 4 }, .result = ACCEPT, .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc src_reg negative", @@ -97,6 +99,7 @@ .result = REJECT, .errstr = "invalid access to map value, value_size=48 off=44 size=8", .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc and spill", @@ -126,6 +129,7 @@ .fixup_map_hash_48b = { 4 }, .result = ACCEPT, .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc and spill negative", @@ -156,6 +160,7 @@ .result = REJECT, .errstr = "invalid access to map value, value_size=48 off=48 size=8", .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc three regs", @@ -182,6 +187,7 @@ .fixup_map_hash_48b = { 4 }, .result = ACCEPT, .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc after call", @@ -210,6 +216,7 @@ .fixup_map_hash_48b = { 4 }, .result = ACCEPT, .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc in callee", @@ -240,6 +247,7 @@ .fixup_map_hash_48b = { 4 }, .result = ACCEPT, .prog_type = BPF_PROG_TYPE_TRACEPOINT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, { "regalloc, spill, JEQ", diff --git a/tools/testing/selftests/bpf/verifier/wide_access.c b/tools/testing/selftests/bpf/verifier/wide_access.c index ccade9312d21..55af248efa93 100644 --- a/tools/testing/selftests/bpf/verifier/wide_access.c +++ b/tools/testing/selftests/bpf/verifier/wide_access.c @@ -1,4 +1,4 @@ -#define BPF_SOCK_ADDR_STORE(field, off, res, err) \ +#define BPF_SOCK_ADDR_STORE(field, off, res, err, flgs) \ { \ "wide store to bpf_sock_addr." #field "[" #off "]", \ .insns = { \ @@ -11,31 +11,36 @@ .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ .errstr = err, \ + .flags = flgs, \ } /* user_ip6[0] is u64 aligned */ BPF_SOCK_ADDR_STORE(user_ip6, 0, ACCEPT, - NULL), + NULL, 0), BPF_SOCK_ADDR_STORE(user_ip6, 1, REJECT, - "invalid bpf_context access off=12 size=8"), + "invalid bpf_context access off=12 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), BPF_SOCK_ADDR_STORE(user_ip6, 2, ACCEPT, - NULL), + NULL, 0), BPF_SOCK_ADDR_STORE(user_ip6, 3, REJECT, - "invalid bpf_context access off=20 size=8"), + "invalid bpf_context access off=20 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), /* msg_src_ip6[0] is _not_ u64 aligned */ BPF_SOCK_ADDR_STORE(msg_src_ip6, 0, REJECT, - "invalid bpf_context access off=44 size=8"), + "invalid bpf_context access off=44 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), BPF_SOCK_ADDR_STORE(msg_src_ip6, 1, ACCEPT, - NULL), + NULL, 0), BPF_SOCK_ADDR_STORE(msg_src_ip6, 2, REJECT, - "invalid bpf_context access off=52 size=8"), + "invalid bpf_context access off=52 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), BPF_SOCK_ADDR_STORE(msg_src_ip6, 3, REJECT, - "invalid bpf_context access off=56 size=8"), + "invalid bpf_context access off=56 size=8", 0), #undef BPF_SOCK_ADDR_STORE -#define BPF_SOCK_ADDR_LOAD(field, off, res, err) \ +#define BPF_SOCK_ADDR_LOAD(field, off, res, err, flgs) \ { \ "wide load from bpf_sock_addr." #field "[" #off "]", \ .insns = { \ @@ -48,26 +53,31 @@ BPF_SOCK_ADDR_STORE(msg_src_ip6, 3, REJECT, .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ .errstr = err, \ + .flags = flgs, \ } /* user_ip6[0] is u64 aligned */ BPF_SOCK_ADDR_LOAD(user_ip6, 0, ACCEPT, - NULL), + NULL, 0), BPF_SOCK_ADDR_LOAD(user_ip6, 1, REJECT, - "invalid bpf_context access off=12 size=8"), + "invalid bpf_context access off=12 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), BPF_SOCK_ADDR_LOAD(user_ip6, 2, ACCEPT, - NULL), + NULL, 0), BPF_SOCK_ADDR_LOAD(user_ip6, 3, REJECT, - "invalid bpf_context access off=20 size=8"), + "invalid bpf_context access off=20 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), /* msg_src_ip6[0] is _not_ u64 aligned */ BPF_SOCK_ADDR_LOAD(msg_src_ip6, 0, REJECT, - "invalid bpf_context access off=44 size=8"), + "invalid bpf_context access off=44 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), BPF_SOCK_ADDR_LOAD(msg_src_ip6, 1, ACCEPT, - NULL), + NULL, 0), BPF_SOCK_ADDR_LOAD(msg_src_ip6, 2, REJECT, - "invalid bpf_context access off=52 size=8"), + "invalid bpf_context access off=52 size=8", + F_NEEDS_EFFICIENT_UNALIGNED_ACCESS), BPF_SOCK_ADDR_LOAD(msg_src_ip6, 3, REJECT, - "invalid bpf_context access off=56 size=8"), + "invalid bpf_context access off=56 size=8", 0), #undef BPF_SOCK_ADDR_LOAD