diff options
| author | riastradh <riastradh@NetBSD.org> | 2022-05-22 11:29:54 +0000 |
|---|---|---|
| committer | riastradh <riastradh@NetBSD.org> | 2022-05-22 11:29:54 +0000 |
| commit | 0d9f80405019bf577653273b50ef7199a8ed79b6 (patch) | |
| tree | 958611f47db6794c5416bd8076c9927d52d3630a /sys/opencrypto | |
| parent | 1394336ee83ff1d44627a2fe1792f7f2c50d0948 (diff) | |
crypto(4): Fix possible use-after-free in race around detach.
This is extremely unlikely because I don't think we have any drivers
for removable crypto decelerators^Waccelerators...but if we were to
sprout one, and someone ran crypto_dispatch concurrently with
crypto_unregister, cryptodev_cb/mcb would enter with crp->crp_etype =
EAGAIN and with CRYPTO_F_DONE set in crp->crp_flags. In this case,
cryptodev_cb/mcb would issue crypto_dispatch but -- since nothing
clears CRYPTO_F_DONE -- it would _also_ consider the request done and
notify the ioctl thread of that.
With this change, we return early if crypto_dispatch succeeds. No
need to consult CRYPTO_F_DONE: if the callback is invoked it's done,
and if we try to redispatch it on EAGAIN but crypto_dispatch fails,
it's done. (Soon we'll get rid of the possibility of crypto_dispatch
failing synchronously, but not just yet.)
XXX This path could really use some testing!
Diffstat (limited to 'sys/opencrypto')
| -rw-r--r-- | sys/opencrypto/cryptodev.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index e87bd96173d..413f5fc8a8d 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -1,4 +1,4 @@ -/* $NetBSD: cryptodev.c,v 1.115 2022/05/21 23:11:03 riastradh Exp $ */ +/* $NetBSD: cryptodev.c,v 1.116 2022/05/22 11:29:54 riastradh Exp $ */ /* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $ */ /* $OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey Exp $ */ @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.115 2022/05/21 23:11:03 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.116 2022/05/22 11:29:54 riastradh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -715,20 +715,18 @@ static int cryptodev_cb(struct cryptop *crp) { struct csession *cse = crp->crp_opaque; - int error = 0; + int error; - mutex_enter(&cryptodev_mtx); - cse->error = crp->crp_etype; - if (crp->crp_etype == EAGAIN) { - /* always drop mutex to call dispatch routine */ - mutex_exit(&cryptodev_mtx); + if ((error = crp->crp_etype) == EAGAIN) { error = crypto_dispatch(crp); - mutex_enter(&cryptodev_mtx); - } - if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) { - crp->crp_devflags |= CRYPTODEV_F_RET; - cv_signal(&crp->crp_cv); + if (error == 0) + return 0; } + + mutex_enter(&cryptodev_mtx); + cse->error = error; + crp->crp_devflags |= CRYPTODEV_F_RET; + cv_signal(&crp->crp_cv); mutex_exit(&cryptodev_mtx); return 0; } @@ -737,15 +735,16 @@ static int cryptodev_mcb(struct cryptop *crp) { struct csession *cse = crp->crp_opaque; + int error; - mutex_enter(&cryptodev_mtx); - cse->error = crp->crp_etype; - if (crp->crp_etype == EAGAIN) { - mutex_exit(&cryptodev_mtx); - (void)crypto_dispatch(crp); - mutex_enter(&cryptodev_mtx); + if ((error = crp->crp_etype) == EAGAIN) { + error = crypto_dispatch(crp); + if (error == 0) + return 0; } + mutex_enter(&cryptodev_mtx); + cse->error = error; TAILQ_INSERT_TAIL(&crp->fcrp->crp_ret_mq, crp, crp_next); selnotify(&crp->fcrp->sinfo, 0, 0); mutex_exit(&cryptodev_mtx); |
