apparmor: move fperm computation into policy_unpack
authorJohn Johansen <john.johansen@canonical.com>
Thu, 12 Nov 2020 18:07:25 +0000 (10:07 -0800)
committerJohn Johansen <john.johansen@canonical.com>
Mon, 3 Oct 2022 21:49:02 +0000 (14:49 -0700)
fperm computation is only needed during policy_unpack so move the
code there to isolate it fromt the run time code.

Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/file.c
security/apparmor/include/file.h
security/apparmor/policy_unpack.c

index 710b7d7..1227ae8 100644 (file)
@@ -175,103 +175,6 @@ static int path_name(const char *op, struct aa_label *label,
 }
 
 /**
- * map_old_perms - map old file perms layout to the new layout
- * @old: permission set in old mapping
- *
- * Returns: new permission mapping
- */
-static u32 map_old_perms(u32 old)
-{
-       u32 new = old & 0xf;
-       if (old & MAY_READ)
-               new |= AA_MAY_GETATTR | AA_MAY_OPEN;
-       if (old & MAY_WRITE)
-               new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
-                      AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN;
-       if (old & 0x10)
-               new |= AA_MAY_LINK;
-       /* the old mapping lock and link_subset flags where overlaid
-        * and use was determined by part of a pair that they were in
-        */
-       if (old & 0x20)
-               new |= AA_MAY_LOCK | AA_LINK_SUBSET;
-       if (old & 0x40) /* AA_EXEC_MMAP */
-               new |= AA_EXEC_MMAP;
-
-       return new;
-}
-
-static void __aa_compute_fperms_allow(struct aa_perms *perms,
-                                     struct aa_dfa *dfa,
-                                     unsigned int state)
-{
-       perms->allow |= AA_MAY_GETATTR;
-
-       /* change_profile wasn't determined by ownership in old mapping */
-       if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
-               perms->allow |= AA_MAY_CHANGE_PROFILE;
-       if (ACCEPT_TABLE(dfa)[state] & 0x40000000)
-               perms->allow |= AA_MAY_ONEXEC;
-}
-
-static struct aa_perms __aa_compute_fperms_user(struct aa_dfa *dfa,
-                                               unsigned int state)
-{
-       struct aa_perms perms = { };
-
-       perms.allow = map_old_perms(dfa_user_allow(dfa, state));
-       perms.audit = map_old_perms(dfa_user_audit(dfa, state));
-       perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
-       perms.xindex = dfa_user_xindex(dfa, state);
-
-       __aa_compute_fperms_allow(&perms, dfa, state);
-
-       return perms;
-}
-
-static struct aa_perms __aa_compute_fperms_other(struct aa_dfa *dfa,
-                                                unsigned int state)
-{
-       struct aa_perms perms = { };
-
-       perms.allow = map_old_perms(dfa_other_allow(dfa, state));
-       perms.audit = map_old_perms(dfa_other_audit(dfa, state));
-       perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
-       perms.xindex = dfa_other_xindex(dfa, state);
-
-       __aa_compute_fperms_allow(&perms, dfa, state);
-
-       return perms;
-}
-
-/**
- * aa_compute_fperms - convert dfa compressed perms to internal perms and store
- *                    them so they can be retrieved later.
- * @file_rules: a file_rules structure containing a dfa (NOT NULL) for which
- *             permissions will be computed   (NOT NULL)
- *
- * TODO: convert from dfa + state to permission entry
- */
-void aa_compute_fperms(struct aa_file_rules *file_rules)
-{
-       int state;
-       int state_count = file_rules->dfa->tables[YYTD_ID_BASE]->td_lolen;
-
-       // DFAs are restricted from having a state_count of less than 2
-       file_rules->fperms_table = kvzalloc(
-                       state_count * 2 * sizeof(struct aa_perms), GFP_KERNEL);
-
-       // Since fperms_table is initialized with zeroes via kvzalloc(), we can
-       // skip the trap state (state == 0)
-       for (state = 1; state < state_count; state++) {
-               file_rules->fperms_table[state * 2] =
-                       __aa_compute_fperms_user(file_rules->dfa, state);
-               file_rules->fperms_table[state * 2 + 1] =
-                       __aa_compute_fperms_other(file_rules->dfa, state);
-       }
-}
-
-/**
  * aa_lookup_fperms - convert dfa compressed perms to internal perms
  * @dfa: dfa to lookup perms for   (NOT NULL)
  * @state: state in dfa
index ab201d6..1f9e54a 100644 (file)
@@ -184,7 +184,6 @@ struct aa_file_rules {
        struct aa_perms *fperms_table;
 };
 
-void aa_compute_fperms(struct aa_file_rules *file_rules);
 struct aa_perms *aa_lookup_fperms(struct aa_file_rules *file_rules,
                                 unsigned int state, struct path_cond *cond);
 unsigned int aa_str_perms(struct aa_file_rules *file_rules, unsigned int start,
index 70b7a35..c22c681 100644 (file)
@@ -669,6 +669,104 @@ static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)
        return strcmp(data->key, *key);
 }
 
+/**
+ * map_old_perms - map old file perms layout to the new layout
+ * @old: permission set in old mapping
+ *
+ * Returns: new permission mapping
+ */
+static u32 map_old_perms(u32 old)
+{
+       u32 new = old & 0xf;
+
+       if (old & MAY_READ)
+               new |= AA_MAY_GETATTR | AA_MAY_OPEN;
+       if (old & MAY_WRITE)
+               new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
+                      AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN;
+       if (old & 0x10)
+               new |= AA_MAY_LINK;
+       /* the old mapping lock and link_subset flags where overlaid
+        * and use was determined by part of a pair that they were in
+        */
+       if (old & 0x20)
+               new |= AA_MAY_LOCK | AA_LINK_SUBSET;
+       if (old & 0x40) /* AA_EXEC_MMAP */
+               new |= AA_EXEC_MMAP;
+
+       return new;
+}
+
+static void __aa_compute_fperms_allow(struct aa_perms *perms,
+                                     struct aa_dfa *dfa,
+                                     unsigned int state)
+{
+       perms->allow |= AA_MAY_GETATTR;
+
+       /* change_profile wasn't determined by ownership in old mapping */
+       if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
+               perms->allow |= AA_MAY_CHANGE_PROFILE;
+       if (ACCEPT_TABLE(dfa)[state] & 0x40000000)
+               perms->allow |= AA_MAY_ONEXEC;
+}
+
+static struct aa_perms __aa_compute_fperms_user(struct aa_dfa *dfa,
+                                               unsigned int state)
+{
+       struct aa_perms perms = { };
+
+       perms.allow = map_old_perms(dfa_user_allow(dfa, state));
+       perms.audit = map_old_perms(dfa_user_audit(dfa, state));
+       perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
+       perms.xindex = dfa_user_xindex(dfa, state);
+
+       __aa_compute_fperms_allow(&perms, dfa, state);
+
+       return perms;
+}
+
+static struct aa_perms __aa_compute_fperms_other(struct aa_dfa *dfa,
+                                                unsigned int state)
+{
+       struct aa_perms perms = { };
+
+       perms.allow = map_old_perms(dfa_other_allow(dfa, state));
+       perms.audit = map_old_perms(dfa_other_audit(dfa, state));
+       perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
+       perms.xindex = dfa_other_xindex(dfa, state);
+
+       __aa_compute_fperms_allow(&perms, dfa, state);
+
+       return perms;
+}
+
+/**
+ * aa_compute_fperms - convert dfa compressed perms to internal perms and store
+ *                    them so they can be retrieved later.
+ * @file_rules: a file_rules structure containing a dfa (NOT NULL) for which
+ *             permissions will be computed   (NOT NULL)
+ *
+ * TODO: convert from dfa + state to permission entry
+ */
+static void aa_compute_fperms(struct aa_file_rules *file_rules)
+{
+       int state;
+       int state_count = file_rules->dfa->tables[YYTD_ID_BASE]->td_lolen;
+
+       // DFAs are restricted from having a state_count of less than 2
+       file_rules->fperms_table = kvzalloc(
+                       state_count * 2 * sizeof(struct aa_perms), GFP_KERNEL);
+
+       // Since fperms_table is initialized with zeroes via kvzalloc(), we can
+       // skip the trap state (state == 0)
+       for (state = 1; state < state_count; state++) {
+               file_rules->fperms_table[state * 2] =
+                       __aa_compute_fperms_user(file_rules->dfa, state);
+               file_rules->fperms_table[state * 2 + 1] =
+                       __aa_compute_fperms_other(file_rules->dfa, state);
+       }
+}
+
 static u32 *aa_compute_xmatch_perms(struct aa_dfa *xmatch)
 {
        u32 *perms_table;