PERFORCE change 75414 for review

Wayne Salamon wsalamon at FreeBSD.org
Sun Apr 17 21:09:35 GMT 2005


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

Change 75414 by wsalamon at rickenbacker on 2005/04/17 21:09:12

	Change the names of the triggers to be more generic, not specific to 
	auditd. Change the logic in the case of no disk space to suspend 
	auditing (unless hard-stop is set, then panic). Auditing will resume
	when the new log file is given to the kernel.

Affected files ...

.. //depot/projects/trustedbsd/audit3/contrib/audit_supt/auditd/auditd.c#10 edit
.. //depot/projects/trustedbsd/audit3/sys/bsm/audit.h#12 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/kern_audit.c#19 edit

Differences ...

==== //depot/projects/trustedbsd/audit3/contrib/audit_supt/auditd/auditd.c#10 (text+ko) ====

@@ -389,43 +389,16 @@
 }
 
 /*
- * Read the control file for triggers and handle appropriately.
- */
-int wait_for_triggers()
-{
-	int num;
-	unsigned int trigger;
-
-	for (;;) {
-		num = read(triggerfd, &trigger, sizeof(trigger));
-		if ((num == -1) && (errno != EINTR)) {
-			syslog(LOG_ERR, "%s: error %d\n", __FUNCTION__, errno);
-			return (-1);
-		}
-		if (num == 0) {
-			syslog(LOG_INFO, "%s: read EOF\n", __FUNCTION__);
-			return (-1);
-		}
-		syslog(LOG_INFO, "%s: read %d\n", __FUNCTION__, trigger);
-		if (trigger == AUDITD_TRIGGER_CLOSE_AND_DIE) 
-			break;
-		else
-			handle_auditd_trigger(trigger);
-	}
-	syslog(LOG_INFO, "auditd exiting.\n");
-	return(close_all());
-}
-
-/*
  * Suppress duplicate messages within a 30 second interval.
  * This should be enough to time to rotate log files without
  * thrashing from soft warnings generated before the log is
  * actually rotated.
  */
 #define DUPLICATE_INTERVAL 30
-int handle_auditd_trigger(int flags)
+void
+handle_audit_trigger(int trigger)
 {
-	static int last_flags;
+	static int last_trigger;
 	static time_t last_time;
 	struct dir_ent *dirent;
 	int rc;
@@ -440,24 +413,21 @@
 
 	if(gettimeofday(&ts, &tzp) == 0) {
 		tt = (time_t)ts.tv_sec;
-		if ((flags == last_flags) && 
+		if ((trigger == last_trigger) && 
 		    (tt < (last_time + DUPLICATE_INTERVAL))) {
-			return 0;
+			return;
 		}
-		last_flags = flags;
+		last_trigger = trigger;
 		last_time = tt;
 	}
 
-	syslog(LOG_INFO, 
-	  "handle_audit_trigger() called within auditd with flags = %d\n",
-			flags);
 	/* 
 	 * Message processing is done here 
  	 */
 	dirent = TAILQ_FIRST(&dir_q); 
-	switch(flags) {
+	switch(trigger) {
 
-	case AUDITD_TRIGGER_LOW_SPACE:
+	case AUDIT_TRIGGER_LOW_SPACE:
 		syslog(LOG_INFO, "Got low space trigger\n");
 		if(dirent && (dirent->softlim != 1)) {
 			TAILQ_REMOVE(&dir_q, dirent, dirs);
@@ -490,7 +460,7 @@
 		}
 		break;
 
-	case AUDITD_TRIGGER_NO_SPACE:
+	case AUDIT_TRIGGER_NO_SPACE:
 		syslog(LOG_INFO, "Got no space trigger\n");
 
 		/* delete current dir, go on to next */
@@ -507,7 +477,7 @@
 		
 		break;
 
-	case AUDITD_TRIGGER_OPEN_NEW :
+	case AUDIT_TRIGGER_OPEN_NEW :
 		syslog(LOG_INFO, "Got open new trigger\n");
 		/* create a new file and swap with the one being 
 		 * used in kernel */
@@ -515,7 +485,7 @@
 			syslog(LOG_ERR, "Error swapping audit file\n");	
 		break;
 
-	case AUDITD_TRIGGER_READ_FILE :
+	case AUDIT_TRIGGER_READ_FILE :
 		syslog(LOG_INFO, "Got read file trigger\n");
 		if(read_control_file() == -1) {
 			syslog(LOG_ERR, "Error in audit control file\n");				
@@ -523,9 +493,37 @@
 		break;
 
 	default :
+		syslog(LOG_ERR, "Got unknown trigger %d\n", trigger);
 		break;
 	}
-	return 0;
+	return;
+}
+
+/*
+ * Read the control file for triggers and handle appropriately.
+ */
+int wait_for_triggers()
+{
+	int num;
+	unsigned int trigger;
+
+	for (;;) {
+		num = read(triggerfd, &trigger, sizeof(trigger));
+		if ((num == -1) && (errno != EINTR)) {
+			syslog(LOG_ERR, "%s: error %d\n", __FUNCTION__, errno);
+			return (-1);
+		}
+		if (num == 0) {
+			syslog(LOG_INFO, "%s: read EOF\n", __FUNCTION__);
+			return (-1);
+		}
+		syslog(LOG_INFO, "%s: read %d\n", __FUNCTION__, trigger);
+		if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE) 
+			break;
+		else
+			handle_audit_trigger(trigger);
+	}
+	return(close_all());
 }
 
 /*
@@ -625,7 +623,7 @@
 	int aufd;
 	token_t *tok;
 
-	if ((triggerfd = open(AUDITD_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
+	if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
 		syslog(LOG_ERR, "Error opening trigger file\n");
 		fail_exit();
 	}
@@ -707,6 +705,7 @@
 	setup(flags);
 
 	rc = wait_for_triggers();
+	syslog(LOG_INFO, "auditd exiting.\n");
 
 	exit (rc);
 }

==== //depot/projects/trustedbsd/audit3/sys/bsm/audit.h#12 (text+ko) ====

@@ -42,21 +42,23 @@
 /*
  * File that will be read for trigger events from the kerenl
  */
-#define AUDITD_TRIGGER_FILE	"/dev/audit"
+#define AUDIT_TRIGGER_FILE	"/dev/audit"
 
 /*
  * Minimum noumber of free blocks on the filesystem containing the audit
- * log necessary to avoid a hard log rotation.
+ * log necessary to avoid a hard log rotation. DO NOT SET THIS VALUE TO 0
+ * as the kernel does an unsigned compare, plus we want to leave a few blocks
+ * free so userspace can terminate the log, etc.
  */
-#define AUDIT_HARD_LIMIT_FREE_BLOCKS	16
+#define AUDIT_HARD_LIMIT_FREE_BLOCKS	4
 /* 
  * Triggers for the audit daemon
  */
-#define AUDITD_TRIGGER_LOW_SPACE	1
-#define AUDITD_TRIGGER_OPEN_NEW 	2
-#define AUDITD_TRIGGER_READ_FILE 	3
-#define AUDITD_TRIGGER_CLOSE_AND_DIE 	4
-#define AUDITD_TRIGGER_NO_SPACE		5
+#define AUDIT_TRIGGER_LOW_SPACE		1
+#define AUDIT_TRIGGER_OPEN_NEW 		2
+#define AUDIT_TRIGGER_READ_FILE 	3
+#define AUDIT_TRIGGER_CLOSE_AND_DIE 	4
+#define AUDIT_TRIGGER_NO_SPACE		5
 
 /*
  * Pre-defined audit IDs

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

@@ -328,6 +328,8 @@
 	struct vattr vattr;
 	struct statfs *mnt_stat = &vp->v_mount->mnt_stat;
 
+static int ctr = 0;
+
 	mtx_assert(&Giant, MA_OWNED);
 
 	/*
@@ -339,30 +341,33 @@
 	 */
 	ret = VFS_STATFS(vp->v_mount, mnt_stat, td);
 	if (ret)
+{
 		goto out;
+}
 
 	ret = VOP_GETATTR(vp, &vattr, cred, td);
 	if (ret)
+{
 		goto out;
+}
 
 	/* update the global stats struct */
 	audit_fstat.af_currsz = vattr.va_size; 
 
-	/* 
-	 * Send a message to the audit daemon when disk space is getting
-	 * low.
+	/*
 	 * XXX Need to decide what to do if the trigger to the audit daemon
 	 * fails.
 	 */
 
 	/* 
 	 * If we fall below minimum free blocks (hard limit), tell the audit
-	 * daemon to force a rotation off of the file system. If we fall 
-	 * below the minimum percent free blocks (soft limit), then kindly 
-	 * suggest to the audit daemon to do something.
+	 * daemon to force a rotation off of the file system. We also stop
+	 * writing, which means this audit record is probably lost.
+	 * If we fall below the minimum percent free blocks (soft limit), 
+	 * then kindly suggest to the audit daemon to do something.
 	 */
 	if (mnt_stat->f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) {
-		ret = send_trigger(AUDITD_TRIGGER_NO_SPACE);
+		ret = send_trigger(AUDIT_TRIGGER_NO_SPACE);
 		if (ret != 0) {
 			printf(
     "Failed audit_triggers(AUDIT_TRIGGER_NO_SPACE): %d\n", ret);
@@ -371,12 +376,27 @@
 			 * panic?
 			 */
 		}
+		/* Hopefully userspace did something about all the previous
+		 * triggers that were sent prior to this critical condition.
+		 * If fail-stop is set, then we're done; goodnight Gracie.
+		 */
+		if (audit_fail_stop)
+			panic("Audit log space exhausted and fail-stop set.");
+		else {
+			audit_suspended = 1;
+			ret = ENOSPC;
+			goto out;
+		}
 	} else
+		/* 
+		 * Send a message to the audit daemon that disk space 
+		 * is getting low.
+		 */
 		if (audit_qctrl.aq_minfree != 0) {
 			temp = mnt_stat->f_blocks / (100 / 
 			    audit_qctrl.aq_minfree);
 			if (mnt_stat->f_bfree < temp) {
-				ret = send_trigger(AUDITD_TRIGGER_LOW_SPACE);
+				ret = send_trigger(AUDIT_TRIGGER_LOW_SPACE);
 				if (ret != 0) {
 					printf(
     "Failed audit_triggers(AUDIT_TRIGGER_LOW_SPACE): %d\n", ret);
@@ -393,10 +413,10 @@
 	    (audit_file_rotate_wait == 0) && 
 	    (vattr.va_size >= audit_fstat.af_filesz)) {
 		audit_file_rotate_wait = 1;
-		ret = send_trigger(AUDITD_TRIGGER_OPEN_NEW);
+		ret = send_trigger(AUDIT_TRIGGER_OPEN_NEW);
 		if (ret != 0) {
 			printf(
-    "Failed audit_triggers(AUDITD_TRIGGER_OPEN_NEW): %d\n", ret);
+    "Failed audit_triggers(AUDIT_TRIGGER_OPEN_NEW): %d\n", ret);
 		/* XXX what to do here? */
 		}
 	}
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list