summaryrefslogtreecommitdiffstats
path: root/sys/dev/ciss/ciss.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2009-09-16 23:17:22 +0000
committerscottl <scottl@FreeBSD.org>2009-09-16 23:17:22 +0000
commita4f91455d4908e2e358a05a8d2ba214615baa09f (patch)
tree094a50e7b8e63cebce6eb81722c96453dbfa2b7b /sys/dev/ciss/ciss.c
parent7780e2c81f386e967efdc0944036426a38d5631c (diff)
downloadFreeBSD-src-a4f91455d4908e2e358a05a8d2ba214615baa09f.zip
FreeBSD-src-a4f91455d4908e2e358a05a8d2ba214615baa09f.tar.gz
Fix locking around copyout() operations.
Diffstat (limited to 'sys/dev/ciss/ciss.c')
-rw-r--r--sys/dev/ciss/ciss.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index b09575e..f95b689 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -2567,15 +2567,16 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
/*
* Allocate an in-kernel databuffer if required, copy in user data.
*/
+ mtx_unlock(&sc->ciss_mtx);
cr->cr_length = ioc->buf_size;
if (ioc->buf_size > 0) {
if ((cr->cr_data = malloc(ioc->buf_size, CISS_MALLOC_CLASS, M_NOWAIT)) == NULL) {
error = ENOMEM;
- goto out;
+ goto out_unlocked;
}
if ((error = copyin(ioc->buf, cr->cr_data, ioc->buf_size))) {
debug(0, "copyin: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
- goto out;
+ goto out_unlocked;
}
}
@@ -2586,6 +2587,7 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
bcopy(&ioc->Request, &cc->cdb, sizeof(cc->cdb));
/* XXX anything else to populate here? */
+ mtx_lock(&sc->ciss_mtx);
/*
* Run the command.
@@ -2606,15 +2608,19 @@ ciss_user_command(struct ciss_softc *sc, IOCTL_Command_struct *ioc)
* Copy the results back to the user.
*/
bcopy(ce, &ioc->error_info, sizeof(*ce));
+ mtx_unlock(&sc->ciss_mtx);
if ((ioc->buf_size > 0) &&
(error = copyout(cr->cr_data, ioc->buf, ioc->buf_size))) {
debug(0, "copyout: bad data buffer %p/%d", ioc->buf, ioc->buf_size);
- goto out;
+ goto out_unlocked;
}
/* done OK */
error = 0;
+out_unlocked:
+ mtx_lock(&sc->ciss_mtx);
+
out:
if ((cr != NULL) && (cr->cr_data != NULL))
free(cr->cr_data, CISS_MALLOC_CLASS);
OpenPOWER on IntegriCloud