selftests/bpf: Add dynptr var_off tests
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Sat, 21 Jan 2023 00:22:39 +0000 (05:52 +0530)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 21 Jan 2023 01:55:03 +0000 (17:55 -0800)
Ensure that variable offset is handled correctly, and verifier takes
both fixed and variable part into account. Also ensures that only
constant var_off is allowed.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20230121002241.2113993-11-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/dynptr_fail.c

index f1e0478..2d899f2 100644 (file)
@@ -794,3 +794,43 @@ int dynptr_pruning_type_confusion(struct __sk_buff *ctx)
        );
        return 0;
 }
+
+SEC("?tc")
+__failure __msg("dynptr has to be at a constant offset") __log_level(2)
+int dynptr_var_off_overwrite(struct __sk_buff *ctx)
+{
+       asm volatile (
+               "r9 = 16;                               \
+                *(u32 *)(r10 - 4) = r9;                \
+                r8 = *(u32 *)(r10 - 4);                \
+                if r8 >= 0 goto vjmp1;                 \
+                r0 = 1;                                \
+                exit;                                  \
+       vjmp1:                                          \
+                if r8 <= 16 goto vjmp2;                \
+                r0 = 1;                                \
+                exit;                                  \
+       vjmp2:                                          \
+                r8 &= 16;                              \
+                r1 = %[ringbuf] ll;                    \
+                r2 = 8;                                \
+                r3 = 0;                                \
+                r4 = r10;                              \
+                r4 += -32;                             \
+                r4 += r8;                              \
+                call %[bpf_ringbuf_reserve_dynptr];    \
+                r9 = 0xeB9F;                           \
+                *(u64 *)(r10 - 16) = r9;               \
+                r1 = r10;                              \
+                r1 += -32;                             \
+                r1 += r8;                              \
+                r2 = 0;                                \
+                call %[bpf_ringbuf_discard_dynptr];    "
+               :
+               : __imm(bpf_ringbuf_reserve_dynptr),
+                 __imm(bpf_ringbuf_discard_dynptr),
+                 __imm_addr(ringbuf)
+               : __clobber_all
+       );
+       return 0;
+}