diff options
author | John Johansen <john.johansen@canonical.com> | 2020-11-19 10:37:48 -0800 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2022-10-03 14:49:03 -0700 |
commit | 53bdc46f4bdd20d477afb374767cabe627fd04ae (patch) | |
tree | b251f2dc7ddc5fef5e65d6f0b6ba1b963af0283b /security | |
parent | e2967ede22978f132cd52929edff96c701bde0eb (diff) | |
download | linux-stable-53bdc46f4bdd20d477afb374767cabe627fd04ae.tar.gz linux-stable-53bdc46f4bdd20d477afb374767cabe627fd04ae.tar.bz2 linux-stable-53bdc46f4bdd20d477afb374767cabe627fd04ae.zip |
apparmor: combine file_rules and aa_policydb into a single shared struct
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>
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/apparmorfs.c | 3 | ||||
-rw-r--r-- | security/apparmor/domain.c | 7 | ||||
-rw-r--r-- | security/apparmor/file.c | 20 | ||||
-rw-r--r-- | security/apparmor/include/file.h | 39 | ||||
-rw-r--r-- | security/apparmor/include/policy.h | 14 | ||||
-rw-r--r-- | security/apparmor/policy.c | 5 | ||||
-rw-r--r-- | security/apparmor/policy_unpack.c | 11 |
7 files changed, 40 insertions, 59 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 117783779337..1625fee17fc7 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -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 = { }; diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 4fcdcc0de48c..819b7828cbc4 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -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, diff --git a/security/apparmor/file.c b/security/apparmor/file.c index 1227ae839154..d2be851be412 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c @@ -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; diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h index 1f9e54aa1adf..736b8f655404 100644 --- a/security/apparmor/include/file.h +++ b/security/apparmor/include/file.h @@ -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 diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 0dec18cd95e5..9bafeb3847d5 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -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; diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 6c3086e2c820..0814ee57a06b 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -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; diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index ed063385a83b..726fa02026b5 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -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; } |