apparmor: compute xmatch permissions on profile load
Rather than computing xmatch permissions each time access is requested, these permissions can be computed once on profile load and stored for lookup. Signed-off-by: Mike Salvatore <mike.salvatore@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
408d53e923
commit
b5b5799350
@ -339,7 +339,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
|
||||
/* Check xattr value */
|
||||
state = aa_dfa_match_len(profile->xmatch, state, value,
|
||||
size);
|
||||
perm = dfa_user_allow(profile->xmatch, state);
|
||||
perm = profile->xmatch_perms[state];
|
||||
if (!(perm & MAY_EXEC)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
@ -419,7 +419,7 @@ restart:
|
||||
|
||||
state = aa_dfa_leftmatch(profile->xmatch, DFA_START,
|
||||
name, &count);
|
||||
perm = dfa_user_allow(profile->xmatch, state);
|
||||
perm = profile->xmatch_perms[state];
|
||||
/* any accepting state means a valid match. */
|
||||
if (perm & MAY_EXEC) {
|
||||
int ret = 0;
|
||||
|
@ -104,6 +104,7 @@ struct aa_data {
|
||||
* @attach: human readable attachment string
|
||||
* @xmatch: optional extended matching for unconfined executables names
|
||||
* @xmatch_len: xmatch prefix len, used to determine xmatch priority
|
||||
* @xmatch_perms: precomputed permissions for the xmatch DFA indexed by state
|
||||
* @audit: the auditing mode of the profile
|
||||
* @mode: the enforcement mode of the profile
|
||||
* @path_flags: flags controlling path generation behavior
|
||||
@ -140,6 +141,7 @@ struct aa_profile {
|
||||
const char *attach;
|
||||
struct aa_dfa *xmatch;
|
||||
unsigned int xmatch_len;
|
||||
u32 *xmatch_perms;
|
||||
enum audit_mode audit;
|
||||
long mode;
|
||||
u32 path_flags;
|
||||
|
@ -231,6 +231,7 @@ void aa_free_profile(struct aa_profile *profile)
|
||||
kfree_sensitive(profile->secmark);
|
||||
kfree_sensitive(profile->dirname);
|
||||
aa_put_dfa(profile->xmatch);
|
||||
kvfree(profile->xmatch_perms);
|
||||
aa_put_dfa(profile->policy.dfa);
|
||||
|
||||
if (profile->data) {
|
||||
|
@ -669,6 +669,23 @@ static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)
|
||||
return strcmp(data->key, *key);
|
||||
}
|
||||
|
||||
static u32 *aa_compute_xmatch_perms(struct aa_dfa *xmatch)
|
||||
{
|
||||
u32 *perms_table;
|
||||
int state;
|
||||
int state_count = xmatch->tables[YYTD_ID_BASE]->td_lolen;
|
||||
|
||||
// DFAs are restricted from having a state_count of less than 2
|
||||
perms_table = kvcalloc(state_count, sizeof(u32), GFP_KERNEL);
|
||||
|
||||
// Since perms_table is initialized with zeroes via kvcalloc(), we can
|
||||
// skip the trap state (state == 0)
|
||||
for (state = 1; state < state_count; state++)
|
||||
perms_table[state] = dfa_user_allow(xmatch, state);
|
||||
|
||||
return perms_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* unpack_profile - unpack a serialized profile
|
||||
* @e: serialized data extent information (NOT NULL)
|
||||
@ -727,13 +744,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
||||
info = "bad xmatch";
|
||||
goto fail;
|
||||
}
|
||||
/* xmatch_len is not optional if xmatch is set */
|
||||
/* neither xmatch_len not xmatch_perms are optional if xmatch is set */
|
||||
if (profile->xmatch) {
|
||||
if (!unpack_u32(e, &tmp, NULL)) {
|
||||
info = "missing xmatch len";
|
||||
goto fail;
|
||||
}
|
||||
profile->xmatch_len = tmp;
|
||||
|
||||
profile->xmatch_perms = aa_compute_xmatch_perms(
|
||||
profile->xmatch);
|
||||
}
|
||||
|
||||
/* disconnected attachment string is optional */
|
||||
|
Loading…
Reference in New Issue
Block a user