diff options
-rw-r--r-- | security/apparmor/file.c | 6 | ||||
-rw-r--r-- | security/apparmor/policy_unpack.c | 57 |
2 files changed, 44 insertions, 19 deletions
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; } |