aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita Proshkin <n.proshkin@yadro.com>2023-12-27 14:44:50 +0500
committerMartin Mares <mj@ucw.cz>2024-02-17 23:44:25 +0100
commit0ce6ff4aafb36a7923511a8da6bbbebb642e3109 (patch)
tree8841228bfb70ecc04528c97711b8472eed9b3849
parente5d1d2dbb64cafd33f9b012b7959b61319dcd250 (diff)
downloadpciutils-0ce6ff4aafb36a7923511a8da6bbbebb642e3109.tar.gz
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:
-rw-r--r--ls-caps.c1
-rw-r--r--lspci.c1
2 files changed, 2 insertions, 0 deletions
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)