Module Name: src Committed By: pgoyette Date: Tue Jan 21 20:33:01 UTC 2014
Modified Files: src/sys/opencrypto: cryptodev.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.73 -r1.74 src/sys/opencrypto/cryptodev.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/opencrypto/cryptodev.c diff -u src/sys/opencrypto/cryptodev.c:1.73 src/sys/opencrypto/cryptodev.c:1.74 --- src/sys/opencrypto/cryptodev.c:1.73 Tue Jan 21 18:54:28 2014 +++ src/sys/opencrypto/cryptodev.c Tue Jan 21 20:33:01 2014 @@ -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 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 cm */ 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; }