diff options
| author | Yonghong Song <yonghong.song@linux.dev> | 2026-09-12 12:52:01 -0700 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-09-12 20:54:17 -0700 |
| commit | afe897e89918434be8600250dbdda977aa99f53d (patch) | |
| tree | b7d9e63b1a5f804bf5a1afcd703ec5e2b304fffc /kernel | |
| parent | 3672c60cd1633dbed7a2ea5fd0ebc27cb947b773 (diff) | |
| download | linux-next-afe897e89918434be8600250dbdda977aa99f53d.tar.gz linux-next-afe897e89918434be8600250dbdda977aa99f53d.zip | |
bpf: Read a kfunc's __sz argument only when it is in a register
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 <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20260912195201.982215-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/verifier.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 617a277c3558..0c6a404167ca 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -13641,13 +13641,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; } |
