summaryrefslogtreecommitdiffstats
path: root/sys/security/audit/audit.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-06-05 14:48:17 +0000
committerrwatson <rwatson@FreeBSD.org>2006-06-05 14:48:17 +0000
commit4f317e157608e1b894810563738d4706ca17a07e (patch)
tree299259998d5bd315eb95c846662bd4113c0913bf /sys/security/audit/audit.c
parenta5b858d3fd9e18072e6c667da827f7fa363e5707 (diff)
downloadFreeBSD-src-4f317e157608e1b894810563738d4706ca17a07e.zip
FreeBSD-src-4f317e157608e1b894810563738d4706ca17a07e.tar.gz
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming audit trails to specify parameters for which audit records are of interest, including selecting records not required by the global trail. Allowing application interest specification without changing the global configuration allows intrusion detection systems to run without interfering with global auditing or each other (if multiple are present). To implement this: - Kernel audit records now carry a flag to indicate whether they have been selected by the global trail or by the audit pipe subsystem, set during record commit, so that this information is available after BSM conversion when delivering the BSM to the trail and audit pipes in the audit worker thread asynchronously. Preselection by either record target will cause the record to be kept. - Similar changes to preselection when the audit record is created when the system call is entering: consult both the global trail and pipes. - au_preselect() now accepts the class in order to avoid repeatedly looking up the mask for each preselection test. - Define a series of ioctls that allow applications to specify whether they want to track the global trail, or program their own preselection parameters: they may specify their own flags and naflags masks, similar to the global masks of the same name, as well as a set of per-auid masks. They also set a per-pipe mode specifying whether they track the global trail, or user their own -- the door is left open for future additional modes. A new ioctl is defined to allow a user process to flush the current audit pipe queue, which can be used after reprogramming pre-selection to make sure that only records of interest are received in future reads. - Audit pipe data structures are extended to hold the additional fields necessary to support preselection. By default, audit pipes track the global trail, so "praudit /dev/auditpipe" will track the global audit trail even though praudit doesn't program the audit pipe selection model. - Comment about the complexities of potentially adding partial read support to audit pipes. By using a set of ioctls, applications can select which records are of interest, and toggle the preselection mode. Obtained from: TrustedBSD Project
Diffstat (limited to 'sys/security/audit/audit.c')
-rw-r--r--sys/security/audit/audit.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/sys/security/audit/audit.c b/sys/security/audit/audit.c
index 0161c43..d61bb99 100644
--- a/sys/security/audit/audit.c
+++ b/sys/security/audit/audit.c
@@ -332,6 +332,9 @@ audit_free(struct kaudit_record *ar)
void
audit_commit(struct kaudit_record *ar, int error, int retval)
{
+ au_event_t event;
+ au_class_t class;
+ au_id_t auid;
int sorf;
struct au_mask *aumask;
@@ -377,14 +380,18 @@ audit_commit(struct kaudit_record *ar, int error, int retval)
break;
}
- if (au_preselect(ar->k_ar.ar_event, aumask, sorf) != 0)
- ar->k_ar_commit |= AR_COMMIT_KERNEL;
-
- /*
- * XXXRW: Why is this necessary? Should we ever accept a record that
- * we're not willing to commit?
- */
- if ((ar->k_ar_commit & (AR_COMMIT_USER | AR_COMMIT_KERNEL)) == 0) {
+ auid = ar->k_ar.ar_subj_auid;
+ event = ar->k_ar.ar_event;
+ class = au_event_class(event);
+
+ ar->k_ar_commit |= AR_COMMIT_KERNEL;
+ if (au_preselect(event, class, aumask, sorf) != 0)
+ ar->k_ar_commit |= AR_PRESELECT_TRAIL;
+ if (audit_pipe_preselect(auid, event, class, sorf,
+ ar->k_ar_commit & AR_PRESELECT_TRAIL) != 0)
+ ar->k_ar_commit |= AR_PRESELECT_PIPE;
+ if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE)) ==
+ 0) {
mtx_lock(&audit_mtx);
audit_pre_q_len--;
mtx_unlock(&audit_mtx);
@@ -446,8 +453,10 @@ audit_commit(struct kaudit_record *ar, int error, int retval)
void
audit_syscall_enter(unsigned short code, struct thread *td)
{
- int audit_event;
struct au_mask *aumask;
+ au_class_t class;
+ au_event_t event;
+ au_id_t auid;
KASSERT(td->td_ar == NULL, ("audit_syscall_enter: td->td_ar != NULL"));
@@ -464,15 +473,16 @@ audit_syscall_enter(unsigned short code, struct thread *td)
if (code >= td->td_proc->p_sysent->sv_size)
return;
- audit_event = td->td_proc->p_sysent->sv_table[code].sy_auevent;
- if (audit_event == AUE_NULL)
+ event = td->td_proc->p_sysent->sv_table[code].sy_auevent;
+ if (event == AUE_NULL)
return;
/*
* Check which audit mask to use; either the kernel non-attributable
* event mask or the process audit mask.
*/
- if (td->td_proc->p_au->ai_auid == AU_DEFAUDITID)
+ auid = td->td_proc->p_au->ai_auid;
+ if (auid == AU_DEFAUDITID)
aumask = &audit_nae_mask;
else
aumask = &td->td_proc->p_au->ai_mask;
@@ -481,8 +491,8 @@ audit_syscall_enter(unsigned short code, struct thread *td)
* Allocate an audit record, if preselection allows it, and store
* in the thread for later use.
*/
- if (au_preselect(audit_event, aumask,
- AU_PRS_FAILURE | AU_PRS_SUCCESS)) {
+ class = au_event_class(event);
+ if (au_preselect(event, class, aumask, AU_PRS_BOTH)) {
/*
* If we're out of space and need to suspend unprivileged
* processes, do that here rather than trying to allocate
@@ -499,8 +509,10 @@ audit_syscall_enter(unsigned short code, struct thread *td)
cv_wait(&audit_fail_cv, &audit_mtx);
panic("audit_failing_stop: thread continued");
}
- td->td_ar = audit_new(audit_event, td);
- } else
+ td->td_ar = audit_new(event, td);
+ } else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0))
+ td->td_ar = audit_new(event, td);
+ else
td->td_ar = NULL;
}
OpenPOWER on IntegriCloud