Skip to content

Commit 1732ebc

Browse files
Pu Lehuiborkmann
authored andcommitted
riscv, bpf: Fix unpredictable kernel crash about RV64 struct_ops
We encountered a kernel crash triggered by the bpf_tcp_ca testcase as show below: Unable to handle kernel paging request at virtual address ff60000088554500 Oops [#1] ... CPU: 3 PID: 458 Comm: test_progs Tainted: G OE 6.8.0-rc1-kselftest_plain #1 Hardware name: riscv-virtio,qemu (DT) epc : 0xff60000088554500 ra : tcp_ack+0x288/0x1232 epc : ff60000088554500 ra : ffffffff80cc7166 sp : ff2000000117ba50 gp : ffffffff82587b60 tp : ff60000087be0040 t0 : ff60000088554500 t1 : ffffffff801ed24e t2 : 0000000000000000 s0 : ff2000000117bbc0 s1 : 0000000000000500 a0 : ff20000000691000 a1 : 0000000000000018 a2 : 0000000000000001 a3 : ff60000087be03a0 a4 : 0000000000000000 a5 : 0000000000000000 a6 : 0000000000000021 a7 : ffffffff8263f880 s2 : 000000004ac3c13b s3 : 000000004ac3c13a s4 : 0000000000008200 s5 : 0000000000000001 s6 : 0000000000000104 s7 : ff2000000117bb00 s8 : ff600000885544c0 s9 : 0000000000000000 s10: ff60000086ff0b80 s11: 000055557983a9c0 t3 : 0000000000000000 t4 : 000000000000ffc4 t5 : ffffffff8154f170 t6 : 0000000000000030 status: 0000000200000120 badaddr: ff60000088554500 cause: 000000000000000c Code: c796 67d7 0000 0000 0052 0002 c13b 4ac3 0000 0000 (0001) 0000 ---[ end trace 0000000000000000 ]--- The reason is that commit 2cd3e37 ("x86/cfi,bpf: Fix bpf_struct_ops CFI") changes the func_addr of arch_prepare_bpf_trampoline in struct_ops from NULL to non-NULL, while we use func_addr on RV64 to differentiate between struct_ops and regular trampoline. When the struct_ops testcase is triggered, it emits wrong prologue and epilogue, and lead to unpredictable issues. After commit 2cd3e37, we can use BPF_TRAMP_F_INDIRECT to distinguish them as it always be set in struct_ops. Fixes: 2cd3e37 ("x86/cfi,bpf: Fix bpf_struct_ops CFI") Signed-off-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Björn Töpel <bjorn@rivosinc.com> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20240123023207.1917284-1-pulehui@huaweicloud.com
1 parent 1347775 commit 1732ebc

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

arch/riscv/net/bpf_jit_comp64.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
795795
struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
796796
struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
797797
struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
798+
bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT;
798799
void *orig_call = func_addr;
799800
bool save_ret;
800801
u32 insn;
@@ -878,7 +879,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
878879

879880
stack_size = round_up(stack_size, 16);
880881

881-
if (func_addr) {
882+
if (!is_struct_ops) {
882883
/* For the trampoline called from function entry,
883884
* the frame of traced function and the frame of
884885
* trampoline need to be considered.
@@ -998,7 +999,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
998999

9991000
emit_ld(RV_REG_S1, -sreg_off, RV_REG_FP, ctx);
10001001

1001-
if (func_addr) {
1002+
if (!is_struct_ops) {
10021003
/* trampoline called from function entry */
10031004
emit_ld(RV_REG_T0, stack_size - 8, RV_REG_SP, ctx);
10041005
emit_ld(RV_REG_FP, stack_size - 16, RV_REG_SP, ctx);

0 commit comments

Comments
 (0)