diff mbox series

[1/4] usbip: add sysfs_lock to synchronize sysfs code paths

Message ID 20210416205319.14075-1-tseewald@gmail.com
State New
Headers show
Series [1/4] usbip: add sysfs_lock to synchronize sysfs code paths | expand

Commit Message

Tom Seewald April 16, 2021, 8:53 p.m. UTC
From: Shuah Khan <skhan@linuxfoundation.org>

commit 4e9c93af7279b059faf5bb1897ee90512b258a12 upstream.

Fuzzing uncovered race condition between sysfs code paths in usbip
drivers. Device connect/disconnect code paths initiated through
sysfs interface are prone to races if disconnect happens during
connect and vice versa.

This problem is common to all drivers while it can be reproduced easily
in vhci_hcd. Add a sysfs_lock to usbip_device struct to protect the paths.

Use this in vhci_hcd to protect sysfs paths. For a complete fix, usip_host
and usip-vudc drivers and the event handler will have to use this lock to
protect the paths. These changes will be done in subsequent patches.

Cc: stable@vger.kernel.org # 4.9.x
Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
Link: https://lore.kernel.org/r/b6568f7beae702bbc236a545d3c020106ca75eac.1616807117.git.skhan@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Tom Seewald <tseewald@gmail.com>
---
 drivers/usb/usbip/usbip_common.h |  3 +++
 drivers/usb/usbip/vhci_hcd.c     |  1 +
 drivers/usb/usbip/vhci_sysfs.c   | 30 +++++++++++++++++++++++++-----
 3 files changed, 29 insertions(+), 5 deletions(-)

Comments

Shuah Khan April 16, 2021, 9:44 p.m. UTC | #1
On 4/16/21 2:53 PM, Tom Seewald wrote:
> From: Shuah Khan <skhan@linuxfoundation.org>
> 
> commit 9dbf34a834563dada91366c2ac266f32ff34641a upstream.
> 
> Fuzzing uncovered race condition between sysfs code paths in usbip
> drivers. Device connect/disconnect code paths initiated through
> sysfs interface are prone to races if disconnect happens during
> connect and vice versa.
> 
> Use sysfs_lock to protect sysfs paths in stub-dev.
> 
> Cc: stable@vger.kernel.org # 4.9.x
> Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com
> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
> Link: https://lore.kernel.org/r/2b182f3561b4a065bf3bf6dce3b0e9944ba17b3f.1616807117.git.skhan@linuxfoundation.org
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Tom Seewald <tseewald@gmail.com>
> ---


Thank you for the backport.

Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>

Greg, please pick this up for 4.9.x

thanks,
-- Shuah
Shuah Khan April 16, 2021, 9:45 p.m. UTC | #2
On 4/16/21 2:53 PM, Tom Seewald wrote:
> From: Shuah Khan <skhan@linuxfoundation.org>
> 
> commit 363eaa3a450abb4e63bd6e3ad79d1f7a0f717814 upstream.
> 
> Fuzzing uncovered race condition between sysfs code paths in usbip
> drivers. Device connect/disconnect code paths initiated through
> sysfs interface are prone to races if disconnect happens during
> connect and vice versa.
> 
> Use sysfs_lock to synchronize event handler with sysfs paths
> in usbip drivers.
> 
> Cc: stable@vger.kernel.org # 4.9.x
> Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com
> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
> Link: https://lore.kernel.org/r/c5c8723d3f29dfe3d759cfaafa7dd16b0dfe2918.1616807117.git.skhan@linuxfoundation.org
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Tom Seewald <tseewald@gmail.com>
> ---
>   drivers/usb/usbip/usbip_event.c | 2 ++
>   1 file changed, 2 insertions(+)
> 

Thank you for the backport.

Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>

Greg, please pick this up for 4.9.x

thanks,
-- Shuah
Greg Kroah-Hartman April 19, 2021, 12:23 p.m. UTC | #3
On Fri, Apr 16, 2021 at 03:43:45PM -0600, Shuah Khan wrote:
> On 4/16/21 2:53 PM, Tom Seewald wrote:

> > From: Shuah Khan <skhan@linuxfoundation.org>

> > 

> > commit 4e9c93af7279b059faf5bb1897ee90512b258a12 upstream.

> > 

> > Fuzzing uncovered race condition between sysfs code paths in usbip

> > drivers. Device connect/disconnect code paths initiated through

> > sysfs interface are prone to races if disconnect happens during

> > connect and vice versa.

> > 

> > This problem is common to all drivers while it can be reproduced easily

> > in vhci_hcd. Add a sysfs_lock to usbip_device struct to protect the paths.

> > 

> > Use this in vhci_hcd to protect sysfs paths. For a complete fix, usip_host

> > and usip-vudc drivers and the event handler will have to use this lock to

> > protect the paths. These changes will be done in subsequent patches.

> > 

> > Cc: stable@vger.kernel.org # 4.9.x

> > Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com

> > Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

> > Link: https://lore.kernel.org/r/b6568f7beae702bbc236a545d3c020106ca75eac.1616807117.git.skhan@linuxfoundation.org

> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

> > Signed-off-by: Tom Seewald <tseewald@gmail.com>

> > ---

> >   drivers/usb/usbip/usbip_common.h |  3 +++

> >   drivers/usb/usbip/vhci_hcd.c     |  1 +

> >   drivers/usb/usbip/vhci_sysfs.c   | 30 +++++++++++++++++++++++++-----

> >   3 files changed, 29 insertions(+), 5 deletions(-)

> > 

> 

> Thank you for the backport.

> 

> Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>

> 

> Greg, please pick this up for 4.9.x


Also for 4.14.y, right?
Shuah Khan April 19, 2021, 9:42 p.m. UTC | #4
On 4/19/21 6:23 AM, Greg Kroah-Hartman wrote:
> On Fri, Apr 16, 2021 at 03:43:45PM -0600, Shuah Khan wrote:

>> On 4/16/21 2:53 PM, Tom Seewald wrote:

>>> From: Shuah Khan <skhan@linuxfoundation.org>

>>>

>>> commit 4e9c93af7279b059faf5bb1897ee90512b258a12 upstream.

>>>

>>> Fuzzing uncovered race condition between sysfs code paths in usbip

>>> drivers. Device connect/disconnect code paths initiated through

>>> sysfs interface are prone to races if disconnect happens during

>>> connect and vice versa.

>>>

>>> This problem is common to all drivers while it can be reproduced easily

>>> in vhci_hcd. Add a sysfs_lock to usbip_device struct to protect the paths.

>>>

>>> Use this in vhci_hcd to protect sysfs paths. For a complete fix, usip_host

>>> and usip-vudc drivers and the event handler will have to use this lock to

>>> protect the paths. These changes will be done in subsequent patches.

>>>

>>> Cc: stable@vger.kernel.org # 4.9.x

>>> Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com

>>> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

>>> Link: https://lore.kernel.org/r/b6568f7beae702bbc236a545d3c020106ca75eac.1616807117.git.skhan@linuxfoundation.org

>>> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

>>> Signed-off-by: Tom Seewald <tseewald@gmail.com>

>>> ---

>>>    drivers/usb/usbip/usbip_common.h |  3 +++

>>>    drivers/usb/usbip/vhci_hcd.c     |  1 +

>>>    drivers/usb/usbip/vhci_sysfs.c   | 30 +++++++++++++++++++++++++-----

>>>    3 files changed, 29 insertions(+), 5 deletions(-)

>>>

>>

>> Thank you for the backport.

>>

>> Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>

>>

>> Greg, please pick this up for 4.9.x

> 

> Also for 4.14.y, right?

> 


It made it into 4.14 already. We are good with 4.14.y

5f2a149564ee2b41ab09e90add21153bd5be64d3

thanks,
-- Shuah
Greg Kroah-Hartman April 20, 2021, 7:30 a.m. UTC | #5
On Mon, Apr 19, 2021 at 03:42:06PM -0600, Shuah Khan wrote:
> On 4/19/21 6:23 AM, Greg Kroah-Hartman wrote:

> > On Fri, Apr 16, 2021 at 03:43:45PM -0600, Shuah Khan wrote:

> > > On 4/16/21 2:53 PM, Tom Seewald wrote:

> > > > From: Shuah Khan <skhan@linuxfoundation.org>

> > > > 

> > > > commit 4e9c93af7279b059faf5bb1897ee90512b258a12 upstream.

> > > > 

> > > > Fuzzing uncovered race condition between sysfs code paths in usbip

> > > > drivers. Device connect/disconnect code paths initiated through

> > > > sysfs interface are prone to races if disconnect happens during

> > > > connect and vice versa.

> > > > 

> > > > This problem is common to all drivers while it can be reproduced easily

> > > > in vhci_hcd. Add a sysfs_lock to usbip_device struct to protect the paths.

> > > > 

> > > > Use this in vhci_hcd to protect sysfs paths. For a complete fix, usip_host

> > > > and usip-vudc drivers and the event handler will have to use this lock to

> > > > protect the paths. These changes will be done in subsequent patches.

> > > > 

> > > > Cc: stable@vger.kernel.org # 4.9.x

> > > > Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com

> > > > Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

> > > > Link: https://lore.kernel.org/r/b6568f7beae702bbc236a545d3c020106ca75eac.1616807117.git.skhan@linuxfoundation.org

> > > > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

> > > > Signed-off-by: Tom Seewald <tseewald@gmail.com>

> > > > ---

> > > >    drivers/usb/usbip/usbip_common.h |  3 +++

> > > >    drivers/usb/usbip/vhci_hcd.c     |  1 +

> > > >    drivers/usb/usbip/vhci_sysfs.c   | 30 +++++++++++++++++++++++++-----

> > > >    3 files changed, 29 insertions(+), 5 deletions(-)

> > > > 

> > > 

> > > Thank you for the backport.

> > > 

> > > Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>

> > > 

> > > Greg, please pick this up for 4.9.x

> > 

> > Also for 4.14.y, right?

> > 

> 

> It made it into 4.14 already. We are good with 4.14.y

> 

> 5f2a149564ee2b41ab09e90add21153bd5be64d3


Ugh, sorry, my fault, I hadn't updated my "what was released in what
stable version" on my laptop that I was working from yesterday.  They
are obviously all merged in 4.14 :(

Thanks for this.

greg k-h
diff mbox series

Patch

diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
index 0b199a2664c0..3d47c681aea2 100644
--- a/drivers/usb/usbip/usbip_common.h
+++ b/drivers/usb/usbip/usbip_common.h
@@ -278,6 +278,9 @@  struct usbip_device {
 	/* lock for status */
 	spinlock_t lock;
 
+	/* mutex for synchronizing sysfs store paths */
+	struct mutex sysfs_lock;
+
 	int sockfd;
 	struct socket *tcp_socket;
 
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index 8bda6455dfcb..fb7b03029b8e 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -907,6 +907,7 @@  static void vhci_device_init(struct vhci_device *vdev)
 	vdev->ud.side   = USBIP_VHCI;
 	vdev->ud.status = VDEV_ST_NULL;
 	spin_lock_init(&vdev->ud.lock);
+	mutex_init(&vdev->ud.sysfs_lock);
 
 	INIT_LIST_HEAD(&vdev->priv_rx);
 	INIT_LIST_HEAD(&vdev->priv_tx);
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index ca00d38d22af..3496b402aa1b 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -161,6 +161,8 @@  static int vhci_port_disconnect(struct vhci_hcd *vhci, __u32 rhport)
 
 	usbip_dbg_vhci_sysfs("enter\n");
 
+	mutex_lock(&vdev->ud.sysfs_lock);
+
 	/* lock */
 	spin_lock_irqsave(&vhci->lock, flags);
 	spin_lock(&vdev->ud.lock);
@@ -171,6 +173,7 @@  static int vhci_port_disconnect(struct vhci_hcd *vhci, __u32 rhport)
 		/* unlock */
 		spin_unlock(&vdev->ud.lock);
 		spin_unlock_irqrestore(&vhci->lock, flags);
+		mutex_unlock(&vdev->ud.sysfs_lock);
 
 		return -EINVAL;
 	}
@@ -181,6 +184,8 @@  static int vhci_port_disconnect(struct vhci_hcd *vhci, __u32 rhport)
 
 	usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
 
+	mutex_unlock(&vdev->ud.sysfs_lock);
+
 	return 0;
 }
 
@@ -309,30 +314,36 @@  static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
 	vhci = hcd_to_vhci(hcd);
 	vdev = &vhci->vdev[rhport];
 
+	mutex_lock(&vdev->ud.sysfs_lock);
+
 	/* Extract socket from fd. */
 	socket = sockfd_lookup(sockfd, &err);
 	if (!socket) {
 		dev_err(dev, "failed to lookup sock");
-		return -EINVAL;
+		err = -EINVAL;
+		goto unlock_mutex;
 	}
 	if (socket->type != SOCK_STREAM) {
 		dev_err(dev, "Expecting SOCK_STREAM - found %d",
 			socket->type);
 		sockfd_put(socket);
-		return -EINVAL;
+		err = -EINVAL;
+		goto unlock_mutex;
 	}
 
 	/* create threads before locking */
 	tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
 	if (IS_ERR(tcp_rx)) {
 		sockfd_put(socket);
-		return -EINVAL;
+		err = -EINVAL;
+		goto unlock_mutex;
 	}
 	tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
 	if (IS_ERR(tcp_tx)) {
 		kthread_stop(tcp_rx);
 		sockfd_put(socket);
-		return -EINVAL;
+		err = -EINVAL;
+		goto unlock_mutex;
 	}
 
 	/* get task structs now */
@@ -353,7 +364,8 @@  static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
 		kthread_stop_put(tcp_tx);
 
 		dev_err(dev, "port %d already used\n", rhport);
-		return -EINVAL;
+		err = -EINVAL;
+		goto unlock_mutex;
 	}
 
 	dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
@@ -378,7 +390,15 @@  static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
 
 	rh_port_connect(vdev, speed);
 
+	dev_info(dev, "Device attached\n");
+
+	mutex_unlock(&vdev->ud.sysfs_lock);
+
 	return count;
+
+unlock_mutex:
+	mutex_unlock(&vdev->ud.sysfs_lock);
+	return err;
 }
 static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);