summaryrefslogtreecommitdiff
path: root/security/apparmor/policy_unpack.c
diff options
context:
space:
mode:
authorMike Salvatore <mike.salvatore@canonical.com>2020-05-31 17:52:06 +0300
committerJohn Johansen <john.johansen@canonical.com>2022-10-04 00:49:02 +0300
commitb5b57993504f91785fa70e002e5e494fb549726e (patch)
tree3d3a6cc40d0949486554351e6889ed5fc594fb98 /security/apparmor/policy_unpack.c
parent408d53e923bd852d5d80243a642004163db53a87 (diff)
downloadlinux-b5b57993504f91785fa70e002e5e494fb549726e.tar.xz
apparmor: compute xmatch permissions on profile load
Rather than computing xmatch permissions each time access is requested, these permissions can be computed once on profile load and stored for lookup. Signed-off-by: Mike Salvatore <mike.salvatore@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/policy_unpack.c')
-rw-r--r--security/apparmor/policy_unpack.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 54175bca4256..70b7a35b5b96 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -669,6 +669,23 @@ static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)
return strcmp(data->key, *key);
}
+static u32 *aa_compute_xmatch_perms(struct aa_dfa *xmatch)
+{
+ u32 *perms_table;
+ int state;
+ int 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(u32), GFP_KERNEL);
+
+ // Since perms_table is initialized with zeroes via kvcalloc(), we can
+ // skip the trap state (state == 0)
+ for (state = 1; state < state_count; state++)
+ perms_table[state] = dfa_user_allow(xmatch, state);
+
+ return perms_table;
+}
+
/**
* unpack_profile - unpack a serialized profile
* @e: serialized data extent information (NOT NULL)
@@ -727,13 +744,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
info = "bad xmatch";
goto fail;
}
- /* xmatch_len is not optional if xmatch is set */
+ /* neither xmatch_len not xmatch_perms are optional if xmatch is set */
if (profile->xmatch) {
if (!unpack_u32(e, &tmp, NULL)) {
info = "missing xmatch len";
goto fail;
}
profile->xmatch_len = tmp;
+
+ profile->xmatch_perms = aa_compute_xmatch_perms(
+ profile->xmatch);
}
/* disconnected attachment string is optional */