aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/usbip
diff options
context:
space:
mode:
authorBernard Blackham <bernard@largestprime.net>2012-10-22 06:45:00 +1100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-22 13:38:04 -0700
commit3d0a2a22c91e58bfe933115d63cdce60ad2b3a11 (patch)
tree73c1fdcac0186bcadb54124a94d92d6b971f7c9b /drivers/staging/usbip
parentc7f0089931dfaefba81001c88449250867582ba6 (diff)
staging: usbip: Don't leak struct file.
usbip takes a reference on a struct file which is passed in via sysfs. Previously, this reference was never cleaned up, although the socket it referred to was. This patch drops the corresponding reference (found with the socket's ->file backpointer) instead of just closing the socket. Signed-off-by: Bernard Blackham <b-linuxgit@largestprime.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/usbip')
-rw-r--r--drivers/staging/usbip/stub_dev.c3
-rw-r--r--drivers/staging/usbip/usbip_common.c4
-rw-r--r--drivers/staging/usbip/vhci_hcd.c10
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c6
4 files changed, 17 insertions, 6 deletions
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index 1e1eb4c14d7..79298d06863 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -18,6 +18,7 @@
*/
#include <linux/device.h>
+#include <linux/file.h>
#include <linux/kthread.h>
#include <linux/module.h>
@@ -203,7 +204,7 @@ static void stub_shutdown_connection(struct usbip_device *ud)
* not touch NULL socket.
*/
if (ud->tcp_socket) {
- sock_release(ud->tcp_socket);
+ fput(ud->tcp_socket->file);
ud->tcp_socket = NULL;
}
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 4a10034ff2c..75189feac38 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -413,8 +413,10 @@ struct socket *sockfd_to_socket(unsigned int sockfd)
inode = file->f_dentry->d_inode;
- if (!inode || !S_ISSOCK(inode->i_mode))
+ if (!inode || !S_ISSOCK(inode->i_mode)) {
+ fput(file);
return NULL;
+ }
socket = SOCKET_I(inode);
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index a6143781e2a..77d77f72cb1 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -18,6 +18,7 @@
*/
#include <linux/init.h>
+#include <linux/file.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
@@ -804,8 +805,8 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
pr_info("stop threads\n");
/* active connection is closed */
- if (vdev->ud.tcp_socket != NULL) {
- sock_release(vdev->ud.tcp_socket);
+ if (vdev->ud.tcp_socket) {
+ fput(vdev->ud.tcp_socket->file);
vdev->ud.tcp_socket = NULL;
}
pr_info("release socket\n");
@@ -851,7 +852,10 @@ static void vhci_device_reset(struct usbip_device *ud)
usb_put_dev(vdev->udev);
vdev->udev = NULL;
- ud->tcp_socket = NULL;
+ if (ud->tcp_socket) {
+ fput(ud->tcp_socket->file);
+ ud->tcp_socket = NULL;
+ }
ud->status = VDEV_ST_NULL;
spin_unlock(&ud->lock);
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index 7ce9c2f7e44..c66e9c05c76 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -18,6 +18,7 @@
*/
#include <linux/kthread.h>
+#include <linux/file.h>
#include <linux/net.h>
#include "usbip_common.h"
@@ -189,7 +190,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
if (valid_args(rhport, speed) < 0)
return -EINVAL;
- /* check sockfd */
+ /* Extract socket from fd. */
+ /* The correct way to clean this up is to fput(socket->file). */
socket = sockfd_to_socket(sockfd);
if (!socket)
return -EINVAL;
@@ -206,6 +208,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
spin_unlock(&vdev->ud.lock);
spin_unlock(&the_controller->lock);
+ fput(socket->file);
+
dev_err(dev, "port %d already used\n", rhport);
return -EINVAL;
}