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; if (ar == NULL) return; /* * Decide whether to commit the audit record by checking the error * value from the system call and using the appropriate audit mask. */ if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) aumask = &audit_nae_mask; else aumask = &ar->k_ar.ar_subj_amask; if (error) sorf = AU_PRS_FAILURE; else sorf = AU_PRS_SUCCESS; /* * syscalls.master sometimes contains a prototype event number, which * we will transform into a more specific event number now that we * have more complete information gathered during the system call. */ switch(ar->k_ar.ar_event) { case AUE_OPEN_RWTC: ar->k_ar.ar_event = audit_flags_and_error_to_openevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_OPENAT_RWTC: ar->k_ar.ar_event = audit_flags_and_error_to_openatevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_SYSCTL: ar->k_ar.ar_event = audit_ctlname_to_sysctlevent( ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); break; case AUE_AUDITON: /* Convert the auditon() command to an event. */ ar->k_ar.ar_event = auditon_command_event(ar->k_ar.ar_arg_cmd); break; } 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 | AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE)) == 0) { mtx_lock(&audit_mtx); audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } ar->k_ar.ar_errno = error; ar->k_ar.ar_retval = retval; nanotime(&ar->k_ar.ar_endtime); /* * Note: it could be that some records initiated while audit was * enabled should still be committed? */ mtx_lock(&audit_mtx); if (audit_suspended || !audit_enabled) { audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } /* * Constrain the number of committed audit records based on the * configurable parameter. */ while (audit_q_len >= audit_qctrl.aq_hiwater) cv_wait(&audit_watermark_cv, &audit_mtx); TAILQ_INSERT_TAIL(&audit_q, ar, k_q); audit_q_len++; audit_pre_q_len--; cv_signal(&audit_worker_cv); mtx_unlock(&audit_mtx); }
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; if (ar == NULL) return; ar->k_ar.ar_errno = error; ar->k_ar.ar_retval = retval; nanotime(&ar->k_ar.ar_endtime); /* * Decide whether to commit the audit record by checking the error * value from the system call and using the appropriate audit mask. */ if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) aumask = &audit_nae_mask; else aumask = &ar->k_ar.ar_subj_amask; if (error) sorf = AU_PRS_FAILURE; else sorf = AU_PRS_SUCCESS; /* * syscalls.master sometimes contains a prototype event number, which * we will transform into a more specific event number now that we * have more complete information gathered during the system call. */ switch(ar->k_ar.ar_event) { case AUE_OPEN_RWTC: ar->k_ar.ar_event = audit_flags_and_error_to_openevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_OPENAT_RWTC: ar->k_ar.ar_event = audit_flags_and_error_to_openatevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_SYSCTL: ar->k_ar.ar_event = audit_ctlname_to_sysctlevent( ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); break; case AUE_AUDITON: /* Convert the auditon() command to an event. */ ar->k_ar.ar_event = auditon_command_event(ar->k_ar.ar_arg_cmd); break; case AUE_MSGSYS: if (ARG_IS_VALID(ar, ARG_SVIPC_WHICH)) ar->k_ar.ar_event = audit_msgsys_to_event(ar->k_ar.ar_arg_svipc_which); break; case AUE_SEMSYS: if (ARG_IS_VALID(ar, ARG_SVIPC_WHICH)) ar->k_ar.ar_event = audit_semsys_to_event(ar->k_ar.ar_arg_svipc_which); break; case AUE_SHMSYS: if (ARG_IS_VALID(ar, ARG_SVIPC_WHICH)) ar->k_ar.ar_event = audit_shmsys_to_event(ar->k_ar.ar_arg_svipc_which); break; } 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; #ifdef KDTRACE_HOOKS /* * Expose the audit record to DTrace, both to allow the "commit" probe * to fire if it's desirable, and also to allow a decision to be made * about later firing with BSM in the audit worker. */ if (dtaudit_hook_commit != NULL) { if (dtaudit_hook_commit(ar, auid, event, class, sorf) != 0) ar->k_ar_commit |= AR_PRESELECT_DTRACE; } #endif if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE | AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE | AR_PRESELECT_DTRACE)) == 0) { mtx_lock(&audit_mtx); audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } /* * Note: it could be that some records initiated while audit was * enabled should still be committed? * * NB: The check here is not for audit_syscalls because any * DTrace-related obligations have been fulfilled above -- we're just * down to the trail and pipes now. */ mtx_lock(&audit_mtx); if (audit_trail_suspended || !audit_trail_enabled) { audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } /* * Constrain the number of committed audit records based on the * configurable parameter. */ while (audit_q_len >= audit_qctrl.aq_hiwater) cv_wait(&audit_watermark_cv, &audit_mtx); TAILQ_INSERT_TAIL(&audit_q, ar, k_q); audit_q_len++; audit_pre_q_len--; cv_signal(&audit_worker_cv); mtx_unlock(&audit_mtx); }
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; int audit_override; if (ar == NULL) return; /* * Decide whether to commit the audit record by checking the error * value from the system call and using the appropriate audit mask. */ if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) aumask = &audit_nae_mask; else aumask = &ar->k_ar.ar_subj_amask; if (error) sorf = AU_PRS_FAILURE; else sorf = AU_PRS_SUCCESS; switch(ar->k_ar.ar_event) { case AUE_OPEN_RWTC: /* * The open syscall always writes a AUE_OPEN_RWTC event; * change it to the proper type of event based on the flags * and the error value. */ ar->k_ar.ar_event = audit_flags_and_error_to_openevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_OPEN_EXTENDED_RWTC: /* * The open_extended syscall always writes a * AUE_OPEN_EXTENDEDRWTC event; change it to the proper type of * event based on the flags and the error value. */ ar->k_ar.ar_event = audit_flags_and_error_to_openextendedevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_OPENAT_RWTC: /* * The openat syscall always writes a * AUE_OPENAT_RWTC event; change it to the proper type of * event based on the flags and the error value. */ ar->k_ar.ar_event = audit_flags_and_error_to_openatevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_OPENBYID_RWT: /* * The openbyid syscall always writes a * AUE_OPENBYID_RWT event; change it to the proper type of * event based on the flags and the error value. */ ar->k_ar.ar_event = audit_flags_and_error_to_openbyidevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_SYSCTL: ar->k_ar.ar_event = audit_ctlname_to_sysctlevent( ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); break; case AUE_AUDITON: /* Convert the auditon() command to an event. */ ar->k_ar.ar_event = auditon_command_event(ar->k_ar.ar_arg_cmd); break; case AUE_FCNTL: /* Convert some fcntl() commands to their own events. */ ar->k_ar.ar_event = audit_fcntl_command_event( ar->k_ar.ar_arg_cmd, ar->k_ar.ar_arg_fflags, error); break; } auid = ar->k_ar.ar_subj_auid; event = ar->k_ar.ar_event; class = au_event_class(event); /* * See if we need to override the audit_suspend and audit_enabled * flags. * * XXXss - This check needs to be generalized so new filters can * easily be added. */ audit_override = (AUE_SESSION_START == event || AUE_SESSION_UPDATE == event || AUE_SESSION_END == event || AUE_SESSION_CLOSE == 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 | AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE | AR_PRESELECT_FILTER)) == 0) { mtx_lock(&audit_mtx); audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } ar->k_ar.ar_errno = error; ar->k_ar.ar_retval = retval; nanotime(&ar->k_ar.ar_endtime); /* * Note: it could be that some records initiated while audit was * enabled should still be committed? */ mtx_lock(&audit_mtx); if (!audit_override && (audit_suspended || !audit_enabled)) { audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } /* * Constrain the number of committed audit records based on the * configurable parameter. */ while (audit_q_len >= audit_qctrl.aq_hiwater) cv_wait(&audit_watermark_cv, &audit_mtx); TAILQ_INSERT_TAIL(&audit_q, ar, k_q); audit_q_len++; audit_pre_q_len--; cv_signal(&audit_worker_cv); mtx_unlock(&audit_mtx); }