diff mbox series

[v9,3/6] PCI: Consolidate delimiter handling into pci_dev_str_match()

Message ID SI2PR01MB439377D9DE029526BDF897BBDCB62@SI2PR01MB4393.apcprd01.prod.exchangelabs.com
State New
Headers show
Series PCI: Add support for ACS Enhanced Capability | expand

Commit Message

Wei Wang Sept. 3, 2026, 3:46 a.m. UTC
Callers of pci_dev_str_match() manually checked for the ';' or ','
delimiter and advanced the parameter pointer past it. Move this common
logic into pci_dev_str_match() so callers no longer need to duplicate it.

As a side effect of this consolidation, pci_dev_str_match() now enforces
stricter boundary checks on successful matches. Previously, if a user
provided a malformed parameter with garbage characters appended to a
valid BDF (e.g., "pci=config_acs=110x@0000:04:00.0foo"), the callers
would silently accept the prefix match and ignore the trailing garbage.
Now, pci_dev_str_match() strictly verifies that the matched token is
immediately followed by a valid delimiter (';', ',') or the null
terminator ('\0'), returning -EINVAL if it encounters invalid trailing
characters.

Signed-off-by: Wei Wang <wei.w.wang@hotmail.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/pci/pci.c | 40 ++++++++++++++++++----------------------
 1 file changed, 18 insertions(+), 22 deletions(-)

Comments

sashiko-bot@kernel.org Sept. 3, 2026, 4:15 a.m. UTC | #1
> Callers of pci_dev_str_match() manually checked for the ';' or ','
> delimiter and advanced the parameter pointer past it. Move this common
> logic into pci_dev_str_match() so callers no longer need to duplicate it.
> 
> As a side effect of this consolidation, pci_dev_str_match() now enforces
> stricter boundary checks on successful matches. Previously, if a user
> provided a malformed parameter with garbage characters appended to a
> valid BDF (e.g., "pci=config_acs=110x@0000:04:00.0foo"), the callers
> would silently accept the prefix match and ignore the trailing garbage.
> Now, pci_dev_str_match() strictly verifies that the matched token is
> immediately followed by a valid delimiter (';', ',') or the null
> terminator ('\0'), returning -EINVAL if it encounters invalid trailing
> characters.
> 
> Signed-off-by: Wei Wang <wei.w.wang@hotmail.com>

Sashiko has reviewed this patch and found no issues. It looks great!
diff mbox series

Patch

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 2af679111a9b..587c013f04db 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -336,7 +336,7 @@  static int pci_dev_str_match_path(struct pci_dev *dev, const char *path,
  * pci_dev_str_match - test if a string matches a device
  * @dev: the PCI device to test
  * @p: string to match the device against
- * @endptr: pointer to the string after the match
+ * @endptr: pointer to the string after the match, with the delimiter skipped
  *
  * Test if a string (typically from a kernel parameter) matches a specified
  * PCI device. The string may be of one of the following formats:
@@ -390,8 +390,13 @@  static int pci_dev_str_match(struct pci_dev *dev, const char *p,
 		    (!subsystem_vendor ||
 			    subsystem_vendor == dev->subsystem_vendor) &&
 		    (!subsystem_device ||
-			    subsystem_device == dev->subsystem_device))
-			goto found;
+			    subsystem_device == dev->subsystem_device)) {
+			ret = 1;
+			goto out;
+		}
+
+		/* No matching string found */
+		ret = 0;
 	} else {
 		/*
 		 * PCI Bus, Device, Function IDs are specified
@@ -401,15 +406,18 @@  static int pci_dev_str_match(struct pci_dev *dev, const char *p,
 		if (ret < 0)
 			return ret;
 		else if (ret)
-			goto found;
+			goto out;
 	}
+out:
+	/*
+	 * Whether we matched (ret == 1) or didn't (ret == 0),
+	 * ensure the token ends with a valid boundary.
+	 */
+	if (*p != '\0' && *p != ';' && *p != ',')
+		return -EINVAL;
 
-	*endptr = p;
-	return 0;
-
-found:
-	*endptr = p;
-	return 1;
+	*endptr = *p == '\0' ? p : p + 1;
+	return ret;
 }
 
 static u8 __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
@@ -964,12 +972,6 @@  static void __pci_config_acs(struct pci_dev *dev, struct pci_acs *caps,
 			/* Found a match */
 			break;
 		}
-
-		if (*p != ';' && *p != ',') {
-			/* End of param or invalid format */
-			break;
-		}
-		p++;
 	}
 
 	if (ret != 1)
@@ -6488,12 +6490,6 @@  static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev,
 			       p);
 			break;
 		}
-
-		if (*p != ';' && *p != ',') {
-			/* End of param or invalid format */
-			break;
-		}
-		p++;
 	}
 out:
 	spin_unlock(&resource_alignment_lock);