Commit e0b7b91c72db ("bpf: Support stack arguments for kfunc calls") supported stack arguments for kfunc's. In bpf_kfunc_stack_access_bytes(), the size of a ptr + __sz pair is read from const_reg_vals[] at index 'BPF_REG_1 + arg + 1'. Past the fifth argument that index leaves the argument registers and reaches 6 through 9, which are the callee saved registers R6 through R9. The verifier does record constants for those, so a __sz argument passed on the stack can take the value of an unrelated register as its size. Fix it by guard size_reg which has to be less than or equal to MAX_BPF_FUNC_REG_ARGS. Fixes: e0b7b91c72db ("bpf: Support stack arguments for kfunc calls") Signed-off-by: Yonghong Song --- kernel/bpf/verifier.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 9e79750e2480..fed576b8f7fe 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -13771,13 +13771,14 @@ s64 bpf_kfunc_stack_access_bytes(struct bpf_verifier_env *env, struct bpf_insn * goto out; } - /* ptr + __sz/__szk pair: size is in the next register */ + /* ptr + __sz/__szk pair: the size follows the pointer */ if (arg + 1 < nargs && (btf_param_match_suffix(btf, &args[arg + 1], "__sz") || btf_param_match_suffix(btf, &args[arg + 1], "__szk"))) { int size_reg = BPF_REG_1 + arg + 1; - if (aux->const_reg_mask & BIT(size_reg)) { + if (size_reg <= MAX_BPF_FUNC_REG_ARGS && + (aux->const_reg_mask & BIT(size_reg))) { size = (s64)aux->const_reg_vals[size_reg]; goto out; } -- 2.52.0