[lvc-project] [PATCH] thunderbolt: verify PCI resource type and size in nhi_probe()
Dmitry Antipov
dmantipov at yandex.ru
Fri Aug 7 11:37:57 MSK 2026
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]
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