Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95652cac authored by John Johansen's avatar John Johansen
Browse files

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: default avatarJohn Johansen <john.johansen@canonical.com>
Acked-by: default avatarSeth Arnold <seth.arnold@canonical.com>
parent 6e0654d2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);

+24 −11
Original line number Diff line number Diff line
@@ -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 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
	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)