From ec6851ae0ab4587e610e260ddda75f92f3389f91 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 15 Apr 2023 00:50:32 -0700 Subject: [PATCH] apparmor: fix: kzalloc perms tables for shared dfas Currently the permstables of the shared dfas are not shared, and need to be allocated and copied. In the future this should be addressed with a larger rework on dfa and pdb ref counts and structure sharing. BugLink: http://bugs.launchpad.net/bugs/2017903 Fixes: 217af7e2f4de ("apparmor: refactor profile rules and attachments") Cc: stable@vger.kernel.org Signed-off-by: John Johansen Reviewed-by: Jon Tourville --- security/apparmor/policy.c | 13 +++++++++++++ security/apparmor/policy_unpack.c | 26 ++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index a8fcc72..b38f7b2 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -589,7 +589,15 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name, profile->label.flags |= FLAG_NULL; rules = list_first_entry(&profile->rules, typeof(*rules), list); rules->file.dfa = aa_get_dfa(nulldfa); + rules->file.perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL); + if (!rules->file.perms) + goto fail; + rules->file.size = 2; rules->policy.dfa = aa_get_dfa(nulldfa); + rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL); + if (!rules->policy.perms) + goto fail; + rules->policy.size = 2; if (parent) { profile->path_flags = parent->path_flags; @@ -600,6 +608,11 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name, } return profile; + +fail: + aa_free_profile(profile); + + return NULL; } /** diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 2a50d32..f171f8a 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -982,9 +982,14 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; } } - } else + } else { rules->policy.dfa = aa_get_dfa(nulldfa); - + rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), + GFP_KERNEL); + if (!rules->policy.perms) + goto fail; + rules->policy.size = 2; + } /* get file rules */ error = unpack_pdb(e, &rules->file, false, true, &info); if (error) { @@ -1001,9 +1006,22 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) rules->policy.start[AA_CLASS_FILE]) { rules->file.dfa = aa_get_dfa(rules->policy.dfa); rules->file.start[AA_CLASS_FILE] = rules->policy.start[AA_CLASS_FILE]; - } else + rules->file.perms = kcalloc(rules->policy.size, + sizeof(struct aa_perms), + GFP_KERNEL); + if (!rules->file.perms) + goto fail; + memcpy(rules->file.perms, rules->policy.perms, + rules->policy.size * sizeof(struct aa_perms)); + rules->file.size = rules->policy.size; + } else { rules->file.dfa = aa_get_dfa(nulldfa); - + rules->file.perms = kcalloc(2, sizeof(struct aa_perms), + GFP_KERNEL); + if (!rules->file.perms) + goto fail; + rules->file.size = 2; + } error = -EPROTO; if (aa_unpack_nameX(e, AA_STRUCT, "data")) { info = "out of memory"; -- 2.7.4