From: John Johansen Date: Fri, 13 Nov 2020 09:46:23 +0000 (-0800) Subject: apparmor: convert fperm lookup to use accept as an index X-Git-Tag: v6.2-rc1~86^2~50 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=7572fea31e3e5c4c19154ccc064eb1f83dfe1333;p=tomoyo%2Ftomoyo-test1.git 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 --- diff --git a/security/apparmor/file.c b/security/apparmor/file.c index d2be851be412..7bddec3df75f 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c @@ -188,13 +188,15 @@ struct aa_perms default_perms = {}; struct aa_perms *aa_lookup_fperms(struct aa_policydb *file_rules, unsigned int state, struct path_cond *cond) { + unsigned int index = ACCEPT_TABLE(file_rules->dfa)[state]; + if (!(file_rules->perms)) return &default_perms; 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]); } /** diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index f2a075986e49..4cf62c1be388 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -837,6 +837,29 @@ static struct aa_perms *compute_perms(struct aa_dfa *dfa) } /** + * 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 * @e: serialized data extent information (NOT NULL) * @ns_name: pointer of newly allocated copy of %NULL in case of error @@ -1051,6 +1074,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) "dfa_start")) /* default start state */ 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 && profile->policy.start[AA_CLASS_FILE]) { 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 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")) { info = "out of memory"; 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; for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) { - if (!verify_xindex(dfa_user_xindex(dfa, i), table_size)) - return false; - if (!verify_xindex(dfa_other_xindex(dfa, i), table_size)) + if (!verify_xindex(ACCEPT_TABLE(dfa)[i], table_size)) return false; } return true; @@ -1211,14 +1232,16 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size) * @profile: profile to verify (NOT NULL) * * Returns: 0 if passes verification else error + * + * This verification is post any unpack mapping or changes */ static int verify_profile(struct aa_profile *profile) { if (profile->file.dfa && - !verify_dfa_xindex(profile->file.dfa, - profile->file.trans.size)) { - audit_iface(profile, NULL, NULL, "Invalid named transition", - NULL, -EPROTO); + !verify_dfa_xindex(profile->file.dfa, + profile->file.trans.size)) { + audit_iface(profile, NULL, NULL, + "Unpack: Invalid named transition", NULL, -EPROTO); return -EPROTO; }