diff options
author | Romain Izard <romain.izard.pro@gmail.com> | 2018-09-20 10:49:04 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-01 20:59:02 -0400 |
commit | f2924d4b16ae138c2de6a0e73f526fb638330858 (patch) | |
tree | 2236f1758b03e710e950ee39bbb452163a8fc7e2 | |
parent | dcb44ac0601e7fcda6d9d9930fd80c7124240146 (diff) |
usb: cdc_acm: Do not leak URB buffers
When the ACM TTY port is disconnected, the URBs it uses must be killed, and
then the buffers must be freed. Unfortunately a previous refactor removed
the code freeing the buffers because it looked extremely similar to the
code killing the URBs.
As a result, there were many new leaks for each plug/unplug cycle of a
CDC-ACM device, that were detected by kmemleak.
Restore the missing code, and the memory leak is removed.
Fixes: ba8c931ded8d ("cdc-acm: refactor killing urbs")
Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>
Acked-by: Oliver Neukum <oneukum@suse.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f9b40a9dc4d3..bc03b0a690b4 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1514,6 +1514,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
1514 | { | 1514 | { |
1515 | struct acm *acm = usb_get_intfdata(intf); | 1515 | struct acm *acm = usb_get_intfdata(intf); |
1516 | struct tty_struct *tty; | 1516 | struct tty_struct *tty; |
1517 | int i; | ||
1517 | 1518 | ||
1518 | /* sibling interface is already cleaning up */ | 1519 | /* sibling interface is already cleaning up */ |
1519 | if (!acm) | 1520 | if (!acm) |
@@ -1544,6 +1545,11 @@ static void acm_disconnect(struct usb_interface *intf) | |||
1544 | 1545 | ||
1545 | tty_unregister_device(acm_tty_driver, acm->minor); | 1546 | tty_unregister_device(acm_tty_driver, acm->minor); |
1546 | 1547 | ||
1548 | usb_free_urb(acm->ctrlurb); | ||
1549 | for (i = 0; i < ACM_NW; i++) | ||
1550 | usb_free_urb(acm->wb[i].urb); | ||
1551 | for (i = 0; i < acm->rx_buflimit; i++) | ||
1552 | usb_free_urb(acm->read_urbs[i]); | ||
1547 | acm_write_buffers_free(acm); | 1553 | acm_write_buffers_free(acm); |
1548 | usb_free_coherent(acm->dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1554 | usb_free_coherent(acm->dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
1549 | acm_read_buffers_free(acm); | 1555 | acm_read_buffers_free(acm); |