Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2084826pxb; Mon, 12 Apr 2021 14:02:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwGDVwTh+JP8gbyop9TJW03xTrlO+XrsjAn8Qs+Ts6wgGwtkGnS+CC0/PwXRsWxIbGly5eK X-Received: by 2002:a05:6402:4309:: with SMTP id m9mr32165201edc.25.1618261350890; Mon, 12 Apr 2021 14:02:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618261350; cv=none; d=google.com; s=arc-20160816; b=Z9E2o7REmEBVgsxkzovJbFBgeq+3WwA2SythQw3o9og12eqE4FfFUwo5sT2cC2zwL6 yLtvraagouKX1HPt4/kNyPqa4vrwMOvgrijNFKl0+U74YkIS6Ma3+saL5b/l0KOQd/8O ERNNoSzHFVYkLHYENNwextsFoDBrBaZPFdgRSj+QeKabKe0Gfk0cFFKo62yukgfL8rDz a8ZEozjs5Oyg7emMq0eX7QGayDBDG2gDO75kCi/r6+5sJFQ0zT3Zcxj+glZ8poA60zcr vVbyXJ626u1m6Bybt0i4KFnDkMeIygJ0I4uBhSt3JhuP3HN6cADgBzPTrvJ4N8xWnqxn v4bQ== 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=ea7cw8ewkTsOhj5TrmtSjyNVAbUVPX8JKbe/a56idIjeHrTWTjr2jKVshoMqPkAq3/ 3GlkO2uPt8q7ygkDrJroylU8H9JqjAz8VLzfPFccpJr/PfDZNwdtTVt9+HhVQDigJ6M0 o4YUygwm/fDjNCL/mlj6Mft5VDaLvsexk1EQlx+Yd741QNpwYgO1TMM35J+/4UpIab7Z IlyDxTr6V61MMI6OeBm4Cr0CxYGiMMwwAv05U8AEkQwQyEFLG59npBTJGgMO7uKNhOsc fTkbrkd0MmpliYi0Df/K3Dn+9JMSU8rtWL912hdqopboIwtDI7Yid6yRXiS5XzYjTtJu N+4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="x/8+U2bz"; 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 ss2si5015647ejb.370.2021.04.12.14.02.07; Mon, 12 Apr 2021 14:02:30 -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="x/8+U2bz"; 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 S240084AbhDLJEo (ORCPT + 99 others); Mon, 12 Apr 2021 05:04:44 -0400 Received: from mail.kernel.org ([198.145.29.99]:45830 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238846AbhDLIzA (ORCPT ); Mon, 12 Apr 2021 04:55:00 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 261EA61370; Mon, 12 Apr 2021 08:53:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1618217593; bh=nD1XbmUtLI57bRf4xzb+SI/BIIQnh6f3jKjJJIW1DMg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=x/8+U2bzCoHX8sncpe40VutheBz6Q/ecddqCCBKnqODQ+NV1eb1pN73lbpinfXhof 1EqM/bp7WEbj4nN9QirQr+V/agh5ni6V2n1TUz1KOMrvYGDO9LHsYyZd4LdsyxLEAE 5UEOd5yqdJVBqxrinEIJLMs7RhlPkJaai1uJ6pGE= 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.10 073/188] usbip: add sysfs_lock to synchronize sysfs code paths Date: Mon, 12 Apr 2021 10:39:47 +0200 Message-Id: <20210412084016.093272343@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210412084013.643370347@linuxfoundation.org> References: <20210412084013.643370347@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);