summary refs log tree commit diff
path: root/security
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2018-05-03 00:39:58 -0700
committerJohn Johansen <john.johansen@canonical.com>2018-06-07 01:50:48 -0700
commit2ab47dae54d567bbb1ad3e96e5b2601cc13f4d2b (patch)
tree74701da99807b936cf7fb7474fcd38dacf140ef8 /security
parente79c26d04043b15de64f082d4da52e9fff7ca607 (diff)
downloadlinux-2ab47dae54d567bbb1ad3e96e5b2601cc13f4d2b.tar.gz
apparmor: modify audit rule support to support profile stacks
Allows for audit rules, where a rule could specify a profile stack
A//&B, while extending the current semantic so if the label specified
in the audit rule is a subset of the secid it is considered a match.

Eg. if the secid resolves to the label stack A//&B//&C

Then an audit rule specifying a label of

  A - would match
  B - would match
  C - would match
  D - would not
  A//&B - would match as a subset
  A//&C - would match as a subset
  B//&C - would match as a subset
  A//&B//&C - would match

  A//&D - would not match, because while A does match, D is also
  specified and does not

Note: audit rules are currently assumed to be coming from the root
namespace.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/audit.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 7ac7c8190cc4..575f3e9c8c80 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -165,7 +165,7 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
 }
 
 struct aa_audit_rule {
-	char *profile;
+	struct aa_label *label;
 };
 
 void aa_audit_rule_free(void *vrule)
@@ -173,7 +173,8 @@ void aa_audit_rule_free(void *vrule)
 	struct aa_audit_rule *rule = vrule;
 
 	if (rule) {
-		kfree(rule->profile);
+		if (!IS_ERR(rule->label))
+			aa_put_label(rule->label);
 		kfree(rule);
 	}
 }
@@ -196,13 +197,11 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
 	if (!rule)
 		return -ENOMEM;
 
-	rule->profile = kstrdup(rulestr, GFP_KERNEL);
-
-	if (!rule->profile) {
-		kfree(rule);
-		return -ENOMEM;
-	}
-
+	/* Currently rules are treated as coming from the root ns */
+	rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr,
+				     GFP_KERNEL, true, false);
+	if (IS_ERR(rule->label))
+		return PTR_ERR(rule->label);
 	*vrule = rule;
 
 	return 0;
@@ -229,8 +228,6 @@ int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
 {
 	struct aa_audit_rule *rule = vrule;
 	struct aa_label *label;
-	struct label_it i;
-	struct aa_profile *profile;
 	int found = 0;
 
 	label = aa_secid_to_label(sid);
@@ -238,12 +235,8 @@ int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
 	if (!label)
 		return -ENOENT;
 
-	label_for_each(i, label, profile) {
-		if (strcmp(rule->profile, profile->base.hname) == 0) {
-			found = 1;
-			break;
-		}
-	}
+	if (aa_label_is_subset(label, rule->label))
+		found = 1;
 
 	switch (field) {
 	case AUDIT_SUBJ_ROLE: