PERFORCE change 105886 for review

Robert Watson rwatson at FreeBSD.org
Sat Sep 9 10:12:02 UTC 2006


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

Change 105886 by rwatson at rwatson_sesame on 2006/09/09 10:11:45

	Improve debugging output for auditd: mention what error caused a
	rename failure.  Remove \n's.
	
	Rename AUDIT_TRIGGER_OPEN_NEW to AUDIT_TRIGGER_ROTATE_USER, and
	add AUDIT_TRIGGER_ROTATE_KERNEL, to distinguish a rotate sourced
	from the user and from the kernel.
	
	Disable rate limiting on certain kernel-sourced triggers --
	specifically rotate, because it won't be retransmitted, so if we
	miss it, we won't see it again and the audit trail will grow
	indefinitely.  This is bad.  Maintain rate limiting for other
	space-related events.
	
	Don't generate a syslog event for sigchld.  It's boring.
	Likewise for a trigger read event, since we'll document the
	details of the event in a separate log message.
	
	Annotate a few bugs in how we handle mappings (we don't remove
	old ones if deleted), and that we need to incrementally update
	the kernel policy, not overwrite it, or we lose argc/argv/...
	flags.  We need those to be stored in audit_control at some
	point.
	
	Fix a typo in the AUDITOFF_WARN string.
	
	Update the maximum user record size to MAXAUDITDATA from 1k.

Affected files ...

.. //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#7 edit
.. //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#19 edit
.. //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#6 edit
.. //depot/projects/trustedbsd/openbsm/bsm/audit.h#20 edit

Differences ...

==== //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#7 (text+ko) ====

@@ -30,7 +30,7 @@
  *
  * @APPLE_BSD_LICENSE_HEADER_END@
  *
- * $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#6 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#7 $
  */
 /*
  * Program to trigger the audit daemon with a message that is either:
@@ -75,7 +75,7 @@
 		switch(ch) {
 
 		case 'n':
-			trigger = AUDIT_TRIGGER_OPEN_NEW;
+			trigger = AUDIT_TRIGGER_ROTATE_USER;
 			break;
 
 		case 's':

==== //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#19 (text+ko) ====

@@ -30,7 +30,7 @@
  *
  * @APPLE_BSD_LICENSE_HEADER_END@
  *
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#18 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#19 $
  */
 
 #include <sys/types.h>
@@ -160,8 +160,9 @@
 			*ptr = '.';
 			strcpy(ptr+1, TS);
 			if (rename(oldname, lastfile) != 0)
-				syslog(LOG_ERR, "Could not rename %s to %s",
-				    oldname, lastfile);
+				syslog(LOG_ERR,
+				    "Could not rename %s to %s: %m", oldname,
+				    lastfile);
 			else
 				syslog(LOG_INFO, "renamed %s to %s",
 				    oldname, lastfile);
@@ -286,7 +287,7 @@
 		free(dirent->dirname);
 		free(dirent);
 	}
-	syslog(LOG_ERR, "Log directories exhausted\n");
+	syslog(LOG_ERR, "Log directories exhausted");
 	return (-1);
 }
 
@@ -343,7 +344,7 @@
 	 * XXX is generated here?
 	 */
 	if (0 == (ret = getacmin(&minval))) {
-		syslog(LOG_DEBUG, "min free = %d\n", minval);
+		syslog(LOG_DEBUG, "min free = %d", minval);
 		if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
 			syslog(LOG_ERR,
 			    "could not get audit queue settings");
@@ -494,31 +495,65 @@
 }
 
 /*
- * 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.
+ * Handle the audit trigger event.
+ *
+ * We suppress (ignore) duplicated triggers in close succession in order to
+ * try to avoid thrashing-like behavior.  However, not all triggers can be
+ * ignored, as triggers generally represent edge triggers, not level
+ * triggers, and won't be retransmitted if the condition persists.  Of
+ * specific concern is the rotate trigger -- if one is dropped, then it will
+ * not be retransmitted, and the log file will grow in an unbounded fashion.
  */
 #define	DUPLICATE_INTERVAL	30
 static void
 handle_audit_trigger(int trigger)
 {
-	static int last_trigger;
+	static int last_trigger, last_warning;
 	static time_t last_time;
 	struct dir_ent *dirent;
+	struct timeval ts;
+	struct timezone tzp;
+	time_t tt;
 
 	/*
-	 * Suppres duplicate messages from the kernel within the specified
+	 * Suppress duplicate messages from the kernel within the specified
 	 * interval.
 	 */
-	struct timeval ts;
-	struct timezone tzp;
-	time_t tt;
-
 	if (gettimeofday(&ts, &tzp) == 0) {
 		tt = (time_t)ts.tv_sec;
-		if ((trigger == last_trigger) &&
-		    (tt < (last_time + DUPLICATE_INTERVAL)))
-			return;
+		switch (trigger) {
+		case AUDIT_TRIGGER_LOW_SPACE:
+		case AUDIT_TRIGGER_NO_SPACE:
+			/*
+			 * Triggers we can suppress.  Of course, we also need
+			 * to rate limit the warnings, so apply the same
+			 * interval limit on syslog messages.
+			 */
+			if ((trigger == last_trigger) &&
+			    (tt < (last_time + DUPLICATE_INTERVAL))) {
+				if (tt >= (last_warning + DUPLICATE_INTERVAL))
+					syslog(LOG_INFO,
+					    "Suppressing duplicate trigger %d",
+					    trigger);
+				return;
+			}
+			last_warning = tt;
+			break;
+
+		case AUDIT_TRIGGER_ROTATE_KERNEL:
+		case AUDIT_TRIGGER_ROTATE_USER:
+		case AUDIT_TRIGGER_READ_FILE:
+			/*
+			 * Triggers that we cannot suppress.
+			 */
+			break;
+		}
+
+		/*
+		 * Only update last_trigger after aborting due to a duplicate
+		 * trigger, not before, or we will never allow that trigger
+		 * again.
+		 */
 		last_trigger = trigger;
 		last_time = tt;
 	}
@@ -528,7 +563,6 @@
  	 */
 	dirent = TAILQ_FIRST(&dir_q);
 	switch(trigger) {
-
 	case AUDIT_TRIGGER_LOW_SPACE:
 		syslog(LOG_INFO, "Got low space trigger");
 		if (dirent && (dirent->softlim != 1)) {
@@ -554,7 +588,8 @@
 		} else {
 			/*
 			 * Continue auditing to the current file.  Also
-			 * generate  an allsoft warning.
+			 * generate an allsoft warning.
+			 *
 			 * XXX do we want to do this ?
 			 */
 			audit_warn_allsoft();
@@ -577,12 +612,14 @@
 		audit_warn_allhard(++allhardcount);
 		break;
 
-	case AUDIT_TRIGGER_OPEN_NEW:
+	case AUDIT_TRIGGER_ROTATE_KERNEL:
+	case AUDIT_TRIGGER_ROTATE_USER:
 		/*
 		 * Create a new file and swap with the one being used in
 		 * kernel
 		 */
-		syslog(LOG_INFO, "Got open new trigger");
+		syslog(LOG_INFO, "Got open new trigger from %s", trigger ==
+		    AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
 		if (swap_audit_file() == -1)
 			syslog(LOG_ERR, "Error swapping audit file");
 		break;
@@ -656,10 +693,8 @@
 			syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
 			break;
 		}
-		if (sigchlds != sigchlds_handled) {
-			syslog(LOG_DEBUG, "%s: SIGCHLD", __FUNCTION__);
+		if (sigchlds != sigchlds_handled)
 			handle_sigchld();
-		}
 		if (sighups != sighups_handled) {
 			syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
 			handle_sighup();
@@ -670,7 +705,6 @@
 			syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
 			return (-1);
 		}
-		syslog(LOG_DEBUG, "%s: read %d", __FUNCTION__, trigger);
 		if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
 			break;
 		else
@@ -695,6 +729,7 @@
 	/*
 	 * Process the audit event file, obtaining a class mapping for each
 	 * event, and send that mapping into the kernel.
+	 *
 	 * XXX There's a risk here that the BSM library will return NULL
 	 * for an event when it can't properly map it to a class. In that
 	 * case, we will not process any events beyond the one that failed,
@@ -703,10 +738,17 @@
 	ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
 	ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
 	if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) {
+		if (ev.ae_name != NULL)
+			free(ev.ae_name);
 		syslog(LOG_ERR,
 		    "Memory allocation error when configuring audit controls.");
 		return (-1);
 	}
+
+	/*
+	 * XXXRW: Currently we have no way to remove mappings from the kernel
+	 * when they are removed from the file-based mappings.
+	 */
 	evp = &ev;
 	setauevent();
 	while ((evp = getauevent_r(evp)) != NULL) {
@@ -747,6 +789,10 @@
 
 	/*
 	 * Set the audit policy flags based on passed in parameter values.
+	 *
+	 * XXXRW: This removes existing policy flags not related to cnt/ahlt.
+	 * We need a way to merge configuration policy and command line
+	 * argument policy.
 	 */
 	if (auditon(A_SETPOLICY, &global_flags, sizeof(global_flags)))
 		syslog(LOG_ERR, "Failed to set audit policy.");

==== //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#6 (text+ko) ====

@@ -30,7 +30,7 @@
  *
  * @APPLE_BSD_LICENSE_HEADER_END@
  *
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#5 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#6 $
  */
 
 #ifndef _AUDITD_H_
@@ -61,7 +61,7 @@
 
 #define	HARDLIM_ALL_WARN	"allhard"
 #define	SOFTLIM_ALL_WARN	"allsoft"
-#define	AUDITOFF_WARN		"aditoff"
+#define	AUDITOFF_WARN		"auditoff"
 #define	EBUSY_WARN		"ebusy"
 #define	GETACDIR_WARN		"getacdir"
 #define	HARDLIM_WARN		"hard"

==== //depot/projects/trustedbsd/openbsm/bsm/audit.h#20 (text+ko) ====

@@ -30,7 +30,7 @@
  *
  * @APPLE_BSD_LICENSE_HEADER_END@
  *
- * $P4: //depot/projects/trustedbsd/openbsm/bsm/audit.h#19 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bsm/audit.h#20 $
  */
 
 #ifndef _BSM_AUDIT_H
@@ -46,12 +46,13 @@
  * Triggers for the audit daemon.
  */
 #define	AUDIT_TRIGGER_MIN		1
-#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
-#define	AUDIT_TRIGGER_MAX		5
+#define	AUDIT_TRIGGER_LOW_SPACE		1	/* Below low watermark. */
+#define	AUDIT_TRIGGER_ROTATE_KERNEL	2	/* Kernel requests rotate. */
+#define	AUDIT_TRIGGER_READ_FILE		3	/* Re-read config file. */
+#define	AUDIT_TRIGGER_CLOSE_AND_DIE	4	/* Terminate audit. */
+#define	AUDIT_TRIGGER_NO_SPACE		5	/* Below min free space. */
+#define	AUDIT_TRIGGER_ROTATE_USER	6	/* User requests roate. */
+#define	AUDIT_TRIGGER_MAX		6
 
 /*
  * Special file that will be read for trigger events from the kernel
@@ -164,12 +165,12 @@
 #define	AUDIT_PERZONE	0x2000
 
 /*
- * Audit queue control parameters.
+ * Default audit queue control parameters.
  */
 #define	AQ_HIWATER	100
 #define	AQ_MAXHIGH	10000
 #define	AQ_LOWATER	10
-#define	AQ_BUFSZ	1024
+#define	AQ_BUFSZ	MAXAUDITDATA
 #define	AQ_MAXBUFSZ	1048576
 
 /*


More information about the p4-projects mailing list