Skip to content

Commit 8cbf062

Browse files
Hou TaoAlexei Starovoitov
Hou Tao
authored and
Alexei Starovoitov
committed
bpf: Reject kfunc calls that overflow insn->imm
Now kfunc call uses s32 to represent the offset between the address of kfunc and __bpf_call_base, but it doesn't check whether or not s32 will be overflowed. The overflow is possible when kfunc is in module and the offset between module and kernel is greater than 2GB. Take arm64 as an example, before commit b2eed9b ("arm64/kernel: kaslr: reduce module randomization range to 2 GB"), the offset between module symbol and __bpf_call_base will in 4GB range due to KASLR and may overflow s32. So add an extra checking to reject these invalid kfunc calls. Signed-off-by: Hou Tao <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Yonghong Song <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent d2b94f3 commit 8cbf062

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

kernel/bpf/verifier.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
18421842
struct bpf_kfunc_desc *desc;
18431843
const char *func_name;
18441844
struct btf *desc_btf;
1845+
unsigned long call_imm;
18451846
unsigned long addr;
18461847
int err;
18471848

@@ -1926,9 +1927,17 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
19261927
return -EINVAL;
19271928
}
19281929

1930+
call_imm = BPF_CALL_IMM(addr);
1931+
/* Check whether or not the relative offset overflows desc->imm */
1932+
if ((unsigned long)(s32)call_imm != call_imm) {
1933+
verbose(env, "address of kernel function %s is out of range\n",
1934+
func_name);
1935+
return -EINVAL;
1936+
}
1937+
19291938
desc = &tab->descs[tab->nr_descs++];
19301939
desc->func_id = func_id;
1931-
desc->imm = BPF_CALL_IMM(addr);
1940+
desc->imm = call_imm;
19321941
desc->offset = offset;
19331942
err = btf_distill_func_proto(&env->log, desc_btf,
19341943
func_proto, func_name,

0 commit comments

Comments
 (0)