apparmor: convert xmatch to using the new shared policydb struct

continue permission unification by converting xmatch to use the
policydb struct that is used by the other profile dfas.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2020-11-21 01:42:40 -08:00
parent 53bdc46f4b
commit 048d495444
6 changed files with 28 additions and 29 deletions

View File

@ -1095,7 +1095,7 @@ static int seq_profile_attach_show(struct seq_file *seq, void *v)
struct aa_profile *profile = labels_profile(label);
if (profile->attach)
seq_printf(seq, "%s\n", profile->attach);
else if (profile->xmatch)
else if (profile->xmatch.dfa)
seq_puts(seq, "<unknown>\n");
else
seq_printf(seq, "%s\n", profile->base.name);

View File

@ -321,7 +321,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
might_sleep();
/* transition from exec match to xattr set */
state = aa_dfa_outofband_transition(profile->xmatch, state);
state = aa_dfa_outofband_transition(profile->xmatch.dfa, state);
d = bprm->file->f_path.dentry;
for (i = 0; i < profile->xattr_count; i++) {
@ -335,18 +335,19 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
* that not present xattr can be distinguished from a 0
* length value or rule that matches any value
*/
state = aa_dfa_null_transition(profile->xmatch, state);
state = aa_dfa_null_transition(profile->xmatch.dfa,
state);
/* Check xattr value */
state = aa_dfa_match_len(profile->xmatch, state, value,
size);
perm = profile->xmatch_perms[state].allow;
state = aa_dfa_match_len(profile->xmatch.dfa, state,
value, size);
perm = profile->xmatch.perms[state].allow;
if (!(perm & MAY_EXEC)) {
ret = -EINVAL;
goto out;
}
}
/* transition to next element */
state = aa_dfa_outofband_transition(profile->xmatch, state);
state = aa_dfa_outofband_transition(profile->xmatch.dfa, state);
if (size < 0) {
/*
* No xattr match, so verify if transition to
@ -413,13 +414,14 @@ restart:
* as another profile, signal a conflict and refuse to
* match.
*/
if (profile->xmatch) {
if (profile->xmatch.dfa) {
unsigned int state, count;
u32 perm;
state = aa_dfa_leftmatch(profile->xmatch, DFA_START,
name, &count);
perm = profile->xmatch_perms[state].allow;
state = aa_dfa_leftmatch(profile->xmatch.dfa,
profile->xmatch.start[AA_CLASS_XMATCH],
name, &count);
perm = profile->xmatch.perms[state].allow;
/* any accepting state means a valid match. */
if (perm & MAY_EXEC) {
int ret = 0;

View File

@ -26,6 +26,7 @@
#define AA_CLASS_MOUNT 7
#define AA_CLASS_PTRACE 9
#define AA_CLASS_SIGNAL 10
#define AA_CLASS_XMATCH 11
#define AA_CLASS_NET 14
#define AA_CLASS_LABEL 16
#define AA_CLASS_POSIX_MQUEUE 17

View File

@ -113,7 +113,6 @@ 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
@ -148,9 +147,8 @@ struct aa_profile {
const char *rename;
const char *attach;
struct aa_dfa *xmatch;
struct aa_policydb xmatch;
unsigned int xmatch_len;
struct aa_perms *xmatch_perms;
enum audit_mode audit;
long mode;

View File

@ -230,8 +230,7 @@ void aa_free_profile(struct aa_profile *profile)
kfree_sensitive(profile->secmark[i].label);
kfree_sensitive(profile->secmark);
kfree_sensitive(profile->dirname);
aa_put_dfa(profile->xmatch);
kvfree(profile->xmatch_perms);
aa_destroy_policydb(&profile->xmatch);
aa_destroy_policydb(&profile->policy);
if (profile->data) {
rht = profile->data;

View File

@ -771,7 +771,7 @@ static struct aa_perms *compute_fperms(struct aa_dfa *dfa)
static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch)
{
struct aa_perms *perms_table;
struct aa_perms *perms;
int state;
int state_count;
@ -779,14 +779,13 @@ static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch)
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(struct aa_perms),
GFP_KERNEL);
perms = kvcalloc(state_count, sizeof(struct aa_perms), GFP_KERNEL);
/* zero init so skip the trap state (state == 0) */
for (state = 1; state < state_count; state++)
perms_table[state].allow = dfa_user_allow(xmatch, state);
perms[state].allow = dfa_user_allow(xmatch, state);
return perms_table;
return perms;
}
static u32 map_other(u32 x)
@ -888,23 +887,23 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
(void) unpack_str(e, &profile->attach, "attach");
/* xmatch is optional and may be NULL */
profile->xmatch = unpack_dfa(e);
if (IS_ERR(profile->xmatch)) {
error = PTR_ERR(profile->xmatch);
profile->xmatch = NULL;
profile->xmatch.dfa = unpack_dfa(e);
if (IS_ERR(profile->xmatch.dfa)) {
error = PTR_ERR(profile->xmatch.dfa);
profile->xmatch.dfa = NULL;
info = "bad xmatch";
goto fail;
}
/* neither xmatch_len not xmatch_perms are optional if xmatch is set */
if (profile->xmatch) {
if (profile->xmatch.dfa) {
if (!unpack_u32(e, &tmp, NULL)) {
info = "missing xmatch len";
goto fail;
}
profile->xmatch_len = tmp;
profile->xmatch_perms = compute_xmatch_perms(profile->xmatch);
if (!profile->xmatch_perms) {
profile->xmatch.start[AA_CLASS_XMATCH] = DFA_START;
profile->xmatch.perms = compute_xmatch_perms(profile->xmatch.dfa);
if (!profile->xmatch.perms) {
info = "failed to convert xmatch permission table";
goto fail;
}