diff options
author | Mike Salvatore <mike.salvatore@canonical.com> | 2020-05-31 16:52:06 +0200 |
---|---|---|
committer | John Johansen <john.johansen@canonical.com> | 2022-10-03 23:49:02 +0200 |
commit | b5b57993504f91785fa70e002e5e494fb549726e (patch) | |
tree | 3d3a6cc40d0949486554351e6889ed5fc594fb98 /security | |
parent | apparmor: compute file permissions on profile load (diff) | |
download | linux-b5b57993504f91785fa70e002e5e494fb549726e.tar.xz linux-b5b57993504f91785fa70e002e5e494fb549726e.zip |
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')
-rw-r--r-- | security/apparmor/domain.c | 4 | ||||
-rw-r--r-- | security/apparmor/include/policy.h | 2 | ||||
-rw-r--r-- | security/apparmor/policy.c | 1 | ||||
-rw-r--r-- | security/apparmor/policy_unpack.c | 22 |
4 files changed, 26 insertions, 3 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 2c99edd8953a..22351b6d71e6 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -339,7 +339,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm, /* Check xattr value */ state = aa_dfa_match_len(profile->xmatch, state, value, size); - perm = dfa_user_allow(profile->xmatch, state); + perm = profile->xmatch_perms[state]; if (!(perm & MAY_EXEC)) { ret = -EINVAL; goto out; @@ -419,7 +419,7 @@ restart: state = aa_dfa_leftmatch(profile->xmatch, DFA_START, name, &count); - perm = dfa_user_allow(profile->xmatch, state); + perm = profile->xmatch_perms[state]; /* any accepting state means a valid match. */ if (perm & MAY_EXEC) { int ret = 0; diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 639b5b248e63..128c6a9430d4 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -104,6 +104,7 @@ struct aa_data { * @attach: human readable attachment string * @xmatch: optional extended matching for unconfined executables names * @xmatch_len: xmatch prefix len, used to determine xmatch priority + * @xmatch_perms: precomputed permissions for the xmatch DFA indexed by state * @audit: the auditing mode of the profile * @mode: the enforcement mode of the profile * @path_flags: flags controlling path generation behavior @@ -140,6 +141,7 @@ struct aa_profile { const char *attach; struct aa_dfa *xmatch; unsigned int xmatch_len; + u32 *xmatch_perms; enum audit_mode audit; long mode; u32 path_flags; diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index fbdfcef91c61..e2d23cd85cd2 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -231,6 +231,7 @@ void aa_free_profile(struct aa_profile *profile) kfree_sensitive(profile->secmark); kfree_sensitive(profile->dirname); aa_put_dfa(profile->xmatch); + kvfree(profile->xmatch_perms); aa_put_dfa(profile->policy.dfa); if (profile->data) { 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 */ |