* [PATCH net-next v3] ice: fix packet corruption due to extraneous page flip
@ 2026-05-12 18:12 John Ousterhout
2026-05-13 6:15 ` Greg KH
0 siblings, 1 reply; 3+ messages in thread
From: John Ousterhout @ 2026-05-12 18:12 UTC (permalink / raw)
To: ouster; +Cc: stable
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.6+
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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net-next v3] ice: fix packet corruption due to extraneous page flip
2026-05-12 18:12 [PATCH net-next v3] ice: fix packet corruption due to extraneous page flip John Ousterhout
@ 2026-05-13 6:15 ` Greg KH
2026-05-13 16:18 ` John Ousterhout
0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2026-05-13 6:15 UTC (permalink / raw)
To: John Ousterhout; +Cc: stable
On Tue, May 12, 2026 at 11:12:28AM -0700, John Ousterhout wrote:
> 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.6+
> 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
>
>
<formletter>
This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read:
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.
</formletter>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-next v3] ice: fix packet corruption due to extraneous page flip
2026-05-13 6:15 ` Greg KH
@ 2026-05-13 16:18 ` John Ousterhout
0 siblings, 0 replies; 3+ messages in thread
From: John Ousterhout @ 2026-05-13 16:18 UTC (permalink / raw)
To: Greg KH; +Cc: stable
On Tue, May 12, 2026 at 11:15 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Tue, May 12, 2026 at 11:12:28AM -0700, John Ousterhout wrote:
> > 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.6+
> > 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
> >
> >
>
> <formletter>
>
> This is not the correct way to submit patches for inclusion in the
> stable kernel tree. Please read:
> https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
> for how to do this properly.
>
> </formletter>
Apologies for this non-standard submission. I read the referenced page
before making my submission (and I have just read it again), but I
don't believe this submission can conform to any of the 3 recommended
formats. This is because there is not (and cannot be) an upstream
commit for this bug, since the buggy code has been removed. The patch
only applies to stable past releases (see the commit message).
Any advice you can provide on how to make this patch more conforming
would be most welcome.
-John-
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-13 16:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-12 18:12 [PATCH net-next v3] ice: fix packet corruption due to extraneous page flip John Ousterhout
2026-05-13 6:15 ` Greg KH
2026-05-13 16:18 ` John Ousterhout
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox