summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2020-11-13 10:46:23 +0100
committerJohn Johansen <john.johansen@canonical.com>2022-10-03 23:49:03 +0200
commit7572fea31e3e5c4c19154ccc064eb1f83dfe1333 (patch)
tree1e8d88025b616942011630f911f4935a1533d740
parentapparmor: convert xmatch to using the new shared policydb struct (diff)
downloadlinux-7572fea31e3e5c4c19154ccc064eb1f83dfe1333.tar.xz
linux-7572fea31e3e5c4c19154ccc064eb1f83dfe1333.zip
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>
-rw-r--r--security/apparmor/file.c6
-rw-r--r--security/apparmor/policy_unpack.c57
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;
}