diff options
Diffstat (limited to 'security/apparmor/audit.c')
| -rw-r--r-- | security/apparmor/audit.c | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c index 8f9ecac7f8de..eeaddfe0c0fb 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,91 @@ 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 | struct aa_label *label; | ||
| 169 | }; | ||
| 170 | |||
| 171 | void aa_audit_rule_free(void *vrule) | ||
| 172 | { | ||
| 173 | struct aa_audit_rule *rule = vrule; | ||
| 174 | |||
| 175 | if (rule) { | ||
| 176 | if (!IS_ERR(rule->label)) | ||
| 177 | aa_put_label(rule->label); | ||
| 178 | kfree(rule); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | ||
| 183 | { | ||
| 184 | struct aa_audit_rule *rule; | ||
| 185 | |||
| 186 | switch (field) { | ||
| 187 | case AUDIT_SUBJ_ROLE: | ||
| 188 | if (op != Audit_equal && op != Audit_not_equal) | ||
| 189 | return -EINVAL; | ||
| 190 | break; | ||
| 191 | default: | ||
| 192 | return -EINVAL; | ||
| 193 | } | ||
| 194 | |||
| 195 | rule = kzalloc(sizeof(struct aa_audit_rule), GFP_KERNEL); | ||
| 196 | |||
| 197 | if (!rule) | ||
| 198 | return -ENOMEM; | ||
| 199 | |||
| 200 | /* Currently rules are treated as coming from the root ns */ | ||
| 201 | rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr, | ||
| 202 | GFP_KERNEL, true, false); | ||
| 203 | if (IS_ERR(rule->label)) { | ||
| 204 | aa_audit_rule_free(rule); | ||
| 205 | return PTR_ERR(rule->label); | ||
| 206 | } | ||
| 207 | |||
| 208 | *vrule = rule; | ||
| 209 | return 0; | ||
| 210 | } | ||
| 211 | |||
| 212 | int aa_audit_rule_known(struct audit_krule *rule) | ||
| 213 | { | ||
| 214 | int i; | ||
| 215 | |||
| 216 | for (i = 0; i < rule->field_count; i++) { | ||
| 217 | struct audit_field *f = &rule->fields[i]; | ||
| 218 | |||
| 219 | switch (f->type) { | ||
| 220 | case AUDIT_SUBJ_ROLE: | ||
| 221 | return 1; | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | ||
| 229 | struct audit_context *actx) | ||
| 230 | { | ||
| 231 | struct aa_audit_rule *rule = vrule; | ||
| 232 | struct aa_label *label; | ||
| 233 | int found = 0; | ||
| 234 | |||
| 235 | label = aa_secid_to_label(sid); | ||
| 236 | |||
| 237 | if (!label) | ||
| 238 | return -ENOENT; | ||
| 239 | |||
| 240 | if (aa_label_is_subset(label, rule->label)) | ||
| 241 | found = 1; | ||
| 242 | |||
| 243 | switch (field) { | ||
| 244 | case AUDIT_SUBJ_ROLE: | ||
| 245 | switch (op) { | ||
| 246 | case Audit_equal: | ||
| 247 | return found; | ||
| 248 | case Audit_not_equal: | ||
| 249 | return !found; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | return 0; | ||
| 253 | } | ||
