Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Feb 2016 14:01:36 +0000 (UTC)
From:      Stefan Esser <se@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r295806 - head/usr.sbin/pciconf
Message-ID:  <201602191401.u1JE1acp007220@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: se
Date: Fri Feb 19 14:01:35 2016
New Revision: 295806
URL: https://svnweb.freebsd.org/changeset/base/295806

Log:
  Fix possible out-of-bounds access detected by Ulrich Spörleins "scan-build".
  Some invalid PCI device selectors could cause read access to an initialized
  variable next to the array (local loop index variable).
  
  While here, the parser has been made more strict with regard to the syntax
  of PCI device selectors as documented in the man-page. E.g. "pci:" used to
  be interpreted as "pci0:0".
  
  MFC after:	3 days

Modified:
  head/usr.sbin/pciconf/pciconf.c

Modified: head/usr.sbin/pciconf/pciconf.c
==============================================================================
--- head/usr.sbin/pciconf/pciconf.c	Fri Feb 19 11:25:18 2016	(r295805)
+++ head/usr.sbin/pciconf/pciconf.c	Fri Feb 19 14:01:35 2016	(r295806)
@@ -897,7 +897,6 @@ static struct pcisel
 parsesel(const char *str)
 {
 	const char *ep;
-	const char *epbase;
 	char *eppos;
 	struct pcisel sel;
 	unsigned long selarr[4];
@@ -909,30 +908,27 @@ parsesel(const char *str)
 	else
 		ep = str;
 
-	epbase = ep;
-
 	if (strncmp(ep, "pci", 3) == 0) {
 		ep += 3;
 		i = 0;
-		do {
+		while (isdigit(*ep) && i < 4) {
 			selarr[i++] = strtoul(ep, &eppos, 10);
 			ep = eppos;
-		} while ((*ep == ':' || *ep == '.') && *++ep != '\0' && i < 4);
-
-		if (i > 2)
-			sel.pc_func = selarr[--i];
-		else
-			sel.pc_func = 0;
-		sel.pc_dev = selarr[--i];
-		sel.pc_bus = selarr[--i];
-		if (i > 0)
-			sel.pc_domain = selarr[--i];
-		else
-			sel.pc_domain = 0;
+			if (*ep == ':') {
+				ep++;
+				if (*ep  == '\0')
+					i = 0;
+			}
+		}
+		if (i > 0 && *ep == '\0') {
+			sel.pc_func = (i > 2) ? selarr[--i] : 0;
+			sel.pc_dev = (i > 0) ? selarr[--i] : 0;
+			sel.pc_bus = (i > 0) ? selarr[--i] : 0;
+			sel.pc_domain = (i > 0) ? selarr[--i] : 0;
+			return (sel);
+		}
 	}
-	if (*ep != '\x0' || ep == epbase)
-		errx(1, "cannot parse selector %s", str);
-	return sel;
+	errx(1, "cannot parse selector %s", str);
 }
 
 static struct pcisel



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201602191401.u1JE1acp007220>