Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

riscv, bpf: Fix possible infinite tailcall when CONFIG_CFI_CLANG is enabled

When CONFIG_CFI_CLANG is enabled, the number of prologue instructions
skipped by tailcall needs to include the kcfi instruction, otherwise the
TCC will be initialized every tailcall is called, which may result in
infinite tailcalls.

Fixes: e63985ecd226 ("bpf, riscv64/cfi: Support kCFI + BPF on riscv64")
Signed-off-by: Pu Lehui <pulehui@huawei.com>
Acked-by: Björn Töpel <bjorn@kernel.org>
Link: https://lore.kernel.org/r/20241008124544.171161-1-pulehui@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Pu Lehui and committed by
Alexei Starovoitov
30a59cc7 4538a38f

+3 -1
+3 -1
arch/riscv/net/bpf_jit_comp64.c
··· 18 18 #define RV_MAX_REG_ARGS 8 19 19 #define RV_FENTRY_NINSNS 2 20 20 #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) 21 + #define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI_CLANG) ? 1 : 0) 21 22 /* imm that allows emit_imm to emit max count insns */ 22 23 #define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF 23 24 ··· 272 271 if (!is_tail_call) 273 272 emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); 274 273 emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA, 275 - is_tail_call ? (RV_FENTRY_NINSNS + 1) * 4 : 0, /* skip reserved nops and TCC init */ 274 + /* kcfi, fentry and TCC init insns will be skipped on tailcall */ 275 + is_tail_call ? (RV_KCFI_NINSNS + RV_FENTRY_NINSNS + 1) * 4 : 0, 276 276 ctx); 277 277 } 278 278