--- a/sys/dev/disk/sili/sili.c +++ b/sys/dev/disk/sili/sili.c @@ -116,6 +116,23 @@ int sili_port_alloc(struct sili_softc *sc, u_int port) { + /* + * The port-register window must actually cover this port's + * subregion. bus_space_subregion() performs no validation of the + * offset against the parent mapping, so a device decoding an + * undersized BAR(2) (see sili_pci_attach()) would otherwise drive + * MMIO reads/writes past the pmap-mapped window and panic the + * kernel (or scribble on an adjacent device mapping). + */ + if (sc->sc_pregs == NULL || + rman_get_size(sc->sc_pregs) < SILI_PORT_REGION(port) + + SILI_PORT_SIZE) { + device_printf(sc->sc_dev, + "port regs window too small for port %u\n", + port); + return (EINVAL); + } + struct sili_port *ap; struct ata_port *at; struct sili_prb *prb;