OSDN Git Service

apparmor: fix: kzalloc perms tables for shared dfas
authorJohn Johansen <john.johansen@canonical.com>
Sat, 15 Apr 2023 07:50:32 +0000 (00:50 -0700)
committerJohn Johansen <john.johansen@canonical.com>
Thu, 6 Jul 2023 18:05:58 +0000 (11:05 -0700)
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 <john.johansen@canonical.com>
Reviewed-by: Jon Tourville <jontourville@me.com>
security/apparmor/policy.c
security/apparmor/policy_unpack.c

index a8fcc72..b38f7b2 100644 (file)
@@ -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;
 }
 
 /**
index 2a50d32..f171f8a 100644 (file)
@@ -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";