PERFORCE change 96706 for review

Robert Watson rwatson at FreeBSD.org
Fri May 5 16:17:44 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=96706

Change 96706 by rwatson at rwatson_zoo on 2006/05/05 16:11:23

	First pass implementations of get / set / delete / flush auid
	preselection rules.  Not tested.
	
	Rename auditpipe_preselect to auditpipe_ioctl_preselect as an
	ioctl argument to prevent excessively similar name to
	audit_pipe_preselect.  It's still not a very good structure name,
	as the string 'auid' should probably appear in it.
	
	Add better locking for various ioctls.

Affected files ...

.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_ioctl.h#10 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#20 edit

Differences ...

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_ioctl.h#10 (text+ko) ====

@@ -38,9 +38,9 @@
  * structures, add new revised ones to be used by new ioctls, and keep the
  * old structures and ioctls for backwards compatibility.
  */
-struct auditpipe_preselect {
-	au_id_t		ap_auid;
-	au_mask_t	ap_mask;
+struct auditpipe_ioctl_preselect {
+	au_id_t		aip_auid;
+	au_mask_t	aip_mask;
 };
 
 /*
@@ -56,9 +56,9 @@
 #define	AUDITPIPE_GET_PRESELECT_NAFLAGS	_IOR(AUDITPIPE_IOBASE, 8, au_mask_t)
 #define	AUDITPIPE_SET_PRESELECT_NAFLAGS	_IOW(AUDITPIPE_IOBASE, 9, au_mask_t)
 #define	AUDITPIPE_GET_PRESELECT_AUID	_IOR(AUDITPIPE_IOBASE, 10,	\
-					    struct auditpipe_preselect)
+					    struct auditpipe_ioctl_preselect)
 #define	AUDITPIPE_SET_PRESELECT_AUID	_IOW(AUDITPIPE_IOBASE, 11,	\
-					    struct auditpipe_preselect)
+					    struct auditpipe_ioctl_preselect)
 #define	AUDITPIPE_DELETE_PRESELECT_AUID	_IOW(AUDITPIPE_IOBASE, 12, au_id_t)
 #define	AUDITPIPE_FLUSH_PRESELECT_AUID	_IO(AUDITPIPE_IOBASE, 13)
 #define	AUDITPIPE_GET_PRESELECT_TRAIL	_IOR(AUDITPIPE_IOBASE, 14, int)

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#20 (text+ko) ====

@@ -200,6 +200,97 @@
 }
 
 /*
+ * Find an audit pipe preselection specification for an auid, if any.
+ */
+static struct audit_pipe_preselect *
+audit_pipe_preselect_find(struct audit_pipe *ap, au_id_t auid)
+{
+	struct audit_pipe_preselect *app;
+
+	mtx_assert(&audit_pipe_mtx, MA_OWNED);
+
+	TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) {
+		if (app->app_auid == auid)
+			return (app);
+	}
+	return (NULL);
+}
+
+static int
+audit_pipe_preselect_get(struct audit_pipe *ap, au_id_t auid,
+    au_mask_t *maskp)
+{
+	struct audit_pipe_preselect *app;
+	int error;
+
+	mtx_lock(&audit_pipe_mtx);
+	app = audit_pipe_preselect_find(ap, auid);
+	if (app != NULL) {
+		*maskp = app->app_mask;
+		error = 0;
+	} else
+		error = ENOENT;
+	mtx_unlock(&audit_pipe_mtx);
+	return (error);
+}
+
+static void
+audit_pipe_preselect_set(struct audit_pipe *ap, au_id_t auid, au_mask_t mask)
+{
+	struct audit_pipe_preselect *app, *app_new;
+
+	/*
+	 * Pessimistically assume that the auid doesn't already have a mask
+	 * set, and allocate.  We will free it if it is unneeded.
+	 */
+	app_new = malloc(sizeof(*app_new), M_AUDIT_PIPE_PRESELECT, M_WAITOK);
+	mtx_lock(&audit_pipe_mtx);
+	app = audit_pipe_preselect_find(ap, auid);
+	if (app == NULL) {
+		app = app_new;
+		app_new = NULL;
+		app->app_auid = auid;
+		TAILQ_INSERT_TAIL(&ap->ap_preselect_list, app, app_list);
+	}
+	app->app_mask = mask;
+	mtx_unlock(&audit_pipe_mtx);
+	if (app_new != NULL)
+		free(app_new, M_AUDIT_PIPE_PRESELECT);
+}
+
+static int
+audit_pipe_preselect_delete(struct audit_pipe *ap, au_id_t auid)
+{
+	struct audit_pipe_preselect *app;
+	int error;
+
+	mtx_lock(&audit_pipe_mtx);
+	app = audit_pipe_preselect_find(ap, auid);
+	if (app != NULL) {
+		TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list);
+		error = 0;
+	} else
+		error = ENOENT;
+	mtx_unlock(&audit_pipe_mtx);
+	if (app != NULL)
+		free(app, M_AUDIT_PIPE_PRESELECT);
+	return (error);
+}
+
+static void
+audit_pipe_preselect_flush(struct audit_pipe *ap)
+{
+	struct audit_pipe_preselect *app;
+
+	mtx_lock(&audit_pipe_mtx);
+	while ((app = TAILQ_FIRST(&ap->ap_preselect_list)) != NULL) {
+		TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list);
+		free(app, M_AUDIT_PIPE_PRESELECT);
+	}
+	mtx_unlock(&audit_pipe_mtx);
+}
+
+/*
  * Determine whether a specific audit pipe matches a record with these
  * properties.  Algorithm is as follows:
  *
@@ -220,10 +311,7 @@
 	if ((ap->ap_flags & AUDIT_PIPE_TRAIL) && trail_preselect)
 		return (1);
 
-	TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) {
-		if (app->app_auid == auid)
-			break;
-	}
+	app = audit_pipe_preselect_find(ap, auid);
 	if (app == NULL) {
 		if (auid == AU_DEFAUDITID)
 			return (au_preselect(event, class,
@@ -539,7 +627,7 @@
 audit_pipe_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
     struct thread *td)
 {
-	struct auditpipe_preselect *aps;
+	struct auditpipe_ioctl_preselect *aip;
 	struct audit_pipe *ap;
 	au_mask_t *maskp;
 	au_id_t auid;
@@ -625,63 +713,80 @@
 		break;
 
 	case AUDITPIPE_GET_PRESELECT_FLAGS:
+		mtx_lock(&audit_pipe_mtx);
 		maskp = (au_mask_t *)data;
 		*maskp = ap->ap_preselect_flags;
+		mtx_unlock(&audit_pipe_mtx);
 		error = 0;
 		break;
 
 	case AUDITPIPE_SET_PRESELECT_FLAGS:
+		mtx_lock(&audit_pipe_mtx);
 		maskp = (au_mask_t *)data;
 		ap->ap_preselect_flags = *maskp;
+		mtx_unlock(&audit_pipe_mtx);
 		error = 0;
 		break;
 
 	case AUDITPIPE_GET_PRESELECT_NAFLAGS:
+		mtx_lock(&audit_pipe_mtx);
 		maskp = (au_mask_t *)data;
 		*maskp = ap->ap_preselect_naflags;
+		mtx_unlock(&audit_pipe_mtx);
 		error = 0;
 		break;
 
 	case AUDITPIPE_SET_PRESELECT_NAFLAGS:
+		mtx_lock(&audit_pipe_mtx);
 		maskp = (au_mask_t *)data;
 		ap->ap_preselect_naflags = *maskp;
+		mtx_unlock(&audit_pipe_mtx);
 		error = 0;
 		break;
 
 	case AUDITPIPE_GET_PRESELECT_AUID:
-		aps = (struct auditpipe_preselect *)data;
-		error = EOPNOTSUPP;
+		aip = (struct auditpipe_ioctl_preselect *)data;
+		error = audit_pipe_preselect_get(ap, aip->aip_auid,
+		    &aip->aip_mask);
 		break;
 
 	case AUDITPIPE_SET_PRESELECT_AUID:
-		aps = (struct auditpipe_preselect *)data;
-		error = EOPNOTSUPP;
+		aip = (struct auditpipe_ioctl_preselect *)data;
+		audit_pipe_preselect_set(ap, aip->aip_auid, aip->aip_mask);
+		error = 0;
 		break;
 
 	case AUDITPIPE_DELETE_PRESELECT_AUID:
 		auid = *(au_id_t *)data;
-		error = EOPNOTSUPP;
+		error = audit_pipe_preselect_delete(ap, auid);
 		break;
 
 	case AUDITPIPE_FLUSH_PRESELECT_AUID:
-		error = EOPNOTSUPP;
+		audit_pipe_preselect_flush(ap);
+		error = 0;
 		break;
 
 	case AUDITPIPE_GET_PRESELECT_TRAIL:
+		mtx_lock(&audit_pipe_mtx);
 		*(int *)data = (ap->ap_flags & AUDIT_PIPE_TRAIL) ? 1 : 0;
+		mtx_unlock(&audit_pipe_mtx);
 		error = 0;
 		break;
 
 	case AUDITPIPE_SET_PRESELECT_TRAIL:
+		mtx_lock(&audit_pipe_mtx);
 		if (*(int *)data)
 			ap->ap_flags |= AUDIT_PIPE_TRAIL;
 		else
 			ap->ap_flags &= ~AUDIT_PIPE_TRAIL;
+		mtx_unlock(&audit_pipe_mtx);
 		error = 0;
 		break;
 
 	case AUDITPIPE_FLUSH:
+		mtx_lock(&audit_pipe_mtx);
 		audit_pipe_flush(ap);
+		mtx_unlock(&audit_pipe_mtx);
 		error = 0;
 		break;
 


More information about the trustedbsd-cvs mailing list