Add a verifier test for scalar += rdonly_untrusted_mem. The program gets a read-only untrusted memory value from bpf_rdonly_cast(..., 0), adds it to a scalar destination, and then applies a bitwise operation to the result.
The addition itself is allowed, but the result must be tracked as a pointer. The verifier should reject the following bitwise operation instead of preserving stale scalar state. Add coverage for scalar -= pointer and scalar ^= pointer as well. This prevents the early return from bypassing normal pointer ALU rejection. Signed-off-by: Nuoqi Gui <[email protected]> --- .../selftests/bpf/progs/mem_rdonly_untrusted.c | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/mem_rdonly_untrusted.c b/tools/testing/selftests/bpf/progs/mem_rdonly_untrusted.c index 5b4453747c23..67633129ed41 100644 --- a/tools/testing/selftests/bpf/progs/mem_rdonly_untrusted.c +++ b/tools/testing/selftests/bpf/progs/mem_rdonly_untrusted.c @@ -77,6 +77,58 @@ int offset_not_tracked(void *ctx) return s; } +SEC("socket") +__failure +__msg("R1 bitwise operator &= on pointer prohibited") +__naked void scalar_add_tracks_pointer(void) +{ + asm volatile ("r1 = 0;" + "r2 = 0;" + "call %[bpf_rdonly_cast];" + "r1 = 0;" + "r1 += r0;" + "r1 &= 1;" + "r0 = 0;" + "exit;" + : + : __imm(bpf_rdonly_cast) + : __clobber_all); +} + +SEC("socket") +__failure +__msg("R1 tried to subtract pointer from scalar") +__naked void scalar_sub_ptr_not_ok(void) +{ + asm volatile ("r1 = 0;" + "r2 = 0;" + "call %[bpf_rdonly_cast];" + "r1 = 0;" + "r1 -= r0;" + "r0 = 0;" + "exit;" + : + : __imm(bpf_rdonly_cast) + : __clobber_all); +} + +SEC("socket") +__failure +__msg("R1 bitwise operator ^= on pointer prohibited") +__naked void scalar_xor_ptr_not_ok(void) +{ + asm volatile ("r1 = 0;" + "r2 = 0;" + "call %[bpf_rdonly_cast];" + "r1 = 0;" + "r1 ^= r0;" + "r0 = 0;" + "exit;" + : + : __imm(bpf_rdonly_cast) + : __clobber_all); +} + SEC("socket") __failure __msg("cannot write into rdonly_untrusted_mem") -- 2.34.1

