mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-24 14:33:38 +00:00
hv: Add checks in pci_enumerate_ext_cap to guard against malformed lists
In pci_enumerate_ext_cap we assume the extended capability linked lists are always legal and correct, which might not be true when there was a faulty hardware. This patch adds checks (time to live) to guard against malformed extended capability linked lists. v2: Add error printing when node_limit <= 0. Tracked-On: #6571 Signed-off-by: Yifan Liu <yifan1.liu@intel.com> Reviewed-by: Wang, Yu1 <yu1.wang@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
b59c489750
commit
1d831cd3a2
@ -726,11 +726,17 @@ static void pci_enumerate_ext_cap(struct pci_pdev *pdev)
|
|||||||
uint32_t hdr, pos, pre_pos = 0U;
|
uint32_t hdr, pos, pre_pos = 0U;
|
||||||
uint8_t pcie_dev_type;
|
uint8_t pcie_dev_type;
|
||||||
|
|
||||||
|
/* guard against malformed list */
|
||||||
|
int node_limit;
|
||||||
|
|
||||||
pos = PCI_ECAP_BASE_PTR;
|
pos = PCI_ECAP_BASE_PTR;
|
||||||
|
|
||||||
|
/* minimum 8 bytes per cap */
|
||||||
|
node_limit = (PCIE_CONFIG_SPACE_SIZE - PCI_CONFIG_SPACE_SIZE) / 8;
|
||||||
|
|
||||||
/* PCI Express Extended Capability must have 4 bytes header */
|
/* PCI Express Extended Capability must have 4 bytes header */
|
||||||
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
|
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
|
||||||
while (hdr != 0U) {
|
while ((hdr != 0U) && (node_limit > 0)) {
|
||||||
if (PCI_ECAP_ID(hdr) == PCIZ_SRIOV) {
|
if (PCI_ECAP_ID(hdr) == PCIZ_SRIOV) {
|
||||||
pdev->sriov.capoff = pos;
|
pdev->sriov.capoff = pos;
|
||||||
pdev->sriov.caplen = PCI_SRIOV_CAP_LEN;
|
pdev->sriov.caplen = PCI_SRIOV_CAP_LEN;
|
||||||
@ -767,8 +773,20 @@ static void pci_enumerate_ext_cap(struct pci_pdev *pdev)
|
|||||||
if (pos == 0U) {
|
if (pos == 0U) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (pos < PCI_CONFIG_SPACE_SIZE) {
|
||||||
|
pr_err("pdev %x:%x.%x: Illegal PCIe extended capability offset %x",
|
||||||
|
pdev->bdf.bits.b, pdev->bdf.bits.d, pdev->bdf.bits.f, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
|
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
|
||||||
|
node_limit--;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (node_limit <= 0) {
|
||||||
|
pr_err("%s: pdev[%x:%x.%x] Malformed linked list in PCIe extended \
|
||||||
|
capability region detected\n", __func__, pdev->bdf.bits.b,
|
||||||
|
pdev->bdf.bits.d, pdev->bdf.bits.f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user