From: Martin KaFai Lau <martin.lau@linux.dev>
To: Jakub Sitnicki <jakub@cloudflare.com>
Cc: "Alexei Starovoitov" <ast@kernel.org>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Arthur Fabre" <arthur@arthurfabre.com>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Eric Dumazet" <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
"Jesper Dangaard Brouer" <hawk@kernel.org>,
"Jesse Brandeburg" <jbrandeburg@cloudflare.com>,
"Joanne Koong" <joannelkoong@gmail.com>,
"Lorenzo Bianconi" <lorenzo@kernel.org>,
"Toke Høiland-Jørgensen" <thoiland@redhat.com>,
"Yan Zhai" <yan@cloudflare.com>,
kernel-team@cloudflare.com, netdev@vger.kernel.org,
bpf@vger.kernel.org, "Stanislav Fomichev" <sdf@fomichev.me>
Subject: Re: [PATCH bpf-next v6 9/9] selftests/bpf: Cover metadata access from a modified skb clone
Date: Fri, 8 Aug 2025 14:31:33 -0700 [thread overview]
Message-ID: <e30d66a8-c4de-4d81-880d-36d996b67854@linux.dev> (raw)
In-Reply-To: <87h5yi82gp.fsf@cloudflare.com>
On 8/8/25 4:41 AM, Jakub Sitnicki wrote:
> On Thu, Aug 07, 2025 at 05:33 PM -07, Martin KaFai Lau wrote:
>> On 8/4/25 5:52 AM, Jakub Sitnicki wrote:
>>> +/* Check that skb_meta dynptr is empty */
>>> +SEC("tc")
>>> +int ing_cls_dynptr_empty(struct __sk_buff *ctx)
>>> +{
>>> + struct bpf_dynptr data, meta;
>>> + struct ethhdr *eth;
>>> +
>>> + bpf_dynptr_from_skb(ctx, 0, &data);
>>> + eth = bpf_dynptr_slice_rdwr(&data, 0, NULL, sizeof(*eth));
>>
>> If this is bpf_dynptr_slice() instead of bpf_dynptr_slice_rdwr() and...
>>
>>> + if (!eth)
>>> + goto out;
>>> + /* Ignore non-test packets */
>>> + if (eth->h_proto != 0)
>>> + goto out;
>>> + /* Packet write to trigger unclone in prologue */
>>> + eth->h_proto = 42;
>>
>> ... remove this eth->h_proto write.
>>
>> Then bpf_dynptr_write() will succeed. like,
>>
>> bpf_dynptr_from_skb(ctx, 0, &data);
>> eth = bpf_dynptr_slice(&data, 0, NULL, sizeof(*eth));
>> if (!eth)
>> goto out;
>>
>> /* Ignore non-test packets */
>> if (eth->h_proto != 0)
>> goto out;
>>
>> bpf_dynptr_from_skb_meta(ctx, 0, &meta);
>> /* Expect write to fail because skb is a clone. */
>> err = bpf_dynptr_write(&meta, 0, (void *)eth, sizeof(*eth), 0);
>>
>> The bpf_dynptr_write for a skb dynptr will do the pskb_expand_head(). The
>> skb_meta dynptr write is only a memmove. It probably can also do
>> pskb_expand_head() and change it to keep the data_meta.
>>
>> Another option is to set the DYNPTR_RDONLY_BIT in bpf_dynptr_from_skb_meta() for
>> a clone skb. This restriction can be removed in the future.
>
> Ah, crap. Forgot that bpf_dynptr_write->bpf_skb_store_bytes calls
> bpf_try_make_writable(skb) behind the scenes.
>
> OK, so the head page copy for skb clone happens either in BPF prologue
> or lazily inside bpf_dynptr_write() call today.
>
> Best if I make it consistent for skb_meta from the start, no?
>
> Happy to take a shot at tweaking pskb_expand_head() to keep the metadata
> in tact, while at it.
There is no write helper for the data_meta now. It must directly write to
skb->data_meta, so data_meta is a read-only for a clone now. I guess the current
use case is mostly for tc to read the data_meta immediately after the xdp prog
has added it (fwiw, it is how we tried to use it also), so it is usually not a
clone (?). Not even sure if it currently has a write use case considering, 1)
there is no bpf_"skb"_adjust_meta, and 2) the upper layer cannot use it.
No strong opinion to either copy the metadata on a clone or set the dynptr
rdonly for a clone. I am ok with either way.
A brain dump:
On one hand, it is hard to comment without visibility on how will it look like
when data_meta can be preserved in the future, e.g. what may be the overhead but
there is flags in bpf_dynptr_from_skb_meta and bpf_dynptr_write, so there is
some flexibility. On the other hand, having a copy will be less surprise on the
clone skb like what we have discovered in this and the earlier email thread but
I suspect there is actually no write use case on the skb data_meta now.
next prev parent reply other threads:[~2025-08-08 21:31 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-04 12:52 [PATCH bpf-next v6 0/9] Add a dynptr type for skb metadata for TC BPF Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 1/9] bpf: Add dynptr type for skb metadata Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 2/9] bpf: Enable read/write access to skb metadata through a dynptr Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 3/9] selftests/bpf: Cover verifier checks for skb_meta dynptr type Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 4/9] selftests/bpf: Pass just bpf_map to xdp_context_test helper Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 5/9] selftests/bpf: Parametrize test_xdp_context_tuntap Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 6/9] selftests/bpf: Cover read access to skb metadata via dynptr Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 7/9] selftests/bpf: Cover write " Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 8/9] selftests/bpf: Cover read/write to skb metadata at an offset Jakub Sitnicki
2025-08-04 12:52 ` [PATCH bpf-next v6 9/9] selftests/bpf: Cover metadata access from a modified skb clone Jakub Sitnicki
2025-08-08 0:33 ` Martin KaFai Lau
2025-08-08 11:41 ` Jakub Sitnicki
2025-08-08 21:31 ` Martin KaFai Lau [this message]
2025-08-12 13:12 ` Jakub Sitnicki
2025-08-12 18:20 ` Martin KaFai Lau
2025-08-13 10:51 ` 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=e30d66a8-c4de-4d81-880d-36d996b67854@linux.dev \
--to=martin.lau@linux.dev \
--cc=andrii@kernel.org \
--cc=arthur@arthurfabre.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=jakub@cloudflare.com \
--cc=jbrandeburg@cloudflare.com \
--cc=joannelkoong@gmail.com \
--cc=kernel-team@cloudflare.com \
--cc=kuba@kernel.org \
--cc=lorenzo@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=sdf@fomichev.me \
--cc=thoiland@redhat.com \
--cc=yan@cloudflare.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.