lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250221093027.wo74lqkbycky2vu5@skbuf>
Date: Fri, 21 Feb 2025 11:30:27 +0200
From: Vladimir Oltean <vladimir.oltean@....com>
To: Wei Fang <wei.fang@....com>
Cc: Claudiu Manoil <claudiu.manoil@....com>,
	Clark Wang <xiaoning.wang@....com>,
	"andrew+netdev@...n.ch" <andrew+netdev@...n.ch>,
	"davem@...emloft.net" <davem@...emloft.net>,
	"edumazet@...gle.com" <edumazet@...gle.com>,
	"kuba@...nel.org" <kuba@...nel.org>,
	"pabeni@...hat.com" <pabeni@...hat.com>,
	Ioana Ciornei <ioana.ciornei@....com>,
	"Y.B. Lu" <yangbo.lu@....com>,
	"michal.swiatkowski@...ux.intel.com" <michal.swiatkowski@...ux.intel.com>,
	"netdev@...r.kernel.org" <netdev@...r.kernel.org>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	"imx@...ts.linux.dev" <imx@...ts.linux.dev>,
	"stable@...r.kernel.org" <stable@...r.kernel.org>
Subject: Re: [PATCH v2 net 9/9] net: enetc: fix the off-by-one issue in
 enetc_map_tx_tso_buffs()

On Fri, Feb 21, 2025 at 04:56:03AM +0200, Wei Fang wrote:
> I agree with you that we finally need a helper function to replace all the
> same code blocks, but I'd like to do that for net-next tree, because as I
> replied in patch 2, we don't need the count variable. Currently I am more
> focused on solving the problem itself rather than optimizing it. Of course
> if you think this is necessary, I can add these changes in the next version. :)

Does it cost anything extra to centralize the logic that these patches
are _already_ touching into a single function? My "unsquashed" diff
below centralizes all occurrences of that logic, but you don't need to
centralize for "net" the occurences that the bug fix patches aren't touching.

> > diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c
> > b/drivers/net/ethernet/freescale/enetc/enetc.c
> > index 6178157611db..a70e92dcbe2c 100644
> > --- a/drivers/net/ethernet/freescale/enetc/enetc.c
> > +++ b/drivers/net/ethernet/freescale/enetc/enetc.c
> > @@ -106,6 +106,24 @@ static void enetc_free_tx_frame(struct enetc_bdr
> > *tx_ring,
> >  	}
> >  }
> > 
> > +/**
> > + * enetc_unwind_tx_frame() - Unwind the DMA mappings of a multi-buffer TX
> > frame
> > + * @tx_ring: Pointer to the TX ring on which the buffer descriptors are located
> > + * @count: Number of TX buffer descriptors which need to be unmapped
> > + * @i: Index of the last successfully mapped TX buffer descriptor
> > + */
> > +static void enetc_unwind_tx_frame(struct enetc_bdr *tx_ring, int count, int i)
> > +{
> > +	while (count--) {
> > +		struct enetc_tx_swbd *tx_swbd = &tx_ring->tx_swbd[i];
> > +
> > +		enetc_free_tx_frame(tx_ring, tx_swbd);
> > +		if (i == 0)
> > +			i = tx_ring->bd_count;
> > +		i--;
> > +	}
> > +}
> > +
> >  /* Let H/W know BD ring has been updated */
> >  static void enetc_update_tx_ring_tail(struct enetc_bdr *tx_ring)
> >  {
> > @@ -399,13 +417,7 @@ static int enetc_map_tx_buffs(struct enetc_bdr
> > *tx_ring, struct sk_buff *skb)
> >  dma_err:
> >  	dev_err(tx_ring->dev, "DMA map error");
> > 
> > -	while (count--) {
> > -		tx_swbd = &tx_ring->tx_swbd[i];
> > -		enetc_free_tx_frame(tx_ring, tx_swbd);
> > -		if (i == 0)
> > -			i = tx_ring->bd_count;
> > -		i--;
> > -	}
> > +	enetc_unwind_tx_frame(tx_ring, count, i);
> > 
> >  	return 0;
> >  }
> > @@ -752,7 +764,6 @@ static int enetc_lso_map_data(struct enetc_bdr
> > *tx_ring, struct sk_buff *skb,
> > 
> >  static int enetc_lso_hw_offload(struct enetc_bdr *tx_ring, struct sk_buff *skb)
> >  {
> > -	struct enetc_tx_swbd *tx_swbd;
> >  	struct enetc_lso_t lso = {0};
> >  	int err, i, count = 0;
> > 
> > @@ -776,13 +787,7 @@ static int enetc_lso_hw_offload(struct enetc_bdr
> > *tx_ring, struct sk_buff *skb)
> >  	return count;
> > 
> >  dma_err:
> > -	do {
> > -		tx_swbd = &tx_ring->tx_swbd[i];
> > -		enetc_free_tx_frame(tx_ring, tx_swbd);
> > -		if (i == 0)
> > -			i = tx_ring->bd_count;
> > -		i--;
> > -	} while (--count);
> > +	enetc_unwind_tx_frame(tx_ring, count, i);
> > 
> >  	return 0;
> >  }
> > @@ -877,13 +882,7 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr
> > *tx_ring, struct sk_buff *skb
> >  	dev_err(tx_ring->dev, "DMA map error");
> > 
> >  err_chained_bd:
> > -	while (count--) {
> > -		tx_swbd = &tx_ring->tx_swbd[i];
> > -		enetc_free_tx_frame(tx_ring, tx_swbd);
> > -		if (i == 0)
> > -			i = tx_ring->bd_count;
> > -		i--;
> > -	}
> > +	enetc_unwind_tx_frame(tx_ring, count, i);
> > 
> >  	return 0;
> >  }
> > 
> > With the definitions laid out explicitly in a kernel-doc, doesn't the
> > rest of the patch look a bit wrong? Why would you increment "count"
> 
> Sorry, I don't understand what you mean " With the definitions laid ou
> explicitly in a kernel-doc", which kernel-doc?

This kernel-doc:

/**
 * enetc_unwind_tx_frame() - Unwind the DMA mappings of a multi-buffer TX frame
 * @count: Number of TX buffer descriptors which need to be unmapped
 * @i: Index of the last successfully mapped TX buffer descriptor

The definitions of "count" and "i" are what I'm talking about. It's
clear to me that the "i" that is passed is not the index of the last
successfully mapped TX BD.

> > before enetc_map_tx_tso_data() succeeds? Why isn't the problem that "i"
> > needs to be rolled back on enetc_map_tx_tso_data() failure instead?
> 
> The root cause of this issue as you said is that "I" and "count" are not
> synchronized. Either moving count++ before enetc_map_tx_tso_data()
> or rolling back 'i' after enetc_map_tx_tso_data() fails should solve the
> issue. There is no problem with the former, it just loops one more time,
> and actually the loop does nothing.

Sorry, I don't understand "there is no problem, it just loops one more
time, actually the loop does nothing"? What do you mean, could you
explain more? Why wouldn't it be a problem, if the loop runs one more
time than TX BDs were added to the ring, that we try to unmap the DMA
buffer of a TXBD that was previously passed to hardware as part of a
previous enetc_update_tx_ring_tail()?

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ