From: Pavel Skripkin <hidden> Date: 2021-07-26 15:29:59
Hi, Marc and can drivers maintainers/reviewers!
A long time ago syzbot reported memory leak in mcba_usb can driver[1]. It was
using strange pattern for allocating coherent buffers, which was leading to
memory leaks. Yesterday I got a report, that mcba_usb stopped working since my commit.
I came up with quick fix and all started working well.
There are at least 3 more drivers with this pattern, I decided to fix leaks
in them too, since code is actually the same (I guess, driver authors just copy pasted
code parts). Each of following patches is combination of 91c02557174b
("can: mcba_usb: fix memory leak in mcba_usb") and my yesterday fix [2].
Dear maintainers/reviewers, if You have one of these hardware pieces, please, test
these patches and report any errors you will find.
[1] https://syzkaller.appspot.com/bug?id=c94c1c23e829d5ac97995d51219f0c5a0cd1fa54
[2] https://lore.kernel.org/netdev/20210725103630.23864-1-paskripkin@gmail.com/
With regards,
Pavel Skripkin
Pavel Skripkin (3):
can: usb_8dev: fix memory leak
can: ems_usb: fix memory leak
can: esd_usb2: fix memory leak
drivers/net/can/usb/ems_usb.c | 14 +++++++++++++-
drivers/net/can/usb/esd_usb2.c | 16 +++++++++++++++-
drivers/net/can/usb/usb_8dev.c | 15 +++++++++++++--
3 files changed, 41 insertions(+), 4 deletions(-)
--
2.32.0
From: Pavel Skripkin <hidden> Date: 2021-07-26 15:30:28
In usb_8dev_start() MAX_RX_URBS coherent buffers are allocated and there
is nothing, that frees them:
1) In callback function the urb is resubmitted and that's all
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER
is not set (see usb_8dev_start) and this flag cannot be used with
coherent buffers.
So, all allocated buffers should be freed with usb_free_coherent()
explicitly.
Side note: This code looks like a copy-paste of other can drivers.
The same patch was applied to mcba_usb driver and it works nice
with real hardware. There is no change in functionality, only clean-up
code for coherent buffers
Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices")
Signed-off-by: Pavel Skripkin <redacted>
---
drivers/net/can/usb/usb_8dev.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
@@ -733,6 +734,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)for(i=0;i<MAX_RX_URBS;i++){structurb*urb=NULL;u8*buf;+dma_addr_tbuf_dma;/* create a URB, and a buffer for it */urb=usb_alloc_urb(0,GFP_KERNEL);
@@ -742,7 +744,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)}buf=usb_alloc_coherent(priv->udev,RX_BUFFER_SIZE,GFP_KERNEL,-&urb->transfer_dma);+&buf_dma);if(!buf){netdev_err(netdev,"No memory left for USB buffer\n");usb_free_urb(urb);
@@ -750,6 +752,8 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)break;}+urb->transfer_dma=buf_dma;+usb_fill_bulk_urb(urb,priv->udev,usb_rcvbulkpipe(priv->udev,USB_8DEV_ENDP_DATA_RX),
@@ -767,6 +771,9 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)break;}+priv->rxbuf[i]=buf;+priv->rxbuf_dma[i]=buf_dma;+/* Drop reference, USB core will take care of freeing it */usb_free_urb(urb);}
From: Pavel Skripkin <hidden> Date: 2021-07-26 15:30:47
In ems_usb_start() MAX_RX_URBS coherent buffers are allocated and there
is nothing, that frees them:
1) In callback function the urb is resubmitted and that's all
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER
is not set (see ems_usb_start) and this flag cannot be used with
coherent buffers.
So, all allocated buffers should be freed with usb_free_coherent()
explicitly.
Side note: This code looks like a copy-paste of other can drivers.
The same patch was applied to mcba_usb driver and it works nice
with real hardware. There is no change in functionality, only clean-up
code for coherent buffers
Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
Signed-off-by: Pavel Skripkin <redacted>
---
drivers/net/can/usb/ems_usb.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
@@ -255,6 +255,8 @@ struct ems_usb {unsignedintfree_slots;/* remember number of available slots */structems_cpc_msgactive_params;/* active controller parameters */+void*rxbuf[MAX_RX_URBS];+dma_addr_trxbuf_dma[MAX_RX_URBS];};staticvoidems_usb_read_interrupt_callback(structurb*urb)
@@ -587,6 +589,7 @@ static int ems_usb_start(struct ems_usb *dev)for(i=0;i<MAX_RX_URBS;i++){structurb*urb=NULL;u8*buf=NULL;+dma_addr_tbuf_dma;/* create a URB, and a buffer for it */urb=usb_alloc_urb(0,GFP_KERNEL);
@@ -596,7 +599,7 @@ static int ems_usb_start(struct ems_usb *dev)}buf=usb_alloc_coherent(dev->udev,RX_BUFFER_SIZE,GFP_KERNEL,-&urb->transfer_dma);+&buf_dma);if(!buf){netdev_err(netdev,"No memory left for USB buffer\n");usb_free_urb(urb);
@@ -604,6 +607,8 @@ static int ems_usb_start(struct ems_usb *dev)break;}+urb->transfer_dma=buf_dma;+usb_fill_bulk_urb(urb,dev->udev,usb_rcvbulkpipe(dev->udev,2),buf,RX_BUFFER_SIZE,ems_usb_read_bulk_callback,dev);
@@ -619,6 +624,9 @@ static int ems_usb_start(struct ems_usb *dev)break;}+dev->rxbuf[i]=buf;+dev->rxbuf_dma[i]=buf_dma;+/* Drop reference, USB core will take care of freeing it */usb_free_urb(urb);}
From: Pavel Skripkin <hidden> Date: 2021-07-26 15:31:09
In esd_usb2_setup_rx_urbs() MAX_RX_URBS coherent buffers are
allocated and there is nothing, that frees them:
1) In callback function the urb is resubmitted and that's all
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER
is not set (see esd_usb2_setup_rx_urbs) and this flag cannot be used
with coherent buffers.
So, all allocated buffers should be freed with usb_free_coherent()
explicitly.
Side note: This code looks like a copy-paste of other can drivers.
The same patch was applied to mcba_usb driver and it works nice
with real hardware. There is no change in functionality, only clean-up
code for coherent buffers
Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device")
Signed-off-by: Pavel Skripkin <redacted>
---
drivers/net/can/usb/esd_usb2.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
@@ -545,6 +547,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)for(i=0;i<MAX_RX_URBS;i++){structurb*urb=NULL;u8*buf=NULL;+dma_addr_tbuf_dma;/* create a URB, and a buffer for it */urb=usb_alloc_urb(0,GFP_KERNEL);
@@ -554,7 +557,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)}buf=usb_alloc_coherent(dev->udev,RX_BUFFER_SIZE,GFP_KERNEL,-&urb->transfer_dma);+&buf_dma);if(!buf){dev_warn(dev->udev->dev.parent,"No memory left for USB buffer\n");
@@ -562,6 +565,8 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)gotofreeurb;}+urb->transfer_dma=buf_dma;+usb_fill_bulk_urb(urb,dev->udev,usb_rcvbulkpipe(dev->udev,1),buf,RX_BUFFER_SIZE,
@@ -574,8 +579,12 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)usb_unanchor_urb(urb);usb_free_coherent(dev->udev,RX_BUFFER_SIZE,buf,urb->transfer_dma);+gotofreeusrb;}+dev->rxbuf[i]=buf;+dev->rxbuf_dma[i]=buf_dma;+freeurb:/* Drop reference, USB core will take care of freeing it */usb_free_urb(urb);
From: Pavel Skripkin <hidden> Date: 2021-07-26 17:29:45
On Mon, 26 Jul 2021 18:29:38 +0300
Pavel Skripkin [off-list ref] wrote:
Hi, Marc and can drivers maintainers/reviewers!
I reread this I found out, that I missed logic here.
I mean:
A long time ago syzbot reported memory leak in mcba_usb can
driver[1]. It was using strange pattern for allocating coherent
buffers, which was leading to memory leaks.
I fixed this wrong pattern in mcba_usb driver and
Yesterday I got a report,
that mcba_usb stopped working since my commit. I came up with quick
fix and all started working well.
There are at least 3 more drivers with this pattern, I decided to fix
leaks in them too, since code is actually the same (I guess, driver
authors just copy pasted code parts). Each of following patches is
combination of 91c02557174b ("can: mcba_usb: fix memory leak in
mcba_usb") and my yesterday fix [2].
Dear maintainers/reviewers, if You have one of these hardware pieces,
please, test these patches and report any errors you will find.
[1]
https://syzkaller.appspot.com/bug?id=c94c1c23e829d5ac97995d51219f0c5a0cd1fa54
[2]
https://lore.kernel.org/netdev/20210725103630.23864-1-paskripkin@gmail.com/
With regards,
Pavel Skripkin
Pavel Skripkin (3):
can: usb_8dev: fix memory leak
can: ems_usb: fix memory leak
can: esd_usb2: fix memory leak
drivers/net/can/usb/ems_usb.c | 14 +++++++++++++-
drivers/net/can/usb/esd_usb2.c | 16 +++++++++++++++-
drivers/net/can/usb/usb_8dev.c | 15 +++++++++++++--
3 files changed, 41 insertions(+), 4 deletions(-)
From: Marc Kleine-Budde <mkl@pengutronix.de> Date: 2021-07-26 20:02:32
On 26.07.2021 20:29:16, Pavel Skripkin wrote:
On Mon, 26 Jul 2021 18:29:38 +0300
Pavel Skripkin [off-list ref] wrote:
quoted
Hi, Marc and can drivers maintainers/reviewers!
I reread this I found out, that I missed logic here.
I mean:
quoted
A long time ago syzbot reported memory leak in mcba_usb can
driver[1]. It was using strange pattern for allocating coherent
buffers, which was leading to memory leaks.
I fixed this wrong pattern in mcba_usb driver and
Thanks for your patches! Please resend them with an updated description
and the fixed patch 3.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
From: Pavel Skripkin <hidden> Date: 2021-07-27 16:59:36
Hi, Marc and can drivers maintainers/reviewers!
A long time ago syzbot reported memory leak in mcba_usb can driver[1]. It was
using strange pattern for allocating coherent buffers, which was leading to
memory leaks. I fixed this wrong pattern in mcba_usb driver and yesterday I got
a report, that mcba_usb stopped working since my commit. I came up with quick fix
and all started working well.
There are at least 3 more drivers with this pattern, I decided to fix leaks
in them too, since code is actually the same (I guess, driver authors just copy pasted
code parts). Each of following patches is combination of 91c02557174b
("can: mcba_usb: fix memory leak in mcba_usb") and my yesterday fix [2].
Dear maintainers/reviewers, if You have one of these hardware pieces, please, test
these patches and report any errors you will find.
[1] https://syzkaller.appspot.com/bug?id=c94c1c23e829d5ac97995d51219f0c5a0cd1fa54
[2] https://lore.kernel.org/netdev/20210725103630.23864-1-paskripkin@gmail.com/
v1 -> v2
Fixed compilation error in 3rd patch
Fixed cover letter
With regards,
Pavel Skripkin
Pavel Skripkin (3):
can: usb_8dev: fix memory leak
can: ems_usb: fix memory leak
can: esd_usb2: fix memory leak
drivers/net/can/usb/ems_usb.c | 14 +++++++++++++-
drivers/net/can/usb/esd_usb2.c | 16 +++++++++++++++-
drivers/net/can/usb/usb_8dev.c | 15 +++++++++++++--
3 files changed, 41 insertions(+), 4 deletions(-)
--
2.32.0
From: Pavel Skripkin <hidden> Date: 2021-07-27 17:00:19
In usb_8dev_start() MAX_RX_URBS coherent buffers are allocated and there
is nothing, that frees them:
1) In callback function the urb is resubmitted and that's all
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER
is not set (see usb_8dev_start) and this flag cannot be used with
coherent buffers.
So, all allocated buffers should be freed with usb_free_coherent()
explicitly.
Side note: This code looks like a copy-paste of other can drivers.
The same patch was applied to mcba_usb driver and it works nice
with real hardware. There is no change in functionality, only clean-up
code for coherent buffers
Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices")
Signed-off-by: Pavel Skripkin <redacted>
---
drivers/net/can/usb/usb_8dev.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
@@ -733,6 +734,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)for(i=0;i<MAX_RX_URBS;i++){structurb*urb=NULL;u8*buf;+dma_addr_tbuf_dma;/* create a URB, and a buffer for it */urb=usb_alloc_urb(0,GFP_KERNEL);
@@ -742,7 +744,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)}buf=usb_alloc_coherent(priv->udev,RX_BUFFER_SIZE,GFP_KERNEL,-&urb->transfer_dma);+&buf_dma);if(!buf){netdev_err(netdev,"No memory left for USB buffer\n");usb_free_urb(urb);
@@ -750,6 +752,8 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)break;}+urb->transfer_dma=buf_dma;+usb_fill_bulk_urb(urb,priv->udev,usb_rcvbulkpipe(priv->udev,USB_8DEV_ENDP_DATA_RX),
@@ -767,6 +771,9 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)break;}+priv->rxbuf[i]=buf;+priv->rxbuf_dma[i]=buf_dma;+/* Drop reference, USB core will take care of freeing it */usb_free_urb(urb);}
From: Pavel Skripkin <hidden> Date: 2021-07-27 17:00:41
In ems_usb_start() MAX_RX_URBS coherent buffers are allocated and there
is nothing, that frees them:
1) In callback function the urb is resubmitted and that's all
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER
is not set (see ems_usb_start) and this flag cannot be used with
coherent buffers.
So, all allocated buffers should be freed with usb_free_coherent()
explicitly.
Side note: This code looks like a copy-paste of other can drivers.
The same patch was applied to mcba_usb driver and it works nice
with real hardware. There is no change in functionality, only clean-up
code for coherent buffers
Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
Signed-off-by: Pavel Skripkin <redacted>
---
drivers/net/can/usb/ems_usb.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
@@ -255,6 +255,8 @@ struct ems_usb {unsignedintfree_slots;/* remember number of available slots */structems_cpc_msgactive_params;/* active controller parameters */+void*rxbuf[MAX_RX_URBS];+dma_addr_trxbuf_dma[MAX_RX_URBS];};staticvoidems_usb_read_interrupt_callback(structurb*urb)
@@ -587,6 +589,7 @@ static int ems_usb_start(struct ems_usb *dev)for(i=0;i<MAX_RX_URBS;i++){structurb*urb=NULL;u8*buf=NULL;+dma_addr_tbuf_dma;/* create a URB, and a buffer for it */urb=usb_alloc_urb(0,GFP_KERNEL);
@@ -596,7 +599,7 @@ static int ems_usb_start(struct ems_usb *dev)}buf=usb_alloc_coherent(dev->udev,RX_BUFFER_SIZE,GFP_KERNEL,-&urb->transfer_dma);+&buf_dma);if(!buf){netdev_err(netdev,"No memory left for USB buffer\n");usb_free_urb(urb);
@@ -604,6 +607,8 @@ static int ems_usb_start(struct ems_usb *dev)break;}+urb->transfer_dma=buf_dma;+usb_fill_bulk_urb(urb,dev->udev,usb_rcvbulkpipe(dev->udev,2),buf,RX_BUFFER_SIZE,ems_usb_read_bulk_callback,dev);
@@ -619,6 +624,9 @@ static int ems_usb_start(struct ems_usb *dev)break;}+dev->rxbuf[i]=buf;+dev->rxbuf_dma[i]=buf_dma;+/* Drop reference, USB core will take care of freeing it */usb_free_urb(urb);}
From: Pavel Skripkin <hidden> Date: 2021-07-27 17:00:57
In esd_usb2_setup_rx_urbs() MAX_RX_URBS coherent buffers are
allocated and there is nothing, that frees them:
1) In callback function the urb is resubmitted and that's all
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER
is not set (see esd_usb2_setup_rx_urbs) and this flag cannot be used
with coherent buffers.
So, all allocated buffers should be freed with usb_free_coherent()
explicitly.
Side note: This code looks like a copy-paste of other can drivers.
The same patch was applied to mcba_usb driver and it works nice
with real hardware. There is no change in functionality, only clean-up
code for coherent buffers
Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device")
Signed-off-by: Pavel Skripkin <redacted>
---
drivers/net/can/usb/esd_usb2.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
@@ -545,6 +547,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)for(i=0;i<MAX_RX_URBS;i++){structurb*urb=NULL;u8*buf=NULL;+dma_addr_tbuf_dma;/* create a URB, and a buffer for it */urb=usb_alloc_urb(0,GFP_KERNEL);
@@ -554,7 +557,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)}buf=usb_alloc_coherent(dev->udev,RX_BUFFER_SIZE,GFP_KERNEL,-&urb->transfer_dma);+&buf_dma);if(!buf){dev_warn(dev->udev->dev.parent,"No memory left for USB buffer\n");
@@ -562,6 +565,8 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)gotofreeurb;}+urb->transfer_dma=buf_dma;+usb_fill_bulk_urb(urb,dev->udev,usb_rcvbulkpipe(dev->udev,1),buf,RX_BUFFER_SIZE,
@@ -574,8 +579,12 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)usb_unanchor_urb(urb);usb_free_coherent(dev->udev,RX_BUFFER_SIZE,buf,urb->transfer_dma);+gotofreeurb;}+dev->rxbuf[i]=buf;+dev->rxbuf_dma[i]=buf_dma;+freeurb:/* Drop reference, USB core will take care of freeing it */usb_free_urb(urb);
From: Marc Kleine-Budde <mkl@pengutronix.de> Date: 2021-07-28 07:56:27
On 27.07.2021 19:59:12, Pavel Skripkin wrote:
Hi, Marc and can drivers maintainers/reviewers!
A long time ago syzbot reported memory leak in mcba_usb can driver[1]. It was
using strange pattern for allocating coherent buffers, which was leading to
memory leaks. I fixed this wrong pattern in mcba_usb driver and yesterday I got
a report, that mcba_usb stopped working since my commit. I came up with quick fix
and all started working well.
There are at least 3 more drivers with this pattern, I decided to fix leaks
in them too, since code is actually the same (I guess, driver authors just copy pasted
code parts). Each of following patches is combination of 91c02557174b
("can: mcba_usb: fix memory leak in mcba_usb") and my yesterday fix [2].
Dear maintainers/reviewers, if You have one of these hardware pieces, please, test
these patches and report any errors you will find.
Added to linux-can-next/testing.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung West/Dortmund | Phone: +49-231-2826-924 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |