diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/policy_unpack.c | 43 | ||||
-rw-r--r-- | security/apparmor/policy_unpack_test.c | 12 |
2 files changed, 33 insertions, 22 deletions
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index a1fe0a5e8e57..7d3b3e664c1c 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 0a969b2e03db..1a43d538c4c0 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); |