From a28a4d77b6ae826aec5331854d735c0f360c7115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20E=C3=9Fer?= Date: Fri, 19 Feb 2016 14:01:35 +0000 Subject: [PATCH] =?UTF-8?q?Fix=20possible=20out-of-bounds=20access=20detec?= =?UTF-8?q?ted=20by=20Ulrich=20Sp=C3=B6rleins=20"scan-build".=20Some=20inv?= =?UTF-8?q?alid=20PCI=20device=20selectors=20could=20cause=20read=20access?= =?UTF-8?q?=20to=20an=20initialized=20variable=20next=20to=20the=20array?= =?UTF-8?q?=20(local=20loop=20index=20variable).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- usr.sbin/pciconf/pciconf.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c index e743a891a2a6..d62ce77f6ccf 100644 --- a/usr.sbin/pciconf/pciconf.c +++ b/usr.sbin/pciconf/pciconf.c @@ -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