mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
bpf: Validate stack arg reads against caller state
check_stack_arg_read() bounds a stack argument index with the callee's BTF-derived argument count, then uses the index in the caller's stack_arg_regs[] array. The array's actual logical length is recorded in caller->out_stack_arg_cnt, so the bound and indexed object can diverge. A crafted BPF_PROG_LOAD can use an argument mismatch to mark a static subprogram's BTF information unreliable. Later calls return from btf_check_subprog_call() before check_outgoing_stack_args(), while check_func_call() continues the static call on -EINVAL. The callee can then read a slot that the caller never allocated or initialized. The earlier commit4286f5deee("bpf: Validate outgoing stack args when btf_prepare_func_args fails") closed this hole for the first call, but not for later calls after the subprogram has been marked unreliable. Callbacks have a related problem. The verifier can make incoming stack arguments readable from outgoing slots at the helper call site. However, helpers and kfuncs invoke callbacks through an ABI that passes at most five arguments, so the runtime callback receives no stack arguments. Async callback verification can also reach check_stack_arg_read() without a caller frame. On x86-64, KASAN reports the direct-call out-of-bounds copy as: BUG: KASAN: slab-out-of-bounds in check_load_mem+0xb51/0xc60 Read of size 80 at addr ffff8881009af550 by task poc/131 Call Trace: check_stack_arg_read at kernel/bpf/verifier.c:4234 (inlined by) check_load_mem at kernel/bpf/verifier.c:6645 do_check_common at kernel/bpf/verifier.c:19568 bpf_check at kernel/bpf/verifier.c:21318 bpf_prog_load at kernel/bpf/syscall.c:3134 Reject callback subprograms with incoming stack arguments before their state is pushed. For direct calls, retrieve the slot with bpf_get_spilled_stack_arg(), which validates the index against the caller's out_stack_arg_cnt and rejects uninitialized slots before copying the register state. Fixes:0f6bd5e7a8("bpf: Support stack arguments for bpf functions") Reported-by: <co+eada64ce90ecebce@bugs.sh> Signed-off-by: Weiming Shi <bestswngs@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261026015250.1674676-1-bestswngs@gmail.com
This commit is contained in:
parent
00d2cdf163
commit
90aedf8854
|
|
@ -4666,7 +4666,12 @@ static int check_stack_arg_read(struct bpf_verifier_env *env, struct bpf_func_st
|
|||
}
|
||||
|
||||
caller = vstate->frame[vstate->curframe - 1];
|
||||
arg = &caller->stack_arg_regs[spi];
|
||||
arg = bpf_get_spilled_stack_arg(spi, caller);
|
||||
if (!arg) {
|
||||
verbose(env, "invalid read from uninitialized stack arg off %d\n", off);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
cur = vstate->frame[vstate->curframe];
|
||||
bpf_diag_mod_begin(env, &cur->regs[dst_regno], arg, BPF_DIAG_MOD_WRITE);
|
||||
cur->regs[dst_regno] = *arg;
|
||||
|
|
@ -11451,6 +11456,10 @@ static int push_callback_call(struct bpf_verifier_env *env, struct bpf_insn *ins
|
|||
err = btf_check_subprog_call(env, subprog);
|
||||
if (err == -EFAULT)
|
||||
return err;
|
||||
if (bpf_in_stack_arg_cnt(&env->subprog_info[subprog])) {
|
||||
verbose(env, "callback subprog cannot have stack args\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* set_callee_state is used for direct subprog calls, but we are
|
||||
* interested in validating only BPF helpers that can call subprogs as
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user