summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorse <se@FreeBSD.org>2016-02-19 14:01:35 +0000
committerse <se@FreeBSD.org>2016-02-19 14:01:35 +0000
commit73c7c751cd8eb41281c92805b26881cbeb69c607 (patch)
tree8895acf745257fbc49f37b35c6eceeedde010941
parent150af2e5cbe0eabb7467483c17efb5a832892fa0 (diff)
downloadFreeBSD-src-73c7c751cd8eb41281c92805b26881cbeb69c607.zip
FreeBSD-src-73c7c751cd8eb41281c92805b26881cbeb69c607.tar.gz
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
-rw-r--r--usr.sbin/pciconf/pciconf.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c
index e743a89..d62ce77 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
OpenPOWER on IntegriCloud