From: sashiko-bot@kernel.org
To: "Shuai Liu" <847807867@qq.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH v2] usb: storage: don't hold dev_mutex across the max_lun control transfer
Date: Mon, 09 Nov 2026 00:13:15 +0000 [thread overview]
Message-ID: <sashiko-outbox-204202@kernel.org> (raw)
In-Reply-To: <tencent_5A9A9E45415EADE916B7558C66A2C4DD4F05@qq.com>
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] usb: storage: unlocked usb_stor_Bulk_max_lun() races with reset
and I/O
--
commit f8913af4317f2585b6b4e25b82f0040382c7198c
Author: Shuai Liu <847807867@qq.com>
usb: storage: don't hold dev_mutex across the max_lun control transfer
This commit changes usb_stor_Bulk_max_lun() to use usb_control_msg_recv()
and calls it outside us->dev_mutex in usb_stor_scan_dwork().
> diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
> index 823a4b2e9033b..d973bfd0f23d1 100644
> --- a/drivers/usb/storage/usb.c
> +++ b/drivers/usb/storage/usb.c
> @@ -980,19 +980,26 @@ static void usb_stor_scan_dwork(struct work_struct *work)
>
> dev_dbg(dev, "starting scan\n");
>
> - /* For bulk-only devices, determine the max LUN value */
> + /*
> + * For bulk-only devices, determine the max LUN value.
> + * usb_stor_Bulk_max_lun() sleeps in a synchronous transfer, so it
> + * must not run under us->dev_mutex (the reset path takes dev_mutex
> + * while holding the device lock). Lock only to publish the result.
> + */
> if (us->protocol == USB_PR_BULK &&
> !(us->fflags & US_FL_SINGLE_LUN) &&
> !(us->fflags & US_FL_SCM_MULT_TARG)) {
> + int max_lun = usb_stor_Bulk_max_lun(us);
> +
> mutex_lock(&us->dev_mutex);
> - us->max_lun = usb_stor_Bulk_max_lun(us);
> + us->max_lun = max_lun;
> /*
> * Allow proper scanning of devices that present more than 8 LUNs
> * While not affecting other devices that may need the previous
> * behavior
> */
> - if (us->max_lun >= 8)
> - us_to_host(us)->max_lun = us->max_lun+1;
> + if (max_lun >= 8)
> + us_to_host(us)->max_lun = max_lun + 1;
> mutex_unlock(&us->dev_mutex);
> }
[Severity: High]
Does calling usb_stor_Bulk_max_lun() without us->dev_mutex break the
quiescence contract of usb_stor_pre_reset() and usb_stor_suspend(), and
race with concurrent resets or SCSI commands?
usb_stor_pre_reset() and usb_stor_suspend() take us->dev_mutex to ensure
all driver URBs have completed and no new URBs are submitted during reset
or suspend:
drivers/usb/storage/usb.c:usb_stor_pre_reset() {
struct us_data *us = usb_get_intfdata(iface);
/* Make sure no command runs during the reset */
mutex_lock(&us->dev_mutex);
return 0;
}
With usb_stor_Bulk_max_lun() unlocked:
CPU0 (scan_dwork) CPU1 (usb_reset_device)
usb_stor_scan_dwork()
usb_stor_pre_reset()
mutex_lock(&us->dev_mutex)
usb_reset_and_verify_device()
hub_port_reset()
usb_stor_Bulk_max_lun()
usb_control_msg_recv() <-- EP0 transfer runs during reset and fails
usb_stor_post_reset()
mutex_unlock(&us->dev_mutex)
mutex_lock(&us->dev_mutex)
us->max_lun = 0; <-- LUNs > 0 permanently lost
Instead of waiting on us->dev_mutex for usb_stor_post_reset() to finish,
usb_control_msg_recv() runs during port reset and EP0 re-enumeration,
fails, and causes usb_stor_Bulk_max_lun() to return 0, hiding all LUNs
above 0 on multi-LUN devices. Because scsi_add_host() is called in
usb_stor_probe2() before scan_dwork runs, an unlocked GET_MAX_LUN can also
run concurrently on the device with Bulk-Only transfers and resets in
usb_stor_control_thread() and device_reset().
Also, is the ABBA deadlock described in the comment and commit message
possible? Neither usb_stor_control_msg() nor usb_submit_urb() acquires
udev->dev.mutex, and quiesce_and_remove_host() never takes us->dev_mutex
either; it waits in cancel_delayed_work_sync(&us->scan_dwork) for the work
item to finish, while switching from usb_stor_control_msg() to
usb_control_msg_recv() makes the 10-second wait uninterruptible and no
longer abortable via US_FLIDX_ABORTING.
--
Sashiko AI review · https://sashiko.dev/#/patchset/tencent_5A9A9E45415EADE916B7558C66A2C4DD4F05@qq.com?part=1
next prev parent reply other threads:[~2026-11-09 0:13 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-08 23:53 [PATCH v2] usb: storage: don't hold dev_mutex across the max_lun control transfer Shuai Liu
2026-11-09 0:13 ` sashiko-bot [this message]
2026-11-09 2:10 ` [usb-storage] " Alan Stern
2026-11-09 11:06 ` Shuai Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-204202@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=847807867@qq.com \
--cc=linux-usb@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox