summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-09-06 16:33:56 -0700
committerJohn Johansen <john.johansen@canonical.com>2018-02-09 11:30:01 -0800
commit95652cac83605d96cf3849e80e3e3f4dce74f5da (patch)
tree7359f5c6003ac7e7af47eeceed173bc10fb3a4a1
parent6e0654d20ed9679cbf75a0ff7cd786e364f7f09a (diff)
apparmor: provide a bounded version of label_parse
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>
-rw-r--r--security/apparmor/include/label.h3
-rw-r--r--security/apparmor/label.c35
2 files changed, 27 insertions, 11 deletions
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
index 80e9ba9d172c..d871e7ff0952 100644
--- a/security/apparmor/include/label.h
+++ b/security/apparmor/include/label.h
@@ -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);
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index 31e2f701d971..4721338ad551 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -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)