Commit 3d0a2a22 authored by Bernard Blackham's avatar Bernard Blackham Committed by Greg Kroah-Hartman

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: default avatarBernard Blackham <b-linuxgit@largestprime.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c7f00899
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/file.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -203,7 +204,7 @@ static void stub_shutdown_connection(struct usbip_device *ud) ...@@ -203,7 +204,7 @@ static void stub_shutdown_connection(struct usbip_device *ud)
* not touch NULL socket. * not touch NULL socket.
*/ */
if (ud->tcp_socket) { if (ud->tcp_socket) {
sock_release(ud->tcp_socket); fput(ud->tcp_socket->file);
ud->tcp_socket = NULL; ud->tcp_socket = NULL;
} }
......
...@@ -413,8 +413,10 @@ struct socket *sockfd_to_socket(unsigned int sockfd) ...@@ -413,8 +413,10 @@ struct socket *sockfd_to_socket(unsigned int sockfd)
inode = file->f_dentry->d_inode; inode = file->f_dentry->d_inode;
if (!inode || !S_ISSOCK(inode->i_mode)) if (!inode || !S_ISSOCK(inode->i_mode)) {
fput(file);
return NULL; return NULL;
}
socket = SOCKET_I(inode); socket = SOCKET_I(inode);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/file.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -804,8 +805,8 @@ static void vhci_shutdown_connection(struct usbip_device *ud) ...@@ -804,8 +805,8 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
pr_info("stop threads\n"); pr_info("stop threads\n");
/* active connection is closed */ /* active connection is closed */
if (vdev->ud.tcp_socket != NULL) { if (vdev->ud.tcp_socket) {
sock_release(vdev->ud.tcp_socket); fput(vdev->ud.tcp_socket->file);
vdev->ud.tcp_socket = NULL; vdev->ud.tcp_socket = NULL;
} }
pr_info("release socket\n"); pr_info("release socket\n");
...@@ -851,7 +852,10 @@ static void vhci_device_reset(struct usbip_device *ud) ...@@ -851,7 +852,10 @@ static void vhci_device_reset(struct usbip_device *ud)
usb_put_dev(vdev->udev); usb_put_dev(vdev->udev);
vdev->udev = NULL; vdev->udev = NULL;
if (ud->tcp_socket) {
fput(ud->tcp_socket->file);
ud->tcp_socket = NULL; ud->tcp_socket = NULL;
}
ud->status = VDEV_ST_NULL; ud->status = VDEV_ST_NULL;
spin_unlock(&ud->lock); spin_unlock(&ud->lock);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
*/ */
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/file.h>
#include <linux/net.h> #include <linux/net.h>
#include "usbip_common.h" #include "usbip_common.h"
...@@ -189,7 +190,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, ...@@ -189,7 +190,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
if (valid_args(rhport, speed) < 0) if (valid_args(rhport, speed) < 0)
return -EINVAL; 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); socket = sockfd_to_socket(sockfd);
if (!socket) if (!socket)
return -EINVAL; return -EINVAL;
...@@ -206,6 +208,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, ...@@ -206,6 +208,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
spin_unlock(&vdev->ud.lock); spin_unlock(&vdev->ud.lock);
spin_unlock(&the_controller->lock); spin_unlock(&the_controller->lock);
fput(socket->file);
dev_err(dev, "port %d already used\n", rhport); dev_err(dev, "port %d already used\n", rhport);
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment