2023-01-26 10:17:23

by Jonas Suhr Christensen

[permalink] [raw]
Subject: [PATCH 1/2] net: ll_temac: fix DMA resources leak

Add missing conversion of address when unmapping dma region causing
unmapping to silently fail. At some point resulting in buffer
overrun eg. when releasing device.

Signed-off-by: Jonas Suhr Christensen <[email protected]>
---
drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 1066420d6a83..66c04027f230 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -300,6 +300,7 @@ static void temac_dma_bd_release(struct net_device *ndev)
{
struct temac_local *lp = netdev_priv(ndev);
int i;
+ struct cdmac_bd *bd;

/* Reset Local Link (DMA) */
lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
@@ -307,9 +308,14 @@ static void temac_dma_bd_release(struct net_device *ndev)
for (i = 0; i < lp->rx_bd_num; i++) {
if (!lp->rx_skb[i])
break;
- dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys,
+
+ bd = &lp->rx_bd_v[1];
+ dma_unmap_single(ndev->dev.parent, be32_to_cpu(bd->phys),
XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE);
+ bd->phys = 0;
+ bd->len = 0;
dev_kfree_skb(lp->rx_skb[i]);
+ lp->rx_skb[i] = NULL;
}
if (lp->rx_bd_v)
dma_free_coherent(ndev->dev.parent,
--
2.39.1



2023-01-26 10:17:26

by Jonas Suhr Christensen

[permalink] [raw]
Subject: [PATCH 2/2] net: ll_temac: improve reset of buffer on dma mapping

Free buffer and set pointer to null on dma mapping error.

Signed-off-by: Jonas Suhr Christensen <[email protected]>
---
drivers/net/ethernet/xilinx/ll_temac_main.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 66c04027f230..5595ba57a126 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -376,8 +376,11 @@ static int temac_dma_bd_init(struct net_device *ndev)
skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data,
XTE_MAX_JUMBO_FRAME_SIZE,
DMA_FROM_DEVICE);
- if (dma_mapping_error(ndev->dev.parent, skb_dma_addr))
+ if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) {
+ dev_kfree_skb(lp->rx_skb[i]);
+ lp->rx_skb[i] = NULL;
goto out;
+ }
lp->rx_bd_v[i].phys = cpu_to_be32(skb_dma_addr);
lp->rx_bd_v[i].len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE);
lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND);
--
2.39.1


2023-01-28 07:13:34

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH 2/2] net: ll_temac: improve reset of buffer on dma mapping

On Thu, 26 Jan 2023 11:16:07 +0100 Jonas Suhr Christensen wrote:
> Free buffer and set pointer to null on dma mapping error.

Why? I don't see a leak. You should provide motivation in the commit
message.

2023-01-28 07:20:48

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH 1/2] net: ll_temac: fix DMA resources leak

On Thu, 26 Jan 2023 11:16:06 +0100 Jonas Suhr Christensen wrote:
> Add missing conversion of address when unmapping dma region causing
> unmapping to silently fail. At some point resulting in buffer
> overrun eg. when releasing device.

Could you add a Fixes tag pointing to the commit which introduced
the bug? It will help the stable teams backport the patch.

When reposting please put [PATCH net v2] as the prefix (noting
the target tree for the benefit of bots/CIs).

> Signed-off-by: Jonas Suhr Christensen <[email protected]>
> ---
> drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
> index 1066420d6a83..66c04027f230 100644
> --- a/drivers/net/ethernet/xilinx/ll_temac_main.c
> +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
> @@ -300,6 +300,7 @@ static void temac_dma_bd_release(struct net_device *ndev)
> {
> struct temac_local *lp = netdev_priv(ndev);
> int i;
> + struct cdmac_bd *bd;

nit: we like variable declarations longest to shortest in networking
so before the int i; pls

> /* Reset Local Link (DMA) */
> lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);


2023-01-30 12:41:19

by Esben Haabendal

[permalink] [raw]
Subject: Re: [PATCH 2/2] net: ll_temac: improve reset of buffer on dma mapping

Jakub Kicinski <[email protected]> writes:

> On Thu, 26 Jan 2023 11:16:07 +0100 Jonas Suhr Christensen wrote:
>> Free buffer and set pointer to null on dma mapping error.
>
> Why? I don't see a leak. You should provide motivation in the commit
> message.

I don't think there is a leak. But if one of the dma_map_single() calls
in temac_dma_bd_init() fails, the error handling calls into
temac_dma_bd_release(), which will then call dma_unmap_single() on the
address that failed to be mapped.

Can we be sure that doing so is always safe? If not, this change
ensures that we only unmap buffers that were succesfully mapped.

/Esben

2023-01-30 12:44:12

by Esben Haabendal

[permalink] [raw]
Subject: Re: [PATCH 1/2] net: ll_temac: fix DMA resources leak

Jakub Kicinski <[email protected]> writes:

> On Thu, 26 Jan 2023 11:16:06 +0100 Jonas Suhr Christensen wrote:
>> Add missing conversion of address when unmapping dma region causing
>> unmapping to silently fail. At some point resulting in buffer
>> overrun eg. when releasing device.
>
> Could you add a Fixes tag pointing to the commit which introduced
> the bug? It will help the stable teams backport the patch.

Fixes: fdd7454ecb29 ("net: ll_temac: Fix support for little-endian platforms")

> When reposting please put [PATCH net v2] as the prefix (noting
> the target tree for the benefit of bots/CIs).
>
>> Signed-off-by: Jonas Suhr Christensen <[email protected]>
>> ---
>> drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +++++++-
>> 1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
>> index 1066420d6a83..66c04027f230 100644
>> --- a/drivers/net/ethernet/xilinx/ll_temac_main.c
>> +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
>> @@ -300,6 +300,7 @@ static void temac_dma_bd_release(struct net_device *ndev)
>> {
>> struct temac_local *lp = netdev_priv(ndev);
>> int i;
>> + struct cdmac_bd *bd;
>
> nit: we like variable declarations longest to shortest in networking
> so before the int i; pls
>
>> /* Reset Local Link (DMA) */
>> lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);

2023-01-30 20:42:26

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH 2/2] net: ll_temac: improve reset of buffer on dma mapping

On Mon, 30 Jan 2023 13:40:56 +0100 [email protected] wrote:
> > On Thu, 26 Jan 2023 11:16:07 +0100 Jonas Suhr Christensen wrote:
> >> Free buffer and set pointer to null on dma mapping error.
> >
> > Why? I don't see a leak. You should provide motivation in the commit
> > message.
>
> I don't think there is a leak. But if one of the dma_map_single() calls
> in temac_dma_bd_init() fails, the error handling calls into
> temac_dma_bd_release(), which will then call dma_unmap_single() on the
> address that failed to be mapped.

I see, seems worth fixing. Please explain that in the commit message,
it's not immediately clear what the concern is, otherwise.
On top of that please add a Fixes tag here as well and repost.

> Can we be sure that doing so is always safe? If not, this change
> ensures that we only unmap buffers that were succesfully mapped.

2023-01-30 21:56:20

by Christophe JAILLET

[permalink] [raw]
Subject: Re: [PATCH 1/2] net: ll_temac: fix DMA resources leak

Le 26/01/2023 à 11:16, Jonas Suhr Christensen a écrit :
> Add missing conversion of address when unmapping dma region causing
> unmapping to silently fail. At some point resulting in buffer
> overrun eg. when releasing device.
>
> Signed-off-by: Jonas Suhr Christensen <[email protected]>
> ---
> drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
> index 1066420d6a83..66c04027f230 100644
> --- a/drivers/net/ethernet/xilinx/ll_temac_main.c
> +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
> @@ -300,6 +300,7 @@ static void temac_dma_bd_release(struct net_device *ndev)
> {
> struct temac_local *lp = netdev_priv(ndev);
> int i;
> + struct cdmac_bd *bd;
>
> /* Reset Local Link (DMA) */
> lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
> @@ -307,9 +308,14 @@ static void temac_dma_bd_release(struct net_device *ndev)
> for (i = 0; i < lp->rx_bd_num; i++) {
> if (!lp->rx_skb[i])
> break;
> - dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys,
> +
> + bd = &lp->rx_bd_v[1];

Hi,
just a naive question from s.o. who knows nothing of this code:

Is really [1] ([one]) expected here?
[i] would look more "standard" in a 'for' loop.

just my 2c,

CJ


> + dma_unmap_single(ndev->dev.parent, be32_to_cpu(bd->phys),
> XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE);
> + bd->phys = 0;
> + bd->len = 0;
> dev_kfree_skb(lp->rx_skb[i]);
> + lp->rx_skb[i] = NULL;
> }
> if (lp->rx_bd_v)
> dma_free_coherent(ndev->dev.parent,


2023-01-31 00:21:02

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH 1/2] net: ll_temac: fix DMA resources leak

On Mon, 30 Jan 2023 22:56:04 +0100 Christophe JAILLET wrote:
> > - dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys,
> > +
> > + bd = &lp->rx_bd_v[1];
>
> Hi,
> just a naive question from s.o. who knows nothing of this code:
>
> Is really [1] ([one]) expected here?
> [i] would look more "standard" in a 'for' loop.

Wow, good eye.