Commit 60d2c438 authored by Luis Gerhorst's avatar Luis Gerhorst Committed by Alexei Starovoitov
Browse files

bpf: Test nospec after dead stack write in helper



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: default avatarLuis Gerhorst <luis.gerhorst@fau.de>
Reported-by: default avatarYinhao Hu <dddddd@hust.edu.cn>
Reported-by: default avatarKaiyan Mei <M202472210@hust.edu.cn>
Reported-by: default avatarDongliang Mu <dzm91@hust.edu.cn>
Link: https://lore.kernel.org/bpf/7678017d-b760-4053-a2d8-a6879b0dbeeb@hust.edu.cn/
Link: https://lore.kernel.org/r/20260127115912.3026761-3-luis.gerhorst@fau.de


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent cd3b6a3d
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -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";