1 |
From 0e865f0c31928d6a313269ef624907eec55287c4 Mon Sep 17 00:00:00 2001 |
2 |
From: Pavel Skripkin <paskripkin@gmail.com> |
3 |
Date: Tue, 27 Jul 2021 19:59:57 +0300 |
4 |
Subject: can: usb_8dev: fix memory leak |
5 |
|
6 |
From: Pavel Skripkin <paskripkin@gmail.com> |
7 |
|
8 |
commit 0e865f0c31928d6a313269ef624907eec55287c4 upstream. |
9 |
|
10 |
In usb_8dev_start() MAX_RX_URBS coherent buffers are allocated and |
11 |
there is nothing, that frees them: |
12 |
|
13 |
1) In callback function the urb is resubmitted and that's all |
14 |
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER |
15 |
is not set (see usb_8dev_start) and this flag cannot be used with |
16 |
coherent buffers. |
17 |
|
18 |
So, all allocated buffers should be freed with usb_free_coherent() |
19 |
explicitly. |
20 |
|
21 |
Side note: This code looks like a copy-paste of other can drivers. The |
22 |
same patch was applied to mcba_usb driver and it works nice with real |
23 |
hardware. There is no change in functionality, only clean-up code for |
24 |
coherent buffers. |
25 |
|
26 |
Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices") |
27 |
Link: https://lore.kernel.org/r/d39b458cd425a1cf7f512f340224e6e9563b07bd.1627404470.git.paskripkin@gmail.com |
28 |
Cc: linux-stable <stable@vger.kernel.org> |
29 |
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> |
30 |
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> |
31 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
32 |
--- |
33 |
drivers/net/can/usb/usb_8dev.c | 15 +++++++++++++-- |
34 |
1 file changed, 13 insertions(+), 2 deletions(-) |
35 |
|
36 |
--- a/drivers/net/can/usb/usb_8dev.c |
37 |
+++ b/drivers/net/can/usb/usb_8dev.c |
38 |
@@ -137,7 +137,8 @@ struct usb_8dev_priv { |
39 |
u8 *cmd_msg_buffer; |
40 |
|
41 |
struct mutex usb_8dev_cmd_lock; |
42 |
- |
43 |
+ void *rxbuf[MAX_RX_URBS]; |
44 |
+ dma_addr_t rxbuf_dma[MAX_RX_URBS]; |
45 |
}; |
46 |
|
47 |
/* tx frame */ |
48 |
@@ -733,6 +734,7 @@ static int usb_8dev_start(struct usb_8de |
49 |
for (i = 0; i < MAX_RX_URBS; i++) { |
50 |
struct urb *urb = NULL; |
51 |
u8 *buf; |
52 |
+ dma_addr_t buf_dma; |
53 |
|
54 |
/* create a URB, and a buffer for it */ |
55 |
urb = usb_alloc_urb(0, GFP_KERNEL); |
56 |
@@ -742,7 +744,7 @@ static int usb_8dev_start(struct usb_8de |
57 |
} |
58 |
|
59 |
buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, |
60 |
- &urb->transfer_dma); |
61 |
+ &buf_dma); |
62 |
if (!buf) { |
63 |
netdev_err(netdev, "No memory left for USB buffer\n"); |
64 |
usb_free_urb(urb); |
65 |
@@ -750,6 +752,8 @@ static int usb_8dev_start(struct usb_8de |
66 |
break; |
67 |
} |
68 |
|
69 |
+ urb->transfer_dma = buf_dma; |
70 |
+ |
71 |
usb_fill_bulk_urb(urb, priv->udev, |
72 |
usb_rcvbulkpipe(priv->udev, |
73 |
USB_8DEV_ENDP_DATA_RX), |
74 |
@@ -767,6 +771,9 @@ static int usb_8dev_start(struct usb_8de |
75 |
break; |
76 |
} |
77 |
|
78 |
+ priv->rxbuf[i] = buf; |
79 |
+ priv->rxbuf_dma[i] = buf_dma; |
80 |
+ |
81 |
/* Drop reference, USB core will take care of freeing it */ |
82 |
usb_free_urb(urb); |
83 |
} |
84 |
@@ -836,6 +843,10 @@ static void unlink_all_urbs(struct usb_8 |
85 |
|
86 |
usb_kill_anchored_urbs(&priv->rx_submitted); |
87 |
|
88 |
+ for (i = 0; i < MAX_RX_URBS; ++i) |
89 |
+ usb_free_coherent(priv->udev, RX_BUFFER_SIZE, |
90 |
+ priv->rxbuf[i], priv->rxbuf_dma[i]); |
91 |
+ |
92 |
usb_kill_anchored_urbs(&priv->tx_submitted); |
93 |
atomic_set(&priv->active_tx_urbs, 0); |
94 |
|