提交 8cbf062a 编写于 作者: H Hou Tao 提交者: Alexei Starovoitov

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 b2eed9b5 ("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: NHou Tao <houtao1@huawei.com>
Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
Acked-by: NYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20220215065732.3179408-1-houtao1@huawei.com
上级 d2b94f33
...@@ -1842,6 +1842,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset) ...@@ -1842,6 +1842,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
struct bpf_kfunc_desc *desc; struct bpf_kfunc_desc *desc;
const char *func_name; const char *func_name;
struct btf *desc_btf; struct btf *desc_btf;
unsigned long call_imm;
unsigned long addr; unsigned long addr;
int err; int err;
...@@ -1926,9 +1927,17 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset) ...@@ -1926,9 +1927,17 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
return -EINVAL; return -EINVAL;
} }
call_imm = BPF_CALL_IMM(addr);
/* Check whether or not the relative offset overflows desc->imm */
if ((unsigned long)(s32)call_imm != call_imm) {
verbose(env, "address of kernel function %s is out of range\n",
func_name);
return -EINVAL;
}
desc = &tab->descs[tab->nr_descs++]; desc = &tab->descs[tab->nr_descs++];
desc->func_id = func_id; desc->func_id = func_id;
desc->imm = BPF_CALL_IMM(addr); desc->imm = call_imm;
desc->offset = offset; desc->offset = offset;
err = btf_distill_func_proto(&env->log, desc_btf, err = btf_distill_func_proto(&env->log, desc_btf,
func_proto, func_name, func_proto, func_name,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册