From 0ce6ff4aafb36a7923511a8da6bbbebb642e3109 Mon Sep 17 00:00:00 2001 From: Nikita Proshkin Date: Wed, 27 Dec 2023 14:44:50 +0500 Subject: lspci: Fix unsynchronized caches in lspci struct device and pci struct pci_dev lspci initializes both caches for the device to the same memory block in its scan_device function. Latter calls to config_fetch function will realloc cache in struct device, but not in struct pci_dev leading to the invalid pointer in the latter. pci_dev cache is used by pci_read_* functions, what will lead to a possible use-after-free situations. Example: With patch: --- ls-caps.c | 1 + lspci.c | 1 + 2 files changed, 2 insertions(+) diff --git a/ls-caps.c b/ls-caps.c index 2c99812..bc1443a 100644 --- a/ls-caps.c +++ b/ls-caps.c @@ -1812,6 +1812,7 @@ show_caps(struct device *d, int where) break; case PCI_CAP_ID_EXP: type = cap_express(d, where, cap); + struct pci_cap* test = pci_find_cap(d->dev, PCI_CAP_ID_EXP, PCI_CAP_NORMAL); can_have_ext_caps = 1; break; case PCI_CAP_ID_MSIX: diff --git a/lspci.c b/lspci.c index 9452cd3..071cc11 100644 --- a/lspci.c +++ b/lspci.c @@ -107,6 +107,7 @@ config_fetch(struct device *d, unsigned int pos, unsigned int len) d->config = xrealloc(d->config, d->config_bufsize); d->present = xrealloc(d->present, d->config_bufsize); memset(d->present + orig_size, 0, d->config_bufsize - orig_size); + pci_setup_cache(d->dev, d->config, d->dev->cache_len); } result = pci_read_block(d->dev, pos, d->config + pos, len); if (result) -- cgit 1.2.3-korg