Try creating a dynptr, then overwriting second slot with first slot of another dynptr. Then, the first slot of first dynptr should also be invalidated, but without our fix that does not happen. As a consequence, the unfixed case allows passing first dynptr (as the kernel check only checks for slot_type and then first_slot == true). Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> --- .../testing/selftests/bpf/progs/dynptr_fail.c | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/dynptr_fail.c b/tools/testing/selftests/bpf/progs/dynptr_fail.c index 9477c238af57..cf2d12329a1e 100644 --- a/tools/testing/selftests/bpf/progs/dynptr_fail.c +++ b/tools/testing/selftests/bpf/progs/dynptr_fail.c @@ -834,3 +834,69 @@ int dynptr_var_off_overwrite(struct __sk_buff *ctx) ); return 0; } + +SEC("?tc") +__failure __msg("cannot overwrite referenced dynptr") __log_level(2) +int dynptr_partial_slot_invalidate(struct __sk_buff *ctx) +{ + asm volatile ( + "r6 = %[ringbuf] ll;" + "r7 = %[array_map4] ll;" + "r1 = r7;" + "r2 = r10;" + "r2 += -8;" + "r9 = 0;" + "*(u64 *)(r2 + 0) = r9;" + "r3 = r2;" + "r4 = 0;" + "r8 = r2;" + "call %[bpf_map_update_elem];" + "r1 = r7;" + "r2 = r8;" + "call %[bpf_map_lookup_elem];" + "if r0 != 0 goto sjmp1;" + "exit;" + "sjmp1:" + "r7 = r0;" + "r1 = r6;" + "r2 = 8;" + "r3 = 0;" + "r4 = r10;" + "r4 += -24;" + "call %[bpf_ringbuf_reserve_dynptr];" + "*(u64 *)(r10 - 16) = r9;" + "r1 = r7;" + "r2 = 8;" + "r3 = 0;" + "r4 = r10;" + "r4 += -16;" + "call %[bpf_dynptr_from_mem];" + "r1 = r10;" + "r1 += -512;" + "r2 = 488;" + "r3 = r10;" + "r3 += -24;" + "r4 = 0;" + "r5 = 0;" + "call %[bpf_dynptr_read];" + "r8 = 1;" + "if r0 != 0 goto sjmp2;" + "r8 = 0;" + "sjmp2:" + "r1 = r10;" + "r1 += -24;" + "r2 = 0;" + "call %[bpf_ringbuf_discard_dynptr];" + : + : __imm(bpf_map_update_elem), + __imm(bpf_map_lookup_elem), + __imm(bpf_ringbuf_reserve_dynptr), + __imm(bpf_ringbuf_discard_dynptr), + __imm(bpf_dynptr_from_mem), + __imm(bpf_dynptr_read), + __imm_addr(ringbuf), + __imm_addr(array_map4) + : __clobber_all + ); + return 0; +} -- 2.39.1