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;
 	}

Reply via email to