DF-5776 / fix.diff
--- sys/bus/pci/pci_user.c.orig 2026-10-11 19:42:42.705974246 +0000 +++ sys/bus/pci/pci_user.c 2026-10-11 19:42:42.729973935 +0000 @@ -606,8 +606,19 @@ case 4: case 2: case 1: - /* Make sure register is not negative and aligned. */ + /* + * Make sure the register offset is non-negative, + * aligned, and within the largest configuration + * space any access mechanism can decode (PCIe + * ECAM: 4KB). Offsets beyond PCIE_REGMAX can + * never reach a device; reject them here instead + * of letting the MD cfgreg layer silently drop + * the access while the ioctl still reports + * success (error = 0). The subtraction form + * avoids signed overflow for pi_reg ~ INT_MAX. + */ if (io->pi_reg < 0 || + io->pi_reg > PCIE_REGMAX + 1 - io->pi_width || io->pi_reg & (io->pi_width - 1)) { error = EINVAL; break; @@ -676,6 +687,19 @@ bio = (struct pci_bar_io *)ap->a_data; /* + * Defense in depth: pbi_reg is used both as a resource + * ID and as a config-space offset (pci_read_config, + * width 4); validate it explicitly instead of relying + * solely on the resource-list lookup and the MD cfgreg + * clamps. + */ + if (bio->pbi_reg < 0 || bio->pbi_reg > PCIE_REGMAX || + bio->pbi_reg & 3) { + error = EINVAL; + break; + } + + /* * Assume that the user-level bus number is * in fact the physical PCI bus number. */ |