From: sashiko-bot@kernel.org
To: "Brian Bunker" <brian@purestorage.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v6 2/5] scsi: core: Add scsi_update_inquiry_data() for updating INQUIRY data
Date: Mon, 12 Oct 2026 21:27:17 +0000 [thread overview]
Message-ID: <sashiko-outbox-168624@kernel.org> (raw)
In-Reply-To: <20261012210511.16061-3-brian@purestorage.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] scsi: use-after-free on inquiry buffer for concurrent lockless readers
- [High] scsi: data race on struct scsi_device bitfields corrupts concurrent state updates
- [Medium] scsi: torn reads of INQUIRY strings in procfs and target during rescan
- [Medium] scsi: core: silent truncation of inq_len in scsi_update_inquiry_data()
--
commit 8e9aa2b82f339c1aae88807580c6d0982c8177fa
Author: Brian Bunker <brian@purestorage.com>
scsi: core: Add scsi_update_inquiry_data() for updating INQUIRY data
Add a new function scsi_update_inquiry_data() that can safely update all
INQUIRY-derived fields for an existing SCSI device:
- Vendor, model, revision strings
- Peripheral qualifier and device type
- Capability flags (removable, lockable, tagged queuing support, etc.)
- ATA device detection and allow_restart setting
> diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
> index 3af9e77847f70..b80378ecf4856 100644
> --- a/drivers/scsi/scsi.c
> +++ b/drivers/scsi/scsi.c
[ ... ]
> @@ -549,6 +550,183 @@ void scsi_attach_vpd(struct scsi_device *sdev)
[ ... ]
> +int scsi_update_inquiry_data(struct scsi_device *sdev,
> + unsigned char *inq_result, size_t inq_len)
> +{
[ ... ]
> + had_prior_inquiry = (sdev->inquiry != NULL);
> + old_type = sdev->type;
> + old_periph_qual = sdev->inq_periph_qual;
> +
> + kfree(sdev->inquiry);
> + sdev->inquiry = new_inquiry;
> + sdev->inquiry_len = inq_len;
[Severity: High]
This frees and replaces the existing sdev->inquiry buffer dynamically on a
live device. However, there are multiple existing paths that read the inquiry
buffer locklessly, such as inline subsystem helpers in
include/scsi/scsi_device.h:
scsi_device_enclosure() {
return sdev->inquiry ? (sdev->inquiry[6] & (1<<6)) : 1;
}
Since these lockless readers do not acquire inquiry_mutex and there is no RCU
protection, can a concurrent I/O path or sysfs read dereference the freed
inquiry pointer, resulting in a use-after-free? Furthermore, do these
non-atomic updates to the pointer and its length expose lockless readers to
torn state?
[Severity: Medium]
sdev->inquiry_len is an unsigned char (8 bits), while inq_len is a size_t.
If a manual rescan passes an inq_len of 256, will this assignment silently
truncate the length to 0, causing the device's sysfs inquiry attribute to
return 0 bytes?
> + strscpy(sdev->vendor, sdev->inquiry + INQUIRY_VENDOR_OFFSET);
> + strscpy(sdev->model, sdev->inquiry + INQUIRY_MODEL_OFFSET);
> + /*
> + * memcpy() instead of strscpy() because strscpy() would read past
> + * the end of sdev->inquiry if its length is exactly 36 bytes.
> + */
> + memcpy(sdev->rev, sdev->inquiry + INQUIRY_REVISION_OFFSET,
> + INQUIRY_REVISION_LEN);
[Severity: Medium]
This patch makes the INQUIRY string arrays mutable at runtime. While the
updates are protected by inquiry_mutex, unprotected readers like procfs and
the PSCSI target read these character arrays without acquiring the newly
introduced inquiry_mutex:
proc_print_scsidevice() {
for (i = 0; i < 8; i++) {
if (sdev->vendor[i] >= 0x20)
...
}
Will unprotected readers race with these non-atomic strscpy() updates, causing
torn reads that expose mixed or garbled strings?
> + sdev->rev[INQUIRY_REVISION_LEN] = '\0';
> + sdev->inq_periph_qual = (inq_result[0] >> 5) & 7;
[ ... ]
> + /*
> + * Update device type from INQUIRY byte 0.
> + * BLIST_ISROM is a quirk for devices that report wrong type but should
> + * be treated as (removable) CD-ROM. Override to TYPE_ROM as exception.
> + */
> + if (sdev->sdev_bflags & BLIST_ISROM) {
> + sdev->type = TYPE_ROM;
> + sdev->removable = 1;
> + } else {
> + sdev->type = inq_result[0] & 0x1f;
> + sdev->removable = (inq_result[1] & 0x80) >> 7;
[Severity: High]
These assignments update capability bitfields (e.g., is_ata, removable,
lockable) on a live device while holding only inquiry_mutex. In
struct scsi_device, these capability bitfields are packed into the same memory
word as highly dynamic operational state bitfields:
unsigned is_ata:1;
unsigned removable:1;
unsigned changed:1; /* Data invalid due to media change */
unsigned busy:1; /* Used to prevent races */
Since other subsystems modify the operational bitfields without holding
inquiry_mutex (for example, scsi_test_unit_ready() sets sdev->changed = 1 in
softirq context), does this cause a non-atomic read-modify-write on the shared
word? Could this race overwrite and lose critical runtime state changes like
media change notifications?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261012210511.16061-1-brian@purestorage.com?part=2
next prev parent reply other threads:[~2026-10-12 21:27 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 21:05 [PATCH v6 0/5] scsi: Refresh INQUIRY data and reprobe on rescan Brian Bunker
2026-10-12 21:05 ` [PATCH v6 1/5] scsi: core: Protect INQUIRY sysfs attributes with mutex Brian Bunker
2026-10-12 21:05 ` [PATCH v6 2/5] scsi: core: Add scsi_update_inquiry_data() for updating INQUIRY data Brian Bunker
2026-10-12 21:27 ` sashiko-bot [this message]
2026-10-13 10:02 ` Damien Le Moal
2026-10-12 21:05 ` [PATCH v6 3/5] scsi: core: Refactor scsi_add_lun() to use scsi_update_inquiry_data() Brian Bunker
2026-10-12 21:27 ` sashiko-bot
2026-10-12 21:05 ` [PATCH v6 4/5] scsi: core: Add device reprobe support to scsi_rescan_device() Brian Bunker
2026-10-12 21:27 ` sashiko-bot
2026-10-12 21:05 ` [PATCH v6 5/5] scsi: core: Handle reprobe for existing devices during SCSI scan Brian Bunker
2026-10-12 21:24 ` sashiko-bot
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-168624@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=brian@purestorage.com \
--cc=linux-scsi@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.