1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * Access vector cache interface for object managers.
41da177e4SLinus Torvalds *
5*0fe53224SStephen Smalley * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
61da177e4SLinus Torvalds */
71da177e4SLinus Torvalds #ifndef _SELINUX_AVC_H_
81da177e4SLinus Torvalds #define _SELINUX_AVC_H_
91da177e4SLinus Torvalds
101da177e4SLinus Torvalds #include <linux/stddef.h>
111da177e4SLinus Torvalds #include <linux/errno.h>
121da177e4SLinus Torvalds #include <linux/kernel.h>
131da177e4SLinus Torvalds #include <linux/kdev_t.h>
141da177e4SLinus Torvalds #include <linux/spinlock.h>
151da177e4SLinus Torvalds #include <linux/init.h>
16d9250deaSKaiGai Kohei #include <linux/audit.h>
172bf49690SThomas Liu #include <linux/lsm_audit.h>
181da177e4SLinus Torvalds #include <linux/in6.h>
191da177e4SLinus Torvalds #include "flask.h"
201da177e4SLinus Torvalds #include "av_permissions.h"
211da177e4SLinus Torvalds #include "security.h"
221da177e4SLinus Torvalds
231da177e4SLinus Torvalds /*
241da177e4SLinus Torvalds * An entry in the AVC.
251da177e4SLinus Torvalds */
261da177e4SLinus Torvalds struct avc_entry;
271da177e4SLinus Torvalds
281da177e4SLinus Torvalds struct task_struct;
291da177e4SLinus Torvalds struct inode;
301da177e4SLinus Torvalds struct sock;
311da177e4SLinus Torvalds struct sk_buff;
321da177e4SLinus Torvalds
331da177e4SLinus Torvalds /*
341da177e4SLinus Torvalds * AVC statistics
351da177e4SLinus Torvalds */
36f5269710SEric Paris struct avc_cache_stats {
371da177e4SLinus Torvalds unsigned int lookups;
381da177e4SLinus Torvalds unsigned int misses;
391da177e4SLinus Torvalds unsigned int allocations;
401da177e4SLinus Torvalds unsigned int reclaims;
411da177e4SLinus Torvalds unsigned int frees;
421da177e4SLinus Torvalds };
431da177e4SLinus Torvalds
443f0882c4SEric Paris /*
453f0882c4SEric Paris * We only need this data after we have decided to send an audit message.
463f0882c4SEric Paris */
47899838b2SEric Paris struct selinux_audit_data {
483b3b0e4fSEric Paris u32 ssid;
493b3b0e4fSEric Paris u32 tsid;
503b3b0e4fSEric Paris u16 tclass;
513b3b0e4fSEric Paris u32 requested;
523b3b0e4fSEric Paris u32 audited;
533b3b0e4fSEric Paris u32 denied;
543f0882c4SEric Paris int result;
55494688efSGONG, Ruiqi } __randomize_layout;
563f0882c4SEric Paris
573f0882c4SEric Paris /*
581da177e4SLinus Torvalds * AVC operations
591da177e4SLinus Torvalds */
601da177e4SLinus Torvalds
611da177e4SLinus Torvalds void __init avc_init(void);
621da177e4SLinus Torvalds
avc_audit_required(u32 requested,struct av_decision * avd,int result,u32 auditdeny,u32 * deniedp)632e334057SEric Paris static inline u32 avc_audit_required(u32 requested,
642e334057SEric Paris struct av_decision *avd,
652e334057SEric Paris int result,
662e334057SEric Paris u32 auditdeny,
672e334057SEric Paris u32 *deniedp)
682e334057SEric Paris {
692e334057SEric Paris u32 denied, audited;
702e334057SEric Paris denied = requested & ~avd->allowed;
712e334057SEric Paris if (unlikely(denied)) {
722e334057SEric Paris audited = denied & avd->auditdeny;
732e334057SEric Paris /*
742e334057SEric Paris * auditdeny is TRICKY! Setting a bit in
752e334057SEric Paris * this field means that ANY denials should NOT be audited if
762e334057SEric Paris * the policy contains an explicit dontaudit rule for that
772e334057SEric Paris * permission. Take notice that this is unrelated to the
782e334057SEric Paris * actual permissions that were denied. As an example lets
792e334057SEric Paris * assume:
802e334057SEric Paris *
812e334057SEric Paris * denied == READ
822e334057SEric Paris * avd.auditdeny & ACCESS == 0 (not set means explicit rule)
832e334057SEric Paris * auditdeny & ACCESS == 1
842e334057SEric Paris *
852e334057SEric Paris * We will NOT audit the denial even though the denied
862e334057SEric Paris * permission was READ and the auditdeny checks were for
872e334057SEric Paris * ACCESS
882e334057SEric Paris */
892e334057SEric Paris if (auditdeny && !(auditdeny & avd->auditdeny))
902e334057SEric Paris audited = 0;
912e334057SEric Paris } else if (result)
922e334057SEric Paris audited = denied = requested;
932e334057SEric Paris else
942e334057SEric Paris audited = requested & avd->auditallow;
952e334057SEric Paris *deniedp = denied;
962e334057SEric Paris return audited;
972e334057SEric Paris }
982e334057SEric Paris
99e67b7985SStephen Smalley int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
100ca7786a2SStephen Smalley u32 requested, u32 audited, u32 denied, int result,
1010188d5c0SStephen Smalley struct common_audit_data *a);
1022e334057SEric Paris
1032e334057SEric Paris /**
1042e334057SEric Paris * avc_audit - Audit the granting or denial of permissions.
1052e334057SEric Paris * @ssid: source security identifier
1062e334057SEric Paris * @tsid: target security identifier
1072e334057SEric Paris * @tclass: target security class
1082e334057SEric Paris * @requested: requested permissions
1092e334057SEric Paris * @avd: access vector decisions
1102e334057SEric Paris * @result: result from avc_has_perm_noaudit
1112e334057SEric Paris * @a: auxiliary audit data
1122e334057SEric Paris *
1132e334057SEric Paris * Audit the granting or denial of permissions in accordance
1142e334057SEric Paris * with the policy. This function is typically called by
1152e334057SEric Paris * avc_has_perm() after a permission check, but can also be
1162e334057SEric Paris * called directly by callers who use avc_has_perm_noaudit()
1172e334057SEric Paris * in order to separate the permission check from the auditing.
1182e334057SEric Paris * For example, this separation is useful when the permission check must
1192e334057SEric Paris * be performed under a lock, to allow the lock to be released
1202e334057SEric Paris * before calling the auditing code.
1212e334057SEric Paris */
avc_audit(u32 ssid,u32 tsid,u16 tclass,u32 requested,struct av_decision * avd,int result,struct common_audit_data * a)122e67b7985SStephen Smalley static inline int avc_audit(u32 ssid, u32 tsid,
1231da177e4SLinus Torvalds u16 tclass, u32 requested,
1242bf49690SThomas Liu struct av_decision *avd,
1252bf49690SThomas Liu int result,
126d99cf13fSAl Viro struct common_audit_data *a)
1272e334057SEric Paris {
1282e334057SEric Paris u32 audited, denied;
1291d349292SEric Paris audited = avc_audit_required(requested, avd, result, 0, &denied);
1302e334057SEric Paris if (likely(!audited))
1312e334057SEric Paris return 0;
132e67b7985SStephen Smalley return slow_avc_audit(ssid, tsid, tclass,
133ca7786a2SStephen Smalley requested, audited, denied, result,
1340188d5c0SStephen Smalley a);
1352e334057SEric Paris }
1361da177e4SLinus Torvalds
1372c3c05dbSStephen Smalley #define AVC_STRICT 1 /* Ignore permissive mode. */
138fa1aa143SJeff Vander Stoep #define AVC_EXTENDED_PERMS 2 /* update extended permissions */
139e67b7985SStephen Smalley int avc_has_perm_noaudit(u32 ssid, u32 tsid,
1401da177e4SLinus Torvalds u16 tclass, u32 requested,
1412c3c05dbSStephen Smalley unsigned flags,
1421da177e4SLinus Torvalds struct av_decision *avd);
1431da177e4SLinus Torvalds
144e67b7985SStephen Smalley int avc_has_perm(u32 ssid, u32 tsid,
1451da177e4SLinus Torvalds u16 tclass, u32 requested,
146cb4fbe57SLinus Torvalds struct common_audit_data *auditdata);
1471da177e4SLinus Torvalds
148e67b7985SStephen Smalley int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
149fa1aa143SJeff Vander Stoep u8 driver, u8 perm, struct common_audit_data *ad);
150fa1aa143SJeff Vander Stoep
151fa1aa143SJeff Vander Stoep
152e67b7985SStephen Smalley u32 avc_policy_seqno(void);
153788e7dd4SYuichi Nakamura
1541da177e4SLinus Torvalds #define AVC_CALLBACK_GRANT 1
1551da177e4SLinus Torvalds #define AVC_CALLBACK_TRY_REVOKE 2
1561da177e4SLinus Torvalds #define AVC_CALLBACK_REVOKE 4
1571da177e4SLinus Torvalds #define AVC_CALLBACK_RESET 8
1581da177e4SLinus Torvalds #define AVC_CALLBACK_AUDITALLOW_ENABLE 16
1591da177e4SLinus Torvalds #define AVC_CALLBACK_AUDITALLOW_DISABLE 32
1601da177e4SLinus Torvalds #define AVC_CALLBACK_AUDITDENY_ENABLE 64
1611da177e4SLinus Torvalds #define AVC_CALLBACK_AUDITDENY_DISABLE 128
162fa1aa143SJeff Vander Stoep #define AVC_CALLBACK_ADD_XPERMS 256
1631da177e4SLinus Torvalds
164562c99f2SWanlong Gao int avc_add_callback(int (*callback)(u32 event), u32 events);
1651da177e4SLinus Torvalds
1661da177e4SLinus Torvalds /* Exported to selinuxfs */
167e67b7985SStephen Smalley int avc_get_hash_stats(char *page);
168e67b7985SStephen Smalley unsigned int avc_get_cache_threshold(void);
169e67b7985SStephen Smalley void avc_set_cache_threshold(unsigned int cache_threshold);
1701da177e4SLinus Torvalds
1711da177e4SLinus Torvalds #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1721da177e4SLinus Torvalds DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats);
1731da177e4SLinus Torvalds #endif
1741da177e4SLinus Torvalds
1751da177e4SLinus Torvalds #endif /* _SELINUX_AVC_H_ */
1761da177e4SLinus Torvalds
177