From: Ilya Maximets <i.maximets@ovn.org>
To: Norbert Szetei <norbert@doyensec.com>,
Ilya Maximets <i.maximets@ovn.org>,
Willem de Bruijn <willemb@google.com>,
Pavel Begunkov <asml.silence@gmail.com>
Cc: netdev@vger.kernel.org, "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Aaron Conole <aconole@redhat.com>,
Eelco Chaudron <echaudro@redhat.com>,
Steffen Klassert <steffen.klassert@secunet.com>,
Kuan-Ting Chen <h3xrabbit@gmail.com>,
dev@openvswitch.org, linux-kernel@vger.kernel.org,
"Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: [PATCH net 1/2] openvswitch: only skb_tx_error() a packet we are about to drop
Date: Fri, 14 Aug 2026 14:31:32 +0200 [thread overview]
Message-ID: <00a1176a-8b1f-47b1-9376-349cd08ad313@ovn.org> (raw)
In-Reply-To: <741D4072-50EE-437B-BFC3-CDFE94C93F8A@doyensec.com>
On 8/14/26 1:01 PM, Norbert Szetei wrote:
> Thanks for the review. Sashiko flagged
Hmm. I do not see any reports in either of the instances. Do you have a link?
> that the moved call may still be
> reachable through the RECIRC action, and I confirmed dynamically that it is.
> With 1/2 applied, a flow matching recirc_id 0 exactly, with actions
> RECIRC(1), OUTPUT(0) instead of USERSPACE(unbound), OUTPUT(0), reproduces
> the same issue. So please hold off on 1/2.
>
> Moving the call to the "default" branch assumes that branch only sees a
> packet the datapath owns. For a non-last OVS_ACTION_ATTR_RECIRC,
> clone_execute() does
>
> skb = last ? skb : skb_clone(skb, GFP_ATOMIC);
> ...
> ovs_dp_process_packet(skb, clone);
>
> so a clone lands there while do_execute_actions() carries on with the
> original. The clone shares skb_shinfo() exactly for the skbs this series is
> about, since skb_clone() -> skb_orphan_frags() returns early on
> SKBFL_DONT_ORPHAN and does not copy the frags - so settling the uarg
> through the clone clears SKBFL_SHARED_FRAG for the skb still being
> forwarded.
AFAIU, operations on a cloned skb performed via proper skb helpers must
not affect the original. That's the whole point of the clone. However,
in this case indeed it looks like the skb_tx_copy() just modifies the
shared info not checking if it is shared or not. And this sounds like
a bug in skb_tx_copy().
>
> Removing the call, as I originally suggested, does fix this in my testing.
> If you would still rather keep it, how would you prefer to solve this?
Just removing the call from openvswitch module doesn't solve the problem.
Packet may enter OVS already cloned somewhere else in the stack, and at
any other point in the kernel where skb_tx_copy() is called it may be
operating on a clone of some other skb causing the exact same issue. So,
it needs to be addressed inside the skb_tx_copy() itself.
On the other hand, reading the history of this function, it seems like it
lost of its meaning with commit 1f8b977ab32d ("sock: enable MSG_ZEROCOPY")
from Willem that changed it to just call skb_zcopy_clear(skb, true); This
changed the "false" signaling to "true". So it doesn't even signal an error
anymore.
Later, in commit 753f1ca4e1e5 ("net: introduce managed frags infrastructure")
Pavel added skb_zcopy_downgrade_managed(skb); call that takes extra frag
references. Though it seems pointless for an skb that must be freed right
after.
So, I'm not sure if this function is useful in general. Feels like it is
only harmful as it directly modifies shared data with no regards to clones.
We have two options here:
1. Minimal fix: add something like skb_cloned() guard into skb_tx_copy().
2. Remove skb_tx_copy() entirely (all calls and the definition) as it
seems pointless after 1f8b977ab32d.
Any thoughts? Willem, Pavel, others?
>
> Thanks,
> Norbert
>
>> On Aug 13, 2026, at 12:00, Ilya Maximets <i.maximets@ovn.org> wrote:
>>
>> On 8/13/26 7:47 AM, Norbert Szetei wrote:
>>> queue_userspace_packet() borrows the packet skb -- it only copies it into
>>> a private netlink message (user_skb) and does not own it; on return
>>> do_execute_actions() keeps forwarding it through the flow's remaining
>>> actions. Its error path nevertheless calls skb_tx_error(skb), which via
>>> skb_zcopy_clear() does skb_shinfo(skb)->flags &= ~SKBFL_ALL_ZEROCOPY,
>>> stripping SKBFL_SHARED_FRAG from that live skb (skb_tx_error()'s kerneldoc
>>> says "skb must be freed afterwards").
>>>
>>> For a MSG_ZEROCOPY skb carrying page-cache frags, SKBFL_SHARED_FRAG is
>>> what makes esp_input() skb_cow_data() before in-place AEAD; once it is
>>> stripped a later local ESP-in-UDP delivery decrypts in place over pages
>>> the sender does not own -- an unprivileged page-cache write (the
>>> "Fragnesia" primitive).
>>> do_execute_actions() ignores output_userspace()'s return value, so any
>>> action after a failed USERSPACE upcall inherits the stripped skb.
>>>
>>> Move the skb_tx_error() to the flow-miss drop path - the "default"
>>> branch of ovs_dp_process_packet()'s switch(error), before kfree_skb().
>>>
>>> The call has been here since commit 36d5fe6a0007 ("core, nfqueue,
>>> openvswitch: Orphan frags in skb_zerocopy and handle errors") but was
>>> harmless until esp_input() began relying on SKBFL_SHARED_FRAG to gate
>>> in-place decrypt; only then did stripping it on a still-forwarded skb
>>> become a page-cache write primitive.
>>>
>>> Fixes: 36d5fe6a0007 ("core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors")
>>> Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
>>> Cc: stable@vger.kernel.org
>>> Assisted-by: Claude:claude-opus-5
>>> Signed-off-by: Norbert Szetei <norbert@doyensec.com>
>>> ---
>> Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
>
next prev parent reply other threads:[~2026-08-14 12:31 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 5:41 [PATCH net 0/2] net: don't strip zerocopy frag markers from a forwarded skb Norbert Szetei
2026-08-13 5:47 ` [PATCH net 1/2] openvswitch: only skb_tx_error() a packet we are about to drop Norbert Szetei
2026-08-13 5:49 ` [PATCH net 2/2] net: skbuff: don't skb_tx_error() the source skb in skb_zerocopy() Norbert Szetei
2026-08-13 10:01 ` Ilya Maximets
2026-08-13 10:00 ` [PATCH net 1/2] openvswitch: only skb_tx_error() a packet we are about to drop Ilya Maximets
2026-08-14 11:01 ` Norbert Szetei
2026-08-14 12:31 ` Ilya Maximets [this message]
2026-08-14 13:40 ` Norbert Szetei
2026-08-14 14:52 ` Ilya Maximets
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=00a1176a-8b1f-47b1-9376-349cd08ad313@ovn.org \
--to=i.maximets@ovn.org \
--cc=aconole@redhat.com \
--cc=asml.silence@gmail.com \
--cc=davem@davemloft.net \
--cc=dev@openvswitch.org \
--cc=echaudro@redhat.com \
--cc=edumazet@google.com \
--cc=h3xrabbit@gmail.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=norbert@doyensec.com \
--cc=pabeni@redhat.com \
--cc=steffen.klassert@secunet.com \
--cc=willemb@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox