diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-07-25 12:51:42 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-07-25 12:51:42 +0000 |
commit | cb91f1c3d43eb3ce9e571adddd8f4eeb61df7a5c (patch) | |
tree | 3efa9af7801f37febb1cab503248c83d352e845e /sys | |
parent | 7a69ae24a31a85699b6563ff4726c39693424239 (diff) |
Better parameter validation in pciioctl(): check for ioctl number and
access rights before attempting to access the data pointer as a pciio
structure.
ok jsg@ kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/pci.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index c6e19e9304c..43c67efc0d7 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci.c,v 1.65 2009/07/18 16:19:28 miod Exp $ */ +/* $OpenBSD: pci.c,v 1.66 2009/07/25 12:51:41 miod Exp $ */ /* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */ /* @@ -791,10 +791,21 @@ pciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) struct pci_softc *pci = NULL; pci_chipset_tag_t pc; + switch (cmd) { + case PCIOCREAD: + break; + case PCIOCWRITE: + if (!(flag & FWRITE)) + return EPERM; + break; + default: + return ENOTTY; + } + io = (struct pci_io *)data; - PCIDEBUG(("pciioctl cmd %s", cmd == PCIOCREAD ? "pciocread" - : cmd == PCIOCWRITE ? "pciocwrite" : "unknown")); + PCIDEBUG(("pciioctl cmd %s", + cmd == PCIOCREAD ? "pciocread" : "pciocwrite")); PCIDEBUG((" bus %d dev %d func %d reg %x\n", io->pi_sel.pc_bus, io->pi_sel.pc_dev, io->pi_sel.pc_func, io->pi_reg)); @@ -817,9 +828,9 @@ pciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) tag = pci_make_tag(pc, io->pi_sel.pc_bus, io->pi_sel.pc_dev, io->pi_sel.pc_func); - switch(cmd) { + switch (cmd) { case PCIOCREAD: - switch(io->pi_width) { + switch (io->pi_width) { case 4: /* Make sure the register is properly aligned */ if (io->pi_reg & 0x3) @@ -834,10 +845,7 @@ pciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; case PCIOCWRITE: - if (!(flag & FWRITE)) - return EPERM; - - switch(io->pi_width) { + switch (io->pi_width) { case 4: /* Make sure the register is properly aligned */ if (io->pi_reg & 0x3) @@ -850,10 +858,6 @@ pciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; } break; - - default: - error = ENOTTY; - break; } return (error); |