Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}