summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Szetei <norbert@doyensec.com>2026-08-22 11:15:08 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-09-07 17:18:22 +0200
commit15aa81b390d401abf4b8211042470e9e92e3b7fb (patch)
tree9fb3de0a7777409946f2f35e90b97880ea9fd5c7
parent8670d954ec12900212eeaafaee0c167e6f8a3aca (diff)
downloadlinux-15aa81b390d401abf4b8211042470e9e92e3b7fb.tar.gz
linux-15aa81b390d401abf4b8211042470e9e92e3b7fb.zip
net: skbuff: don't touch shared zerocopy state in skb_tx_error()
commit f66bdb1cc0fcd227a062378f8be0b5873aa5600a upstream. skb_tx_error() completes the zerocopy uarg and clears SKBFL_ALL_ZEROCOPY, and skb_zcopy_downgrade_managed() clears SKBFL_MANAGED_FRAG_REFS. Both live in skb_shinfo(), which every clone shares, while the caller only owns the reference it is about to drop. Through a clone it tells the producer its pages are free and drops SKBFL_SHARED_FRAG for an skb that is still in flight. Open vSwitch reaches this with a non-last OVS_ACTION_ATTR_RECIRC: clone_execute() sends a skb_clone() into ovs_dp_process_packet() while do_execute_actions() keeps forwarding the original, and skb_clone() does not privatise the frags here -- skb_orphan_frags() returns early on SKBFL_DONT_ORPHAN. A flow miss on the clone then strips the marker from the packet still being forwarded, and a later local ESP delivery decrypts in place over frags it does not own privately. Skip it for a cloned skb. Nothing is lost: skb_release_data() clears the zerocopy state once the last reference to the shared data goes. Fixes: 25121173f7b1 ("skb: api to report errors for zero copy skbs") Cc: stable@vger.kernel.org Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Ilya Maximets <i.maximets@ovn.org> Tested-by: Jongmin Jang <payload.jang@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/CFAB292A-674B-4C14-BB2C-BB8830AD5659@doyensec.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/core/skbuff.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index dcb5d025dc08..a3d329b2ccfd 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1403,10 +1403,13 @@ EXPORT_SYMBOL(skb_dump);
*
* Report xmit error if a device callback is tracking this skb.
* skb must be freed afterwards.
+ *
+ * Does nothing for a cloned skb: the zerocopy state lives in
+ * skb_shinfo(), which the clones share.
*/
void skb_tx_error(struct sk_buff *skb)
{
- if (skb) {
+ if (skb && !skb_cloned(skb)) {
skb_zcopy_downgrade_managed(skb);
skb_zcopy_clear(skb, true);
}