]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - security/apparmor/policy_unpack.c
Merge branches 'for-5.2/fixes', 'for-5.3/doc', 'for-5.3/ish', 'for-5.3/logitech'...
[linux.git] / security / apparmor / policy_unpack.c
index 01957ce9252b52d436da3f057ec5c97687106431..8cfc9493eefc77b886eecb06ce7037313c39975e 100644 (file)
@@ -219,16 +219,21 @@ static void *kvmemdup(const void *src, size_t len)
 static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
 {
        size_t size = 0;
+       void *pos = e->pos;
 
        if (!inbounds(e, sizeof(u16)))
-               return 0;
+               goto fail;
        size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
        e->pos += sizeof(__le16);
        if (!inbounds(e, size))
-               return 0;
+               goto fail;
        *chunk = e->pos;
        e->pos += size;
        return size;
+
+fail:
+       e->pos = pos;
+       return 0;
 }
 
 /* unpack control byte */
@@ -272,7 +277,7 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
                char *tag = NULL;
                size_t size = unpack_u16_chunk(e, &tag);
                /* if a name is specified it must match. otherwise skip tag */
-               if (name && (!size || strcmp(name, tag)))
+               if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag)))
                        goto fail;
        } else if (name) {
                /* if a name is specified and there is no name tag fail */
@@ -290,62 +295,84 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
 
 static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
 {
+       void *pos = e->pos;
+
        if (unpack_nameX(e, AA_U8, name)) {
                if (!inbounds(e, sizeof(u8)))
-                       return 0;
+                       goto fail;
                if (data)
                        *data = get_unaligned((u8 *)e->pos);
                e->pos += sizeof(u8);
                return 1;
        }
+
+fail:
+       e->pos = pos;
        return 0;
 }
 
 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 (!inbounds(e, sizeof(u32)))
-                       return 0;
+                       goto fail;
                if (data)
                        *data = le32_to_cpu(get_unaligned((__le32 *) e->pos));
                e->pos += sizeof(u32);
                return 1;
        }
+
+fail:
+       e->pos = pos;
        return 0;
 }
 
 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 (!inbounds(e, sizeof(u64)))
-                       return 0;
+                       goto fail;
                if (data)
                        *data = le64_to_cpu(get_unaligned((__le64 *) e->pos));
                e->pos += sizeof(u64);
                return 1;
        }
+
+fail:
+       e->pos = pos;
        return 0;
 }
 
 static size_t unpack_array(struct aa_ext *e, const char *name)
 {
+       void *pos = e->pos;
+
        if (unpack_nameX(e, AA_ARRAY, name)) {
                int size;
                if (!inbounds(e, sizeof(u16)))
-                       return 0;
+                       goto fail;
                size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos));
                e->pos += sizeof(u16);
                return size;
        }
+
+fail:
+       e->pos = pos;
        return 0;
 }
 
 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)) {
                u32 size;
                if (!inbounds(e, sizeof(u32)))
-                       return 0;
+                       goto fail;
                size = le32_to_cpu(get_unaligned((__le32 *) e->pos));
                e->pos += sizeof(u32);
                if (inbounds(e, (size_t) size)) {
@@ -354,6 +381,9 @@ static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
                        return size;
                }
        }
+
+fail:
+       e->pos = pos;
        return 0;
 }
 
@@ -370,9 +400,10 @@ static int unpack_str(struct aa_ext *e, const char **string, const char *name)
                        if (src_str[size - 1] != 0)
                                goto fail;
                        *string = src_str;
+
+                       return size;
                }
        }
-       return size;
 
 fail:
        e->pos = pos;