All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bjoern Doebel <doebel@amazon.de>
To: Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S . Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>, <netdev@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, Bjoern Doebel <doebel@amazon.de>,
	<stable@vger.kernel.org>
Subject: [PATCH net] loopback: orphan zerocopy frags before releasing the sender in loopback_xmit()
Date: Wed, 9 Sep 2026 08:55:42 +0000	[thread overview]
Message-ID: <20260909085542.3370986-1-doebel@amazon.de> (raw)

AF_PACKET PACKET_TX_RING transmission over the loopback interface can
silently corrupt packet payloads in flight. tpacket_fill_skb() builds
the transmit skb using zerocopy frags. loopback_xmit() then calls bare
skb_orphan(), which runs skb->destructor (tpacket_destruct_skb()) and
marks the ring slot TP_STATUS_AVAILABLE, telling userspace the buffer is
reusable while the in-flight skb frags still reference that buffer.

This is ok if the packet gets processed immediately in loopback's xmit
path before userspace gets a chance to reuse the frag buffer. However,
if the packet gets redirected for instance to another CPU (via RPS),
this opens a window where userspace may already write new data into the
frag buffer before the receiver reads the original content.

Reproducer using txring_overwrite from the net:run_afpackettests selftest:

  ip netns add ns && ip -netns ns link set lo up
  ip netns exec ns sh -c \
      'echo 100 > /sys/class/net/lo/queues/rx-0/rps_cpus'
  taskset -c 0 ip netns exec ns ./txring_overwrite

Commit 5cd8d46ea156 ("packet: copy user buffers before orphan or clone")
is meant to trigger this copy from the skb_orphan_frags{_rx}() call
sites, but loopback_xmit() calls bare skb_orphan() before any of them
run. Address this by taking a kernel-private copy of the skb frags
before going down the receive path.

Fixes: 5cd8d46ea156 ("packet: copy user buffers before orphan or clone")
Cc: stable@vger.kernel.org
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Assisted-by: Kiro:claude-opus-5
---
Verified that the reproducer in the commit message fails 100% right now
and no longer fails after the patch.
---
 drivers/net/loopback.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 1fb6ce6843ade..31ae10a9d7911 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -72,6 +72,23 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
 {
 	int len;
 
+	/* The skb_orphan() below will run the skb's destructor, which
+	 * for AF_PACKET TX-ring senders marks the slot as TP_STATUS_AVAILABLE
+	 * again, even though it still has zerocopy frags pointing to it that
+	 * will only be copied later in the receive path's
+	 * skb_orphan_frags_rx(). As such, if the receive path gets deferred,
+	 * for example by RPS steering the packet to another CPU, this creates
+	 * a race where userspace may fill in new data into the frag before the
+	 * old data gets copied out.
+	 *
+	 * Take a kernel-private copy.
+	 */
+	if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) {
+		dev_core_stats_tx_dropped_inc(dev);
+		kfree_skb_reason(skb, SKB_DROP_REASON_SKB_UCOPY_FAULT);
+		return NETDEV_TX_OK;
+	}
+
 	skb_tx_timestamp(skb);
 
 	/* do not fool net_timestamp_check() with various clock bases */
-- 
2.50.1


             reply	other threads:[~2026-09-09  8:55 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-09  8:55 Bjoern Doebel [this message]
2026-09-09 15:03 ` [PATCH net] loopback: orphan zerocopy frags before releasing the sender in loopback_xmit() Willem de Bruijn
2026-09-10  9:51 ` netdev-bot+sashiko

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=20260909085542.3370986-1-doebel@amazon.de \
    --to=doebel@amazon.de \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=stable@vger.kernel.org \
    --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 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.