Without the fix from the previous commit, the selftest fails:

$ ./tools/testing/selftests/bpf/vmtest.sh -- \
        ./test_progs -t verifier_unpriv
[...]
run_subtest:PASS:obj_open_mem 0 nsec
libbpf: BTF loading error: -EPERM
libbpf: Error loading .BTF into kernel: -EPERM. BTF is optional, ignoring.
libbpf: prog 'unpriv_nospec_after_helper_stack_write': BPF program load failed: 
-EFAULT
libbpf: prog 'unpriv_nospec_after_helper_stack_write': failed to load: -EFAULT
libbpf: failed to load object 'verifier_unpriv'
run_subtest:FAIL:unexpected_load_failure unexpected error: -14 (errno 14)
VERIFIER LOG:
=============
0: R1=ctx() R10=fp0
0: (b7) r0 = 0                        ; R0=P0
1: (55) if r0 != 0x1 goto pc+6 2: R0=Pscalar() R1=ctx() R10=fp0
2: (b7) r2 = 0                        ; R2=P0
3: (bf) r3 = r10                      ; R3=fp0 R10=fp0
4: (07) r3 += -16                     ; R3=fp-16
5: (b7) r4 = 4                        ; R4=P4
6: (b7) r5 = 0                        ; R5=P0
7: (85) call bpf_skb_load_bytes_relative#68
verifier bug: speculation barrier after jump instruction may not have the 
desired effect (BPF_CLASS(insn->code) == BPF_JMP || BPF_CLASS(insn->code) == 
BPF_JMP32)
processed 9 insns (limit 1000000) max_states_per_insn 0 total_states 0 
peak_states 0 mark_read 0
=============
[...]

The test is based on the PoC from the report.

Signed-off-by: Luis Gerhorst <[email protected]>
Reported-by: Yinhao Hu <[email protected]>
Reported-by: Kaiyan Mei <[email protected]>
Reported-by: Dongliang Mu <[email protected]>
Link: 
https://lore.kernel.org/bpf/[email protected]/
---
 .../selftests/bpf/progs/verifier_unpriv.c     | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/verifier_unpriv.c 
b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
index 28b4f7035ceb..8ee1243e62a8 100644
--- a/tools/testing/selftests/bpf/progs/verifier_unpriv.c
+++ b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
@@ -950,4 +950,26 @@ l3_%=:     r0 = 0;                                         
\
 "      ::: __clobber_all);
 }
 
+SEC("socket")
+__description("unpriv: nospec after dead stack write in helper")
+__success __success_unpriv
+__retval(0)
+/* Dead code sanitizer rewrites the call to `goto -1`. */
+__naked void unpriv_dead_helper_stack_write_nospec_result(void)
+{
+       asm volatile ("                                 \
+       r0 = 0;                                         \
+       if r0 != 1 goto l0_%=;                          \
+       r2 = 0;                                         \
+       r3 = r10;                                       \
+       r3 += -16;                                      \
+       r4 = 4;                                         \
+       r5 = 0;                                         \
+       call %[bpf_skb_load_bytes_relative];            \
+l0_%=: exit;                                           \
+"      :
+       : __imm(bpf_skb_load_bytes_relative)
+       : __clobber_all);
+}
+
 char _license[] SEC("license") = "GPL";
-- 
2.52.0


Reply via email to