Commit 53bdc46f authored by John Johansen's avatar John Johansen

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: default avatarJohn Johansen <john.johansen@canonical.com>
parent e2967ede
...@@ -619,7 +619,8 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms, ...@@ -619,7 +619,8 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
return; return;
if (profile->file.dfa && *match_str == AA_CLASS_FILE) { if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
dfa = profile->file.dfa; 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); match_str + 1, match_len - 1);
if (state) { if (state) {
struct path_cond cond = { }; struct path_cond cond = { };
......
...@@ -627,7 +627,7 @@ static struct aa_label *profile_transition(struct aa_profile *profile, ...@@ -627,7 +627,7 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
{ {
struct aa_label *new = NULL; struct aa_label *new = NULL;
const char *info = NULL, *name = NULL, *target = 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 = {}; struct aa_perms perms = {};
bool nonewprivs = false; bool nonewprivs = false;
int error = 0; int error = 0;
...@@ -723,7 +723,7 @@ static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec, ...@@ -723,7 +723,7 @@ static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
char *buffer, struct path_cond *cond, char *buffer, struct path_cond *cond,
bool *secure_exec) bool *secure_exec)
{ {
unsigned int state = profile->file.start; unsigned int state = profile->file.start[AA_CLASS_FILE];
struct aa_perms perms = {}; struct aa_perms perms = {};
const char *xname = NULL, *info = "change_profile onexec"; const char *xname = NULL, *info = "change_profile onexec";
int error = -EACCES; int error = -EACCES;
...@@ -1267,7 +1267,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name, ...@@ -1267,7 +1267,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
if (!error) if (!error)
error = change_profile_perms(profile, target, stack, request, error = change_profile_perms(profile, target, stack, request,
profile->file.start, perms); profile->file.start[AA_CLASS_FILE],
perms);
if (error) if (error)
error = aa_audit_file(profile, perms, op, request, name, error = aa_audit_file(profile, perms, op, request, name,
NULL, target, GLOBAL_ROOT_UID, info, NULL, target, GLOBAL_ROOT_UID, info,
......
...@@ -185,16 +185,16 @@ static int path_name(const char *op, struct aa_label *label, ...@@ -185,16 +185,16 @@ static int path_name(const char *op, struct aa_label *label,
* Returns: a pointer to a file permission set * Returns: a pointer to a file permission set
*/ */
struct aa_perms default_perms = {}; 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) unsigned int state, struct path_cond *cond)
{ {
if (!(file_rules->fperms_table)) if (!(file_rules->perms))
return &default_perms; return &default_perms;
if (uid_eq(current_fsuid(), cond->uid)) 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, ...@@ -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 * 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, const char *name, struct path_cond *cond,
struct aa_perms *perms) struct aa_perms *perms)
{ {
...@@ -226,7 +226,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name, ...@@ -226,7 +226,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
if (profile_unconfined(profile)) if (profile_unconfined(profile))
return 0; 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) if (request & ~perms->allow)
e = -EACCES; e = -EACCES;
return aa_audit_file(profile, perms, op, request, name, NULL, NULL, return aa_audit_file(profile, perms, op, request, name, NULL, NULL,
...@@ -333,7 +334,8 @@ static int profile_path_link(struct aa_profile *profile, ...@@ -333,7 +334,8 @@ static int profile_path_link(struct aa_profile *profile,
error = -EACCES; error = -EACCES;
/* aa_str_perms - handles the case of the dfa being NULL */ /* 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); cond, &lperms);
if (!(lperms.allow & AA_MAY_LINK)) if (!(lperms.allow & AA_MAY_LINK))
...@@ -363,8 +365,8 @@ static int profile_path_link(struct aa_profile *profile, ...@@ -363,8 +365,8 @@ static int profile_path_link(struct aa_profile *profile,
/* Do link perm subset test requiring allowed permission on link are /* Do link perm subset test requiring allowed permission on link are
* a subset of the allowed permissions on target. * a subset of the allowed permissions on target.
*/ */
aa_str_perms(&(profile->file), profile->file.start, tname, cond, aa_str_perms(&(profile->file), profile->file.start[AA_CLASS_FILE],
&perms); tname, cond, &perms);
/* AA_MAY_LINK is not considered in the subset test */ /* AA_MAY_LINK is not considered in the subset test */
request = lperms.allow & ~AA_MAY_LINK; request = lperms.allow & ~AA_MAY_LINK;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "match.h" #include "match.h"
#include "perms.h" #include "perms.h"
struct aa_policydb;
struct aa_profile; struct aa_profile;
struct path; struct path;
...@@ -164,29 +165,9 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms, ...@@ -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 *target, struct aa_label *tlabel, kuid_t ouid,
const char *info, int error); const char *info, int error);
/** struct aa_perms *aa_lookup_fperms(struct aa_policydb *file_rules,
* struct aa_file_rules - components used for file rule permissions unsigned int state, struct path_cond *cond);
* @dfa: dfa to match path names and conditionals against unsigned int aa_str_perms(struct aa_policydb *file_rules, unsigned int start,
* @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,
const char *name, struct path_cond *cond, const char *name, struct path_cond *cond,
struct aa_perms *perms); struct aa_perms *perms);
...@@ -205,18 +186,6 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file, ...@@ -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); 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 * aa_map_file_perms - map file flags to AppArmor permissions
......
...@@ -75,13 +75,21 @@ enum profile_mode { ...@@ -75,13 +75,21 @@ enum profile_mode {
* start: set of start states for the different classes of data * start: set of start states for the different classes of data
*/ */
struct aa_policydb { struct aa_policydb {
/* Generic policy DFA specific rule types will be subsections of it */
struct aa_dfa *dfa; struct aa_dfa *dfa;
struct aa_perms *perms; struct aa_perms *perms;
struct aa_domain trans;
unsigned int start[AA_CLASS_LAST + 1]; 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 /* struct aa_data - generic data structure
* key: name for retrieving this data * key: name for retrieving this data
* size: size of data in bytes * size: size of data in bytes
...@@ -151,7 +159,7 @@ struct aa_profile { ...@@ -151,7 +159,7 @@ struct aa_profile {
int size; int size;
struct aa_policydb policy; struct aa_policydb policy;
struct aa_file_rules file; struct aa_policydb file;
struct aa_caps caps; struct aa_caps caps;
int xattr_count; int xattr_count;
......
...@@ -219,7 +219,7 @@ void aa_free_profile(struct aa_profile *profile) ...@@ -219,7 +219,7 @@ void aa_free_profile(struct aa_profile *profile)
aa_put_ns(profile->ns); aa_put_ns(profile->ns);
kfree_sensitive(profile->rename); kfree_sensitive(profile->rename);
aa_free_file_rules(&profile->file); aa_destroy_policydb(&profile->file);
aa_free_cap_rules(&profile->caps); aa_free_cap_rules(&profile->caps);
aa_free_rlimit_rules(&profile->rlimits); aa_free_rlimit_rules(&profile->rlimits);
...@@ -232,8 +232,7 @@ void aa_free_profile(struct aa_profile *profile) ...@@ -232,8 +232,7 @@ void aa_free_profile(struct aa_profile *profile)
kfree_sensitive(profile->dirname); kfree_sensitive(profile->dirname);
aa_put_dfa(profile->xmatch); aa_put_dfa(profile->xmatch);
kvfree(profile->xmatch_perms); kvfree(profile->xmatch_perms);
aa_put_dfa(profile->policy.dfa); aa_destroy_policydb(&profile->policy);
kvfree(profile->policy.perms);
if (profile->data) { if (profile->data) {
rht = profile->data; rht = profile->data;
profile->data = NULL; profile->data = NULL;
......
...@@ -1048,18 +1048,19 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) ...@@ -1048,18 +1048,19 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
info = "failed to unpack profile file rules"; info = "failed to unpack profile file rules";
goto fail; goto fail;
} else if (profile->file.dfa) { } 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 */ /* default start state */
profile->file.start = DFA_START; profile->file.start[AA_CLASS_FILE] = DFA_START;
} else if (profile->policy.dfa && } else if (profile->policy.dfa &&
profile->policy.start[AA_CLASS_FILE]) { profile->policy.start[AA_CLASS_FILE]) {
profile->file.dfa = aa_get_dfa(profile->policy.dfa); 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 } else
profile->file.dfa = aa_get_dfa(nulldfa); profile->file.dfa = aa_get_dfa(nulldfa);
profile->file.fperms_table = compute_fperms(profile->file.dfa); profile->file.perms = compute_fperms(profile->file.dfa);
if (!profile->file.fperms_table) { if (!profile->file.perms) {
info = "failed to remap file permission table"; info = "failed to remap file permission table";
goto fail; goto fail;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment