Re: [PATCH bpf-next v2 2/5] bpf: track upper 32-bit register halves' liveness in compute_live_registers()
[email protected] Sat, 01 Aug 2026 01:35:08 +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: - [High] Skipping zero-extension for 32-bit kfunc arguments causes ABI violations on architectures that require the caller to extend 32-bit parameters. -- --- Patch [2]: [PATCH bpf-next v2 2/5] bpf: track upper 32-bit register halves' liveness in compute_live_registers() --- commit 2a034896228b7579bf93bf8ae2024cee100ebcba Author: Eduard Zingerman <[email protected]> bpf: track upper 32-bit register halves' liveness in compute_live_registers() This commit extends compute_live_registers() to track the upper and lower register halves' liveness separately. It updates compute_insn_live_regs() to track these bits and infers whether the upper half of a parameter register is used by a kfunc call based on its BTF type size. > diff --git a/kernel/bpf/liveness.c b/kernel/bpf/liveness.c > index ff1e68cc4bd1c..d0bd94c60fee2 100644 > --- a/kernel/bpf/liveness.c > +++ b/kernel/bpf/liveness.c [ ... ] > +static u32 call_use_mask(struct bpf_verifier_env *env, struct bpf_insn *insn) > +{ > + u32 i, use, size, reg_params_num; > + struct bpf_call_summary cs; > + const struct btf_param *p; > + const struct btf_type *t; > + > + if (!bpf_get_call_summary(env, insn, &cs)) > + /* e.g. a bpf-to-bpf call, assume that calls use full 64-bit for each param */ > + return mask_widen(ALL_CALLER_SAVED_REGS & ~BIT(BPF_REG_0)); > + > + if (cs.func_proto) { > + use = 0; > + p = btf_params(cs.func_proto); > + reg_params_num = min(btf_type_vlen(cs.func_proto), MAX_BPF_FUNC_REG_ARGS); > + for (i = 0; i < reg_params_num; i++) { > + t = btf_type_by_id(cs.btf, p[i].type); > + if (IS_ERR(btf_resolve_size(cs.btf, t, &size))) > + goto fallback; > + use |= size <= sizeof(u32) ? reg32_mask(i + 1) : reg64_mask(i + 1); [Severity: High] Does this break the C ABI on architectures that require the caller to zero-extend or sign-extend 32-bit parameters passed in 64-bit registers? By only marking the lower 32 bits as used for smaller parameters with reg32_mask, the upper 32 bits are marked as dead before the kfunc call. Consequently, the verifier computes zext_dst = false for the instruction that previously defined the argument. This causes the JIT to skip inserting a BPF_ZEXT_REG instruction to clear the upper 32 bits on architectures where bpf_jit_needs_zext() is true, such as s390x and PowerPC64. If a BPF program computes a 32-bit value and passes it to a kfunc expecting a 32-bit parameter, the kfunc might operate on garbage data in the upper 32 bits. > + } > + return use; > + } -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=2