Merge tag '6.2-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6
[linux-2.6-microblaze.git] / security / apparmor / label.c
index 0f36ee9..8a2af96 100644 (file)
@@ -197,15 +197,18 @@ static bool vec_is_stale(struct aa_profile **vec, int n)
        return false;
 }
 
-static long union_vec_flags(struct aa_profile **vec, int n, long mask)
+static long accum_vec_flags(struct aa_profile **vec, int n)
 {
-       long u = 0;
+       long u = FLAG_UNCONFINED;
        int i;
 
        AA_BUG(!vec);
 
        for (i = 0; i < n; i++) {
-               u |= vec[i]->label.flags & mask;
+               u |= vec[i]->label.flags & (FLAG_DEBUG1 | FLAG_DEBUG2 |
+                                           FLAG_STALE);
+               if (!(u & vec[i]->label.flags & FLAG_UNCONFINED))
+                       u &= ~FLAG_UNCONFINED;
        }
 
        return u;
@@ -1097,8 +1100,7 @@ static struct aa_label *label_merge_insert(struct aa_label *new,
                else if (k == b->size)
                        return aa_get_label(b);
        }
-       new->flags |= union_vec_flags(new->vec, new->size, FLAG_UNCONFINED |
-                                             FLAG_DEBUG1 | FLAG_DEBUG2);
+       new->flags |= accum_vec_flags(new->vec, new->size);
        ls = labels_set(new);
        write_lock_irqsave(&ls->lock, flags);
        label = __label_insert(labels_set(new), new, false);
@@ -1254,32 +1256,27 @@ out:
        return label;
 }
 
-static inline bool label_is_visible(struct aa_profile *profile,
-                                   struct aa_label *label)
-{
-       return aa_ns_visible(profile->ns, labels_ns(label), true);
-}
-
 /* match a profile and its associated ns component if needed
  * Assumes visibility test has already been done.
  * If a subns profile is not to be matched should be prescreened with
  * visibility test.
  */
-static inline unsigned int match_component(struct aa_profile *profile,
-                                          struct aa_profile *tp,
-                                          unsigned int state)
+static inline aa_state_t match_component(struct aa_profile *profile,
+                                        struct aa_ruleset *rules,
+                                        struct aa_profile *tp,
+                                        aa_state_t state)
 {
        const char *ns_name;
 
        if (profile->ns == tp->ns)
-               return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
+               return aa_dfa_match(rules->policy.dfa, state, tp->base.hname);
 
        /* try matching with namespace name and then profile */
        ns_name = aa_ns_name(profile->ns, tp->ns, true);
-       state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
-       state = aa_dfa_match(profile->policy.dfa, state, ns_name);
-       state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
-       return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
+       state = aa_dfa_match_len(rules->policy.dfa, state, ":", 1);
+       state = aa_dfa_match(rules->policy.dfa, state, ns_name);
+       state = aa_dfa_match_len(rules->policy.dfa, state, ":", 1);
+       return aa_dfa_match(rules->policy.dfa, state, tp->base.hname);
 }
 
 /**
@@ -1298,8 +1295,9 @@ static inline unsigned int match_component(struct aa_profile *profile,
  *        check to be stacked.
  */
 static int label_compound_match(struct aa_profile *profile,
+                               struct aa_ruleset *rules,
                                struct aa_label *label,
-                               unsigned int state, bool subns, u32 request,
+                               aa_state_t state, bool subns, u32 request,
                                struct aa_perms *perms)
 {
        struct aa_profile *tp;
@@ -1309,7 +1307,7 @@ static int label_compound_match(struct aa_profile *profile,
        label_for_each(i, label, tp) {
                if (!aa_ns_visible(profile->ns, tp->ns, subns))
                        continue;
-               state = match_component(profile, tp, state);
+               state = match_component(profile, rules, tp, state);
                if (!state)
                        goto fail;
                goto next;
@@ -1323,12 +1321,12 @@ next:
        label_for_each_cont(i, label, tp) {
                if (!aa_ns_visible(profile->ns, tp->ns, subns))
                        continue;
-               state = aa_dfa_match(profile->policy.dfa, state, "//&");
-               state = match_component(profile, tp, state);
+               state = aa_dfa_match(rules->policy.dfa, state, "//&");
+               state = match_component(profile, rules, tp, state);
                if (!state)
                        goto fail;
        }
-       aa_compute_perms(profile->policy.dfa, state, perms);
+       *perms = *aa_lookup_perms(&rules->policy, state);
        aa_apply_modes_to_perms(profile, perms);
        if ((perms->allow & request) != request)
                return -EACCES;
@@ -1343,6 +1341,7 @@ fail:
 /**
  * label_components_match - find perms for all subcomponents of a label
  * @profile: profile to find perms for
+ * @rules: ruleset to search
  * @label: label to check access permissions for
  * @start: state to start match in
  * @subns: whether to do permission checks on components in a subns
@@ -1356,20 +1355,21 @@ fail:
  *        check to be stacked.
  */
 static int label_components_match(struct aa_profile *profile,
-                                 struct aa_label *label, unsigned int start,
+                                 struct aa_ruleset *rules,
+                                 struct aa_label *label, aa_state_t start,
                                  bool subns, u32 request,
                                  struct aa_perms *perms)
 {
        struct aa_profile *tp;
        struct label_it i;
        struct aa_perms tmp;
-       unsigned int state = 0;
+       aa_state_t state = 0;
 
        /* find first subcomponent to test */
        label_for_each(i, label, tp) {
                if (!aa_ns_visible(profile->ns, tp->ns, subns))
                        continue;
-               state = match_component(profile, tp, start);
+               state = match_component(profile, rules, tp, start);
                if (!state)
                        goto fail;
                goto next;
@@ -1379,16 +1379,16 @@ static int label_components_match(struct aa_profile *profile,
        return 0;
 
 next:
-       aa_compute_perms(profile->policy.dfa, state, &tmp);
+       tmp = *aa_lookup_perms(&rules->policy, state);
        aa_apply_modes_to_perms(profile, &tmp);
        aa_perms_accum(perms, &tmp);
        label_for_each_cont(i, label, tp) {
                if (!aa_ns_visible(profile->ns, tp->ns, subns))
                        continue;
-               state = match_component(profile, tp, start);
+               state = match_component(profile, rules, tp, start);
                if (!state)
                        goto fail;
-               aa_compute_perms(profile->policy.dfa, state, &tmp);
+               tmp = *aa_lookup_perms(&rules->policy, state);
                aa_apply_modes_to_perms(profile, &tmp);
                aa_perms_accum(perms, &tmp);
        }
@@ -1406,6 +1406,7 @@ fail:
 /**
  * aa_label_match - do a multi-component label match
  * @profile: profile to match against (NOT NULL)
+ * @rules: ruleset to search
  * @label: label to match (NOT NULL)
  * @state: state to start in
  * @subns: whether to match subns components
@@ -1414,18 +1415,18 @@ fail:
  *
  * Returns: the state the match finished in, may be the none matching state
  */
-int aa_label_match(struct aa_profile *profile, struct aa_label *label,
-                  unsigned int state, bool subns, u32 request,
-                  struct aa_perms *perms)
+int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+                  struct aa_label *label, aa_state_t state, bool subns,
+                  u32 request, struct aa_perms *perms)
 {
-       int error = label_compound_match(profile, label, state, subns, request,
-                                        perms);
+       int error = label_compound_match(profile, rules, label, state, subns,
+                                        request, perms);
        if (!error)
                return error;
 
        *perms = allperms;
-       return label_components_match(profile, label, state, subns, request,
-                                     perms);
+       return label_components_match(profile, rules, label, state, subns,
+                                     request, perms);
 }