apparmor: combine file_rules and aa_policydb into a single shared struct
authorJohn Johansen <john.johansen@canonical.com>
Thu, 19 Nov 2020 18:37:48 +0000 (10:37 -0800)
committerJohn Johansen <john.johansen@canonical.com>
Mon, 3 Oct 2022 21:49:03 +0000 (14:49 -0700)
file_rules and policydb are almost the same and will need the same
features in the future so combine them.

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

index 1177837..1625fee 100644 (file)
@@ -619,7 +619,8 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
                return;
        if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
                dfa = profile->file.dfa;
-               state = aa_dfa_match_len(dfa, profile->file.start,
+               state = aa_dfa_match_len(dfa,
+                                        profile->file.start[AA_CLASS_FILE],
                                         match_str + 1, match_len - 1);
                if (state) {
                        struct path_cond cond = { };
index 4fcdcc0..819b782 100644 (file)
@@ -627,7 +627,7 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
 {
        struct aa_label *new = NULL;
        const char *info = NULL, *name = NULL, *target = NULL;
-       unsigned int state = profile->file.start;
+       unsigned int state = profile->file.start[AA_CLASS_FILE];
        struct aa_perms perms = {};
        bool nonewprivs = false;
        int error = 0;
@@ -723,7 +723,7 @@ static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
                          char *buffer, struct path_cond *cond,
                          bool *secure_exec)
 {
-       unsigned int state = profile->file.start;
+       unsigned int state = profile->file.start[AA_CLASS_FILE];
        struct aa_perms perms = {};
        const char *xname = NULL, *info = "change_profile onexec";
        int error = -EACCES;
@@ -1267,7 +1267,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
 
        if (!error)
                error = change_profile_perms(profile, target, stack, request,
-                                            profile->file.start, perms);
+                                            profile->file.start[AA_CLASS_FILE],
+                                            perms);
        if (error)
                error = aa_audit_file(profile, perms, op, request, name,
                                      NULL, target, GLOBAL_ROOT_UID, info,
index 1227ae8..d2be851 100644 (file)
@@ -185,16 +185,16 @@ static int path_name(const char *op, struct aa_label *label,
  * Returns: a pointer to a file permission set
  */
 struct aa_perms default_perms = {};
-struct aa_perms *aa_lookup_fperms(struct aa_file_rules *file_rules,
+struct aa_perms *aa_lookup_fperms(struct aa_policydb *file_rules,
                                 unsigned int state, struct path_cond *cond)
 {
-       if (!(file_rules->fperms_table))
+       if (!(file_rules->perms))
                return &default_perms;
 
        if (uid_eq(current_fsuid(), cond->uid))
-               return &(file_rules->fperms_table[state * 2]);
+               return &(file_rules->perms[state * 2]);
 
-       return &(file_rules->fperms_table[state * 2 + 1]);
+       return &(file_rules->perms[state * 2 + 1]);
 }
 
 /**
@@ -207,7 +207,7 @@ struct aa_perms *aa_lookup_fperms(struct aa_file_rules *file_rules,
  *
  * Returns: the final state in @dfa when beginning @start and walking @name
  */
-unsigned int aa_str_perms(struct aa_file_rules *file_rules, unsigned int start,
+unsigned int aa_str_perms(struct aa_policydb *file_rules, unsigned int start,
                          const char *name, struct path_cond *cond,
                          struct aa_perms *perms)
 {
@@ -226,7 +226,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
 
        if (profile_unconfined(profile))
                return 0;
-       aa_str_perms(&(profile->file), profile->file.start, name, cond, perms);
+       aa_str_perms(&(profile->file), profile->file.start[AA_CLASS_FILE],
+                    name, cond, perms);
        if (request & ~perms->allow)
                e = -EACCES;
        return aa_audit_file(profile, perms, op, request, name, NULL, NULL,
@@ -333,7 +334,8 @@ static int profile_path_link(struct aa_profile *profile,
 
        error = -EACCES;
        /* aa_str_perms - handles the case of the dfa being NULL */
-       state = aa_str_perms(&(profile->file), profile->file.start, lname,
+       state = aa_str_perms(&(profile->file),
+                            profile->file.start[AA_CLASS_FILE], lname,
                             cond, &lperms);
 
        if (!(lperms.allow & AA_MAY_LINK))
@@ -363,8 +365,8 @@ static int profile_path_link(struct aa_profile *profile,
        /* Do link perm subset test requiring allowed permission on link are
         * a subset of the allowed permissions on target.
         */
-       aa_str_perms(&(profile->file), profile->file.start, tname, cond,
-                    &perms);
+       aa_str_perms(&(profile->file), profile->file.start[AA_CLASS_FILE],
+                    tname, cond, &perms);
 
        /* AA_MAY_LINK is not considered in the subset test */
        request = lperms.allow & ~AA_MAY_LINK;
index 1f9e54a..736b8f6 100644 (file)
@@ -17,6 +17,7 @@
 #include "match.h"
 #include "perms.h"
 
+struct aa_policydb;
 struct aa_profile;
 struct path;
 
@@ -164,29 +165,9 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
                  const char *target, struct aa_label *tlabel, kuid_t ouid,
                  const char *info, int error);
 
-/**
- * struct aa_file_rules - components used for file rule permissions
- * @dfa: dfa to match path names and conditionals against
- * @perms: permission table indexed by the matched state accept entry of @dfa
- * @trans: transition table for indexed by named x transitions
- *
- * File permission are determined by matching a path against @dfa and
- * then using the value of the accept entry for the matching state as
- * an index into @perms.  If a named exec transition is required it is
- * looked up in the transition table.
- */
-struct aa_file_rules {
-       unsigned int start;
-       struct aa_dfa *dfa;
-       /* struct perms perms; */
-       struct aa_domain trans;
-       /* TODO: add delegate table */
-       struct aa_perms *fperms_table;
-};
-
-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,
+struct aa_perms *aa_lookup_fperms(struct aa_policydb *file_rules,
+                                 unsigned int state, struct path_cond *cond);
+unsigned int aa_str_perms(struct aa_policydb *file_rules, unsigned int start,
                          const char *name, struct path_cond *cond,
                          struct aa_perms *perms);
 
@@ -205,18 +186,6 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
 
 void aa_inherit_files(const struct cred *cred, struct files_struct *files);
 
-static inline void aa_free_fperms_table(struct aa_perms *fperms_table)
-{
-       if (fperms_table)
-               kvfree(fperms_table);
-}
-
-static inline void aa_free_file_rules(struct aa_file_rules *rules)
-{
-       aa_put_dfa(rules->dfa);
-       aa_free_domain_entries(&rules->trans);
-       aa_free_fperms_table(rules->fperms_table);
-}
 
 /**
  * aa_map_file_perms - map file flags to AppArmor permissions
index 0dec18c..9bafeb3 100644 (file)
@@ -75,13 +75,21 @@ enum profile_mode {
  * start: set of start states for the different classes of data
  */
 struct aa_policydb {
-       /* Generic policy DFA specific rule types will be subsections of it */
        struct aa_dfa *dfa;
        struct aa_perms *perms;
+       struct aa_domain trans;
        unsigned int start[AA_CLASS_LAST + 1];
-
 };
 
+static inline void aa_destroy_policydb(struct aa_policydb *policy)
+{
+       aa_put_dfa(policy->dfa);
+       if (policy->perms)
+               kvfree(policy->perms);
+       aa_free_domain_entries(&policy->trans);
+
+}
+
 /* struct aa_data - generic data structure
  * key: name for retrieving this data
  * size: size of data in bytes
@@ -151,7 +159,7 @@ struct aa_profile {
        int size;
 
        struct aa_policydb policy;
-       struct aa_file_rules file;
+       struct aa_policydb file;
        struct aa_caps caps;
 
        int xattr_count;
index 6c3086e..0814ee5 100644 (file)
@@ -219,7 +219,7 @@ void aa_free_profile(struct aa_profile *profile)
        aa_put_ns(profile->ns);
        kfree_sensitive(profile->rename);
 
-       aa_free_file_rules(&profile->file);
+       aa_destroy_policydb(&profile->file);
        aa_free_cap_rules(&profile->caps);
        aa_free_rlimit_rules(&profile->rlimits);
 
@@ -232,8 +232,7 @@ void aa_free_profile(struct aa_profile *profile)
        kfree_sensitive(profile->dirname);
        aa_put_dfa(profile->xmatch);
        kvfree(profile->xmatch_perms);
-       aa_put_dfa(profile->policy.dfa);
-       kvfree(profile->policy.perms);
+       aa_destroy_policydb(&profile->policy);
        if (profile->data) {
                rht = profile->data;
                profile->data = NULL;
index ed06338..726fa02 100644 (file)
@@ -1048,18 +1048,19 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
                info = "failed to unpack profile file rules";
                goto fail;
        } else if (profile->file.dfa) {
-               if (!unpack_u32(e, &profile->file.start, "dfa_start"))
+               if (!unpack_u32(e, &profile->file.start[AA_CLASS_FILE],
+                               "dfa_start"))
                        /* default start state */
-                       profile->file.start = DFA_START;
+                       profile->file.start[AA_CLASS_FILE] = DFA_START;
        } else if (profile->policy.dfa &&
                   profile->policy.start[AA_CLASS_FILE]) {
                profile->file.dfa = aa_get_dfa(profile->policy.dfa);
-               profile->file.start = profile->policy.start[AA_CLASS_FILE];
+               profile->file.start[AA_CLASS_FILE] = profile->policy.start[AA_CLASS_FILE];
        } else
                profile->file.dfa = aa_get_dfa(nulldfa);
 
-       profile->file.fperms_table = compute_fperms(profile->file.dfa);
-       if (!profile->file.fperms_table) {
+       profile->file.perms = compute_fperms(profile->file.dfa);
+       if (!profile->file.perms) {
                info = "failed to remap file permission table";
                goto fail;
        }