diff options
Diffstat (limited to 'security/apparmor/label.c')
-rw-r--r-- | security/apparmor/label.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/security/apparmor/label.c b/security/apparmor/label.c index 470693239e64..e68bcedca976 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c @@ -309,10 +309,8 @@ out: } -static void label_destroy(struct aa_label *label) +void aa_label_destroy(struct aa_label *label) { - struct aa_label *tmp; - AA_BUG(!label); if (!label_isprofile(label)) { @@ -328,16 +326,13 @@ static void label_destroy(struct aa_label *label) } } - if (rcu_dereference_protected(label->proxy->label, true) == label) - rcu_assign_pointer(label->proxy->label, NULL); - + if (label->proxy) { + if (rcu_dereference_protected(label->proxy->label, true) == label) + rcu_assign_pointer(label->proxy->label, NULL); + aa_put_proxy(label->proxy); + } aa_free_secid(label->secid); - tmp = rcu_dereference_protected(label->proxy->label, true); - if (tmp == label) - rcu_assign_pointer(label->proxy->label, NULL); - - aa_put_proxy(label->proxy); label->proxy = (struct aa_proxy *) PROXY_POISON + 1; } @@ -346,7 +341,7 @@ void aa_label_free(struct aa_label *label) if (!label) return; - label_destroy(label); + aa_label_destroy(label); kfree(label); } @@ -550,6 +545,39 @@ bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub) return __aa_label_next_not_in_set(&i, set, sub) == NULL; } +/** + * aa_label_is_unconfined_subset - test if @sub is a subset of @set + * @set: label to test against + * @sub: label to test if is subset of @set + * + * This checks for subset but taking into account unconfined. IF + * @sub contains an unconfined profile that does not have a matching + * unconfined in @set then this will not cause the test to fail. + * Conversely we don't care about an unconfined in @set that is not in + * @sub + * + * Returns: true if @sub is special_subset of @set + * else false + */ +bool aa_label_is_unconfined_subset(struct aa_label *set, struct aa_label *sub) +{ + struct label_it i = { }; + struct aa_profile *p; + + AA_BUG(!set); + AA_BUG(!sub); + + if (sub == set) + return true; + + do { + p = __aa_label_next_not_in_set(&i, set, sub); + if (p && !profile_unconfined(p)) + break; + } while (p); + + return p == NULL; +} /** @@ -1531,13 +1559,13 @@ static const char *label_modename(struct aa_ns *ns, struct aa_label *label, label_for_each(i, label, profile) { if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) { - if (profile->mode == APPARMOR_UNCONFINED) + count++; + if (profile == profile->ns->unconfined) /* special case unconfined so stacks with * unconfined don't report as mixed. ie. * profile_foo//&:ns1:unconfined (mixed) */ continue; - count++; if (mode == -1) mode = profile->mode; else if (mode != profile->mode) @@ -1749,13 +1777,13 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns, AA_DEBUG("label print error"); return; } - seq_printf(f, "%s", str); + seq_puts(f, str); kfree(str); } else if (display_mode(ns, label, flags)) seq_printf(f, "%s (%s)", label->hname, label_modename(ns, label, flags)); else - seq_printf(f, "%s", label->hname); + seq_puts(f, label->hname); } void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags, |