apparmor: convert fperm lookup to use accept as an index

Remap file dfa accept table from embedded perms to index and then move
fperm lookup to use the accept entry as an index into the fperm table.

This is a step toward unifying permission lookup.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2020-11-13 01:46:23 -08:00
parent 048d495444
commit 7572fea31e
2 changed files with 44 additions and 19 deletions

View File

@ -188,13 +188,15 @@ struct aa_perms default_perms = {};
struct aa_perms *aa_lookup_fperms(struct aa_policydb *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)
{ {
unsigned int index = ACCEPT_TABLE(file_rules->dfa)[state];
if (!(file_rules->perms)) 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->perms[state * 2]); return &(file_rules->perms[index]);
return &(file_rules->perms[state * 2 + 1]); return &(file_rules->perms[index + 1]);
} }
/** /**

View File

@ -836,6 +836,29 @@ static struct aa_perms *compute_perms(struct aa_dfa *dfa)
return table; return table;
} }
/**
* remap_dfa_accept - remap old dfa accept table to be an index
* @dfa: dfa to do the remapping on
* @factor: scaling factor for the index conversion.
*
* Used in conjunction with compute_Xperms, it converts old style perms
* that are encoded in the dfa accept tables to the new style where
* there is a permission table and the accept table is an index into
* the permission table.
*/
static void remap_dfa_accept(struct aa_dfa *dfa, unsigned int factor)
{
unsigned int state;
unsigned int state_count = dfa->tables[YYTD_ID_BASE]->td_lolen;
AA_BUG(!dfa);
for (state = 0; state < state_count; state++)
ACCEPT_TABLE(dfa)[state] = state * factor;
kvfree(dfa->tables[YYTD_ID_ACCEPT2]);
dfa->tables[YYTD_ID_ACCEPT2] = NULL;
}
/** /**
* unpack_profile - unpack a serialized profile * unpack_profile - unpack a serialized profile
* @e: serialized data extent information (NOT NULL) * @e: serialized data extent information (NOT NULL)
@ -1051,6 +1074,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
"dfa_start")) "dfa_start"))
/* default start state */ /* default start state */
profile->file.start[AA_CLASS_FILE] = DFA_START; profile->file.start[AA_CLASS_FILE] = DFA_START;
profile->file.perms = compute_fperms(profile->file.dfa);
if (!profile->file.perms) {
info = "failed to remap file permission table";
goto fail;
}
remap_dfa_accept(profile->file.dfa, 2);
if (!unpack_trans_table(e, profile)) {
info = "failed to unpack profile transition table";
goto fail;
}
} 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);
@ -1058,16 +1091,6 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
} else } else
profile->file.dfa = aa_get_dfa(nulldfa); profile->file.dfa = aa_get_dfa(nulldfa);
profile->file.perms = compute_fperms(profile->file.dfa);
if (!profile->file.perms) {
info = "failed to remap file permission table";
goto fail;
}
if (!unpack_trans_table(e, profile)) {
info = "failed to unpack profile transition table";
goto fail;
}
if (unpack_nameX(e, AA_STRUCT, "data")) { if (unpack_nameX(e, AA_STRUCT, "data")) {
info = "out of memory"; info = "out of memory";
profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
@ -1198,9 +1221,7 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
{ {
int i; int i;
for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) { for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
if (!verify_xindex(dfa_user_xindex(dfa, i), table_size)) if (!verify_xindex(ACCEPT_TABLE(dfa)[i], table_size))
return false;
if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
return false; return false;
} }
return true; return true;
@ -1211,14 +1232,16 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
* @profile: profile to verify (NOT NULL) * @profile: profile to verify (NOT NULL)
* *
* Returns: 0 if passes verification else error * Returns: 0 if passes verification else error
*
* This verification is post any unpack mapping or changes
*/ */
static int verify_profile(struct aa_profile *profile) static int verify_profile(struct aa_profile *profile)
{ {
if (profile->file.dfa && if (profile->file.dfa &&
!verify_dfa_xindex(profile->file.dfa, !verify_dfa_xindex(profile->file.dfa,
profile->file.trans.size)) { profile->file.trans.size)) {
audit_iface(profile, NULL, NULL, "Invalid named transition", audit_iface(profile, NULL, NULL,
NULL, -EPROTO); "Unpack: Invalid named transition", NULL, -EPROTO);
return -EPROTO; return -EPROTO;
} }