Mercurial > illumos > illumos-gate
changeset 6697:acd61c9c8407
PSARC/2007/701 EOF and removal of auditconfig -[gs]etfsize
6185615 kernel-based audit statistic feature no longer valid; reimplement in audit_binfile
author | pr131582 |
---|---|
date | Fri, 23 May 2008 02:20:02 -0700 |
parents | a476264b067f |
children | 7f367fb15ddd |
files | usr/src/lib/auditd_plugins/binfile/binfile.c |
diffstat | 1 files changed, 97 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/auditd_plugins/binfile/binfile.c Fri May 23 01:41:17 2008 -0700 +++ b/usr/src/lib/auditd_plugins/binfile/binfile.c Fri May 23 02:20:02 2008 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * write binary audit records directly to a file. @@ -61,6 +61,8 @@ #include <tzfile.h> #include <unistd.h> #include <sys/vfs.h> +#include <limits.h> +#include <syslog.h> #include <security/auditd.h> #include <audit_plugin.h> @@ -79,6 +81,8 @@ #define ALLHARD_DELAY 20 /* Call audit_warn(allhard) every 20 seconds */ +/* minimum reasonable size in bytes to roll over an audit file */ +#define FSIZE_MIN 512000 /* * The directory list is a circular linked list. It is pointed into by @@ -125,6 +129,14 @@ /* preferred dir state */ static int fullness_state = PLENTY_SPACE; +/* + * These are used to implement a maximum size for the auditing + * file. binfile_maxsize is set via the 'p_fsize' parameter to the + * audit_binfile plugin. + */ +static uint_t binfile_cursize = 0; +static uint_t binfile_maxsize = 0; + static int open_log(dirlist_t *); static void @@ -624,6 +636,13 @@ current_dir->dl_fd = newfd; current_dir->dl_filename = strdup(newname); + /* + * New file opened, so reset file size statistic (used + * to ensure audit log does not grow above size limit + * set by p_fsize). + */ + binfile_cursize = 0; + __logpost(newname); DPRINT((dbfp, "binfile: Log opened: %s\n", newname)); @@ -689,12 +708,63 @@ } /* + * Parses p_fsize value and contains it within the range FSIZE_MIN and + * INT_MAX so using uints won't cause an undetected overflow of + * INT_MAX. Defaults to 0 if the value is invalid or is missing. + */ +static void +save_maxsize(char *maxsize) { + /* + * strtol() returns a long which could be larger than int so + * store here for sanity checking first + */ + long proposed_maxsize; + + if (maxsize != NULL) { + /* + * There is no explicit error return from strtol() so + * we may need to depend on the value of errno. + */ + errno = 0; + proposed_maxsize = strtol(maxsize, (char **)NULL, 10); + + /* + * If sizeof(long) is greater than sizeof(int) on this + * platform, proposed_maxsize might be greater than + * INT_MAX without it being reported as ERANGE. + */ + if ((errno == ERANGE) || + ((proposed_maxsize != 0) && + (proposed_maxsize < FSIZE_MIN)) || + (proposed_maxsize > INT_MAX)) { + binfile_maxsize = 0; + DPRINT((dbfp, "binfile: p_fsize parameter out of " + "range: %s\n", maxsize)); + /* + * Inform administrator of the error via + * syslog + */ + __audit_syslog("audit_binfile.so", + LOG_CONS | LOG_NDELAY, + LOG_DAEMON, LOG_ERR, + gettext("p_fsize parameter out of range\n")); + } else { + binfile_maxsize = proposed_maxsize; + } + } else { /* p_fsize string was not present */ + binfile_maxsize = 0; + } + + DPRINT((dbfp, "binfile: set maxsize to %d\n", binfile_maxsize)); +} + +/* * auditd_plugin() writes a buffer to the currently open file. The - * global "openNewFile" is used to force a new log file for cases - * such as the initial open, when minfree is reached or the current - * file system fills up, and "audit -s" with changed audit_control - * data. For "audit -n" a new log file is opened immediately in - * auditd_plugin_open(). + * global "openNewFile" is used to force a new log file for cases such + * as the initial open, when minfree is reached, the p_fsize value is + * exceeded or the current file system fills up, and "audit -s" with + * changed parameters. For "audit -n" a new log file is opened + * immediately in auditd_plugin_open(). * * This function manages one or more audit directories as follows: * @@ -746,6 +816,19 @@ * lock is for activeDir, referenced by open_log() and close_log() */ (void) pthread_mutex_lock(&log_mutex); + + /* + * If this would take us over the maximum size, open a new + * file, unless maxsize is 0, in which case growth of the + * audit log is unrestricted. + */ + if ((binfile_maxsize != 0) && + ((binfile_cursize + in_len) > binfile_maxsize)) { + DPRINT((dbfp, "binfile: maxsize exceeded, opening new audit " + "file.\n")); + openNewFile = 1; + } + while (rc == AUDITD_FAIL) { open_status = 1; if (openNewFile) { @@ -781,6 +864,8 @@ out_len = write(activeDir->dl_fd, input, in_len); DPRINT((dbfp, "binfile: finished the write\n")); + binfile_cursize += out_len; + if (out_len == in_len) { DPRINT((dbfp, "binfile: write_count=%u, sequence=%u," @@ -886,6 +971,7 @@ int reason; char *dirlist; char *minfree; + char *maxsize; kva_t *kv; *error = NULL; @@ -910,9 +996,11 @@ if (kvlist == NULL) { dirlist = NULL; minfree = NULL; + maxsize = NULL; } else { dirlist = kva_match(kv, "p_dir"); minfree = kva_match(kv, "p_minfree"); + maxsize = kva_match(kv, "p_fsize"); } switch (reason) { case 0: /* initial open */ @@ -922,6 +1010,9 @@ openNewFile = 1; /* FALLTHRU */ case 2: /* audit -s */ + /* handle p_fsize parameter */ + save_maxsize(maxsize); + fullness_state = PLENTY_SPACE; status = loadauditlist(dirlist, minfree);