Re: [PATCH bpf-next v2 39/43] bpf: Refuse the prologue for an extension that cannot take it
flat view
From: bot+bpf-ci@kernel.org
Date: 2026-10-17 17:16:52
Also in:
bpf
bpf: Refuse the prologue for an extension that cannot take it
TL;DR: The new check may wrongly reject XDP, SK_MSG and CGROUP_SOCKOPT extensions that write packet data, since their prologues emit nothing. Programs that loaded before could fail with -EINVAL, including on stable.
quoted hunk ↗ jump to hunk
diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c --- a/kernel/bpf/fixups.c +++ b/kernel/bpf/fixups.c
[ ... ]
quoted hunk ↗ jump to hunk
@@ -909,6 +928,13 @@ int bpf_convert_ctx_accesses(struct bpf_verifier_env *env) verifier_bug(env, "gen_prologue is null"); return -EFAULT; } + if (env->seen_direct_write && + env->prog->type == BPF_PROG_TYPE_EXT && + !ext_prog_takes_prologue(env)) { + verbose(env, + "Extension writing packet data must take ctx and scalars only\n"); + return -EINVAL; + } cnt = ops->gen_prologue(insn_buf, env->seen_direct_write, env->prog); if (cnt >= INSN_BUF_SIZE) {
Does this check reject extensions that never get a register-touching
prologue?
An extension inherits the verifier ops of its target, and
may_access_direct_pkt_data() sets seen_direct_write for SCHED_CLS,
SCHED_ACT, LWT_XMIT, SK_SKB, XDP, SK_MSG and CGROUP_SOCKOPT. Only the
first four end up in bpf_unclone_prologue(), through tc_cls_act_prologue()
or sk_skb_prologue().
XDP and SK_MSG use bpf_noop_prologue(), and CGROUP_SOCKOPT uses
cg_sockopt_get_prologue(). Both return 0 and emit no instructions:
static int bpf_noop_prologue(struct bpf_insn *insn_buf, bool direct_write,
const struct bpf_prog *prog)
{
/* Neither direct read nor direct write requires any preliminary
* action.
*/
return 0;
}
The new check runs before gen_prologue() and never looks at what the
prologue is, so for these types nothing is patched in front of the
extension and no register is read or clobbered.
An XDP extension that writes packet data is now refused with -EINVAL if its
first argument is not the ctx, or if any other argument is not a scalar.
For example, freplace of:
int f(__u32 idx, struct xdp_md *ctx)
int f(struct xdp_md *ctx, struct cfg *cfg) (ARG_PTR_TO_MEM)
or of any function taking a struct bpf_dynptr * argument.
check_special_kfunc() also sets seen_direct_write for bpf_dynptr_slice_rdwr()
on any dynptr type.
These programs loaded and ran correctly before this patch. Since the patch
carries a Fixes: tag, the load failure would also reach stable kernels.
The commit message says "A program that writes to packet data starts with
bpf_unclone_prologue()". Is that accurate for XDP, SK_MSG and
CGROUP_SOCKOPT?
Would it be better to run the check after ops->gen_prologue() and only
when it returned a non-zero cnt, i.e. when a prologue that assumes R1 is
the ctx is actually emitted?
No later commit in the series (222dc092c64e..64e0b112d688) touches this
check.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/39051545464