On Mon Jun 15, 2026 at 10:42 PM PDT, Yiyang Chen wrote:
> The conntrack lookup and allocation kfuncs take an opts pointer
> together with an opts__sz argument. The verifier checks only the memory
> range described by opts__sz, but the wrappers unconditionally write
> opts->error whenever the internal lookup or allocation helper returns an
> error.
>
> For an invalid size smaller than the end of opts->error, that write can
> land outside the verifier-checked range. Keep returning NULL for invalid
> arguments, but only report the error through opts->error when the
> supplied size includes the field.
>
> This preserves error reporting for the supported 12-byte and 16-byte
> layouts, and for other invalid sizes that still include opts->error.
>
> Fixes: b4c2b9593a1c ("net/netfilter: Add unstable CT lookup helpers for XDP
> and TC-BPF")
> Fixes: d7e79c97c00c ("net: netfilter: Add kfuncs to allocate and insert CT")
> Signed-off-by: Yiyang Chen <[email protected]>
> ---
> net/netfilter/nf_conntrack_bpf.c | 17 +++++++++++++----
> 1 file changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/net/netfilter/nf_conntrack_bpf.c
> b/net/netfilter/nf_conntrack_bpf.c
> index 40c261cd0af38..3c182024ec509 100644
> --- a/net/netfilter/nf_conntrack_bpf.c
> +++ b/net/netfilter/nf_conntrack_bpf.c
> @@ -65,6 +65,11 @@ enum {
> NF_BPF_CT_OPTS_SZ = 16,
> };
>
> +static bool bpf_ct_opts_has_error(u32 opts_len)
> +{
> + return opts_len >= offsetofend(struct bpf_ct_opts, error);
> +}
> +
> static int bpf_nf_ct_tuple_parse(struct bpf_sock_tuple *bpf_tuple,
> u32 tuple_len, u8 protonum, u8 dir,
> struct nf_conntrack_tuple *tuple)
> @@ -298,7 +303,8 @@ bpf_xdp_ct_alloc(struct xdp_md *xdp_ctx, struct
> bpf_sock_tuple *bpf_tuple,
> nfct = __bpf_nf_ct_alloc_entry(dev_net(ctx->rxq->dev), bpf_tuple,
> tuple__sz,
> opts, opts__sz, 10);
> if (IS_ERR(nfct)) {
> - opts->error = PTR_ERR(nfct);
> + if (bpf_ct_opts_has_error(opts__sz))
> + opts->error = PTR_ERR(nfct);
LLMs have no taste.
Above two lines could have been one helper
bpf_ct_opts_set_error(opts, opts__sz, PTR_ERR(nfct));
Or we can do a step further and simplify the code more.
Turn this:
if (IS_ERR(nfct)) {
opts->error = PTR_ERR(nfct);
return NULL;
}
return (struct nf_conn___init *)nfct;
into:
return (struct nf_conn___init *)bpf_ct_opts_result(opts, opts__sz, nfct);
static void *bpf_ct_opts_result(struct bpf_ct_opts *opts, u32 opts__sz, void
*ret)
{
if (!IS_ERR(ret))
return ret;
if (opts__sz >= offsetofend(struct bpf_ct_opts, error))
opts->error = PTR_ERR(ret);
return NULL;
}
This kind of small improvements should be obvious to any human developer.
Please do NOT send us patches straight out of LLM.
Review it first and think how to improve it.
pw-bot: cr