⬢ DragonFlyBSD Kernel Audit
DF-5776 / fix.diff
← back to finding ↓ download raw
--- 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.
 		 */