BPF List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jakub Sitnicki" <jakub@cloudflare.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH net-next 01/14] bpf: Introduce per-packet metadata storage for BPF programs
Date: Sat, 15 Aug 2026 08:14:51 +0000	[thread overview]
Message-ID: <20260815081451.8817D1F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260814-bpf-meta-inside-skb-ext-v1-1-767edd862656@cloudflare.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] bpf_dynptr_from_skb_ext() mutates skb->extensions without synchronization in TRACING and LSM programs, causing data races.
- [High] bpf_dynptr_from_skb_ext() COWs the SKB extension without invalidating existing dynptr slices in the verifier, leading to a Use-After-Free.
- [High] __bpf_skb_ext_store_bytes() and bpf_skb_ext_pointer() allow lockless mutation of shared SKB extensions on cloned SKBs.
--

--- Patch [1]: [PATCH net-next 01/14] bpf: Introduce per-packet metadata storage for BPF programs ---
commit e0c430f0cc32850ff4a67d41f0ec463446dca9ae
Author: Jakub Sitnicki <jakub@cloudflare.com>

bpf: Introduce per-packet metadata storage for BPF programs

This commit adds a new sk_buff extension (struct bpf_skb_ext) to provide
up to 256 bytes of per-packet storage for BPF programs. The storage is
exposed to BPF programs via the bpf_dynptr_from_skb_ext() kfunc.

> diff --git a/net/core/filter.c b/net/core/filter.c
> index 16845987b2449..2cbb40b392edd 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -12259,6 +12259,48 @@ int __bpf_skb_meta_store_bytes(struct sk_buff *skb, u32 offset,

[ ... ]

> +int __bpf_skb_ext_store_bytes(struct sk_buff *skb, u32 offset,
> +			      const void *from, u32 len, u64 flags)
> +{
> +	struct bpf_skb_ext *ext;
> +
> +	if (unlikely(flags))
> +		return -EINVAL;
> +
> +	ext = skb_ext_find(skb, SKB_EXT_BPF);
> +	if (!ext)
> +		return -ENOENT;
> +
> +	memmove(ext->buf + offset, from, len);

[Severity: High]
Is it safe to directly mutate the extension buffer here without checking if
the SKB is cloned?

If a BPF program creates a writable dynptr, clones the SKB (which increments
the extension's reference count), and then writes to the dynptr, this
memmove() will modify the shared extension block while the cloned SKB might
be executing concurrently on another CPU.

Should this use a mechanism like bpf_try_make_writable() or check
ext->refcnt before mutating to ensure exclusive ownership?

> +	return 0;
> +}
> +#endif /* CONFIG_BPF_SKB_EXT */

[ ... ]

> +__bpf_kfunc int bpf_dynptr_from_skb_ext(struct __sk_buff *skb_, u32 size,
> +					u64 flags,
> +					struct bpf_dynptr *ptr__uninit)
> +{

[ ... ]

> +	ext = skb_ext_add(skb, SKB_EXT_BPF);
> +	if (!ext) {
> +		err = -ENOMEM;
> +		goto error;
> +	}

[Severity: High]
Could this COW operation lead to a use-after-free if existing dynptr slices
are not invalidated?

If a BPF program obtains a direct slice to a read-only SKB extension via
bpf_dynptr_from_skb_ext() and bpf_dynptr_slice(), and then calls
bpf_dynptr_from_skb_ext() again with BPF_SKB_EXT_F_CREATE, this forces a
Copy-On-Write in skb_ext_add(), dropping the reference on the old block.

However, because KF_bpf_dynptr_from_skb_ext is not added to
bpf_is_kfunc_pkt_changing() in the verifier, clear_all_pkt_pointers() won't
be invoked. The previously obtained slice remains valid in the verifier
state, allowing the program to read or write the freed memory.

> +	if (!exists)
> +		memset(ext, 0, sizeof(*ext));
> +out:
> +	bpf_dynptr_init(ptr, skb, BPF_DYNPTR_TYPE_SKB_EXT, 0, size);

[ ... ]

> @@ -12640,6 +12760,21 @@ static int __init bpf_kfunc_init(void)

[ ... ]

> +	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb_ext);
> +	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_kfunc_set_skb_ext);
> +	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_kfunc_set_skb_ext);

[Severity: High]
Can calling bpf_dynptr_from_skb_ext() from TRACING or LSM programs cause
data races on the skb structure?

TRACING and LSM programs can intercept an SKB that is currently shared
(skb->users > 1) and being processed concurrently on multiple CPUs.

Since bpf_dynptr_from_skb_ext() unconditionally calls skb_ext_add(), which
performs lockless read-modify-write operations on skb->active_extensions,
concurrent execution could corrupt the bitfield or overwrite the extension
pointer, leaking the allocated extension block.

> +#endif
>  	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260814-bpf-meta-inside-skb-ext-v1-0-767edd862656@cloudflare.com?part=1

  reply	other threads:[~2026-08-15  8:14 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-14  8:14 [PATCH net-next 00/14] skb extension for BPF metadata Jakub Sitnicki
2026-08-14  8:14 ` [PATCH net-next 01/14] bpf: Introduce per-packet metadata storage for BPF programs Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot [this message]
2026-08-14  8:14 ` [PATCH net-next 02/14] bpf: Allow access to bpf_sock_ops_kern->skb Jakub Sitnicki
2026-08-14  8:14 ` [PATCH net-next 03/14] bpf: Make BPF skb extension survive packet scrubbing Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 04/14] selftests/bpf: Add tests for bpf_dynptr_from_skb_ext Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 05/14] selftests/bpf: Test skb_ext on cloned skbs Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 06/14] selftests/bpf: Test skb_ext survival across veth and GRE Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 07/14] selftests/bpf: Test skb_ext read from cgroup_skb and sk_filter hooks Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 08/14] selftests/bpf: Test skb_ext read from sock_ops and LSM hooks Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 09/14] selftests/bpf: Test skb_ext read from kfree_skb tracepoint Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 10/14] selftests/bpf: Test skb_ext read from netfilter hook Jakub Sitnicki
2026-08-14  8:14 ` [PATCH net-next 11/14] selftests/bpf: Test skb_ext from LWT in, out, and xmit hooks Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 12/14] selftests/bpf: Test skb_ext read from seg6local End.BPF hook Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 13/14] selftests/bpf: Test skb_ext read from sk_skb stream verdict hook Jakub Sitnicki
2026-08-15  8:14   ` sashiko-bot
2026-08-14  8:14 ` [PATCH net-next 14/14] selftests/bpf: Use non-trivial test payload in xdp_context tests Jakub Sitnicki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260815081451.8817D1F00A3D@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=jakub@cloudflare.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox