aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2022-07-16 01:53:46 -0700
committerJohn Johansen <john.johansen@canonical.com>2022-10-03 14:49:03 -0700
commite844fe9b51c984472ea98be3b2d1201ba9ee3213 (patch)
tree167bf6c3beeec74821dd3f2d54b77b3c37b3a361 /security/apparmor
parentbf690f59d0429c62de4db1234f16557eedcb39bf (diff)
downloadlinux-e844fe9b51c984472ea98be3b2d1201ba9ee3213.tar.gz
apparmor: convert policy lookup to use accept as an index
Remap polidydb dfa accept table from embedded perms to an index, and then move the perm lookup to use the accept entry as an index into the perm table. This is done so that the perm table can be separated from the dfa, allowing dfa accept to index to share expanded permission sets. Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/apparmorfs.c2
-rw-r--r--security/apparmor/include/perms.h8
-rw-r--r--security/apparmor/include/policy.h12
-rw-r--r--security/apparmor/label.c6
-rw-r--r--security/apparmor/mount.c8
-rw-r--r--security/apparmor/net.c2
-rw-r--r--security/apparmor/policy_unpack.c19
7 files changed, 33 insertions, 24 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index a2d12b80592bd..f2b78108bae81 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -634,7 +634,7 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
state = aa_dfa_match_len(dfa, profile->policy.start[0],
match_str, match_len);
if (state)
- tmp = *aa_lookup_perms(profile->policy.perms, state);
+ tmp = *aa_lookup_perms(&profile->policy, state);
}
aa_apply_modes_to_perms(profile, &tmp);
aa_perms_accum_raw(perms, &tmp);
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
index 1f3e7680e8092..1014a7bbc0278 100644
--- a/security/apparmor/include/perms.h
+++ b/security/apparmor/include/perms.h
@@ -132,14 +132,6 @@ extern struct aa_perms allperms;
extern struct aa_perms default_perms;
-static inline struct aa_perms *aa_lookup_perms(struct aa_perms *perms,
- unsigned int state)
-{
- if (!(perms))
- return &default_perms;
-
- return &(perms[state]);
-}
void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs,
u32 mask);
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 44d8cbb1c3685..31c0af8762505 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -90,6 +90,18 @@ static inline void aa_destroy_policydb(struct aa_policydb *policy)
}
+static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy,
+ unsigned int state)
+{
+ unsigned int index = ACCEPT_TABLE(policy->dfa)[state];
+
+ if (!(policy->perms))
+ return &default_perms;
+
+ return &(policy->perms[index]);
+}
+
+
/* struct aa_data - generic data structure
* key: name for retrieving this data
* size: size of data in bytes
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index ddb04417bdabf..30cb68641c0f5 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -1328,7 +1328,7 @@ next:
if (!state)
goto fail;
}
- *perms = *aa_lookup_perms(profile->policy.perms, state);
+ *perms = *aa_lookup_perms(&profile->policy, state);
aa_apply_modes_to_perms(profile, perms);
if ((perms->allow & request) != request)
return -EACCES;
@@ -1379,7 +1379,7 @@ static int label_components_match(struct aa_profile *profile,
return 0;
next:
- tmp = *aa_lookup_perms(profile->policy.perms, state);
+ tmp = *aa_lookup_perms(&profile->policy, state);
aa_apply_modes_to_perms(profile, &tmp);
aa_perms_accum(perms, &tmp);
label_for_each_cont(i, label, tp) {
@@ -1388,7 +1388,7 @@ next:
state = match_component(profile, tp, start);
if (!state)
goto fail;
- tmp = *aa_lookup_perms(profile->policy.perms, state);
+ tmp = *aa_lookup_perms(&profile->policy, state);
aa_apply_modes_to_perms(profile, &tmp);
aa_perms_accum(perms, &tmp);
}
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index 1e978c2b1ee45..7594f3a3441e5 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -249,7 +249,7 @@ static int do_match_mnt(struct aa_policydb *policy, unsigned int start,
state = match_mnt_flags(policy->dfa, state, flags);
if (!state)
return 4;
- *perms = *aa_lookup_perms(policy->perms, state);
+ *perms = *aa_lookup_perms(policy, state);
if (perms->allow & AA_MAY_MOUNT)
return 0;
@@ -262,7 +262,7 @@ static int do_match_mnt(struct aa_policydb *policy, unsigned int start,
state = aa_dfa_match(policy->dfa, state, data);
if (!state)
return 5;
- *perms = *aa_lookup_perms(policy->perms, state);
+ *perms = *aa_lookup_perms(policy, state);
if (perms->allow & AA_MAY_MOUNT)
return 0;
}
@@ -584,7 +584,7 @@ static int profile_umount(struct aa_profile *profile, const struct path *path,
state = aa_dfa_match(profile->policy.dfa,
profile->policy.start[AA_CLASS_MOUNT],
name);
- perms = *aa_lookup_perms(profile->policy.perms, state);
+ perms = *aa_lookup_perms(&profile->policy, state);
if (AA_MAY_UMOUNT & ~perms.allow)
error = -EACCES;
@@ -655,7 +655,7 @@ static struct aa_label *build_pivotroot(struct aa_profile *profile,
new_name);
state = aa_dfa_null_transition(profile->policy.dfa, state);
state = aa_dfa_match(profile->policy.dfa, state, old_name);
- perms = *aa_lookup_perms(profile->policy.perms, state);
+ perms = *aa_lookup_perms(&profile->policy, state);
if (AA_MAY_PIVOTROOT & perms.allow)
error = 0;
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index 88e8a7ea54c0c..fcfb97079e1be 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -125,7 +125,7 @@ int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
buffer[1] = cpu_to_be16((u16) type);
state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
4);
- perms = *aa_lookup_perms(profile->policy.perms, state);
+ perms = *aa_lookup_perms(&profile->policy, state);
aa_apply_modes_to_perms(profile, &perms);
return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 4cdc969887832..0917412ba48f4 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -1055,13 +1055,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
}
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
goto fail;
+ profile->policy.perms = compute_perms(profile->policy.dfa);
+ if (!profile->policy.perms) {
+ info = "failed to remap policydb permission table";
+ goto fail;
+ }
+ /* Do not remap internal dfas */
+ remap_dfa_accept(profile->policy.dfa, 1);
} else
profile->policy.dfa = aa_get_dfa(nulldfa);
- profile->policy.perms = compute_perms(profile->policy.dfa);
- if (!profile->policy.perms) {
- info = "failed to remap policydb permission table";
- goto fail;
- }
/* get file rules */
profile->file.dfa = unpack_dfa(e);
@@ -1238,9 +1240,12 @@ static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
*/
static int verify_profile(struct aa_profile *profile)
{
- if (profile->file.dfa &&
+ if ((profile->file.dfa &&
!verify_dfa_xindex(profile->file.dfa,
- profile->file.trans.size)) {
+ profile->file.trans.size)) ||
+ (profile->policy.dfa &&
+ !verify_dfa_xindex(profile->policy.dfa,
+ profile->policy.trans.size))) {
audit_iface(profile, NULL, NULL,
"Unpack: Invalid named transition", NULL, -EPROTO);
return -EPROTO;