aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2022-08-26 09:26:57 -0700
committerJohn Johansen <john.johansen@canonical.com>2022-10-03 14:49:03 -0700
commit371e50a0b19f9765bfb9e4f172e72f4e9a4625bc (patch)
tree9dc2ab1b225616532c4c3da48ad69c5b26a02cc8 /security/apparmor
parentad596ea74e746d60bb7e13f3adde097a08b2089b (diff)
downloadlinux-371e50a0b19f9765bfb9e4f172e72f4e9a4625bc.tar.gz
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: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/policy_unpack.c43
-rw-r--r--security/apparmor/policy_unpack_test.c12
2 files changed, 33 insertions, 22 deletions
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index a1fe0a5e8e57d..7d3b3e664c1c1 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -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 @@ fail:
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);
- /* currently 2^24 bits entries 0-3 */
- if (size > (1 << 24))
+ if (unpack_array(e, NULL, &size) != TRI_TRUE ||
+ size > (1 << 24))
+ /* currently 2^24 bits entries 0-3 */
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 @@ fail:
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;
diff --git a/security/apparmor/policy_unpack_test.c b/security/apparmor/policy_unpack_test.c
index 0a969b2e03dba..1a43d538c4c04 100644
--- a/security/apparmor/policy_unpack_test.c
+++ b/security/apparmor/policy_unpack_test.c
@@ -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);