Commit 371e50a0 authored by John Johansen's avatar John Johansen
Browse files

apparmor: make unpack_array return a trianary value



currently unpack_array() does not return an error nor whether the
array is not present. The ability to detect an error or the array
not being present is needed so rework the unpack_array() to return
the needed information.

Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent ad596ea7
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -67,6 +67,11 @@ struct aa_ext {
	u32 version;
};

#define tri int
#define TRI_TRUE 1
#define TRI_NONE 0
#define TRI_FALSE -1

/* audit callback for unpack fields */
static void audit_cb(struct audit_buffer *ab, void *va)
{
@@ -344,22 +349,22 @@ static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
	return false;
}

static size_t unpack_array(struct aa_ext *e, const char *name)
static tri unpack_array(struct aa_ext *e, const char *name, u16 *size)
{
	void *pos = e->pos;

	if (unpack_nameX(e, AA_ARRAY, name)) {
		int size;
		if (!inbounds(e, sizeof(u16)))
			goto fail;
		size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos));
		*size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
		e->pos += sizeof(u16);
		return size;
		return TRI_TRUE;
	}

	return TRI_NONE;
fail:
	e->pos = pos;
	return 0;
	return TRI_FALSE;
}

static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
@@ -477,11 +482,12 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs)

	/* exec table is optional */
	if (unpack_nameX(e, AA_STRUCT, "xtable")) {
		int i, size;
		u16 size;
		int i;

		size = unpack_array(e, NULL);
		if (unpack_array(e, NULL, &size) != TRI_TRUE ||
		    size > (1 << 24))
		  /* currently 2^24 bits entries 0-3 */
		if (size > (1 << 24))
			goto fail;
		table = kcalloc(size, sizeof(char *), GFP_KERNEL);
		if (!table)
@@ -546,9 +552,11 @@ static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
	void *pos = e->pos;

	if (unpack_nameX(e, AA_STRUCT, "xattrs")) {
		int i, size;
		u16 size;
		int i;

		size = unpack_array(e, NULL);
		if (unpack_array(e, NULL, &size) != TRI_TRUE)
			goto fail;
		profile->xattr_count = size;
		profile->xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL);
		if (!profile->xattrs)
@@ -573,10 +581,12 @@ static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
{
	void *pos = e->pos;
	int i, size;
	u16 size;
	int i;

	if (unpack_nameX(e, AA_STRUCT, "secmark")) {
		size = unpack_array(e, NULL);
		if (unpack_array(e, NULL, &size) != TRI_TRUE)
			goto fail;

		profile->secmark = kcalloc(size, sizeof(struct aa_secmark),
					   GFP_KERNEL);
@@ -620,14 +630,15 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)

	/* rlimits are optional */
	if (unpack_nameX(e, AA_STRUCT, "rlimits")) {
		int i, size;
		u16 size;
		int i;
		u32 tmp = 0;
		if (!unpack_u32(e, &tmp, NULL))
			goto fail;
		profile->rlimits.mask = tmp;

		size = unpack_array(e, NULL);
		if (size > RLIM_NLIMITS)
		if (unpack_array(e, NULL, &size) != TRI_TRUE ||
		    size > RLIM_NLIMITS)
			goto fail;
		for (i = 0; i < size; i++) {
			u64 tmp2 = 0;
+6 −6
Original line number Diff line number Diff line
@@ -144,8 +144,8 @@ static void policy_unpack_test_unpack_array_with_null_name(struct kunit *test)

	puf->e->pos += TEST_ARRAY_BUF_OFFSET;

	array_size = unpack_array(puf->e, NULL);

	KUNIT_EXPECT_EQ(test, unpack_array(puf->e, NULL, &array_size),
			TRI_TRUE);
	KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE);
	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
		puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16) + 1);
@@ -159,8 +159,8 @@ static void policy_unpack_test_unpack_array_with_name(struct kunit *test)

	puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET;

	array_size = unpack_array(puf->e, name);

	KUNIT_EXPECT_EQ(test, unpack_array(puf->e, name, &array_size),
			TRI_TRUE);
	KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE);
	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
		puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16) + 1);
@@ -175,8 +175,8 @@ static void policy_unpack_test_unpack_array_out_of_bounds(struct kunit *test)
	puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET;
	puf->e->end = puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16);

	array_size = unpack_array(puf->e, name);

	KUNIT_EXPECT_EQ(test, unpack_array(puf->e, name, &array_size),
			TRI_TRUE);
	KUNIT_EXPECT_EQ(test, array_size, 0);
	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
		puf->e->start + TEST_NAMED_ARRAY_BUF_OFFSET);