提交 4e9b5ba3 编写于 作者: M Mike Salvatore 提交者: Xie XiuQi

apparmor: reset pos on failure to unpack for various functions

[ Upstream commit 156e42996bd84eccb6acf319f19ce0cb140d00e3 ]

Each function that manipulates the aa_ext struct should reset it's "pos"
member on failure. This ensures that, on failure, no changes are made to
the state of the aa_ext struct.

There are paths were elements are optional and the error path is
used to indicate the optional element is not present. This means
instead of just aborting on error the unpack stream can become
unsynchronized on optional elements, if using one of the affected
functions.

Cc: stable@vger.kernel.org
Fixes: 736ec752 ("AppArmor: policy routines for loading and unpacking policy")
Signed-off-by: NMike Salvatore <mike.salvatore@canonical.com>
Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 6adac824
...@@ -223,16 +223,21 @@ static void *kvmemdup(const void *src, size_t len) ...@@ -223,16 +223,21 @@ static void *kvmemdup(const void *src, size_t len)
static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk) static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
{ {
size_t size = 0; size_t size = 0;
void *pos = e->pos;
if (!inbounds(e, sizeof(u16))) if (!inbounds(e, sizeof(u16)))
return 0; goto fail;
size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
e->pos += sizeof(__le16); e->pos += sizeof(__le16);
if (!inbounds(e, size)) if (!inbounds(e, size))
return 0; goto fail;
*chunk = e->pos; *chunk = e->pos;
e->pos += size; e->pos += size;
return size; return size;
fail:
e->pos = pos;
return 0;
} }
/* unpack control byte */ /* unpack control byte */
...@@ -294,49 +299,66 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) ...@@ -294,49 +299,66 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
{ {
void *pos = e->pos;
if (unpack_nameX(e, AA_U32, name)) { if (unpack_nameX(e, AA_U32, name)) {
if (!inbounds(e, sizeof(u32))) if (!inbounds(e, sizeof(u32)))
return 0; goto fail;
if (data) if (data)
*data = le32_to_cpu(get_unaligned((__le32 *) e->pos)); *data = le32_to_cpu(get_unaligned((__le32 *) e->pos));
e->pos += sizeof(u32); e->pos += sizeof(u32);
return 1; return 1;
} }
fail:
e->pos = pos;
return 0; return 0;
} }
static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
{ {
void *pos = e->pos;
if (unpack_nameX(e, AA_U64, name)) { if (unpack_nameX(e, AA_U64, name)) {
if (!inbounds(e, sizeof(u64))) if (!inbounds(e, sizeof(u64)))
return 0; goto fail;
if (data) if (data)
*data = le64_to_cpu(get_unaligned((__le64 *) e->pos)); *data = le64_to_cpu(get_unaligned((__le64 *) e->pos));
e->pos += sizeof(u64); e->pos += sizeof(u64);
return 1; return 1;
} }
fail:
e->pos = pos;
return 0; return 0;
} }
static size_t unpack_array(struct aa_ext *e, const char *name) static size_t unpack_array(struct aa_ext *e, const char *name)
{ {
void *pos = e->pos;
if (unpack_nameX(e, AA_ARRAY, name)) { if (unpack_nameX(e, AA_ARRAY, name)) {
int size; int size;
if (!inbounds(e, sizeof(u16))) if (!inbounds(e, sizeof(u16)))
return 0; goto fail;
size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos)); size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos));
e->pos += sizeof(u16); e->pos += sizeof(u16);
return size; return size;
} }
fail:
e->pos = pos;
return 0; return 0;
} }
static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
{ {
void *pos = e->pos;
if (unpack_nameX(e, AA_BLOB, name)) { if (unpack_nameX(e, AA_BLOB, name)) {
u32 size; u32 size;
if (!inbounds(e, sizeof(u32))) if (!inbounds(e, sizeof(u32)))
return 0; goto fail;
size = le32_to_cpu(get_unaligned((__le32 *) e->pos)); size = le32_to_cpu(get_unaligned((__le32 *) e->pos));
e->pos += sizeof(u32); e->pos += sizeof(u32);
if (inbounds(e, (size_t) size)) { if (inbounds(e, (size_t) size)) {
...@@ -345,6 +367,9 @@ static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) ...@@ -345,6 +367,9 @@ static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
return size; return size;
} }
} }
fail:
e->pos = pos;
return 0; return 0;
} }
...@@ -361,9 +386,10 @@ static int unpack_str(struct aa_ext *e, const char **string, const char *name) ...@@ -361,9 +386,10 @@ static int unpack_str(struct aa_ext *e, const char **string, const char *name)
if (src_str[size - 1] != 0) if (src_str[size - 1] != 0)
goto fail; goto fail;
*string = src_str; *string = src_str;
return size;
} }
} }
return size;
fail: fail:
e->pos = pos; e->pos = pos;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册