Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1da177e4 LT |
2 | /* |
3 | * Access vector cache interface for object managers. | |
4 | * | |
7efbb60b | 5 | * Author : Stephen Smalley, <sds@tycho.nsa.gov> |
1da177e4 LT |
6 | */ |
7 | #ifndef _SELINUX_AVC_H_ | |
8 | #define _SELINUX_AVC_H_ | |
9 | ||
10 | #include <linux/stddef.h> | |
11 | #include <linux/errno.h> | |
12 | #include <linux/kernel.h> | |
13 | #include <linux/kdev_t.h> | |
14 | #include <linux/spinlock.h> | |
15 | #include <linux/init.h> | |
d9250dea | 16 | #include <linux/audit.h> |
2bf49690 | 17 | #include <linux/lsm_audit.h> |
1da177e4 | 18 | #include <linux/in6.h> |
1da177e4 LT |
19 | #include "flask.h" |
20 | #include "av_permissions.h" | |
21 | #include "security.h" | |
22 | ||
1da177e4 LT |
23 | /* |
24 | * An entry in the AVC. | |
25 | */ | |
26 | struct avc_entry; | |
27 | ||
28 | struct task_struct; | |
1da177e4 LT |
29 | struct inode; |
30 | struct sock; | |
31 | struct sk_buff; | |
32 | ||
1da177e4 LT |
33 | /* |
34 | * AVC statistics | |
35 | */ | |
f5269710 | 36 | struct avc_cache_stats { |
1da177e4 | 37 | unsigned int lookups; |
1da177e4 LT |
38 | unsigned int misses; |
39 | unsigned int allocations; | |
40 | unsigned int reclaims; | |
41 | unsigned int frees; | |
42 | }; | |
43 | ||
3f0882c4 EP |
44 | /* |
45 | * We only need this data after we have decided to send an audit message. | |
46 | */ | |
899838b2 | 47 | struct selinux_audit_data { |
3b3b0e4f EP |
48 | u32 ssid; |
49 | u32 tsid; | |
50 | u16 tclass; | |
51 | u32 requested; | |
52 | u32 audited; | |
53 | u32 denied; | |
3f0882c4 | 54 | int result; |
6b6bc620 | 55 | struct selinux_state *state; |
3f0882c4 EP |
56 | }; |
57 | ||
1da177e4 LT |
58 | /* |
59 | * AVC operations | |
60 | */ | |
61 | ||
62 | void __init avc_init(void); | |
63 | ||
2e334057 EP |
64 | static inline u32 avc_audit_required(u32 requested, |
65 | struct av_decision *avd, | |
66 | int result, | |
67 | u32 auditdeny, | |
68 | u32 *deniedp) | |
69 | { | |
70 | u32 denied, audited; | |
71 | denied = requested & ~avd->allowed; | |
72 | if (unlikely(denied)) { | |
73 | audited = denied & avd->auditdeny; | |
74 | /* | |
75 | * auditdeny is TRICKY! Setting a bit in | |
76 | * this field means that ANY denials should NOT be audited if | |
77 | * the policy contains an explicit dontaudit rule for that | |
78 | * permission. Take notice that this is unrelated to the | |
79 | * actual permissions that were denied. As an example lets | |
80 | * assume: | |
81 | * | |
82 | * denied == READ | |
83 | * avd.auditdeny & ACCESS == 0 (not set means explicit rule) | |
84 | * auditdeny & ACCESS == 1 | |
85 | * | |
86 | * We will NOT audit the denial even though the denied | |
87 | * permission was READ and the auditdeny checks were for | |
88 | * ACCESS | |
89 | */ | |
90 | if (auditdeny && !(auditdeny & avd->auditdeny)) | |
91 | audited = 0; | |
92 | } else if (result) | |
93 | audited = denied = requested; | |
94 | else | |
95 | audited = requested & avd->auditallow; | |
96 | *deniedp = denied; | |
97 | return audited; | |
98 | } | |
99 | ||
6b6bc620 SS |
100 | int slow_avc_audit(struct selinux_state *state, |
101 | u32 ssid, u32 tsid, u16 tclass, | |
ca7786a2 | 102 | u32 requested, u32 audited, u32 denied, int result, |
2e334057 EP |
103 | struct common_audit_data *a, |
104 | unsigned flags); | |
105 | ||
106 | /** | |
107 | * avc_audit - Audit the granting or denial of permissions. | |
108 | * @ssid: source security identifier | |
109 | * @tsid: target security identifier | |
110 | * @tclass: target security class | |
111 | * @requested: requested permissions | |
112 | * @avd: access vector decisions | |
113 | * @result: result from avc_has_perm_noaudit | |
114 | * @a: auxiliary audit data | |
115 | * @flags: VFS walk flags | |
116 | * | |
117 | * Audit the granting or denial of permissions in accordance | |
118 | * with the policy. This function is typically called by | |
119 | * avc_has_perm() after a permission check, but can also be | |
120 | * called directly by callers who use avc_has_perm_noaudit() | |
121 | * in order to separate the permission check from the auditing. | |
122 | * For example, this separation is useful when the permission check must | |
123 | * be performed under a lock, to allow the lock to be released | |
124 | * before calling the auditing code. | |
125 | */ | |
6b6bc620 SS |
126 | static inline int avc_audit(struct selinux_state *state, |
127 | u32 ssid, u32 tsid, | |
2e334057 EP |
128 | u16 tclass, u32 requested, |
129 | struct av_decision *avd, | |
130 | int result, | |
7b20ea25 N |
131 | struct common_audit_data *a, |
132 | int flags) | |
2e334057 EP |
133 | { |
134 | u32 audited, denied; | |
1d349292 | 135 | audited = avc_audit_required(requested, avd, result, 0, &denied); |
2e334057 EP |
136 | if (likely(!audited)) |
137 | return 0; | |
6b6bc620 | 138 | return slow_avc_audit(state, ssid, tsid, tclass, |
ca7786a2 | 139 | requested, audited, denied, result, |
7b20ea25 | 140 | a, flags); |
2e334057 | 141 | } |
1da177e4 | 142 | |
2c3c05db | 143 | #define AVC_STRICT 1 /* Ignore permissive mode. */ |
fa1aa143 | 144 | #define AVC_EXTENDED_PERMS 2 /* update extended permissions */ |
6b6bc620 SS |
145 | int avc_has_perm_noaudit(struct selinux_state *state, |
146 | u32 ssid, u32 tsid, | |
2c3c05db SS |
147 | u16 tclass, u32 requested, |
148 | unsigned flags, | |
149 | struct av_decision *avd); | |
1da177e4 | 150 | |
6b6bc620 SS |
151 | int avc_has_perm(struct selinux_state *state, |
152 | u32 ssid, u32 tsid, | |
cb4fbe57 LT |
153 | u16 tclass, u32 requested, |
154 | struct common_audit_data *auditdata); | |
6b6bc620 SS |
155 | int avc_has_perm_flags(struct selinux_state *state, |
156 | u32 ssid, u32 tsid, | |
7b20ea25 N |
157 | u16 tclass, u32 requested, |
158 | struct common_audit_data *auditdata, | |
159 | int flags); | |
1da177e4 | 160 | |
6b6bc620 SS |
161 | int avc_has_extended_perms(struct selinux_state *state, |
162 | u32 ssid, u32 tsid, u16 tclass, u32 requested, | |
163 | u8 driver, u8 perm, struct common_audit_data *ad); | |
fa1aa143 JVS |
164 | |
165 | ||
6b6bc620 | 166 | u32 avc_policy_seqno(struct selinux_state *state); |
788e7dd4 | 167 | |
1da177e4 LT |
168 | #define AVC_CALLBACK_GRANT 1 |
169 | #define AVC_CALLBACK_TRY_REVOKE 2 | |
170 | #define AVC_CALLBACK_REVOKE 4 | |
171 | #define AVC_CALLBACK_RESET 8 | |
172 | #define AVC_CALLBACK_AUDITALLOW_ENABLE 16 | |
173 | #define AVC_CALLBACK_AUDITALLOW_DISABLE 32 | |
174 | #define AVC_CALLBACK_AUDITDENY_ENABLE 64 | |
175 | #define AVC_CALLBACK_AUDITDENY_DISABLE 128 | |
fa1aa143 | 176 | #define AVC_CALLBACK_ADD_XPERMS 256 |
1da177e4 | 177 | |
562c99f2 | 178 | int avc_add_callback(int (*callback)(u32 event), u32 events); |
1da177e4 LT |
179 | |
180 | /* Exported to selinuxfs */ | |
6b6bc620 SS |
181 | struct selinux_avc; |
182 | int avc_get_hash_stats(struct selinux_avc *avc, char *page); | |
183 | unsigned int avc_get_cache_threshold(struct selinux_avc *avc); | |
184 | void avc_set_cache_threshold(struct selinux_avc *avc, | |
185 | unsigned int cache_threshold); | |
1da177e4 | 186 | |
89c86576 TL |
187 | /* Attempt to free avc node cache */ |
188 | void avc_disable(void); | |
189 | ||
1da177e4 LT |
190 | #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS |
191 | DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats); | |
192 | #endif | |
193 | ||
194 | #endif /* _SELINUX_AVC_H_ */ | |
195 |