Access Vector Cache Auditing

A very prominent example where auditing is a rather crucial requirement is the SELinux access vector cache. Granting or denying permissions is performed by the function avc_audit, which is called from avc_has_perm, that is, whenever a permission query is passed to the security server. First, the function needs to check if auditing is required for the current case (i.e., granting or denial is supposed to be audited or not) as follows:

security/selinux/avc.c void avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, struct av_decision *avd, int result, struct avc_audit_data *a)

struct task_struct *tsk = current; struct inode *inode = NULL; u32 denied, audited; struct audit_buffer *ab;

denied = requested & ~avd->allowed; if (denied) {

audited = denied; if (¡(audited & avd->auditdeny)) return; } else if (result) {

audited = denied = requested;

audited = requested; if (¡(audited & avd->auditallow)) return;

If an audit message needs to be created, the basic information (granting or denial, the access vector in question, and the task's PID) is generated as follows:

security/selinux/avc.c ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC); if (!ab)

return; /* audit_panic has been called */

audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted"); avc_dump_av(ab, tclass,audited); audit_log_format(ab, " for "); if (a && a->tsk)

audit_log_format(ab, " pid=%d comm=", tsk->pid); audit_log_untrustedstring(ab, tsk->comm);

avc_dump_av is used to display an access vector in human-readable form (this is a purely cosmetic conversion). If auxiliary data are associated with the query, it is also put into the audit record. Afterwards the record can be closed.

security/selinux/avc.c if (a) {


audit_log_format(ab, break;


audit_log_format(ab, break;


/* Audit networking related information */

avc_dump_query(ab, ssid, tsid, tclass);


key=%d", a->u.ipc_id); capability=%d", a->u.cap);

Was this article helpful?

0 0

Post a comment