From: John Ousterhout <ouster@cs.stanford.edu>
To: ouster@cs.stanford.edu
Cc: stable@vger.kernel.org
Subject: [PATCH net v3] ice: fix packet corruption due to extraneous page flip
Date: Tue, 12 May 2026 11:15:18 -0700 [thread overview]
Message-ID: <20260512181518.1670-1-ouster@cs.stanford.edu> (raw)
Consider the following sequence of events:
* The bottom half of a buffer page is filled with data from
packet A. The page has a net reference count (reference count
- bias) of 1. The page is returned to the NIC, flipped to
use the top half.
* Before the reference on the page is released, the NIC returns
the page with no data in it ('size' is zero in ice_clean_rx_irq).
In this case the bias does not get decremented. The page still
has a net reference count of 1, so it gets returned to the NIC.
However, ice_put_rx_mbuf flipped the page so that the bottom
half is active.
* If the NIC stores another packet in the page before packet A
has released its reference, the data in packet A will be
overwritten with data from the new packet.
* Unfortunately zero-length buffers occur frequently: they seem
to occur whenever a packet uses every available byte in a
buffer, ending precisely at the end of the buffer. When this
happens the NIC seems to generate an extra zero-length
buffer.
The fix is for ice_put_rx_mbuf not to flip pages that have a
size of 0.
This patch applies directly to longterm stable versions 6.18.27
and 6.12.86; it also seems relevant for 6.6.137 but would need
modifcations for that version. I have not examined earlier
versions.
Unfortunately there is no upstream commit id for this patch because
the ICE driver has undergone a major revision (libeth refactor and
pagepool conversion) that eliminated the buggy code. Thus the
problem no longer exists in the main line.
Cc: stable@vger.kernel.org # 6.12+
Signed-off-by: John Ousterhout <ouster@cs.stanford.edu>
---
drivers/net/ethernet/intel/ice/ice_txrx.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
index 51c459a3e722..081c7a7392b7 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -1215,6 +1215,13 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
xdp_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags;
while (idx != ntc) {
+ union ice_32b_rx_flex_desc *rx_desc;
+ unsigned int size;
+
+ rx_desc = ICE_RX_DESC(rx_ring, idx);
+ size = le16_to_cpu(rx_desc->wb.pkt_len) &
+ ICE_RX_FLX_DESC_PKT_LEN_M;
+
buf = &rx_ring->rx_buf[idx];
if (++idx == cnt)
idx = 0;
@@ -1224,10 +1231,20 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
* To do this, only adjust pagecnt_bias for fragments up to
* the total remaining after the XDP program has run.
*/
- if (verdict != ICE_XDP_CONSUMED)
- ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
- else if (i++ <= xdp_frags)
+ if (verdict != ICE_XDP_CONSUMED) {
+ /* Don't "flip" the page if size is 0: in this case
+ * the data in the current half will not be used so
+ * it's OK to reuse that half. And, since the bias
+ * didn't get decremented for this half, the page can
+ * be returned to the NIC even if the other half is
+ * still in use, so flipping the page could cause
+ * live packet data to be overwritten.
+ */
+ if (size != 0)
+ ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+ } else if (i++ <= xdp_frags) {
buf->pagecnt_bias++;
+ }
ice_put_rx_buf(rx_ring, buf);
}
--
2.43.0
next reply other threads:[~2026-05-12 18:15 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-12 18:15 John Ousterhout [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-05-12 18:19 [PATCH net v3] ice: fix packet corruption due to extraneous page flip John Ousterhout
2026-05-13 9:07 ` David Laight
2026-05-13 16:28 ` John Ousterhout
2026-05-13 20:49 ` David Laight
2026-05-14 4:47 ` John Ousterhout
2026-05-14 10:01 ` David Laight
2026-05-14 16:43 ` Jacob Keller
2026-05-12 18:13 John Ousterhout
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=20260512181518.1670-1-ouster@cs.stanford.edu \
--to=ouster@cs.stanford.edu \
--cc=stable@vger.kernel.org \
/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.