Date: Sun, 17 Apr 2005 21:09:35 GMT From: Wayne Salamon <wsalamon@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 75414 for review Message-ID: <200504172109.j3HL9ZB7029953@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=75414 Change 75414 by wsalamon@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? */ } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200504172109.j3HL9ZB7029953>