Re: [PATCH bpf-next v2 07/13] bpf: Add verifier support for 16-byte returns in R0:R2
[email protected] Tue, 04 Aug 2026 20:52:19 +0000
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] Kfuncs returning 9-15 byte structs leak uninitialized kernel memory via R2 because the verifier bypasses zero-extension. -- --- Patch [7]: [PATCH bpf-next v2 07/13] bpf: Add verifier support for 16-byte returns in R0:R2 --- commit 5c235db7cbd600a1b91b24fbad96652d702b6b3a Author: Yonghong Song <[email protected]> bpf: Add verifier support for 16-byte returns in R0:R2 This commit adds verifier support for returning values in two registers (R0 and R2) for structures between 9 and 16 bytes or __int128. It adds handling for subprogram and kfunc returns to map the second return register to BPF_REG_2. [ ... ] > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 5584178a0e1c7..60b9e587e0947 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c [ ... ] > @@ -10859,6 +10901,22 @@ static void mark_btf_func_reg_size(struct bpf_verifier_env *env, u32 regno, > return __mark_btf_func_reg_size(env, cur_regs(env), regno, reg_size); > } > > +/* Mark the register(s) holding a @size byte kfunc return value as unknown > + * scalars. All of them are processed the same way, only the size differs: > + * a single register may hold a sub-register sized value, while both halves > + * of a register pair are treated as 64-bit wide. > + */ > +static void mark_kfunc_ret_regs(struct bpf_verifier_env *env, > + struct bpf_reg_state *regs, u32 size) > +{ > + u32 i, nregs = ret_regs_cnt(size); > + > + for (i = 0; i < nregs; i++) { > + mark_reg_unknown(env, regs, ret_regs[i]); > + mark_ret_reg_size(env, regs, ret_regs[i], nregs == 1 ? size : sizeof(u64)); [Severity: Medium] For kfuncs returning a struct between 9 and 15 bytes in size, does forcing sizeof(u64) for both return registers bypass zero-extension for R2? If the native compiler only populates the lower bytes of the second return register (e.g. RDX on x86_64) for a <16 byte struct, the upper bits will be left uninitialized. However, setting the size to sizeof(u64) here sets subreg_def to DEF_NOT_SUBREG for R2, which treats R2 as a fully initialized 64-bit scalar. Since the verifier's zero-extension logic only supports zero-extending the destination register (R0 for calls), couldn't a BPF program performing a 64-bit read of R2 leak up to 7 bytes of uninitialized kernel register state? > + } > +} [ ... ] -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=7