apparmor: convert policy lookup to use accept as an index
authorJohn Johansen <john.johansen@canonical.com>
Sat, 16 Jul 2022 08:53:46 +0000 (01:53 -0700)
committerJohn Johansen <john.johansen@canonical.com>
Mon, 3 Oct 2022 21:49:03 +0000 (14:49 -0700)
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>
security/apparmor/apparmorfs.c
security/apparmor/include/perms.h
security/apparmor/include/policy.h
security/apparmor/label.c
security/apparmor/mount.c
security/apparmor/net.c
security/apparmor/policy_unpack.c

index a2d12b80592bdce9f6cfca24b2ba782bdad17294..f2b78108bae81976f9fc26c940ccb555a700f3f8 100644 (file)
@@ -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);
index 1f3e7680e8092b4c1abad3eea2dbb7f78da0fdb9..1014a7bbc0278166b0a8b5d1e4202d55b1042fee 100644 (file)
@@ -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);
index 44d8cbb1c3685273fce078ba29878a78ec60a8b8..31c0af87625056c549248c14d84c7a6860d31280 100644 (file)
@@ -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
index ddb04417bdabf5d922da37e7a2feb14861b8f071..30cb68641c0f505ba5398e2fffe0ded143e51c0f 100644 (file)
@@ -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);
        }
index 1e978c2b1ee45d8ebd94212a9fff17295bacfbf6..7594f3a3441e5b6698ced55737240602a98bca94 100644 (file)
@@ -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;
index 88e8a7ea54c0ca7bc83f1b1b290c1cf386c60e17..fcfb97079e1beea460ef5085097aef53a4126aef 100644 (file)
@@ -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);
index 4cdc9698878324f32a8f9256690e1667a3cb93fa..0917412ba48f4230de616d7e138e54c735d3b253 100644 (file)
@@ -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;