]> git.baikalelectronics.ru Git - kernel.git/commitdiff
apparmor: provide a bounded version of label_parse
authorJohn Johansen <john.johansen@canonical.com>
Wed, 6 Sep 2017 23:33:56 +0000 (16:33 -0700)
committerJohn Johansen <john.johansen@canonical.com>
Fri, 9 Feb 2018 19:30:01 +0000 (11:30 -0800)
some label/context sources might not be guaranteed to be null terminiated
provide a size bounded version of label parse to deal with these.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
security/apparmor/include/label.h
security/apparmor/label.c

index 80e9ba9d172cb9f37fde391c8a101041bda1745f..d871e7ff095275e8a23685449945036d016682eb 100644 (file)
@@ -327,6 +327,9 @@ void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp);
 void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp);
 void aa_label_printk(struct aa_label *label, gfp_t gfp);
 
+struct aa_label *aa_label_strn_parse(struct aa_label *base, const char *str,
+                                    size_t n, gfp_t gfp, bool create,
+                                    bool force_stack);
 struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
                                gfp_t gfp, bool create, bool force_stack);
 
index 31e2f701d97112022e0ea677ccedade5b8c3658c..4721338ad551210f35eb70cc915e85fb1dbe12fe 100644 (file)
@@ -1808,16 +1808,17 @@ void aa_label_printk(struct aa_label *label, gfp_t gfp)
        aa_put_ns(ns);
 }
 
-static int label_count_str_entries(const char *str)
+static int label_count_strn_entries(const char *str, size_t n)
 {
+       const char *end = str + n;
        const char *split;
        int count = 1;
 
        AA_BUG(!str);
 
-       for (split = aa_label_str_split(str);
+       for (split = aa_label_strn_split(str, end - str);
             split;
-            split = aa_label_str_split(str)) {
+            split = aa_label_strn_split(str, end - str)) {
                count++;
                str = split + 3;
        }
@@ -1845,9 +1846,10 @@ static struct aa_profile *fqlookupn_profile(struct aa_label *base,
 }
 
 /**
- * aa_label_parse - parse, validate and convert a text string to a label
+ * aa_label_strn_parse - parse, validate and convert a text string to a label
  * @base: base label to use for lookups (NOT NULL)
  * @str: null terminated text string (NOT NULL)
+ * @n: length of str to parse, will stop at \0 if encountered before n
  * @gfp: allocation type
  * @create: true if should create compound labels if they don't exist
  * @force_stack: true if should stack even if no leading &
@@ -1855,19 +1857,23 @@ static struct aa_profile *fqlookupn_profile(struct aa_label *base,
  * Returns: the matching refcounted label if present
  *     else ERRPTR
  */
-struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
-                               gfp_t gfp, bool create, bool force_stack)
+struct aa_label *aa_label_strn_parse(struct aa_label *base, const char *str,
+                                    size_t n, gfp_t gfp, bool create,
+                                    bool force_stack)
 {
        DEFINE_VEC(profile, vec);
        struct aa_label *label, *currbase = base;
        int i, len, stack = 0, error;
+       const char *end = str + n;
        const char *split;
 
        AA_BUG(!base);
        AA_BUG(!str);
 
-       str = skip_spaces(str);
-       len = label_count_str_entries(str);
+       str = skipn_spaces(str, n);
+       if (str == NULL)
+               return ERR_PTR(-EINVAL);
+       len = label_count_strn_entries(str, end - str);
        if (*str == '&' || force_stack) {
                /* stack on top of base */
                stack = base->size;
@@ -1885,7 +1891,7 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
        for (i = 0; i < stack; i++)
                vec[i] = aa_get_profile(base->vec[i]);
 
-       for (split = aa_label_str_split(str), i = stack;
+       for (split = aa_label_strn_split(str, end - str), i = stack;
             split && i < len; i++) {
                vec[i] = fqlookupn_profile(base, currbase, str, split - str);
                if (!vec[i])
@@ -1897,11 +1903,11 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
                if (vec[i]->ns != labels_ns(currbase))
                        currbase = &vec[i]->label;
                str = split + 3;
-               split = aa_label_str_split(str);
+               split = aa_label_strn_split(str, end - str);
        }
        /* last element doesn't have a split */
        if (i < len) {
-               vec[i] = fqlookupn_profile(base, currbase, str, strlen(str));
+               vec[i] = fqlookupn_profile(base, currbase, str, end - str);
                if (!vec[i])
                        goto fail;
        }
@@ -1933,6 +1939,13 @@ fail:
        goto out;
 }
 
+struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
+                               gfp_t gfp, bool create, bool force_stack)
+{
+       return aa_label_strn_parse(base, str, strlen(str), gfp, create,
+                                  force_stack);
+}
+
 /**
  * aa_labelset_destroy - remove all labels from the label set
  * @ls: label set to cleanup (NOT NULL)