diff options
author | Nikita Proshkin <n.proshkin@yadro.com> | 2023-12-27 14:44:50 +0500 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 2024-02-17 23:44:25 +0100 |
commit | 0ce6ff4aafb36a7923511a8da6bbbebb642e3109 (patch) | |
tree | 8841228bfb70ecc04528c97711b8472eed9b3849 | |
parent | e5d1d2dbb64cafd33f9b012b7959b61319dcd250 (diff) | |
download | pciutils-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.c | 1 | ||||
-rw-r--r-- | lspci.c | 1 |
2 files changed, 2 insertions, 0 deletions
@@ -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: @@ -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) |