svn commit: r270221 - head/sys/security/audit

Davide Italiano davide at FreeBSD.org
Wed Aug 20 16:04:30 UTC 2014


Author: davide
Date: Wed Aug 20 16:04:30 2014
New Revision: 270221
URL: http://svnweb.freebsd.org/changeset/base/270221

Log:
  Replace dev_clone with cdevpriv(9) KPI in audit_pipe code.
  This is (yet another) step towards the removal of device
  cloning from our kernel.
  
  CR:	https://reviews.freebsd.org/D441
  Reviewed by:	kib, rwatson
  Tested by:	pho

Modified:
  head/sys/security/audit/audit_pipe.c

Modified: head/sys/security/audit/audit_pipe.c
==============================================================================
--- head/sys/security/audit/audit_pipe.c	Wed Aug 20 15:57:52 2014	(r270220)
+++ head/sys/security/audit/audit_pipe.c	Wed Aug 20 16:04:30 2014	(r270221)
@@ -112,7 +112,6 @@ struct audit_pipe_preselect {
 #define	AUDIT_PIPE_ASYNC	0x00000001
 #define	AUDIT_PIPE_NBIO		0x00000002
 struct audit_pipe {
-	int				 ap_open;	/* Device open? */
 	u_int				 ap_flags;
 
 	struct selinfo			 ap_selinfo;
@@ -205,6 +204,7 @@ static struct rwlock		 audit_pipe_lock;
 
 #define	AUDIT_PIPE_LIST_LOCK_INIT()	rw_init(&audit_pipe_lock, \
 					    "audit_pipe_list_lock")
+#define	AUDIT_PIPE_LIST_LOCK_DESTROY()	rw_destroy(&audit_pipe_lock)
 #define	AUDIT_PIPE_LIST_RLOCK()		rw_rlock(&audit_pipe_lock)
 #define	AUDIT_PIPE_LIST_RUNLOCK()	rw_runlock(&audit_pipe_lock)
 #define	AUDIT_PIPE_LIST_WLOCK()		rw_wlock(&audit_pipe_lock)
@@ -213,11 +213,11 @@ static struct rwlock		 audit_pipe_lock;
 #define	AUDIT_PIPE_LIST_WUNLOCK()	rw_wunlock(&audit_pipe_lock)
 
 /*
- * Cloning related variables and constants.
+ * Audit pipe device.
  */
-#define	AUDIT_PIPE_NAME		"auditpipe"
-static eventhandler_tag		 audit_pipe_eh_tag;
-static struct clonedevs		*audit_pipe_clones;
+static struct cdev	*audit_pipe_dev;
+
+#define AUDIT_PIPE_NAME	"auditpipe"
 
 /*
  * Special device methods and definition.
@@ -231,7 +231,6 @@ static d_kqfilter_t	audit_pipe_kqfilter;
 
 static struct cdevsw	audit_pipe_cdevsw = {
 	.d_version =	D_VERSION,
-	.d_flags =	D_NEEDMINOR,
 	.d_open =	audit_pipe_open,
 	.d_close =	audit_pipe_close,
 	.d_read =	audit_pipe_read,
@@ -572,8 +571,6 @@ audit_pipe_alloc(void)
 {
 	struct audit_pipe *ap;
 
-	AUDIT_PIPE_LIST_WLOCK_ASSERT();
-
 	ap = malloc(sizeof(*ap), M_AUDIT_PIPE, M_NOWAIT | M_ZERO);
 	if (ap == NULL)
 		return (NULL);
@@ -599,9 +596,11 @@ audit_pipe_alloc(void)
 	/*
 	 * Add to global list and update global statistics.
 	 */
+	AUDIT_PIPE_LIST_WLOCK();
 	TAILQ_INSERT_HEAD(&audit_pipe_list, ap, ap_list);
 	audit_pipe_count++;
 	audit_pipe_ever++;
+	AUDIT_PIPE_LIST_WUNLOCK();
 
 	return (ap);
 }
@@ -653,28 +652,16 @@ audit_pipe_free(struct audit_pipe *ap)
 	audit_pipe_count--;
 }
 
-/*
- * Audit pipe clone routine -- provide specific requested audit pipe, or a
- * fresh one if a specific one is not requested.
- */
 static void
-audit_pipe_clone(void *arg, struct ucred *cred, char *name, int namelen,
-    struct cdev **dev)
+audit_pipe_dtor(void *arg)
 {
-	int i, u;
-
-	if (*dev != NULL)
-		return;
-
-	if (strcmp(name, AUDIT_PIPE_NAME) == 0)
-		u = -1;
-	else if (dev_stdclone(name, NULL, AUDIT_PIPE_NAME, &u) != 1)
-		return;
+	struct audit_pipe *ap;
 
-	i = clone_create(&audit_pipe_clones, &audit_pipe_cdevsw, &u, dev, 0);
-	if (i)
-		*dev = make_dev_credf(MAKEDEV_REF, &audit_pipe_cdevsw, u, cred,
-		    UID_ROOT, GID_WHEEL, 0600, "%s%d", AUDIT_PIPE_NAME, u);
+	ap = arg;
+	AUDIT_PIPE_LIST_WLOCK();
+	AUDIT_PIPE_LOCK(ap);
+	audit_pipe_free(ap);
+	AUDIT_PIPE_LIST_WUNLOCK();
 }
 
 /*
@@ -686,24 +673,19 @@ static int
 audit_pipe_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
 {
 	struct audit_pipe *ap;
+	int error;
 
-	AUDIT_PIPE_LIST_WLOCK();
-	ap = dev->si_drv1;
+	ap = audit_pipe_alloc();
 	if (ap == NULL) {
-		ap = audit_pipe_alloc();
-		if (ap == NULL) {
-			AUDIT_PIPE_LIST_WUNLOCK();
-			return (ENOMEM);
-		}
-		dev->si_drv1 = ap;
-	} else {
-		KASSERT(ap->ap_open, ("audit_pipe_open: ap && !ap_open"));
-		AUDIT_PIPE_LIST_WUNLOCK();
-		return (EBUSY);
+		return (ENOMEM);
 	}
-	ap->ap_open = 1;	/* No lock required yet. */
-	AUDIT_PIPE_LIST_WUNLOCK();
 	fsetown(td->td_proc->p_pid, &ap->ap_sigio);
+	error = devfs_set_cdevpriv(ap, audit_pipe_dtor);
+	if (error != 0) {
+		AUDIT_PIPE_LIST_WLOCK();
+		audit_pipe_free(ap);
+		AUDIT_PIPE_LIST_WUNLOCK();
+	}
 	return (0);
 }
 
@@ -714,18 +696,12 @@ static int
 audit_pipe_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
 {
 	struct audit_pipe *ap;
+	int error;
 
-	ap = dev->si_drv1;
-	KASSERT(ap != NULL, ("audit_pipe_close: ap == NULL"));
-	KASSERT(ap->ap_open, ("audit_pipe_close: !ap_open"));
-
+	error = devfs_get_cdevpriv((void **)&ap);
+	if (error != 0)
+		return (error);
 	funsetown(&ap->ap_sigio);
-	AUDIT_PIPE_LIST_WLOCK();
-	AUDIT_PIPE_LOCK(ap);
-	ap->ap_open = 0;
-	audit_pipe_free(ap);
-	dev->si_drv1 = NULL;
-	AUDIT_PIPE_LIST_WUNLOCK();
 	return (0);
 }
 
@@ -743,8 +719,9 @@ audit_pipe_ioctl(struct cdev *dev, u_lon
 	int error, mode;
 	au_id_t auid;
 
-	ap = dev->si_drv1;
-	KASSERT(ap != NULL, ("audit_pipe_ioctl: ap == NULL"));
+	error = devfs_get_cdevpriv((void **)&ap);
+	if (error != 0)
+		return (error);
 
 	/*
 	 * Audit pipe ioctls: first come standard device node ioctls, then
@@ -948,8 +925,9 @@ audit_pipe_read(struct cdev *dev, struct
 	u_int toread;
 	int error;
 
-	ap = dev->si_drv1;
-	KASSERT(ap != NULL, ("audit_pipe_read: ap == NULL"));
+	error = devfs_get_cdevpriv((void **)&ap);
+	if (error != 0)
+		return (error);
 
 	/*
 	 * We hold an sx(9) lock over read and flush because we rely on the
@@ -1026,12 +1004,12 @@ static int
 audit_pipe_poll(struct cdev *dev, int events, struct thread *td)
 {
 	struct audit_pipe *ap;
-	int revents;
+	int error, revents;
 
 	revents = 0;
-	ap = dev->si_drv1;
-	KASSERT(ap != NULL, ("audit_pipe_poll: ap == NULL"));
-
+	error = devfs_get_cdevpriv((void **)&ap);
+	if (error != 0)
+		return (error);
 	if (events & (POLLIN | POLLRDNORM)) {
 		AUDIT_PIPE_LOCK(ap);
 		if (TAILQ_FIRST(&ap->ap_queue) != NULL)
@@ -1050,10 +1028,11 @@ static int
 audit_pipe_kqfilter(struct cdev *dev, struct knote *kn)
 {
 	struct audit_pipe *ap;
+	int error;
 
-	ap = dev->si_drv1;
-	KASSERT(ap != NULL, ("audit_pipe_kqfilter: ap == NULL"));
-
+	error = devfs_get_cdevpriv((void **)&ap);
+	if (error != 0)
+		return (error);
 	if (kn->kn_filter != EVFILT_READ)
 		return (EINVAL);
 
@@ -1075,7 +1054,6 @@ audit_pipe_kqread(struct knote *kn, long
 	struct audit_pipe *ap;
 
 	ap = (struct audit_pipe *)kn->kn_hook;
-	KASSERT(ap != NULL, ("audit_pipe_kqread: ap == NULL"));
 	AUDIT_PIPE_LOCK_ASSERT(ap);
 
 	if (ap->ap_qlen != 0) {
@@ -1096,8 +1074,6 @@ audit_pipe_kqdetach(struct knote *kn)
 	struct audit_pipe *ap;
 
 	ap = (struct audit_pipe *)kn->kn_hook;
-	KASSERT(ap != NULL, ("audit_pipe_kqdetach: ap == NULL"));
-
 	AUDIT_PIPE_LOCK(ap);
 	knlist_remove(&ap->ap_selinfo.si_note, kn, 1);
 	AUDIT_PIPE_UNLOCK(ap);
@@ -1112,12 +1088,12 @@ audit_pipe_init(void *unused)
 
 	TAILQ_INIT(&audit_pipe_list);
 	AUDIT_PIPE_LIST_LOCK_INIT();
-
-	clone_setup(&audit_pipe_clones);
-	audit_pipe_eh_tag = EVENTHANDLER_REGISTER(dev_clone,
-	    audit_pipe_clone, 0, 1000);
-	if (audit_pipe_eh_tag == NULL)
-		panic("audit_pipe_init: EVENTHANDLER_REGISTER");
+	audit_pipe_dev = make_dev(&audit_pipe_cdevsw, 0, UID_ROOT,
+		GID_WHEEL, 0600, "%s", AUDIT_PIPE_NAME);
+	if (audit_pipe_dev == NULL) {
+		AUDIT_PIPE_LIST_LOCK_DESTROY();
+		panic("Can't initialize audit pipe subsystem");
+	}
 }
 
 SYSINIT(audit_pipe_init, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, audit_pipe_init,


More information about the svn-src-all mailing list