[PATCH] usbip: vhc_hcd: prevent module being removed while device are attached

From: Shuah Khan
Date: Mon Apr 02 2018 - 16:53:17 EST


vhci_hcd module can be removed even when devices are attached. Fix to
prevent module removal when devices are still attached.

Signed-off-by: Shuah Khan <shuahkh@xxxxxxxxxxxxxxx>
---
drivers/usb/usbip/vhci_sysfs.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index 48808388ec33..6a54b9aa92be 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -9,6 +9,7 @@
#include <linux/net.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/module.h>

#include "usbip_common.h"
#include "vhci.h"
@@ -252,6 +253,8 @@ static ssize_t detach_store(struct device *dev, struct device_attribute *attr,
if (ret < 0)
return -EINVAL;

+ module_put(THIS_MODULE);
+
usbip_dbg_vhci_sysfs("Leave\n");

return count;
@@ -302,7 +305,7 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
struct vhci_hcd *vhci_hcd;
struct vhci_device *vdev;
struct vhci *vhci;
- int err;
+ int err, ret;
unsigned long flags;

/*
@@ -339,10 +342,18 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
else
vdev = &vhci->vhci_hcd_hs->vdev[rhport];

+ /* get module ref to avoid being removed with active attached devs */
+ if (!try_module_get(THIS_MODULE)) {
+ ret = -EAGAIN;
+ goto module_get_err;
+ }
+
/* Extract socket from fd. */
socket = sockfd_lookup(sockfd, &err);
- if (!socket)
- return -EINVAL;
+ if (!socket) {
+ ret = -EINVAL;
+ goto error;
+ }

/* now need lock until setting vdev status as used */

@@ -362,7 +373,8 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
* Will be retried from userspace
* if there's another free port.
*/
- return -EBUSY;
+ ret = -EBUSY;
+ goto error;
}

dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
@@ -386,6 +398,11 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
rh_port_connect(vdev, speed);

return count;
+
+error:
+ module_put(THIS_MODULE);
+module_get_err:
+ return ret;
}
static DEVICE_ATTR_WO(attach);

--
2.14.1