|
@@ -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 @@ fail:
|
|
|
|
|
|
|
|
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)
|
|
|
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)
|
|
|
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;
|