Implement in-module ref-counting, and do not allow auto-unload if there
are existing references. Note that manual unloading is not prevented. OK christos@ XXX Also note that there is still a small window where the ref-count can XXX be decremented, and then the process/thread preempted. If auto-unload XXX happens before that thread can return from the module's code, bad XXX things (tm) could happen.
This commit is contained in:
parent
dd68def8c5
commit
1e5d7f9c10
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cryptodev.c,v 1.73 2014/01/21 18:54:28 pgoyette Exp $ */
|
||||
/* $NetBSD: cryptodev.c,v 1.74 2014/01/21 20:33:01 pgoyette 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.73 2014/01/21 18:54:28 pgoyette Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.74 2014/01/21 20:33:01 pgoyette Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -143,6 +143,8 @@ static int cryptoread(dev_t dev, struct uio *uio, int ioflag);
|
||||
static int cryptowrite(dev_t dev, struct uio *uio, int ioflag);
|
||||
static int cryptoselect(dev_t dev, int rw, struct lwp *l);
|
||||
|
||||
static int crypto_refcount = 0; /* Prevent detaching while in use */
|
||||
|
||||
/* Declaration of cloned-device (per-ctxt) entrypoints */
|
||||
static int cryptof_read(struct file *, off_t *, struct uio *,
|
||||
kauth_cred_t, int);
|
||||
@ -262,6 +264,7 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data)
|
||||
*/
|
||||
criofcr->sesn = 1;
|
||||
criofcr->requestid = 1;
|
||||
crypto_refcount++;
|
||||
mutex_exit(&crypto_mtx);
|
||||
(void)fd_clone(criofp, criofd, (FREAD|FWRITE),
|
||||
&cryptofops, criofcr);
|
||||
@ -951,6 +954,7 @@ cryptof_close(struct file *fp)
|
||||
}
|
||||
seldestroy(&fcr->sinfo);
|
||||
fp->f_data = NULL;
|
||||
crypto_refcount--;
|
||||
mutex_exit(&crypto_mtx);
|
||||
|
||||
pool_put(&fcrpl, fcr);
|
||||
@ -1080,6 +1084,7 @@ cryptoopen(dev_t dev, int flag, int mode,
|
||||
*/
|
||||
fcr->sesn = 1;
|
||||
fcr->requestid = 1;
|
||||
crypto_refcount++;
|
||||
mutex_exit(&crypto_mtx);
|
||||
return fd_clone(fp, fd, flag, &cryptofops, fcr);
|
||||
}
|
||||
@ -2206,8 +2211,6 @@ crypto_modcmd(modcmd_t cmd, void *arg)
|
||||
return error;
|
||||
case MODULE_CMD_FINI:
|
||||
#ifdef _MODULE
|
||||
#ifdef notyet
|
||||
/* We need to keep track of open instances before we do this */
|
||||
error = config_cfdata_detach(crypto_cfdata);
|
||||
if (error) {
|
||||
return error;
|
||||
@ -2216,12 +2219,15 @@ crypto_modcmd(modcmd_t cmd, void *arg)
|
||||
config_cfattach_detach(crypto_cd.cd_name, &crypto_ca);
|
||||
config_cfdriver_detach(&crypto_cd);
|
||||
devsw_detach(NULL, &crypto_cdevsw);
|
||||
#else
|
||||
return EOPNOTSUPP;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return error;
|
||||
#ifdef _MODULE
|
||||
case MODULE_CMD_AUTOUNLOAD:
|
||||
if (crypto_refcount != 0)
|
||||
return EBUSY;
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user