From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f198.google.com (mail-oi1-f198.google.com [209.85.167.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C21792561A7 for ; Sat, 15 Aug 2026 14:04:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.198 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786802654; cv=none; b=oYtYBTb2xaiYg6NAXvAHAd4w+KHg3qq1UDgAJn3gOccvMqVYebvUJW4RdxePqmQKsB519xgRsjBjLYr7UtJlk67a9mfkce2R8wOql+oh2/MZrzUy/hWDniLN3GU5bh6jmN8V7ABqNmmYDe1Fd5jgCNIyuQt9ardf3ABEznjJ3XE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786802654; c=relaxed/simple; bh=JVot3XVLpVk978xket8cDc2DMrZyKf17S/BW7g9ZTbY=; h=MIME-Version:Date:In-Reply-To:Message-ID:Subject:From:To: Content-Type; b=CrSrFmXdcm9T+TT4aBvy4+Z9hO1VfO7wOvnk1rk5a6+bI3+zKPP2nyvhxBqDA0p0FHGAZASqFEVRMGrAJvhKf4XOlCCthzpWFH7m1jIMy8+uEhdFy5LdPVvNpDgQwMUjsr6Nb5cj1x/nTAWETnRD5XbtR55BL1XIDl1q6onlL0M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; arc=none smtp.client-ip=209.85.167.198 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com Received: by mail-oi1-f198.google.com with SMTP id 5614622812f47-4a41e3d6fe9so2224101b6e.2 for ; Sat, 15 Aug 2026 07:04:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786802651; x=1787407451; h=content-type:to:from:subject:message-id:in-reply-to:date :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to:content-type; bh=PuDUQDLKYFJHQmLeUFW34olyCadSTI1KZSGTDCNYpdI=; b=eYJnoIvfLkDQOo3zHi7BIzG86gWl/loskni9/yk3fn5sMoqgj5prREP9TlRD5A5Jg8 pPKhTM+2BN9rlo+bZWif3bkYXLTWOIPSC41RWjVnT5jAzK+uufYv+kc+rqMhRPFyRbM0 ilDNKm84IM8VmXPIsrUWAFh3WZjTH9IktAlpRAWHllfVNmnLr2zVYyBtKJBWSMQoMRjY wTrOHyQkLR6eHoQjwPSv5WjzaEzXfyExytYagqXfocvtaFtcm1hFogc6EEauhvf4QWY4 YMKS8iAgAmwI4WIQwHZiFA2fWRA1JUU/8GNUISxDWg4O5JE0Uo+EYVLaFDGfPG2agpdd kuzA== X-Gm-Message-State: AOJu0YzMVd7r/dtfp9GdKJUHmJEH7T202MIhYylnWqYGB4hCZ56brJ/p SEXROkzHK1RJidTWyD/wQS6mu3E8iI8wAv7SqzQXB6PEjulBJC7jw2/p+CiPQgjK7c7+tAa9azY UZTyFuUphcO2/f1HV1ljtPXWRLmsAKzzSGFqEQ0Kz3oeZDAaVCGTKP55dG3g= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Received: by 2002:a05:6808:23c6:b0:486:8a11:6e8b with SMTP id 5614622812f47-4b2412f17c5mr12950455b6e.2.1786802651738; Sat, 15 Aug 2026 07:04:11 -0700 (PDT) Date: Sat, 15 Aug 2026 07:04:11 -0700 In-Reply-To: <6a7ee0b6.91706f20.9568a.0005.GAE@google.com> X-Google-Appengine-App-Id: s~syzkaller X-Google-Appengine-App-Id-Alias: syzkaller Message-ID: <6a8071db.9ebadd4d.20b15e.000d.GAE@google.com> Subject: Forwarded: [PATCH] usbip: vhci_hcd: move sysfs attribute setup into probe/remove From: syzbot To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Content-Type: text/plain; charset="UTF-8" For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: [PATCH] usbip: vhci_hcd: move sysfs attribute setup into probe/remove Author: kartikey406@gmail.com #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master The vhci sysfs attribute group is created in vhci_start() and removed in vhci_stop(), guarded by usb_hcd_is_primary_hcd(). Since vhci_start() and vhci_stop() run from usb_add_hcd()/usb_remove_hcd(), which are each called twice, the attach attribute is live while only one of the two hcds exists: it is created during the first usb_add_hcd() before vhci_hcd_ss is set, and it survives the first usb_put_hcd() during removal. A concurrent write to attach can therefore reach a NULL or freed vhci_hcd_ss. Create the group at the end of vhci_hcd_probe(), after both hcds are added, and remove it at the start of vhci_hcd_remove(), before either reference is dropped. sysfs_remove_group() drains in-flight store callbacks, so no writer can be inside attach_store() once it returns. Reported-by: syzbot+8753715f05759f1a10de@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8753715f05759f1a10de Signed-off-by: Deepanshu Kartikey --- drivers/usb/usbip/vhci_hcd.c | 66 ++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 39e8faf4c18c..90f166f3ae96 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1199,7 +1199,6 @@ static int vhci_start(struct usb_hcd *hcd) { struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd); int id, rhport; - int err; usbip_dbg_vhci_hc("enter vhci_start\n"); @@ -1230,40 +1229,17 @@ static int vhci_start(struct usb_hcd *hcd) return -EINVAL; } - /* vhci_hcd is now ready to be controlled through sysfs */ - if (id == 0 && usb_hcd_is_primary_hcd(hcd)) { - err = vhci_init_attr_group(); - if (err) { - dev_err(hcd_dev(hcd), "init attr group failed, err = %d\n", err); - return err; - } - err = sysfs_create_group(&hcd_dev(hcd)->kobj, &vhci_attr_group); - if (err) { - dev_err(hcd_dev(hcd), "create sysfs files failed, err = %d\n", err); - vhci_finish_attr_group(); - return err; - } - dev_info(hcd_dev(hcd), "created sysfs %s\n", hcd_name(hcd)); - } - return 0; } static void vhci_stop(struct usb_hcd *hcd) { struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd); - int id, rhport; + int rhport; usbip_dbg_vhci_hc("stop VHCI controller\n"); - /* 1. remove the userland interface of vhci_hcd */ - id = hcd_name_to_id(hcd_name(hcd)); - if (id == 0 && usb_hcd_is_primary_hcd(hcd)) { - sysfs_remove_group(&hcd_dev(hcd)->kobj, &vhci_attr_group); - vhci_finish_attr_group(); - } - - /* 2. shutdown all the ports of vhci_hcd */ + /* shutdown all the ports of vhci_hcd */ for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { struct vhci_device *vdev = &vhci_hcd->vdev[rhport]; @@ -1405,8 +1381,25 @@ static int vhci_hcd_probe(struct platform_device *pdev) } usbip_dbg_vhci_hc("bye\n"); + + if (pdev->id == 0) { + ret = vhci_init_attr_group(); + if (ret) { + dev_err_probe(&pdev->dev, ret, "init attr group failed\n"); + goto remove_usb3_hcd; + } + ret = sysfs_create_group(&pdev->dev.kobj, &vhci_attr_group); + if (ret) { + dev_err_probe(&pdev->dev, ret, "create sysfs files failed\n"); + vhci_finish_attr_group(); + goto remove_usb3_hcd; + } + } + return 0; +remove_usb3_hcd: + usb_remove_hcd(hcd_ss); put_usb3_hcd: usb_put_hcd(hcd_ss); remove_usb2_hcd: @@ -1421,17 +1414,30 @@ static int vhci_hcd_probe(struct platform_device *pdev) static void vhci_hcd_remove(struct platform_device *pdev) { struct vhci *vhci = *((void **)dev_get_platdata(&pdev->dev)); + struct usb_hcd *hcd_hs = vhci_hcd_to_hcd(vhci->vhci_hcd_hs); + struct usb_hcd *hcd_ss = vhci_hcd_to_hcd(vhci->vhci_hcd_ss); + + /* + * Remove the userland interface before dropping the hcd references. + * sysfs_remove_group() waits for in-flight attach_store()/detach_store() + * callers to return and rejects new ones, so neither hcd can be reached + * from sysfs by the time it is freed below. + */ + if (pdev->id == 0) { + sysfs_remove_group(&pdev->dev.kobj, &vhci_attr_group); + vhci_finish_attr_group(); + } /* * Disconnects the root hub, * then reverses the effects of usb_add_hcd(), * invoking the HCD's stop() methods. */ - usb_remove_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_ss)); - usb_put_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_ss)); + usb_remove_hcd(hcd_ss); + usb_put_hcd(hcd_ss); - usb_remove_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs)); - usb_put_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs)); + usb_remove_hcd(hcd_hs); + usb_put_hcd(hcd_hs); vhci->vhci_hcd_hs = NULL; vhci->vhci_hcd_ss = NULL; -- 2.43.0