[lvc-project] [PATCH] thunderbolt: verify PCI resource type and size in nhi_probe()
Mika Westerberg
mika.westerberg at linux.intel.com
Fri Aug 7 12:58:31 MSK 2026
Hi,
On Fri, Aug 07, 2026 at 11:37:57AM +0300, Dmitry Antipov wrote:
> Syzbot reproducer at [1] enforces the kernel to probe PCI device 00:02.0
> as Thunderbolt NHI. On QEMU/aarch64 'virt' machine, the device (at least
> with qemu >= 11.0.0) is:
>
> 00:02.0 Class 0100: Device 1af4:1001
> Subsystem: Device 1af4:0002
> Flags: bus master, fast devsel, latency 0, IRQ 47
> I/O ports at 1000 [size=128] <-- Hmmm...
> Memory at 10041000 (32-bit, non-prefetchable) [size=4K]
> Memory at 8000004000 (64-bit, prefetchable) [size=16K]
Yeah, I'm not entirely sure we want to start "fixing" issues like these
where it's clearly not a USB4/TB NHI. IMHO If user forces the driver
somehow to bind to this unrelated device then she/he got what asked for.
> So call to 'pcim_iomap_region(pdev, 0, ...)' in 'nhi_pci_probe()' maps this
> 128-bytes I/O ports area, and call to 'ioread32(nhi->iobase + REG_CAPS)' in
> 'nhi_probe()' issues an invalid access at REG_CAPS (0x39640) offset. Since
> NHI's typical register window size is 256K, simple sanity check whether 1)
> the region is a memory rather than I/O ports and 2) the region is 256K at
> least should be enough to prevent from such a scenario.
>
> [1] https://syzkaller.appspot.com/text?tag=ReproC&x=1564acc6580000
>
> Reported-by: syzbot+901ca72278dfd89daf58 at syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=901ca72278dfd89daf58
> Fixes: 16603153666d ("thunderbolt: Add initial cactus ridge NHI support")
> Signed-off-by: Dmitry Antipov <dmantipov at yandex.ru>
> ---
> drivers/thunderbolt/nhi.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
> index 0f795ea58756..724263c17b3e 100644
> --- a/drivers/thunderbolt/nhi.c
> +++ b/drivers/thunderbolt/nhi.c
> @@ -1186,6 +1186,7 @@ static struct tb *nhi_select_cm(struct tb_nhi *nhi)
> int nhi_probe(struct tb_nhi *nhi)
> {
> struct device *dev = nhi->dev;
> + struct pci_dev *pdev;
> struct tb *tb;
> int res;
>
> @@ -1195,6 +1196,12 @@ int nhi_probe(struct tb_nhi *nhi)
> if (!nhi->ops->init_interrupts)
> return dev_err_probe(dev, -EINVAL, "missing required NHI ops\n");
>
> + pdev = to_pci_dev(dev);
> + if (!pci_resource_is_mem(pdev, 0))
> + return dev_err_probe(dev, -ENODEV, "invalid resource type\n");
> + if (pci_resource_len(pdev, 0) < 0x40000)
> + return dev_err_probe(dev, -ENODEV, "invalid resource size\n");
> +
> nhi->hop_count = ioread32(nhi->iobase + REG_CAPS) & 0x3ff;
> dev_dbg(dev, "total paths: %d\n", nhi->hop_count);
>
> --
> 2.55.0
More information about the lvc-project
mailing list