PERFORCE change 96655 for review

Robert Watson rwatson at FreeBSD.org
Thu May 4 13:59:05 UTC 2006


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

Change 96655 by rwatson at rwatson_zoo on 2006/05/04 13:57:56

	A variety of changes in support of preselection for audit pipes:
	
	- Add two new preselection flags for queued audit records:
	  AR_PRESELECT_TRAIL and AR_PRESELECT_PIPE, which are used to track
	  whether a particular queued record was requested by the global
	  trail configuration, or if some or another pipe has requested it.
	  This flag is now set during record commit preselection to be used
	  by the audit worker in deciding where to send the record.
	
	- au_preselect() now accepts a class argument so that the caller
	  can look up the class once for all trail/pipe preselection and
	  avoid repeated class lookups for an event type.

Affected files ...

.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit.c#27 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_klib.c#6 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#18 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_private.h#26 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_syscalls.c#13 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_worker.c#10 edit

Differences ...

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

@@ -334,6 +334,9 @@
 void
 audit_commit(struct kaudit_record *ar, int error, int retval)
 {
+	au_event_t event;
+	au_class_t class;
+	au_id_t auid;
 	int sorf;
 	struct au_mask *aumask;
 
@@ -379,14 +382,17 @@
 		break;
 	}
 
-	if (au_preselect(ar->k_ar.ar_event, aumask, sorf) != 0)
-		ar->k_ar_commit |= AR_COMMIT_KERNEL;
+	auid = ar->k_ar.ar_subj_auid;
+	event = ar->k_ar.ar_event;
+	class = au_event_class(event);
 
-	/*
-	 * XXXRW: Why is this necessary?  Should we ever accept a record that
-	 * we're not willing to commit?
-	 */
-	if ((ar->k_ar_commit & (AR_COMMIT_USER | AR_COMMIT_KERNEL)) == 0) {
+	ar->k_ar_commit |= AR_COMMIT_KERNEL;
+	if (au_preselect(event, class, aumask, sorf) != 0)
+		ar->k_ar_commit |= AR_PRESELECT_TRAIL;
+	if (audit_pipe_preselect(auid, event, class, sorf) != 0)
+		ar->k_ar_commit |= AR_PRESELECT_PIPE;
+	if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE)) ==
+	    0) {
 		mtx_lock(&audit_mtx);
 		audit_pre_q_len--;
 		mtx_unlock(&audit_mtx);
@@ -448,8 +454,10 @@
 void
 audit_syscall_enter(unsigned short code, struct thread *td)
 {
-	int audit_event;
 	struct au_mask *aumask;
+	au_class_t class;
+	au_event_t event;
+	au_id_t auid;
 
 	KASSERT(td->td_ar == NULL, ("audit_syscall_enter: td->td_ar != NULL"));
 
@@ -466,15 +474,16 @@
 	if (code >= td->td_proc->p_sysent->sv_size)
 		return;
 
-	audit_event = td->td_proc->p_sysent->sv_table[code].sy_auevent;
-	if (audit_event == AUE_NULL)
+	event = td->td_proc->p_sysent->sv_table[code].sy_auevent;
+	if (event == AUE_NULL)
 		return;
 
 	/*
 	 * Check which audit mask to use; either the kernel non-attributable
 	 * event mask or the process audit mask.
 	 */
-	if (td->td_proc->p_au->ai_auid == AU_DEFAUDITID)
+	auid = td->td_proc->p_au->ai_auid;
+	if (auid == AU_DEFAUDITID)
 		aumask = &audit_nae_mask;
 	else
 		aumask = &td->td_proc->p_au->ai_mask;
@@ -483,8 +492,8 @@
 	 * Allocate an audit record, if preselection allows it, and store
 	 * in the thread for later use.
 	 */
-	if (au_preselect(audit_event, aumask,
-			AU_PRS_FAILURE | AU_PRS_SUCCESS)) {
+	class = au_event_class(event);
+	if (au_preselect(event, class, aumask, AU_PRS_BOTH)) {
 		/*
 		 * If we're out of space and need to suspend unprivileged
 		 * processes, do that here rather than trying to allocate
@@ -501,8 +510,10 @@
 			cv_wait(&audit_fail_cv, &audit_mtx);
 			panic("audit_failing_stop: thread continued");
 		}
-		td->td_ar = audit_new(audit_event, td);
-	} else
+		td->td_ar = audit_new(event, td);
+	} else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH))
+		td->td_ar = audit_new(event, td);
+	else
 		td->td_ar = NULL;
 }
 

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

@@ -155,24 +155,21 @@
  * event is part of against the given mask.
  */
 int
-au_preselect(au_event_t event, au_mask_t *mask_p, int sorf)
+au_preselect(au_event_t event, au_class_t class, au_mask_t *mask_p, int sorf)
 {
 	au_class_t effmask = 0;
-	au_class_t ae_class;
 
 	if (mask_p == NULL)
 		return (-1);
 
-	ae_class = au_event_class(event);
-
 	/*
 	 * Perform the actual check of the masks against the event.
 	 */
 	if (sorf & AU_PRS_SUCCESS)
-		effmask |= (mask_p->am_success & ae_class);
+		effmask |= (mask_p->am_success & class);
 
 	if (sorf & AU_PRS_FAILURE)
-		effmask |= (mask_p->am_failure & ae_class);
+		effmask |= (mask_p->am_failure & class);
 
 	if (effmask)
 		return (1);

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

@@ -216,13 +216,13 @@
 	}
 	if (app == NULL) {
 		if (auid == AU_DEFAUDITID)
-			return (au_preselect(event, &ap->ap_preselect_naflags,
-			    sorf));
+			return (au_preselect(event, class,
+			    &ap->ap_preselect_naflags, sorf));
 		else
-			return (au_preselect(event, &ap->ap_preselect_flags,
-			    sorf));
+			return (au_preselect(event, class,
+			    &ap->ap_preselect_flags, sorf));
 	} else
-		return (au_preselect(event, &app->app_mask, sorf));
+		return (au_preselect(event, class, &app->app_mask, sorf));
 	return (0);
 }
 
@@ -239,7 +239,7 @@
 	mtx_lock(&audit_pipe_mtx);
 	TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) {
 		if (audit_pipe_preselect_check(ap, auid, event, class, sorf)) {
-			mtx_lock(&audit_pipe_mtx);
+			mtx_unlock(&audit_pipe_mtx);
 			return (1);
 		}
 	}

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

@@ -84,11 +84,16 @@
 #define	BSM_NOAUDIT	2
 
 /*
- * Defines for the kernel audit record k_ar_commit field.
+ * Defines for the kernel audit record k_ar_commit field.  Flags are set to
+ * indicate what sort of record it is, and which preselection mechanism
+ * selected it.
  */
 #define	AR_COMMIT_KERNEL	0x00000001U
 #define	AR_COMMIT_USER		0x00000010U
 
+#define	AR_PRESELECT_TRAIL	0x00001000U
+#define	AR_PRESELECT_PIPE	0x00002000U
+
 /*
  * Audit data is generated as a stream of struct audit_record structures,
  * linked by struct kaudit_record, and contain storage for possible audit so
@@ -305,7 +310,8 @@
 /*
  * audit_klib prototypes
  */
-int		 au_preselect(au_event_t event, au_mask_t *mask_p, int sorf);
+int		 au_preselect(au_event_t event, au_class_t class,
+		    au_mask_t *mask_p, int sorf);
 au_event_t	 flags_and_error_to_openevent(int oflags, int error);
 void		 au_evclassmap_init(void);
 void		 au_evclassmap_insert(au_event_t event, au_class_t class);

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


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

@@ -321,52 +321,60 @@
 	au_id_t auid;
 	int sorf;
 
-	if (ar->k_ar_commit & AR_COMMIT_USER) {
+	if ((ar->k_ar_commit & AR_COMMIT_USER) &&
+	    (ar->k_ar_commit & AR_PRESELECT_TRAIL)) {
 		error = audit_record_write(audit_vp, audit_cred, audit_td,
 		    ar->k_udata, ar->k_ulen);
 		if (error && audit_panic_on_write_fail)
 			panic("audit_worker: write error %d\n", error);
 		else if (error)
 			printf("audit_worker: write error %d\n", error);
+	}
+	if ((ar->k_ar_commit & AR_COMMIT_USER) &&
+	    (ar->k_ar_commit & AR_PRESELECT_PIPE))
 		audit_pipe_submit_user(ar->k_udata, ar->k_ulen);
-	}
+
+	if (!(ar->k_ar_commit & AR_COMMIT_KERNEL))
+		return;
+
+	auid = ar->k_ar.ar_subj_auid;
+	event = ar->k_ar.ar_event;
+	class = au_event_class(event);
+	if (ar->k_ar.ar_errno == 0)
+		sorf = AU_PRS_SUCCESS;
+	else
+		sorf = AU_PRS_FAILURE;
 
-	if (ar->k_ar_commit & AR_COMMIT_KERNEL) {
-		auid = ar->k_ar.ar_subj_auid;
-		event = ar->k_ar.ar_event;
-		class = au_event_class(event);
-		if (ar->k_ar.ar_errno == 0)
-			sorf = AU_PRS_SUCCESS;
-		else
-			sorf = AU_PRS_FAILURE;
+	ret = kaudit_to_bsm(ar, &bsm);
+	switch (ret) {
+	case BSM_NOAUDIT:
+		return;
 
-		ret = kaudit_to_bsm(ar, &bsm);
-		switch (ret) {
-		case BSM_NOAUDIT:
-			break;
+	case BSM_FAILURE:
+		printf("audit_worker_process_record: BSM_FAILURE\n");
+		return;
 
-		case BSM_FAILURE:
-			printf("audit_worker_process_record: BSM_FAILURE\n");
-			break;
+	case BSM_SUCCESS:
+		break;
 
-		case BSM_SUCCESS:
-			error = audit_record_write(audit_vp, audit_cred,
-			    audit_td, bsm->data, bsm->len);
-			if (error && audit_panic_on_write_fail)
-				panic("audit_worker: write error %d\n",
-				    error);
-			else if (error)
-				printf("audit_worker: write error %d\n",
-				    error);
-			audit_pipe_submit(auid, event, class, sorf,
-			    bsm->data, bsm->len);
-			kau_free(bsm);
-			break;
+	default:
+		panic("kaudit_to_bsm returned %d", ret);
+	}
 
-		default:
-			panic("kaudit_to_bsm returned %d", ret);
-		}
+	if (ar->k_ar_commit & AR_PRESELECT_TRAIL) {
+		error = audit_record_write(audit_vp, audit_cred,
+		    audit_td, bsm->data, bsm->len);
+		if (error && audit_panic_on_write_fail)
+			panic("audit_worker: write error %d\n",
+			    error);
+		else if (error)
+			printf("audit_worker: write error %d\n",
+			    error);
 	}
+	if (ar->k_ar_commit & AR_PRESELECT_PIPE)
+		audit_pipe_submit(auid, event, class, sorf,
+		    bsm->data, bsm->len);
+	kau_free(bsm);
 }
 
 /*


More information about the trustedbsd-cvs mailing list