summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorYonghong Song <yonghong.song@linux.dev>2026-09-12 12:52:01 -0700
committerAlexei Starovoitov <ast@kernel.org>2026-09-12 20:54:17 -0700
commitafe897e89918434be8600250dbdda977aa99f53d (patch)
treeb7d9e63b1a5f804bf5a1afcd703ec5e2b304fffc /kernel
parent3672c60cd1633dbed7a2ea5fd0ebc27cb947b773 (diff)
downloadlinux-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.c5
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;
}