]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
lspci: Fix unsynchronized caches in lspci struct device and pci struct pci_dev
authorNikita Proshkin <n.proshkin@yadro.com>
Wed, 27 Dec 2023 09:44:50 +0000 (14:44 +0500)
committerMartin Mares <mj@ucw.cz>
Sat, 17 Feb 2024 22:44:25 +0000 (23:44 +0100)
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
lspci.c

index 2c99812c4ed25cdb72c7c71054b53365ec78675c..bc1443af8a8b457fe6c94798a57291573113e486 100644 (file)
--- 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 9452cd31a2b0a830f876fd11e13239fd625f9106..071cc117bc682c11917e57d6392a987c6a50d528 100644 (file)
--- 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)