Skip to contentSkip to conversation

Patch "can: gs_usb: fixed disconnect bug by removing erroneous use of kfree()" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Mar 12, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

can: gs_usb: fixed disconnect bug by removing erroneous use of kfree()

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
can-gs_usb-fixed-disconnect-bug-by-removing-erroneous-use-of-kfree.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From e9a2d81b1761093386a0bb8a4f51642ac785ef63 Mon Sep 17 00:00:00 2001

From: Maximilain Schneider <[email protected]>
Date: Tue, 23 Feb 2016 01:17:28 +0000
Subject: can: gs_usb: fixed disconnect bug by removing erroneous use of kfree()

From: Maximilain Schneider <[email protected]>

commit e9a2d81b1761093386a0bb8a4f51642ac785ef63 upstream.

gs_destroy_candev() erroneously calls kfree() on a struct gs_can *, which is allocated through alloc_candev() and should instead be freed using free_candev() alone.

The inappropriate use of kfree() causes the kernel to hang when gs_destroy_candev() is called.

Only the struct gs_usb * which is allocated through kzalloc() should be freed using kfree() when the device is disconnected.

---
 drivers/net/can/usb/gs_usb.c |   24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)
drivers/net/can/usb/gs_usb.c +11 -13
@@ -826,9 +826,8 @@ static struct gs_can *gs_make_candev(uns
 static void gs_destroy_candev(struct gs_can *dev)
 {
 	unregister_candev(dev->netdev);
-	free_candev(dev->netdev);
 	usb_kill_anchored_urbs(&dev->tx_submitted);
-	kfree(dev);
+	free_candev(dev->netdev);
 }
 
 static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -913,12 +912,15 @@ static int gs_usb_probe(struct usb_inter
 	for (i = 0; i < icount; i++) {
 		dev->canch[i] = gs_make_candev(i, intf);
 		if (IS_ERR_OR_NULL(dev->canch[i])) {
+			/* save error code to return later */
+			rc = PTR_ERR(dev->canch[i]);
+
 			/* on failure destroy previously created candevs */
 			icount = i;
-			for (i = 0; i < icount; i++) {
+			for (i = 0; i < icount; i++)
 				gs_destroy_candev(dev->canch[i]);
-				dev->canch[i] = NULL;
-			}
+
+			usb_kill_anchored_urbs(&dev->rx_submitted);
 			kfree(dev);
 			return rc;
 		}
@@ -939,16 +941,12 @@ static void gs_usb_disconnect(struct usb
 		return;
 	}
 
-	for (i = 0; i < GS_MAX_INTF; i++) {
-		struct gs_can *can = dev->canch[i];
-
-		if (!can)
-			continue;
-
-		gs_destroy_candev(can);
-	}
+	for (i = 0; i < GS_MAX_INTF; i++)
+		if (dev->canch[i])
+			gs_destroy_candev(dev->canch[i]);
 
 	usb_kill_anchored_urbs(&dev->rx_submitted);
+	kfree(dev);
 }
 
 static const struct usb_device_id gs_usb_table[] = {

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/can-gs_usb-fixed-disconnect-bug-by-removing-erroneous-use-of-kfree.patch