Skip to content

Commit 5641536

Browse files
ziyefbkAlexei Starovoitov
authored andcommitted
selftests/bpf: Add tests for BPF_END bitwise tracking
Now BPF_END has bitwise tracking support. This patch adds selftests to cover various cases of BPF_END (`bswap(16|32|64)`, `be(16|32|64)`, `le(16|32|64)`) with bitwise propagation. This patch is based on existing `verifier_bswap.c`, and add several types of new tests: 1. Unconditional byte swap operations: - bswap16/bswap32/bswap64 with unknown bytes 2. Endian conversion operations (architecture-aware): - be16/be32/be64: convert to big-endian * on little-endian: do swap * on big-endian: truncation (16/32-bit) or no-op (64-bit) - le16/le32/le64: convert to little-endian * on big-endian: do swap * on little-endian: truncation (16/32-bit) or no-op (64-bit) Each test simulates realistic networking scenarios where a value is masked with unknown bits (e.g., var_off=(0x0; 0x3f00), range=[0,0x3f00]), then byte-swapped, and the verifier must prove the result stays within expected bounds. Specifically, these selftests are based on dead code elimination: If the BPF verifier can precisely track bitwise through byte swap operations, it can prune the trap path (invalid memory access) that should be unreachable, allowing the program to pass verification. If bitwise tracking is incorrect, the verifier cannot prove the trap is unreachable, causing verification failure. The tests use preprocessor conditionals (#ifdef __BYTE_ORDER__) to verify correct behavior on both little-endian and big-endian architectures, and require Clang 18+ for bswap instruction support. Co-developed-by: Shenghao Yuan <shenghaoyuan0928@163.com> Signed-off-by: Shenghao Yuan <shenghaoyuan0928@163.com> Co-developed-by: Yazhou Tang <tangyazhou518@outlook.com> Signed-off-by: Yazhou Tang <tangyazhou518@outlook.com> Signed-off-by: Tianci Cao <ziye@zju.edu.cn> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20260204111503.77871-3-ziye@zju.edu.cn Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 9d21199 commit 5641536

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

tools/testing/selftests/bpf/progs/verifier_bswap.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,49 @@ __naked void bswap_64(void)
4848
: __clobber_all);
4949
}
5050

51+
#define BSWAP_RANGE_TEST(name, op, in_value, out_value) \
52+
SEC("socket") \
53+
__success __log_level(2) \
54+
__msg("r0 &= {{.*}}; R0=scalar({{.*}},var_off=(0x0; " #in_value "))") \
55+
__msg("r0 = " op " r0 {{.*}}; R0=scalar({{.*}},var_off=(0x0; " #out_value "))") \
56+
__naked void name(void) \
57+
{ \
58+
asm volatile ( \
59+
"call %[bpf_get_prandom_u32];" \
60+
"r0 &= " #in_value ";" \
61+
"r0 = " op " r0;" \
62+
"r2 = " #out_value " ll;" \
63+
"if r0 > r2 goto trap_%=;" \
64+
"r0 = 0;" \
65+
"exit;" \
66+
"trap_%=:" \
67+
"r1 = 42;" \
68+
"r0 = *(u64 *)(r1 + 0);" \
69+
"exit;" \
70+
: \
71+
: __imm(bpf_get_prandom_u32) \
72+
: __clobber_all); \
73+
}
74+
75+
BSWAP_RANGE_TEST(bswap16_range, "bswap16", 0x3f00, 0x3f)
76+
BSWAP_RANGE_TEST(bswap32_range, "bswap32", 0x3f00, 0x3f0000)
77+
BSWAP_RANGE_TEST(bswap64_range, "bswap64", 0x3f00, 0x3f000000000000)
78+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
79+
BSWAP_RANGE_TEST(be16_range, "be16", 0x3f00, 0x3f)
80+
BSWAP_RANGE_TEST(be32_range, "be32", 0x3f00, 0x3f0000)
81+
BSWAP_RANGE_TEST(be64_range, "be64", 0x3f00, 0x3f000000000000)
82+
BSWAP_RANGE_TEST(le16_range, "le16", 0x3f00, 0x3f00)
83+
BSWAP_RANGE_TEST(le32_range, "le32", 0x3f00, 0x3f00)
84+
BSWAP_RANGE_TEST(le64_range, "le64", 0x3f00, 0x3f00)
85+
#else
86+
BSWAP_RANGE_TEST(be16_range, "be16", 0x3f00, 0x3f00)
87+
BSWAP_RANGE_TEST(be32_range, "be32", 0x3f00, 0x3f00)
88+
BSWAP_RANGE_TEST(be64_range, "be64", 0x3f00, 0x3f00)
89+
BSWAP_RANGE_TEST(le16_range, "le16", 0x3f00, 0x3f)
90+
BSWAP_RANGE_TEST(le32_range, "le32", 0x3f00, 0x3f0000)
91+
BSWAP_RANGE_TEST(le64_range, "le64", 0x3f00, 0x3f000000000000)
92+
#endif
93+
5194
#else
5295

5396
SEC("socket")

0 commit comments

Comments
 (0)