mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers
@ 2026-10-08 21:02 Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 01/10] net: skbuff: add skb_drop_empty_frags() Josef Bacik
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

v1: https://lore.kernel.org/all/20261007-b4-pskb-pull-tail-drivers-v1-0-9512b0fb977b@toxicpanda.com/

v1->v2:
- New 1/10: skb_drop_empty_frags(). xen-netfront, netxen and qlcnic
  relied on __pskb_pull_tail() releasing zero-length frags even when
  there's nothing to pull, which pskb_may_pull() doesn't do (Sashiko).
- xen-netfront, netxen, qlcnic: call skb_drop_empty_frags() after
  pskb_may_pull().
- skb_drop_empty_frags() checked with a boot-time test under KASAN and
  kmemleak, on cloned and uncloned skbs.

--- Original email (v1) ---

__pskb_pull_tail() is the slow path behind pskb_may_pull() and
__skb_linearize(), and drivers shouldn't be calling it directly.  It
takes the number of bytes to pull relative to the current head and does
no bounds checking on it.  Ask for more than the skb holds and it BUG()s
in skb_copy_bits().  Ask for a negative amount, which is what a caller
computing "len - skb_headlen(skb)" gets once the head is already long
enough, and skb_copy_bits() is handed a length of nearly 4GB to copy
into the head.  Under KASAN that shows up as an out-of-bounds read of
size 4294967288, after which __pskb_pull_tail() returns success with the
skb's head and paged lengths no longer matching its frags.

It also returns NULL on failure with nothing making the caller look at
it.  Eight network drivers call it directly and four of them don't
check.  All four are RX paths where a failed pull is followed by
eth_type_trans() or skb_pull(), which BUG() in __skb_pull() once the
head is shorter than what they pull.  As far as I can tell none of the
four can fail today, since the skb is fresh, isn't shared and has room
in the head, but that only holds because of how each driver happens to
allocate.

pskb_may_pull() and __skb_linearize() take the length the head should
end up with, check it against skb->len and fail cleanly, which is what
every one of these callers wants.  Convert all eight drivers to them,
check the result, and drop the packet on failure.

The last patch makes skb_condense() check its pull as well.  It can't
fail there today, but it would undercount truesize if it ever did.

The callers left in aoe and xen-netfront are fixed separately, through
the block and net trees:

  https://lore.kernel.org/r/20261007-b4-aoe-short-packets-v1-1-db5155f7bb9c@toxicpanda.com
  https://lore.kernel.org/r/20261007-b4-xen-netfront-short-head-v1-1-12d7113a7e4e@toxicpanda.com

Once those are in I'd like to stop exporting __pskb_pull_tail() so new
drivers can't pick it up.

Testing: every touched file builds with W=1 on x86_64 allmodconfig
(ftmac100 on i386, it's 32-bit only).  e1000e under QEMU, which hits
the converted TSO workaround on every TSO packet, passes TCP traffic
between two emulated 82574Ls, and with failslab failing 5% of atomic
allocations the failed pulls drop the packet and nothing falls over.
The same setup with jumbo frames and copybreak off makes
skb_condense() pull frag data into the head tens of thousands of times
a run.  xen-netfront ran as a Xen HVM guest under QEMU's KVM Xen
emulation, with the backend changed to spread frames over 18 and 19 RX
slots, which takes the converted pull in xennet_fill_frags() and its
overflow path.  The other drivers are compile tested only.

Thanks,
Josef

---
Changes in v2:
- Link to v1: https://patch.msgid.link/20261007-b4-pskb-pull-tail-drivers-v1-0-9512b0fb977b@toxicpanda.com

---
Josef Bacik (10):
      net: skbuff: add skb_drop_empty_frags()
      net: ftmac100: check for failure when pulling in the RX header
      net/mlx5e: check for failure when pulling the Ethernet header after XDP
      net: niu: check for failure when pulling in the RX header
      xen/netfront: check for failure when pulling in xennet_fill_frags()
      e1000: use pskb_may_pull() in the 82544 TSO workaround
      e1000e: use pskb_may_pull() in the 82571/2/3 TSO workaround
      netxen: use pskb_may_pull() to pull excess TX frags into the head
      qlcnic: use pskb_may_pull() to pull excess TX frags into the head
      net: skbuff: don't reset truesize in skb_condense() if the pull fails

 drivers/net/ethernet/faraday/ftmac100.c            | 10 ++++-
 drivers/net/ethernet/intel/e1000/e1000_main.c      |  5 +--
 drivers/net/ethernet/intel/e1000e/netdev.c         |  4 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c    |  9 +++--
 .../net/ethernet/qlogic/netxen/netxen_nic_main.c   |  3 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |  3 +-
 drivers/net/ethernet/sun/niu.c                     |  6 ++-
 drivers/net/xen-netfront.c                         | 26 +++++++------
 include/linux/skbuff.h                             |  1 +
 net/core/skbuff.c                                  | 43 +++++++++++++++++++++-
 10 files changed, 84 insertions(+), 26 deletions(-)
---
base-commit: a5e7d8e446af9803e37a3b6a4d416fb41178348f
change-id: 20261006-b4-pskb-pull-tail-drivers-ff4fb2964e1a


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 01/10] net: skbuff: add skb_drop_empty_frags()
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 02/10] net: ftmac100: check for failure when pulling in the RX header Josef Bacik
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

__pskb_pull_tail() releases every zero-length page frag as it walks the
frags array, even when it's asked to pull nothing.  Some drivers depend
on that.  xen-netfront calls it with a zero count on purpose to make
room when a backend fills the frags with empty slots, see commit
d81c5054a5d1 ("xen/netfront: tolerate frags with no data").  netxen and
qlcnic get the same effect when the frags they pull to fit a TX
descriptor happen to be empty.

pskb_may_pull() returns before getting there when the head already
holds the requested length, so these drivers can't simply switch to
it.  Add skb_drop_empty_frags() to do just that part, unsharing the skb
first if it's cloned like __pskb_pull_tail() does.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 include/linux/skbuff.h |  1 +
 net/core/skbuff.c      | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 27ec1e38c828..c1295f6baf6d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2840,6 +2840,7 @@ static inline void *skb_pull_inline(struct sk_buff *skb, unsigned int len)
 void *skb_pull_data(struct sk_buff *skb, size_t len);
 
 void *__pskb_pull_tail(struct sk_buff *skb, int delta);
+int skb_drop_empty_frags(struct sk_buff *skb, gfp_t gfp);
 
 static __always_inline enum skb_drop_reason
 pskb_may_pull_reason(struct sk_buff *skb, unsigned int len)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 43ebe61c7fc4..f798118df112 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3004,6 +3004,46 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta)
 }
 EXPORT_SYMBOL(__pskb_pull_tail);
 
+/**
+ *	skb_drop_empty_frags - release the zero-length page frags of an skb
+ *	@skb: buffer to clean up
+ *	@gfp: allocation priority, used if @skb has to be unshared
+ *
+ *	Releases every page frag of @skb that holds no data and closes up
+ *	the frags array, so the remaining frags keep their order.  The
+ *	frag_list is left alone.  A cloned @skb is unshared first, since
+ *	the frags array is shared between clones.
+ *
+ *	Returns 0 on success, or -ENOMEM if @skb had to be unshared and
+ *	that failed, in which case @skb is unchanged.
+ */
+int skb_drop_empty_frags(struct sk_buff *skb, gfp_t gfp)
+{
+	struct skb_shared_info *shinfo = skb_shinfo(skb);
+	int i, k;
+
+	for (i = 0; i < shinfo->nr_frags; i++)
+		if (!skb_frag_size(&shinfo->frags[i]))
+			break;
+	if (i == shinfo->nr_frags)
+		return 0;
+
+	if (skb_unclone(skb, gfp))
+		return -ENOMEM;
+
+	shinfo = skb_shinfo(skb);
+	for (i = 0, k = 0; i < shinfo->nr_frags; i++) {
+		if (!skb_frag_size(&shinfo->frags[i])) {
+			skb_frag_unref(skb, i);
+			continue;
+		}
+		shinfo->frags[k++] = shinfo->frags[i];
+	}
+	shinfo->nr_frags = k;
+	return 0;
+}
+EXPORT_SYMBOL(skb_drop_empty_frags);
+
 /**
  *	skb_copy_bits - copy bits from skb to kernel buffer
  *	@skb: source skb

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 02/10] net: ftmac100: check for failure when pulling in the RX header
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 01/10] net: skbuff: add skb_drop_empty_frags() Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 03/10] net/mlx5e: check for failure when pulling the Ethernet header after XDP Josef Bacik
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

ftmac100_rx_packet() uses __pskb_pull_tail() to pull either the
Ethernet header or, for small frames, the whole frame into the skb
head, and ignores the return value.  If that pull ever failed,
eth_type_trans() would find less than ETH_HLEN in the head and BUG()
in __skb_pull().

It doesn't fail today because the skb is freshly allocated, isn't
shared and has room in the head, but that's only true because of how
this driver allocates.  Use pskb_may_pull() for the header and
__skb_linearize() for small frames, which is what the two pulls are
doing, and drop the frame if either fails.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/ethernet/faraday/ftmac100.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
index 40ba001d4b3f..a1eb04ead2d8 100644
--- a/drivers/net/ethernet/faraday/ftmac100.c
+++ b/drivers/net/ethernet/faraday/ftmac100.c
@@ -469,15 +469,21 @@ static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed)
 	if (length > 128) {
 		skb->truesize += PAGE_SIZE;
 		/* We pull the minimum amount into linear part */
-		__pskb_pull_tail(skb, ETH_HLEN);
+		ret = pskb_may_pull(skb, ETH_HLEN);
 	} else {
 		/* Small frames are copied into linear part to free one page */
-		__pskb_pull_tail(skb, length);
+		ret = !__skb_linearize(skb);
 	}
 	ftmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);
 
 	ftmac100_rx_pointer_advance(priv);
 
+	if (unlikely(!ret)) {
+		netdev->stats.rx_dropped++;
+		kfree_skb(skb);
+		return true;
+	}
+
 	skb->protocol = eth_type_trans(skb, netdev);
 
 	netdev->stats.rx_packets++;

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 03/10] net/mlx5e: check for failure when pulling the Ethernet header after XDP
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 01/10] net: skbuff: add skb_drop_empty_frags() Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 02/10] net: ftmac100: check for failure when pulling in the RX header Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 04/10] net: niu: check for failure when pulling in the RX header Josef Bacik
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

When an XDP program leaves less than ETH_HLEN in the linear part of a
multi-buffer packet, mlx5e_skb_from_cqe_mpwrq_nonlinear() pulls the rest
of the Ethernet header in from the frags with __pskb_pull_tail() and
ignores the return value.  If that pull fails, eth_type_trans() later
finds less than ETH_HLEN in the head and BUG()s in __skb_pull().

Use pskb_may_pull() instead and drop the packet if it fails.  Pulling
min(ETH_HLEN, skb->len) keeps today's behaviour for a frame shorter
than an Ethernet header.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index e3f915beebe1..b1e1e30a77e2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -2060,9 +2060,12 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
 				pagep->frags++;
 			while (++pagep < frag_page);
 
-			if (len < ETH_HLEN)
-				__pskb_pull_tail(skb, min(ETH_HLEN - len,
-							  skb->data_len));
+			if (len < ETH_HLEN &&
+			    !pskb_may_pull(skb, min(ETH_HLEN, skb->len))) {
+				rq->stats->buff_alloc_err++;
+				dev_kfree_skb_any(skb);
+				return NULL;
+			}
 		}
 	} else {
 		if (xdp_buff_has_frags(&mxbuf->xdp)) {

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 04/10] net: niu: check for failure when pulling in the RX header
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (2 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 03/10] net/mlx5e: check for failure when pulling the Ethernet header after XDP Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 05/10] xen/netfront: check for failure when pulling in xennet_fill_frags() Josef Bacik
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

niu_process_rx_pkt() uses __pskb_pull_tail() to pull the hardware RX
header and the Ethernet header into the skb head, and ignores the
return value.  If that pull failed, the skb_pull() of the RX header
right after it would BUG() in __skb_pull().

It doesn't fail today because the skb is freshly allocated, isn't
shared and has room in the head.  Use pskb_may_pull() anyway and drop
the packet if it fails, rather than depending on that.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/ethernet/sun/niu.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index c74a97fe5464..d1c0e868004d 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -3488,7 +3488,11 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
 
 	len += sizeof(*rh);
 	len = min_t(int, len, sizeof(*rh) + VLAN_ETH_HLEN);
-	__pskb_pull_tail(skb, len);
+	if (unlikely(!pskb_may_pull(skb, len))) {
+		rp->rx_dropped++;
+		kfree_skb(skb);
+		return num_rcr;
+	}
 
 	rh = (struct rx_pkt_hdr1 *) skb->data;
 	if (np->dev->features & NETIF_F_RXHASH)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 05/10] xen/netfront: check for failure when pulling in xennet_fill_frags()
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (3 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 04/10] net: niu: check for failure when pulling in the RX header Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 06/10] e1000: use pskb_may_pull() in the 82544 TSO workaround Josef Bacik
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

When the skb already has MAX_SKB_FRAGS frags, xennet_fill_frags() calls
__pskb_pull_tail() to free up a frag slot.  That frees slots in two
ways: it pulls the start of the packet into the head, and it releases
empty frags, even when there's nothing left to pull.  The second part
is what commit d81c5054a5d1 ("xen/netfront: tolerate frags with no
data") relies on.  The return value is ignored, which works out only
because the nr_frags check right after it drops the packet if no slot
was freed.

Use pskb_may_pull() followed by skb_drop_empty_frags(), and take the
error path explicitly if either fails.  pskb_may_pull() does nothing if
the head already holds pull_to bytes, so the BUG_ON() for pull_to <
skb_headlen(skb), which protected the subtraction, can go.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/xen-netfront.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 2ed673649c48..007fa3bbc9e6 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1174,18 +1174,15 @@ static int xennet_fill_frags(struct netfront_queue *queue,
 
 		RING_COPY_RESPONSE(&queue->rx, ++cons, &rx);
 
-		if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) {
-			unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
-
-			BUG_ON(pull_to < skb_headlen(skb));
-			__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
-		}
-		if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
-			xennet_set_rx_rsp_cons(queue,
-					       ++cons + skb_queue_len(list));
-			kfree_skb(nskb);
-			return -ENOENT;
-		}
+		/* Out of frag slots: pull the start of the packet into the
+		 * head and drop empty frags to make room.
+		 */
+		if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS &&
+		    unlikely(!pskb_may_pull(skb, NETFRONT_SKB_CB(skb)->pull_to) ||
+			     skb_drop_empty_frags(skb, GFP_ATOMIC)))
+			goto err;
+		if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS))
+			goto err;
 
 		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
 				skb_frag_page(nfrag),
@@ -1198,6 +1195,11 @@ static int xennet_fill_frags(struct netfront_queue *queue,
 	xennet_set_rx_rsp_cons(queue, cons);
 
 	return 0;
+
+err:
+	xennet_set_rx_rsp_cons(queue, ++cons + skb_queue_len(list));
+	kfree_skb(nskb);
+	return -ENOENT;
 }
 
 static int checksum_setup(struct net_device *dev, struct sk_buff *skb)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 06/10] e1000: use pskb_may_pull() in the 82544 TSO workaround
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (4 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 05/10] xen/netfront: check for failure when pulling in xennet_fill_frags() Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 07/10] e1000e: use pskb_may_pull() in the 82571/2/3 " Josef Bacik
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

e1000_xmit_frame() uses __pskb_pull_tail() to pull up to 4 bytes of
payload into the head for the 82544 TSO workaround.  It already checks
the result.  Switch to pskb_may_pull(), which takes the length the head
should end up with and checks it against the skb, so this driver no
longer calls __pskb_pull_tail() directly.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/ethernet/intel/e1000/e1000_main.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index d7f5c6f16142..3a55b211f5a6 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -3155,9 +3155,8 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 				    & 4)
 					break;
 				pull_size = min((unsigned int)4, skb->data_len);
-				if (!__pskb_pull_tail(skb, pull_size)) {
-					e_err(drv, "__pskb_pull_tail "
-					      "failed.\n");
+				if (!pskb_may_pull(skb, len + pull_size)) {
+					e_err(drv, "pskb_may_pull failed.\n");
 					dev_kfree_skb_any(skb);
 					return NETDEV_TX_OK;
 				}

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 07/10] e1000e: use pskb_may_pull() in the 82571/2/3 TSO workaround
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (5 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 06/10] e1000: use pskb_may_pull() in the 82544 TSO workaround Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 08/10] netxen: use pskb_may_pull() to pull excess TX frags into the head Josef Bacik
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

e1000_xmit_frame() uses __pskb_pull_tail() to pull up to 4 bytes of
payload into the head when the head holds only the TSO headers.  It
already checks the result.  Switch to pskb_may_pull(), which takes the
length the head should end up with and checks it against the skb, so
this driver no longer calls __pskb_pull_tail() directly.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 844f31ab37ad..e216868e15cb 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -5859,8 +5859,8 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 			unsigned int pull_size;
 
 			pull_size = min_t(unsigned int, 4, skb->data_len);
-			if (!__pskb_pull_tail(skb, pull_size)) {
-				e_err("__pskb_pull_tail failed.\n");
+			if (!pskb_may_pull(skb, len + pull_size)) {
+				e_err("pskb_may_pull failed.\n");
 				dev_kfree_skb_any(skb);
 				return NETDEV_TX_OK;
 			}

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 08/10] netxen: use pskb_may_pull() to pull excess TX frags into the head
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (6 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 07/10] e1000e: use pskb_may_pull() in the 82571/2/3 " Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 09/10] qlcnic: " Josef Bacik
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

netxen_nic_xmit_frame() pulls the frags that don't fit in a TX
descriptor into the head with __pskb_pull_tail().  It already checks the
result.  Switch to pskb_may_pull(), which takes the length the head
should end up with and checks it against the skb, so this driver no
longer calls __pskb_pull_tail() directly.

__pskb_pull_tail() also releases empty frags, even when there's nothing
to pull, so if the frags being pulled are all empty it still gets the
frag count under the limit.  pskb_may_pull() returns early in that case,
so follow it with skb_drop_empty_frags().

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 67d9bf69f8f2..f5f89ed87d95 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -2045,7 +2045,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 			delta += skb_frag_size(frag);
 		}
 
-		if (!__pskb_pull_tail(skb, delta))
+		if (!pskb_may_pull(skb, skb_headlen(skb) + delta) ||
+		    skb_drop_empty_frags(skb, GFP_ATOMIC))
 			goto drop_packet;
 
 		frag_count = 1 + skb_shinfo(skb)->nr_frags;

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 09/10] qlcnic: use pskb_may_pull() to pull excess TX frags into the head
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (7 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 08/10] netxen: use pskb_may_pull() to pull excess TX frags into the head Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:02 ` [PATCH net-next v2 10/10] net: skbuff: don't reset truesize in skb_condense() if the pull fails Josef Bacik
  2026-10-08 21:11 ` [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Jakub Kicinski
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

qlcnic_xmit_frame() pulls the frags that don't fit in a TX descriptor
into the head with __pskb_pull_tail().  It already checks the result.
Switch to pskb_may_pull(), which takes the length the head should end up
with and checks it against the skb, so this driver no longer calls
__pskb_pull_tail() directly.

__pskb_pull_tail() also releases empty frags, even when there's nothing
to pull, so if the frags being pulled are all empty it still gets the
frag count under the limit.  pskb_may_pull() returns early in that case,
so follow it with skb_drop_empty_frags().

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 761ef3bc8193..e7ab5586798b 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -682,7 +682,8 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		for (i = 0; i < (frag_count - QLCNIC_MAX_FRAGS_PER_TX); i++)
 			delta += skb_frag_size(&skb_shinfo(skb)->frags[i]);
 
-		if (!__pskb_pull_tail(skb, delta))
+		if (!pskb_may_pull(skb, skb_headlen(skb) + delta) ||
+		    skb_drop_empty_frags(skb, GFP_ATOMIC))
 			goto drop_packet;
 
 		frag_count = 1 + skb_shinfo(skb)->nr_frags;

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH net-next v2 10/10] net: skbuff: don't reset truesize in skb_condense() if the pull fails
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (8 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 09/10] qlcnic: " Josef Bacik
@ 2026-10-08 21:02 ` Josef Bacik
  2026-10-08 21:11 ` [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Jakub Kicinski
  10 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-08 21:02 UTC (permalink / raw)
  To: Jakub Kicinski, Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn
  Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan,
	Josef Bacik

skb_condense() pulls all of the frag data into the head and then sets
truesize to cover just the head, but it ignores the return value of
__pskb_pull_tail().  If the pull failed, the frags would still be
attached and truesize would undercount them.

It can't fail today.  The caller has checked that the head has room,
that the skb isn't cloned and that the frags are readable, and pulling
all of data_len eats every frag_list skb whole, so nothing is
allocated.  Check the result anyway and leave the skb alone on
failure, so this stays correct if any of that changes.  Use
__skb_linearize(), which is what this pull is.

Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 net/core/skbuff.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f798118df112..556d37981f0f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -7158,7 +7158,8 @@ void skb_condense(struct sk_buff *skb)
 			return;
 
 		/* Nice, we can free page frag(s) right now */
-		__pskb_pull_tail(skb, skb->data_len);
+		if (__skb_linearize(skb))
+			return;
 	}
 	/* At this point, skb->truesize might be over estimated,
 	 * because skb had a fragment, and fragments do not tell

-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers
  2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
                   ` (9 preceding siblings ...)
  2026-10-08 21:02 ` [PATCH net-next v2 10/10] net: skbuff: don't reset truesize in skb_condense() if the pull fails Josef Bacik
@ 2026-10-08 21:11 ` Jakub Kicinski
  2026-10-09 13:43   ` Josef Bacik
  10 siblings, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2026-10-08 21:11 UTC (permalink / raw)
  To: Josef Bacik
  Cc: Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn,
	Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan

On Thu, 08 Oct 2026 21:02:47 +0000 Josef Bacik wrote:
> v1->v2:
> - New 1/10: skb_drop_empty_frags(). xen-netfront, netxen and qlcnic
>   relied on __pskb_pull_tail() releasing zero-length frags even when
>   there's nothing to pull, which pskb_may_pull() doesn't do (Sashiko).
> - xen-netfront, netxen, qlcnic: call skb_drop_empty_frags() after
>   pskb_may_pull().
> - skb_drop_empty_frags() checked with a boot-time test under KASAN and
>   kmemleak, on cloned and uncloned skbs.

Please keep in mind that we ask people to limit themselves to 15
outstanding patches per tree. You have 18 right now.
(200 active netdev contributors + an LLM) x 20 patches == insanity :/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers
  2026-10-08 21:11 ` [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Jakub Kicinski
@ 2026-10-09 13:43   ` Josef Bacik
  0 siblings, 0 replies; 13+ messages in thread
From: Josef Bacik @ 2026-10-09 13:43 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Paolo Abeni, Eric Dumazet, David S. Miller, Andrew Lunn,
	Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
	Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
	Tony Nguyen, Przemek Kitszel, Manish Chopra, Rahul Verma,
	GR-Linux-NIC-Dev, Shahed Shaikh, Simon Horman, netdev,
	linux-kernel, linux-rdma, xen-devel, intel-wired-lan

On Thu, Oct 8, 2026 at 5:11 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Thu, 08 Oct 2026 21:02:47 +0000 Josef Bacik wrote:
> > v1->v2:
> > - New 1/10: skb_drop_empty_frags(). xen-netfront, netxen and qlcnic
> >   relied on __pskb_pull_tail() releasing zero-length frags even when
> >   there's nothing to pull, which pskb_may_pull() doesn't do (Sashiko).
> > - xen-netfront, netxen, qlcnic: call skb_drop_empty_frags() after
> >   pskb_may_pull().
> > - skb_drop_empty_frags() checked with a boot-time test under KASAN and
> >   kmemleak, on cloned and uncloned skbs.
>
> Please keep in mind that we ask people to limit themselves to 15
> outstanding patches per tree. You have 18 right now.
> (200 active netdev contributors + an LLM) x 20 patches == insanity :/

Eesh sorry Jakub, the skbuff BUG_ON() removal series is the more
important one, this series is the followup so I can finish that work.
By outstanding do you mean per-merge window or once I get
notifications for things being merged I'm good to send the next batch?
 Thanks,

Josef

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-10-09 13:43 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-08 21:02 [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 01/10] net: skbuff: add skb_drop_empty_frags() Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 02/10] net: ftmac100: check for failure when pulling in the RX header Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 03/10] net/mlx5e: check for failure when pulling the Ethernet header after XDP Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 04/10] net: niu: check for failure when pulling in the RX header Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 05/10] xen/netfront: check for failure when pulling in xennet_fill_frags() Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 06/10] e1000: use pskb_may_pull() in the 82544 TSO workaround Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 07/10] e1000e: use pskb_may_pull() in the 82571/2/3 " Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 08/10] netxen: use pskb_may_pull() to pull excess TX frags into the head Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 09/10] qlcnic: " Josef Bacik
2026-10-08 21:02 ` [PATCH net-next v2 10/10] net: skbuff: don't reset truesize in skb_condense() if the pull fails Josef Bacik
2026-10-08 21:11 ` [PATCH net-next v2 00/10] net: stop calling __pskb_pull_tail() from drivers Jakub Kicinski
2026-10-09 13:43   ` Josef Bacik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®