[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