Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2127423pxb; Mon, 12 Apr 2021 15:22:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyBoOQ6XiME66AYVOUY2XRn0eRZjnhbYGMRVYpLHWnS/OE9CTeSTrhQzKOoOTO3lekl85n5 X-Received: by 2002:a62:4d85:0:b029:233:301f:781d with SMTP id a127-20020a624d850000b0290233301f781dmr26242509pfb.37.1618266126303; Mon, 12 Apr 2021 15:22:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618266126; cv=none; d=google.com; s=arc-20160816; b=xiPnJAXk+S/+F/oX4wOBvZVSe5Gzhtp30L6COZ7TSCblIQY92gQDq4hgGD8P95T2RE +FcAML+AxAQC9f6u5xZ1Q2vQb7zLepdARJedA3jsWxuGzW8AnI1xXRIWsXp7ayHRewNG V0U685c+v0x1a/+uiMZAadMA718yGRR9y/a7z/pPVKhPyAUZJML0Tz0fVlSEMk8rDHng t0l1yInYOO9JgL7wQ5acWNN611ssNKrH4RPtJ7SRNDA5gVBwcefLg2cM4g4C9oJVNdXB R6RmjG9GnFLZNJvufrFpibZkJ9x47PWTRx+aOWcYPaJFFrcbmcK0RoH8bRB+4qDhnMdG Gmxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ydWUqCtaMjlw6597oERVEhnjv0mHCrlYEpEl9NBPJQQ=; b=KBygmLNoYMjvp7FD+Y723NtjtTQJtJ/Uq+cPWtV1X3uXJ5/Em7RNC0WNUlHzlMfFQP 0Wz2+uZq2MuCRgo/TWtZ9ZE9iBMeRzAOSbCOsQlBBW0dKk+yJxqS++4FsYtisnVmpAyP zGdwP9nbQt9GceAKAiZWRWWZLtImoJMNFqO01bXYPySB1bFJXgD/Wb9AJ5QMsS8rEhCB YpsNBfRr2GimDVh8PkaF3dSRj1AIVj0p7WfTEG0SMlFoLuyEMj2sdJzybLZ4tOYkjY/e 2VBbnV4aftXcXV8Fy6TmcU26r+EiEQ4Q2zHJPMEV8JMAwII3mXAXKS99o+RGKg5Ceuxj qzSg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KOPTy31t; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r26si15464306pgd.246.2021.04.12.15.21.52; Mon, 12 Apr 2021 15:22:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KOPTy31t; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242481AbhDLJ2l (ORCPT + 99 others); Mon, 12 Apr 2021 05:28:41 -0400 Received: from mail.kernel.org ([198.145.29.99]:54810 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239999AbhDLJE2 (ORCPT ); Mon, 12 Apr 2021 05:04:28 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7556D61289; Mon, 12 Apr 2021 09:02:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1618218128; bh=nD1XbmUtLI57bRf4xzb+SI/BIIQnh6f3jKjJJIW1DMg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KOPTy31tfqeHFkdrUrBhlDdvZ6F+SK1Cz58Kp13VtyVJ5OyqQpgbH4/2lN5MEdCWW w373Ppb6mAQhbMdMOljw/ppf+pBxMnUr1YrnoyxxQ+DiIQS2UUlC3tXCgAThyLdSiu 0hEw0oPYj/mUzdZnmjHqVpfYIH6OKy+w2Gf72AiM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Shuah Khan , syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com Subject: [PATCH 5.11 080/210] usbip: add sysfs_lock to synchronize sysfs code paths Date: Mon, 12 Apr 2021 10:39:45 +0200 Message-Id: <20210412084018.683740022@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210412084016.009884719@linuxfoundation.org> References: <20210412084016.009884719@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Shuah Khan 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 Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com Signed-off-by: Shuah Khan Link: https://lore.kernel.org/r/b6568f7beae702bbc236a545d3c020106ca75eac.1616807117.git.skhan@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- 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(-) --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -263,6 +263,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; --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1101,6 +1101,7 @@ static void vhci_device_init(struct vhci 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); --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -185,6 +185,8 @@ static int vhci_port_disconnect(struct v usbip_dbg_vhci_sysfs("enter\n"); + mutex_lock(&vdev->ud.sysfs_lock); + /* lock */ spin_lock_irqsave(&vhci->lock, flags); spin_lock(&vdev->ud.lock); @@ -195,6 +197,7 @@ static int vhci_port_disconnect(struct v /* unlock */ spin_unlock(&vdev->ud.lock); spin_unlock_irqrestore(&vhci->lock, flags); + mutex_unlock(&vdev->ud.sysfs_lock); return -EINVAL; } @@ -205,6 +208,8 @@ static int vhci_port_disconnect(struct v usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); + mutex_unlock(&vdev->ud.sysfs_lock); + return 0; } @@ -349,30 +354,36 @@ static ssize_t attach_store(struct devic else vdev = &vhci->vhci_hcd_hs->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 */ @@ -397,7 +408,8 @@ static ssize_t attach_store(struct devic * Will be retried from userspace * if there's another free port. */ - return -EBUSY; + err = -EBUSY; + goto unlock_mutex; } dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", @@ -422,7 +434,15 @@ static ssize_t attach_store(struct devic 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_WO(attach);