From owner-trustedbsd-cvs@FreeBSD.ORG Sat Sep 9 10:12:05 2006 Return-Path: X-Original-To: trustedbsd-cvs@freebsd.org Delivered-To: trustedbsd-cvs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A3A6616A55F for ; Sat, 9 Sep 2006 10:12:05 +0000 (UTC) (envelope-from owner-perforce@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id DE8F843D58 for ; Sat, 9 Sep 2006 10:12:04 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: from mx2.freebsd.org (mx2.freebsd.org [216.136.204.119]) by cyrus.watson.org (Postfix) with ESMTP id 35DD946CCD for ; Sat, 9 Sep 2006 06:12:04 -0400 (EDT) Received: from hub.freebsd.org (hub.freebsd.org [216.136.204.18]) by mx2.freebsd.org (Postfix) with ESMTP id 98070560C6; Sat, 9 Sep 2006 10:12:02 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: by hub.freebsd.org (Postfix, from userid 32767) id 9297316A416; Sat, 9 Sep 2006 10:12:02 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3AF7516A412 for ; Sat, 9 Sep 2006 10:12:02 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id D1C6A43D5A for ; Sat, 9 Sep 2006 10:12:01 +0000 (GMT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k89AC10D026394 for ; Sat, 9 Sep 2006 10:12:01 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k89AC1hs026391 for perforce@freebsd.org; Sat, 9 Sep 2006 10:12:01 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sat, 9 Sep 2006 10:12:01 GMT Message-Id: <200609091012.k89AC1hs026391@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 105886 for review X-BeenThere: trustedbsd-cvs@FreeBSD.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: TrustedBSD CVS and Perforce commit message list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Sep 2006 10:12:05 -0000 http://perforce.freebsd.org/chv.cgi?CH=105886 Change 105886 by rwatson@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 @@ -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 /*