diff options
author | Matthew Garrett <mjg59@google.com> | 2018-04-16 14:23:58 -0400 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2018-06-07 04:50:47 -0400 |
commit | e79c26d04043b15de64f082d4da52e9fff7ca607 (patch) | |
tree | cdca29dff22fd2e145e5fabf582d0e34cfd947d1 /security | |
parent | b896c54e8d7bbf6d5d48f9296b26c9d3f10ec795 (diff) |
apparmor: Add support for audit rule filtering
This patch adds support to Apparmor for integrating with audit rule
filtering. Right now it only handles SUBJ_ROLE, interpreting it as a
single component of a label. This is sufficient to get Apparmor working
with IMA's appraisal rules without any modifications on the IMA side.
Signed-off-by: Matthew Garrett <mjg59@google.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/audit.c | 95 | ||||
-rw-r--r-- | security/apparmor/include/audit.h | 6 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 7 |
3 files changed, 107 insertions, 1 deletions
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c index 8f9ecac7f8de..7ac7c8190cc4 100644 --- a/security/apparmor/audit.c +++ b/security/apparmor/audit.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "include/audit.h" | 19 | #include "include/audit.h" |
20 | #include "include/policy.h" | 20 | #include "include/policy.h" |
21 | #include "include/policy_ns.h" | 21 | #include "include/policy_ns.h" |
22 | 22 | #include "include/secid.h" | |
23 | 23 | ||
24 | const char *const audit_mode_names[] = { | 24 | const char *const audit_mode_names[] = { |
25 | "normal", | 25 | "normal", |
@@ -163,3 +163,96 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa, | |||
163 | 163 | ||
164 | return aad(sa)->error; | 164 | return aad(sa)->error; |
165 | } | 165 | } |
166 | |||
167 | struct aa_audit_rule { | ||
168 | char *profile; | ||
169 | }; | ||
170 | |||
171 | void aa_audit_rule_free(void *vrule) | ||
172 | { | ||
173 | struct aa_audit_rule *rule = vrule; | ||
174 | |||
175 | if (rule) { | ||
176 | kfree(rule->profile); | ||
177 | kfree(rule); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | ||
182 | { | ||
183 | struct aa_audit_rule *rule; | ||
184 | |||
185 | switch (field) { | ||
186 | case AUDIT_SUBJ_ROLE: | ||
187 | if (op != Audit_equal && op != Audit_not_equal) | ||
188 | return -EINVAL; | ||
189 | break; | ||
190 | default: | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | rule = kzalloc(sizeof(struct aa_audit_rule), GFP_KERNEL); | ||
195 | |||
196 | if (!rule) | ||
197 | return -ENOMEM; | ||
198 | |||
199 | rule->profile = kstrdup(rulestr, GFP_KERNEL); | ||
200 | |||
201 | if (!rule->profile) { | ||
202 | kfree(rule); | ||
203 | return -ENOMEM; | ||
204 | } | ||
205 | |||
206 | *vrule = rule; | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | int aa_audit_rule_known(struct audit_krule *rule) | ||
212 | { | ||
213 | int i; | ||
214 | |||
215 | for (i = 0; i < rule->field_count; i++) { | ||
216 | struct audit_field *f = &rule->fields[i]; | ||
217 | |||
218 | switch (f->type) { | ||
219 | case AUDIT_SUBJ_ROLE: | ||
220 | return 1; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | ||
228 | struct audit_context *actx) | ||
229 | { | ||
230 | struct aa_audit_rule *rule = vrule; | ||
231 | struct aa_label *label; | ||
232 | struct label_it i; | ||
233 | struct aa_profile *profile; | ||
234 | int found = 0; | ||
235 | |||
236 | label = aa_secid_to_label(sid); | ||
237 | |||
238 | if (!label) | ||
239 | return -ENOENT; | ||
240 | |||
241 | label_for_each(i, label, profile) { | ||
242 | if (strcmp(rule->profile, profile->base.hname) == 0) { | ||
243 | found = 1; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | switch (field) { | ||
249 | case AUDIT_SUBJ_ROLE: | ||
250 | switch (op) { | ||
251 | case Audit_equal: | ||
252 | return found; | ||
253 | case Audit_not_equal: | ||
254 | return !found; | ||
255 | } | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index 9c9be9c98c15..b8c8b1066b0a 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h | |||
@@ -189,4 +189,10 @@ static inline int complain_error(int error) | |||
189 | return error; | 189 | return error; |
190 | } | 190 | } |
191 | 191 | ||
192 | void aa_audit_rule_free(void *vrule); | ||
193 | int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule); | ||
194 | int aa_audit_rule_known(struct audit_krule *rule); | ||
195 | int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | ||
196 | struct audit_context *actx); | ||
197 | |||
192 | #endif /* __AA_AUDIT_H */ | 198 | #endif /* __AA_AUDIT_H */ |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8299a5d13fee..10bf36aa477d 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -1198,6 +1198,13 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { | |||
1198 | LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), | 1198 | LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), |
1199 | LSM_HOOK_INIT(task_kill, apparmor_task_kill), | 1199 | LSM_HOOK_INIT(task_kill, apparmor_task_kill), |
1200 | 1200 | ||
1201 | #ifdef CONFIG_AUDIT | ||
1202 | LSM_HOOK_INIT(audit_rule_init, aa_audit_rule_init), | ||
1203 | LSM_HOOK_INIT(audit_rule_known, aa_audit_rule_known), | ||
1204 | LSM_HOOK_INIT(audit_rule_match, aa_audit_rule_match), | ||
1205 | LSM_HOOK_INIT(audit_rule_free, aa_audit_rule_free), | ||
1206 | #endif | ||
1207 | |||
1201 | LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx), | 1208 | LSM_HOOK_INIT(secid_to_secctx, apparmor_secid_to_secctx), |
1202 | LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid), | 1209 | LSM_HOOK_INIT(secctx_to_secid, apparmor_secctx_to_secid), |
1203 | LSM_HOOK_INIT(release_secctx, apparmor_release_secctx), | 1210 | LSM_HOOK_INIT(release_secctx, apparmor_release_secctx), |