summaryrefslogtreecommitdiff
path: root/sys/scsi
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2016-03-16 15:01:56 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2016-03-16 15:01:56 +0000
commite65cc2411fb9d3267c62134393d7506777b03e8a (patch)
treed537b3e4737e909368653f5cb800b5387cf1e8a8 /sys/scsi
parentc7f397c233375064250a50d8cabea634e4e58188 (diff)
Add SDF_DYING checks to more functions in scsi disk, to prevent an
use after free of the scsi link structure during detach. OK krw@
Diffstat (limited to 'sys/scsi')
-rw-r--r--sys/scsi/sd.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 23e9e578019..170a191b205 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sd.c,v 1.265 2016/03/12 15:16:04 krw Exp $ */
+/* $OpenBSD: sd.c,v 1.266 2016/03/16 15:01:55 bluhm Exp $ */
/* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
/*-
@@ -269,8 +269,12 @@ sdattach(struct device *parent, struct device *self, void *aux)
int
sdactivate(struct device *self, int act)
{
+ struct scsi_link *link;
struct sd_softc *sc = (struct sd_softc *)self;
- int rv = 0;
+
+ if (sc->flags & SDF_DYING)
+ return (ENXIO);
+ link = sc->sc_link;
switch (act) {
case DVACT_SUSPEND:
@@ -291,12 +295,12 @@ sdactivate(struct device *self, int act)
if ((sc->flags & SDF_DIRTY) != 0)
sd_flush(sc, SCSI_AUTOCONF);
if (boothowto & RB_POWERDOWN)
- scsi_start(sc->sc_link, SSS_STOP,
+ scsi_start(link, SSS_STOP,
SCSI_IGNORE_ILLEGAL_REQUEST |
SCSI_IGNORE_NOT_READY | SCSI_AUTOCONF);
break;
case DVACT_RESUME:
- scsi_start(sc->sc_link, SSS_START,
+ scsi_start(link, SSS_START,
SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF);
break;
case DVACT_DEACTIVATE:
@@ -304,7 +308,7 @@ sdactivate(struct device *self, int act)
scsi_xsh_del(&sc->sc_xsh);
break;
}
- return (rv);
+ return (0);
}
int
@@ -1032,6 +1036,8 @@ sd_ioctl_cache(struct sd_softc *sc, long cmd, struct dk_cache *dkc)
int big;
int rv;
+ if (sc->flags & SDF_DYING)
+ return (ENXIO);
link = sc->sc_link;
if (ISSET(link->flags, SDEV_UMASS))
@@ -1485,6 +1491,8 @@ sd_size(struct sd_softc *sc, int flags)
{
int rv;
+ if (sc->flags & SDF_DYING)
+ return (ENXIO);
if (SCSISPC(sc->sc_link->inqdata.version) >= 3) {
rv = sd_read_cap_16(sc, flags);
if (rv != 0)
@@ -1809,6 +1817,8 @@ sd_flush(struct sd_softc *sc, int flags)
struct scsi_xfer *xs;
struct scsi_synchronize_cache *cmd;
+ if (sc->flags & SDF_DYING)
+ return;
link = sc->sc_link;
if (link->quirks & SDEV_NOSYNCCACHE)