Date: Thu, 4 May 2006 13:58:55 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 96655 for review Message-ID: <200605041358.k44DwtGf056422@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=96655 Change 96655 by rwatson@rwatson_zoo on 2006/05/04 13:57:56 A variety of changes in support of preselection for audit pipes: - Add two new preselection flags for queued audit records: AR_PRESELECT_TRAIL and AR_PRESELECT_PIPE, which are used to track whether a particular queued record was requested by the global trail configuration, or if some or another pipe has requested it. This flag is now set during record commit preselection to be used by the audit worker in deciding where to send the record. - au_preselect() now accepts a class argument so that the caller can look up the class once for all trail/pipe preselection and avoid repeated class lookups for an event type. Affected files ... .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit.c#27 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_klib.c#6 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#18 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_private.h#26 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_syscalls.c#13 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_worker.c#10 edit Differences ... ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit.c#27 (text+ko) ==== @@ -334,6 +334,9 @@ 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; @@ -379,14 +382,17 @@ break; } - if (au_preselect(ar->k_ar.ar_event, aumask, sorf) != 0) - ar->k_ar_commit |= AR_COMMIT_KERNEL; + auid = ar->k_ar.ar_subj_auid; + event = ar->k_ar.ar_event; + class = au_event_class(event); - /* - * 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) { + 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) != 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); @@ -448,8 +454,10 @@ 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")); @@ -466,15 +474,16 @@ 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; @@ -483,8 +492,8 @@ * 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 @@ -501,8 +510,10 @@ 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)) + td->td_ar = audit_new(event, td); + else td->td_ar = NULL; } ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_klib.c#6 (text+ko) ==== @@ -155,24 +155,21 @@ * event is part of against the given mask. */ int -au_preselect(au_event_t event, au_mask_t *mask_p, int sorf) +au_preselect(au_event_t event, au_class_t class, au_mask_t *mask_p, int sorf) { au_class_t effmask = 0; - au_class_t ae_class; if (mask_p == NULL) return (-1); - ae_class = au_event_class(event); - /* * Perform the actual check of the masks against the event. */ if (sorf & AU_PRS_SUCCESS) - effmask |= (mask_p->am_success & ae_class); + effmask |= (mask_p->am_success & class); if (sorf & AU_PRS_FAILURE) - effmask |= (mask_p->am_failure & ae_class); + effmask |= (mask_p->am_failure & class); if (effmask) return (1); ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_pipe.c#18 (text+ko) ==== @@ -216,13 +216,13 @@ } if (app == NULL) { if (auid == AU_DEFAUDITID) - return (au_preselect(event, &ap->ap_preselect_naflags, - sorf)); + return (au_preselect(event, class, + &ap->ap_preselect_naflags, sorf)); else - return (au_preselect(event, &ap->ap_preselect_flags, - sorf)); + return (au_preselect(event, class, + &ap->ap_preselect_flags, sorf)); } else - return (au_preselect(event, &app->app_mask, sorf)); + return (au_preselect(event, class, &app->app_mask, sorf)); return (0); } @@ -239,7 +239,7 @@ mtx_lock(&audit_pipe_mtx); TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { if (audit_pipe_preselect_check(ap, auid, event, class, sorf)) { - mtx_lock(&audit_pipe_mtx); + mtx_unlock(&audit_pipe_mtx); return (1); } } ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_private.h#26 (text+ko) ==== @@ -84,11 +84,16 @@ #define BSM_NOAUDIT 2 /* - * Defines for the kernel audit record k_ar_commit field. + * Defines for the kernel audit record k_ar_commit field. Flags are set to + * indicate what sort of record it is, and which preselection mechanism + * selected it. */ #define AR_COMMIT_KERNEL 0x00000001U #define AR_COMMIT_USER 0x00000010U +#define AR_PRESELECT_TRAIL 0x00001000U +#define AR_PRESELECT_PIPE 0x00002000U + /* * Audit data is generated as a stream of struct audit_record structures, * linked by struct kaudit_record, and contain storage for possible audit so @@ -305,7 +310,8 @@ /* * audit_klib prototypes */ -int au_preselect(au_event_t event, au_mask_t *mask_p, int sorf); +int au_preselect(au_event_t event, au_class_t class, + au_mask_t *mask_p, int sorf); au_event_t flags_and_error_to_openevent(int oflags, int error); void au_evclassmap_init(void); void au_evclassmap_insert(au_event_t event, au_class_t class); ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_syscalls.c#13 (text+ko) ==== ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_worker.c#10 (text+ko) ==== @@ -321,52 +321,60 @@ au_id_t auid; int sorf; - if (ar->k_ar_commit & AR_COMMIT_USER) { + if ((ar->k_ar_commit & AR_COMMIT_USER) && + (ar->k_ar_commit & AR_PRESELECT_TRAIL)) { error = audit_record_write(audit_vp, audit_cred, audit_td, ar->k_udata, ar->k_ulen); if (error && audit_panic_on_write_fail) panic("audit_worker: write error %d\n", error); else if (error) printf("audit_worker: write error %d\n", error); + } + if ((ar->k_ar_commit & AR_COMMIT_USER) && + (ar->k_ar_commit & AR_PRESELECT_PIPE)) audit_pipe_submit_user(ar->k_udata, ar->k_ulen); - } + + if (!(ar->k_ar_commit & AR_COMMIT_KERNEL)) + return; + + auid = ar->k_ar.ar_subj_auid; + event = ar->k_ar.ar_event; + class = au_event_class(event); + if (ar->k_ar.ar_errno == 0) + sorf = AU_PRS_SUCCESS; + else + sorf = AU_PRS_FAILURE; - if (ar->k_ar_commit & AR_COMMIT_KERNEL) { - auid = ar->k_ar.ar_subj_auid; - event = ar->k_ar.ar_event; - class = au_event_class(event); - if (ar->k_ar.ar_errno == 0) - sorf = AU_PRS_SUCCESS; - else - sorf = AU_PRS_FAILURE; + ret = kaudit_to_bsm(ar, &bsm); + switch (ret) { + case BSM_NOAUDIT: + return; - ret = kaudit_to_bsm(ar, &bsm); - switch (ret) { - case BSM_NOAUDIT: - break; + case BSM_FAILURE: + printf("audit_worker_process_record: BSM_FAILURE\n"); + return; - case BSM_FAILURE: - printf("audit_worker_process_record: BSM_FAILURE\n"); - break; + case BSM_SUCCESS: + break; - case BSM_SUCCESS: - error = audit_record_write(audit_vp, audit_cred, - audit_td, bsm->data, bsm->len); - if (error && audit_panic_on_write_fail) - panic("audit_worker: write error %d\n", - error); - else if (error) - printf("audit_worker: write error %d\n", - error); - audit_pipe_submit(auid, event, class, sorf, - bsm->data, bsm->len); - kau_free(bsm); - break; + default: + panic("kaudit_to_bsm returned %d", ret); + } - default: - panic("kaudit_to_bsm returned %d", ret); - } + if (ar->k_ar_commit & AR_PRESELECT_TRAIL) { + error = audit_record_write(audit_vp, audit_cred, + audit_td, bsm->data, bsm->len); + if (error && audit_panic_on_write_fail) + panic("audit_worker: write error %d\n", + error); + else if (error) + printf("audit_worker: write error %d\n", + error); } + if (ar->k_ar_commit & AR_PRESELECT_PIPE) + audit_pipe_submit(auid, event, class, sorf, + bsm->data, bsm->len); + kau_free(bsm); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605041358.k44DwtGf056422>