From: sashiko-bot@kernel.org
To: "Gary Guo" <gary@garyguo.net>
Cc: cassel@kernel.org, dri-devel@lists.freedesktop.org,
linux-scsi@vger.kernel.org, linux-pci@vger.kernel.org,
dlemoal@kernel.org, linux-ide@vger.kernel.org
Subject: Re: [PATCH v4 2/9] scsi: nsp32: don't store pci_device_id
Date: Fri, 24 Jul 2026 22:02:06 +0000 [thread overview]
Message-ID: <20260724220207.3CE731F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260723-pci_id_fix-v4-2-3580726844e1@garyguo.net>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
Pre-existing issues:
- [High] Unvalidated `driver_data` from dynamic PCI IDs causes an out-of-bounds read of the `nsp32_model` array.
- [High] Missing cleanup of PCI resources and MMIO mapping on probe error path, and missing disable on removal.
- [High] Unprotected global `nsp32_data_base` causes race conditions during concurrent device probes.
- [High] Time-of-Check to Time-of-Use (TOCTOU) race fetching `CurrentSC` locklessly in the ISR.
- [High] Returning a positive value instead of a negative error code on probe failure tricks the PCI core into assuming success, causing a subsequent NULL pointer dereference.
--
--- Patch [2]: [PATCH v4 2/9] scsi: nsp32: don't store pci_device_id ---
commit d3fbc37c7e8ddff13dd3c674aa1a8a1d1f511010
Author: Gary Guo <gary@garyguo.net>
scsi: nsp32: don't store pci_device_id
pci_device_id is not guaranteed to live longer than probe due to presence
of dynamic ID. All information apart from driver_data can be easily
retrieved from pci_dev, so just store driver_data.
> diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
> index e893d56772417..9c9281222a0ac 100644
> --- a/drivers/scsi/nsp32.c
> +++ b/drivers/scsi/nsp32.c
> @@ -1470,7 +1470,7 @@ static int nsp32_show_info(struct seq_file *m, struct Scsi_Host *host)
> (nsp32_read2(base, INDEX_REG) >> 8) & 0xff);
>
> mode_reg = nsp32_index_read1(base, CHIP_MODE);
> - model = data->pci_devid->driver_data;
> + model = data->model;
[Severity: High]
This isn't a bug introduced by this patch, but does this unvalidated model
value (derived from id->driver_data via sysfs new_id) cause an out-of-bounds
read of the fixed-size nsp32_model array?
If a large value for driver_data is supplied, this happens just below when
reading the procfs file:
nsp32_show_info():
seq_printf(m, "OEM: %ld, %s\n",
(mode_reg & (OEM0|OEM1)), nsp32_model[model]);
The same out-of-bounds read also appears in nsp32_probe() during logging.
[ ... ]
> @@ -3340,7 +3340,7 @@ static int nsp32_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> }
>
> data->Pci = pdev;
> - data->pci_devid = id;
> + data->model = id->driver_data;
[Severity: High]
This is a pre-existing issue, but does the lockless use of the global
nsp32_data_base struct cause race conditions during concurrent device probes?
nsp32_probe() writes device-specific resources to this shared global struct:
nsp32_probe():
nsp32_hw_data *data = &nsp32_data_base;
...
data->Pci = pdev;
data->model = id->driver_data;
data->MmioAddress = pci_ioremap_bar(pdev, 1);
nsp32_detect() then copies it to the per-device hostdata. If multiple devices
are probed concurrently (e.g., async probe or hotplug), threads might race to
overwrite these fields, causing devices to steal each other's MMIO mappings.
[Severity: High]
This is another pre-existing issue, but doesn't the error path of
nsp32_probe() fail to clean up PCI resources?
If nsp32_detect() fails, nsp32_probe() returns the error without unmapping
data->MmioAddress or calling pci_disable_device(). Also, on the normal
removal path, nsp32_release() unmaps the IO but entirely skips
pci_disable_device().
[Severity: High]
This is also a pre-existing issue, but does nsp32_detect() returning 1
instead of a negative error code on failure cause issues with the PCI core?
nsp32_probe() propagates this positive value, which the PCI core treats as
success in local_pci_probe(), binding the device even though pci_set_drvdata()
was skipped. When the device is later unbound, nsp32_remove() retrieves a
NULL driver data pointer and passes it to scsi_remove_host(), triggering a
NULL pointer dereference.
> data->IrqNumber = pdev->irq;
> data->BaseAddress = pci_resource_start(pdev, 0);
> data->NumAddress = pci_resource_len (pdev, 0);
> diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
> index 924889f8bd37e..9e65771cb5928 100644
> --- a/drivers/scsi/nsp32.h
> +++ b/drivers/scsi/nsp32.h
> @@ -564,10 +564,10 @@ typedef struct _nsp32_hw_data {
>
> struct scsi_cmnd *CurrentSC;
>
> - struct pci_dev *Pci;
> - const struct pci_device_id *pci_devid;
> - struct Scsi_Host *Host;
> - spinlock_t Lock;
> + struct pci_dev *Pci;
> + int model;
> + struct Scsi_Host *Host;
> + spinlock_t Lock;
[Severity: High]
This isn't a bug introduced by this patch, but is there a Time-of-Check to
Time-of-Use (TOCTOU) race condition when fetching CurrentSC in the ISR?
In do_nsp32_isr(), SCpnt = data->CurrentSC is fetched locklessly before
acquiring host->host_lock.
If the EH thread completes the command concurrently, it frees the DMA mapping,
calls scsi_done(), and sets data->CurrentSC = NULL. The ISR thread might
subsequently acquire the lock and use the stale pre-fetched SCpnt pointer
to modify its result and call nsp32_scsi_done() again, potentially causing a
use-after-free and double completion.
>
> char info_str[100];
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260723-pci_id_fix-v4-0-3580726844e1@garyguo.net?part=2
next prev parent reply other threads:[~2026-07-24 22:02 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 22:00 [PATCH v4 0/9] PCI: Fix UAF and TOCTOU related to dynamic ID Gary Guo
2026-07-23 22:00 ` [PATCH v4 1/9] ata: ata_generic: don't store pci_device_id Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-23 22:00 ` [PATCH v4 2/9] scsi: nsp32: " Gary Guo
2026-07-24 22:02 ` sashiko-bot [this message]
2026-07-23 22:00 ` [PATCH v4 3/9] ipack: tpci200: " Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-23 22:00 ` [PATCH v4 4/9] mlxsw: pci: " Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-23 22:00 ` [PATCH v4 5/9] agp/via: Don't rely on address of pci_device_id Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-23 22:00 ` [PATCH v4 6/9] agp/amd-k7: " Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-23 22:00 ` [PATCH v4 7/9] PCI: Make pci_match_one_device() match on ID instead of device Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-24 22:29 ` Bjorn Helgaas
2026-07-23 22:00 ` [PATCH v4 8/9] PCI: Fix dyn_id add TOCTOU Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-24 22:29 ` Bjorn Helgaas
2026-07-23 22:00 ` [PATCH v4 9/9] PCI: Fix UAF when probe runs concurrent to dyn ID removal Gary Guo
2026-07-24 22:02 ` sashiko-bot
2026-07-24 22:30 ` Bjorn Helgaas
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=20260724220207.3CE731F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=cassel@kernel.org \
--cc=dlemoal@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=linux-ide@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--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.