For profiles that have been replaced reuse the name string so the old and new version of the profile share the same string. This will make some checks/comparisons in labeling quicker.
Signed-off-by: John Johansen <[email protected]> --- security/apparmor/include/policy.h | 1 + security/apparmor/policy.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 4bebbbd..3852cd1 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -65,6 +65,7 @@ enum profile_flags { PFLAG_IMMUTABLE = 0x10, /* don't allow changes/replacement */ PFLAG_USER_DEFINED = 0x20, /* user based profile - lower privs */ PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */ + PFLAG_OWNS_NAME = 0x80, /* profile owns name */ PFLAG_OLD_NULL_TRANS = 0x100, /* use // as the null transition */ PFLAG_INVALID = 0x200, /* profile replaced/removed */ PFLAG_NS_COUNT = 0x400, /* carries NS ref count */ diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 720b952..fab98ff 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -641,7 +641,8 @@ void aa_free_profile(struct aa_profile *profile) } /* free children profiles */ - policy_destroy(&profile->base); + if (PFLAG_OWNS_NAME & profile->flags) + policy_destroy(&profile->base); aa_put_profile(profile->parent); aa_put_namespace(profile->ns); @@ -706,6 +707,8 @@ struct aa_profile *aa_alloc_profile(const char *hname) goto fail; kref_init(&profile->count); + profile->flags = PFLAG_OWNS_NAME; + /* refcount released by caller */ return profile; @@ -748,7 +751,7 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat) goto fail; profile->mode = APPARMOR_COMPLAIN; - profile->flags = PFLAG_NULL; + profile->flags |= PFLAG_NULL; if (hat) profile->flags |= PFLAG_HAT; @@ -779,7 +782,7 @@ struct aa_profile *aa_setup_default_profile(void) return NULL; /* the default profile pretends to be unconfined until it is replaced */ - profile->flags = PFLAG_IX_ON_NAME_ERROR; + profile->flags |= PFLAG_IX_ON_NAME_ERROR; profile->mode = APPARMOR_UNCONFINED; profile->ns = aa_get_namespace(root_ns); @@ -1067,6 +1070,14 @@ static struct aa_policy *__lookup_replace(struct aa_namespace *ns, return policy; } +static void share_name(struct aa_profile *old, struct aa_profile *new) +{ + kzfree(new->base.hname); + old->flags &= ~PFLAG_OWNS_NAME; + new->base.hname = old->base.hname; + new->base.name = old->base.name; +} + /** * aa_replace_profiles - replace profile(s) on the profile list * @udata: serialized data stream (NOT NULL) @@ -1179,6 +1190,7 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace) audit_policy(op, GFP_ATOMIC, new->base.name, NULL, error); if (old) { + share_name(old, new); __replace_profile(old, new); if (rename) { /* TODO: -- 1.7.10.4 -- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
