PERFORCE change 63119 for review
Wayne Salamon
wsalamon at FreeBSD.org
Wed Oct 13 01:14:57 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=63119
Change 63119 by wsalamon at wsalamon_epi on 2004/10/13 01:14:20
Change the auditctl() system call to take just a path.
Enable the kerne->auditd IPC for audit log full and disk full
messages. Uses a FIFO for this communication.
Note: auditd still needs work when rotating the audit log.
Affected files ...
.. //depot/projects/trustedbsd/audit3/contrib/audit_supt/auditd/auditd.c#5 edit
.. //depot/projects/trustedbsd/audit3/sys/bsm/audit.h#6 edit
.. //depot/projects/trustedbsd/audit3/sys/kern/init_sysent.c#5 edit
.. //depot/projects/trustedbsd/audit3/sys/kern/syscalls.c#5 edit
.. //depot/projects/trustedbsd/audit3/sys/kern/syscalls.master#5 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/kern_audit.c#10 edit
.. //depot/projects/trustedbsd/audit3/sys/sys/syscall.h#5 edit
.. //depot/projects/trustedbsd/audit3/sys/sys/syscall.mk#5 edit
.. //depot/projects/trustedbsd/audit3/sys/sys/sysproto.h#6 edit
Differences ...
==== //depot/projects/trustedbsd/audit3/contrib/audit_supt/auditd/auditd.c#5 (text+ko) ====
@@ -185,9 +185,8 @@
if (open(fn, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP) < 0) {
perror("File open");
}
- /* else if (auditctl(AC_SETLOGFILE, fn, strlen(fn)) != 0) { */
- else if (syscall(SYS_auditctl, AC_SETLOGFILE, fn,
- strlen(fn)) != 0) {
+ /* else if (auditctl(AC_SETLOGFILE, fn)) != 0) { */
+ else if (syscall(SYS_auditctl, AC_SETLOGFILE, fn) != 0) {
syslog(LOG_ERR,
"auditctl failed setting log file! : %s\n",
strerror(errno));
@@ -307,7 +306,7 @@
/* flush contents */
/* err_ret = auditctl(NULL); */
- err_ret = syscall(SYS_auditctl, NULL, sizeof(char));
+ err_ret = syscall(SYS_auditctl, AC_SETLOGFILE, NULL);
if (err_ret != 0) {
syslog(LOG_ERR, "auditctl failed! : %s\n",
strerror(errno));
@@ -326,6 +325,10 @@
return (1);
}
endac();
+
+ if(close(controlfd) != 0) {
+ syslog(LOG_ERR, "Error closing control file\n");
+ }
syslog(LOG_INFO, "Finished.\n");
return (0);
}
@@ -350,13 +353,19 @@
/* Set up the signal hander */
if (signal(SIGTERM, relay_signal) == SIG_ERR) {
+ syslog(LOG_ERR,
+ "Could not set signal handler for SIGTERM\n");
fail_exit();
}
if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
+ syslog(LOG_ERR,
+ "Could not set signal handler for SIGCHLD\n");
fail_exit();
}
if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
+ syslog(LOG_ERR,
+ "Could not open PID file\n");
audit_warn_tmpfile();
return -1;
}
@@ -364,7 +373,8 @@
/* attempt to lock the pid file; if a lock is present, exit */
fd = fileno(pidfile);
if(flock(fd, LOCK_EX | LOCK_NB) < 0) {
- syslog(LOG_ERR, "PID file is locked (is another auditd running?).\n");
+ syslog(LOG_ERR,
+ "PID file is locked (is another auditd running?).\n");
audit_warn_ebusy();
return -1;
}
@@ -560,7 +570,8 @@
evc_map.ec_number = ev->ae_number;
evc_map.ec_class = ev->ae_class;
/* if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t)) != 0) { */
- if (syscall(SYS_auditon,A_SETCLASS, &evc_map, sizeof(au_evclass_map_t)) != 0) {
+ if (syscall(SYS_auditon, A_SETCLASS, &evc_map,
+ sizeof(au_evclass_map_t)) != 0) {
syslog(LOG_ERR,
"Failed to register class mapping for event %s",
ev->ae_name);
@@ -630,15 +641,6 @@
return rc;
}
- /* Tell the kernel the name of the auditd control file */
- /*else if (auditctl(AC_SETCTLFILE, fn, strlen(fn)) != 0) { */
- if (syscall(SYS_auditctl, AC_SETCTLFILE, AUDITD_CTL_FILE,
- strlen(AUDITD_CTL_FILE)) != 0) {
- syslog(LOG_ERR,
- "config_auditd_ipc() : failed sending control file "
- " name to the kernel: %s\n",
- strerror(errno));
- }
/* Set up the signal hander */
if (signal(SIGIO, sigio_handler) == SIG_ERR) {
syslog(LOG_ERR,
@@ -646,7 +648,7 @@
return -1;
}
- controlfd = open(AUDITD_CTL_FILE, O_RDONLY);
+ controlfd = open(AUDITD_CTL_FILE, O_RDONLY | O_NONBLOCK);
if (controlfd < 0) {
syslog(LOG_ERR,
"config_auditd_ipc() : error opening control file\n");
@@ -663,6 +665,14 @@
"config_auditd_ipc() : error setting file ASYNC\n");
return -1;
}
+ /* Tell the kernel the name of the auditd control file */
+ /*if (auditctl(AC_SETCTLFILE, fn) != 0) { */
+ if (syscall(SYS_auditctl, AC_SETCTLFILE, AUDITD_CTL_FILE) != 0) {
+ syslog(LOG_ERR,
+ "config_auditd_ipc() : failed sending control file "
+ "name to the kernel: %s\n",
+ strerror(errno));
+ }
return 0;
}
@@ -735,7 +745,7 @@
}
}
- openlog("auditd", LOG_CONS | LOG_PID, LOG_DAEMON);
+ openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY);
syslog(LOG_INFO, "starting...\n");
if (debug == 0 && daemon(0, 0) == -1) {
==== //depot/projects/trustedbsd/audit3/sys/bsm/audit.h#6 (text+ko) ====
@@ -302,7 +302,7 @@
int audit (const void *, int);
int auditon (int, void *, int);
-int auditctl (int, void *, int);
+int auditctl (int, const char *);
int getauid (au_id_t *);
int setauid (const au_id_t *);
int getaudit (struct auditinfo *);
==== //depot/projects/trustedbsd/audit3/sys/kern/init_sysent.c#5 (text+ko) ====
==== //depot/projects/trustedbsd/audit3/sys/kern/syscalls.c#5 (text+ko) ====
==== //depot/projects/trustedbsd/audit3/sys/kern/syscalls.master#5 (text+ko) ====
@@ -705,6 +705,6 @@
*auditinfo_addr, u_int length); } AUE_GETAUDIT_ADDR
451 MSTD { int setaudit_addr(struct auditinfo_addr \
*auditinfo_addr, u_int length); } AUE_SETAUDIT_ADDR
-452 MSTD { int auditctl(int cmd, void *data, u_int length); } AUE_AUDITCTL
+452 MSTD { int auditctl(int cmd, char *path); } AUE_AUDITCTL
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
==== //depot/projects/trustedbsd/audit3/sys/security/audit/kern_audit.c#10 (text+ko) ====
@@ -29,6 +29,7 @@
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
+#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/queue.h>
@@ -63,7 +64,7 @@
* volume, it should be left off unless you want your system
* to churn a lot whenever the audit record flow gets high.
*/
-#define AUDIT_EXCESSIVELY_VERBOSE
+//#define AUDIT_EXCESSIVELY_VERBOSE
#ifdef AUDIT_EXCESSIVELY_VERBOSE
#define AUDIT_PRINTF(x) printf x
#else
@@ -177,6 +178,10 @@
static int audit_file_rotate_wait;
/*
+ * vnode for the audit daemon control file
+ */
+static struct vnode *auditd_ctl_vp;
+/*
* Flags controlling behavior in low storage situations.
* Should we panic if a write fails? Should we fail stop
* if we're out of disk space? Are we currently "failing
@@ -215,7 +220,10 @@
struct thread *td)
{
int ret;
+ int trigger;
struct au_record *bsm;
+ struct vattr vattr;
+ struct statfs *mnt_stat = &vp->v_mount->mnt_stat;
mtx_assert(&Giant, MA_OWNED);
@@ -226,14 +234,11 @@
* and return. However, this is arguably an assertion failure.
* XXX Need a FreeBSD equivalent.
*/
-#if DARWIN_FOO
- struct vattr vattr;
- struct statfs *mnt_stat = &vp->v_mount->mnt_stat;
- ret = VFS_STATFS(vp->v_mount, mnt_stat, p);
+ ret = VFS_STATFS(vp->v_mount, mnt_stat, td);
if (ret)
goto out;
- ret = VOP_GETATTR(vp, &vattr, cred, p);
+ ret = VOP_GETATTR(vp, &vattr, cred, td);
if (ret)
goto out;
@@ -246,11 +251,7 @@
* XXX Need to decide what to do if the trigger to the audit daemon
* fails.
*/
- if(host_get_audit_control_port(host_priv_self(), &audit_port)
- != KERN_SUCCESS)
- printf("Cannot get audit control port\n");
-
- if (audit_port != MACH_PORT_NULL) {
+ if (auditd_ctl_vp != NULL) {
long temp;
/*
@@ -260,9 +261,12 @@
if (audit_qctrl.aq_minfree != 0) {
temp = mnt_stat->f_blocks / (100 / audit_qctrl.aq_minfree);
if (mnt_stat->f_bfree < temp) {
- ret = audit_triggers(audit_port,
- AUDIT_TRIGGER_LOW_SPACE);
- if (ret != KERN_SUCCESS) {
+ trigger = AUDITD_TRIGGER_LOW_SPACE;
+ ret = vn_rdwr(UIO_WRITE, auditd_ctl_vp,
+ (void *)&trigger, sizeof(trigger),
+ (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT,
+ cred, NULL, NULL, td);
+ if (ret != 0) {
printf(
"Failed audit_triggers(AUDIT_TRIGGER_LOW_SPACE): %d\n", ret);
/*
@@ -281,9 +285,12 @@
(audit_file_rotate_wait == 0) &&
(vattr.va_size >= audit_fstat.af_filesz)) {
audit_file_rotate_wait = 1;
- ret = audit_triggers(audit_port,
- AUDIT_TRIGGER_FILE_FULL);
- if (ret != KERN_SUCCESS) {
+ trigger = AUDITD_TRIGGER_FILE_FULL;
+ ret = vn_rdwr(UIO_WRITE, auditd_ctl_vp,
+ (void *)&trigger, sizeof(trigger),
+ (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT,
+ cred, NULL, NULL, td);
+ if (ret != 0) {
printf(
"Failed audit_triggers(AUDIT_TRIGGER_FILE_FULL): %d\n", ret);
/* XXX what to do here? */
@@ -312,7 +319,6 @@
audit_in_failure = 1;
}
-#endif
/*
* If there is a user audit record attached to the kernel record,
* then write the user record.
@@ -370,7 +376,6 @@
kau_free(bsm);
out:
-#if DARWIN_FOO
/*
* When we're done processing the current record, we have to
* check to see if we're in a failure mode, and if so, whether
@@ -379,12 +384,11 @@
*/
if (audit_in_failure &&
audit_q_len == 0 && audit_pre_q_len == 0) {
- VOP_LOCK(vp, LK_DRAIN | LK_INTERLOCK, p);
- (void)VOP_FSYNC(vp, cred, MNT_WAIT, p);
- VOP_UNLOCK(vp, 0, p);
+ VOP_LOCK(vp, LK_DRAIN | LK_INTERLOCK, td);
+ (void)VOP_FSYNC(vp, cred, MNT_WAIT, td);
+ VOP_UNLOCK(vp, 0, td);
panic("Audit store overflow; record queue drained.");
}
-#endif
return (ret);
}
@@ -585,6 +589,7 @@
audit_replacement_flag = 0;
audit_file_rotate_wait = 0;
audit_replacement_vp = NULL;
+ auditd_ctl_vp = NULL;
audit_fstat.af_filesz = 0; /* '0' means unset, unbounded */
audit_fstat.af_currsz = 0;
audit_qctrl.aq_hiwater = AQ_HIWATER;
@@ -1089,7 +1094,6 @@
struct ucred *cred;
struct vnode *vp;
int error, flags;
- union auditctl_udata udata;
error = suser(td);
if (error)
@@ -1098,8 +1102,6 @@
vp = NULL;
cred = NULL;
- memset((void *)&udata, 0, sizeof(udata));
-
switch (uap->cmd) {
case AC_SETLOGFILE:
/*
@@ -1107,18 +1109,11 @@
* validity checks, and grab another reference to the current
* credential.
*/
- if (uap->data != NULL) {
+ if (uap->path != NULL) {
- if ((uap->length <= 0) || (uap->length > MAXPATHLEN))
- return (EINVAL);
-
- error = copyin(uap->data, (void *)&udata, uap->length);
- if (error)
- return (error);
-
mtx_lock(&Giant);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
- udata.ac_path, td);
+ uap->path, td);
flags = audit_open_flags;
error = vn_open(&nd, &flags, 0, -1);
if (error) {
@@ -1141,7 +1136,29 @@
audit_rotate_vnode(cred, vp);
break;
- case AC_SETCTLFD: /* Set control file descriptor */
+
+ case AC_SETCTLFILE: /* Set auditd control file */
+ if (uap->path != NULL) {
+ mtx_lock(&Giant);
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
+ uap->path, td);
+ flags = FWRITE | O_NONBLOCK;
+ error = vn_open(&nd, &flags, 0, -1);
+ if (error) {
+ mtx_unlock(&Giant);
+ return (error);
+ }
+ VOP_UNLOCK(nd.ni_vp, 0, td);
+ vp = nd.ni_vp;
+ if (vp->v_type != VFIFO) {
+ vn_close(vp, audit_close_flags,
+ td->td_ucred, td);
+ mtx_unlock(&Giant);
+ return (EINVAL);
+ }
+ auditd_ctl_vp = vp;
+ mtx_unlock(&Giant);
+ }
break;
}
return (0);
==== //depot/projects/trustedbsd/audit3/sys/sys/syscall.h#5 (text+ko) ====
==== //depot/projects/trustedbsd/audit3/sys/sys/syscall.mk#5 (text+ko) ====
==== //depot/projects/trustedbsd/audit3/sys/sys/sysproto.h#6 (text+ko) ====
@@ -1334,8 +1334,7 @@
};
struct auditctl_args {
char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)];
- char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)];
- char length_l_[PADL_(u_int)]; u_int length; char length_r_[PADR_(u_int)];
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
};
int nosys(struct thread *, struct nosys_args *);
void sys_exit(struct thread *, struct sys_exit_args *);
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