spi: ch341: fix memory leaks and use-after-free
Subsystems (2)
cover spi: ch341: fix memory leaks and use-after-free
Fix probe error handling and devres lifetime to avoid memory leaks and use-after-free.
Johan
Johan Hovold (2):
spi: ch341: fix memory leaks on probe failures
spi: ch341: fix devres lifetime
drivers/spi/spi-ch341.c | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-)
Signature · 1 line
2.52.0
PATCH 1/2 spi: ch341: fix memory leaks on probe failures
Make sure to deregister the controller, disable pins, and kill and free the RX URB on probe failures to mirror disconnect and avoid memory leaks and use-after-free.
Also add an explicit URB kill on disconnect for symmetry (even if that is not strictly required as USB core would have stopped it in the current setup).
--- drivers/spi/spi-ch341.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-)
drivers/spi/spi-ch341.c +25 -11
@@ -173,17 +173,17 @@ static int ch341_probe(struct usb_interface *intf, ch341->tx_buf =devm_kzalloc (&udev->dev,CH341_PACKET_LENGTH ,GFP_KERNEL ); -if (!ch341->tx_buf) -return -ENOMEM ; +if (!ch341->tx_buf) { + ret = -ENOMEM ; + goto err_free_urb; + }usb_fill_bulk_urb (ch341->rx_urb, udev, ch341->read_pipe, ch341->rx_buf, ch341->rx_len, ch341_recv, ch341); ret =usb_submit_urb (ch341->rx_urb,GFP_KERNEL ); -if (ret) { -usb_free_urb (ch341->rx_urb); -return -ENOMEM ; - } +if (ret) + goto err_free_urb; ctrl->bus_num =-1 ; ctrl->mode_bits =SPI_CPHA ;
@@ -195,21 +195,34 @@ static int ch341_probe(struct usb_interface *intf, ret =ch341_config_stream (ch341);if (ret) -return ret; + goto err_kill_urb; ret =ch341_enable_pins (ch341, true);if (ret) -return ret; + goto err_kill_urb; ret =spi_register_controller (ctrl);if (ret) -return ret; + goto err_disable_pins; ch341->spidev =spi_new_device (ctrl, &chip); -if (!ch341->spidev) -return -ENOMEM ; +if (!ch341->spidev) { + ret = -ENOMEM ; + goto err_unregister; + }return 0 ; + +err_unregister: +spi_unregister_controller (ctrl); +err_disable_pins: +ch341_enable_pins (ch341, false); +err_kill_urb: +usb_kill_urb (ch341->rx_urb); +err_free_urb: +usb_free_urb (ch341->rx_urb); + +return ret; }static void ch341_disconnect (struct usb_interface *intf)
@@ -219,6 +232,7 @@ static void ch341_disconnect(struct usb_interface *intf)spi_unregister_device (ch341->spidev);spi_unregister_controller (ch341->ctrl);ch341_enable_pins (ch341, false); +usb_kill_urb (ch341->rx_urb);usb_free_urb (ch341->rx_urb); }
Signature · 1 line
2.52.0
PATCH 2/2 spi: ch341: fix devres lifetime
In reply to Johan HovoldUSB drivers bind to USB interfaces and any device managed resources should have their lifetime tied to the interface rather than parent USB device. This avoids issues like memory leaks when drivers are unbound without their devices being physically disconnected (e.g. on probe deferral or configuration changes).
Fix the controller and driver data lifetime so that they are released on driver unbind.
Note that this also makes sure that the SPI controller is placed correctly under the USB interface in the device tree.
--- drivers/spi/spi-ch341.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/spi/spi-ch341.c +3 -4
@@ -152,7 +152,7 @@ static int ch341_probe(struct usb_interface *intf,if (ret)return ret; - ctrl =devm_spi_alloc_host (&udev->dev,sizeof (struct ch341_spi_dev )); + ctrl =devm_spi_alloc_host (&intf->dev,sizeof (struct ch341_spi_dev ));if (!ctrl)return -ENOMEM ;
@@ -163,7 +163,7 @@ static int ch341_probe(struct usb_interface *intf, ch341->read_pipe =usb_rcvbulkpipe (udev,usb_endpoint_num (in)); ch341->rx_len =usb_endpoint_maxp (in); - ch341->rx_buf =devm_kzalloc (&udev->dev, ch341->rx_len,GFP_KERNEL ); + ch341->rx_buf =devm_kzalloc (&intf->dev, ch341->rx_len,GFP_KERNEL );if (!ch341->rx_buf)return -ENOMEM ;
@@ -171,8 +171,7 @@ static int ch341_probe(struct usb_interface *intf,if (!ch341->rx_urb)return -ENOMEM ; - ch341->tx_buf = -devm_kzalloc (&udev->dev,CH341_PACKET_LENGTH ,GFP_KERNEL ); + ch341->tx_buf =devm_kzalloc (&intf->dev,CH341_PACKET_LENGTH ,GFP_KERNEL );if (!ch341->tx_buf) { ret = -ENOMEM ; goto err_free_urb;
Signature · 1 line
2.52.0
Mark Brown
maintainerQuoted 8 lines · Johan Hovold
spi: ch341: fix memory leaks and use-after-free
Fix probe error handling and devres lifetime to avoid memory leaks and use-after-free.
Johan
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-7.1
Thanks!
[1/2] spi: ch341: fix memory leaks on probe failures
https://git.kernel.org/broonie/spi/c/b99e3ddb91b4 [2/2] spi: ch341: fix devres lifetime https://git.kernel.org/broonie/spi/c/abe572f630bc
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark