apparmor: access to uninitialized variable size may cause loop bounds overflow

Bug #2073852 reported by Colin Ian King
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
linux (Ubuntu)
New
High
John Johansen

Bug Description

Function unpack_secmark on a failed aa_unpack_array call may not set variable size and so the fail path is executing a loop using an undefined bounds on size.

VISIBLE_IF_KUNIT bool aa_unpack_array(struct aa_ext *e, const char *name, u16 *size)
{
        void *pos = e->pos;

        if (aa_unpack_nameX(e, AA_ARRAY, name)) {
                if (!aa_inbounds(e, sizeof(u16)))
                        goto fail;
                ^^ *size not set

                *size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
                e->pos += sizeof(u16);
                return true;
        }

fail:
        e->pos = pos;
        return false;
}

....

static bool unpack_secmark(struct aa_ext *e, struct aa_ruleset *rules)
{
        void *pos = e->pos;
        u16 size;
        int i;

        if (aa_unpack_nameX(e, AA_STRUCT, "secmark")) {
                if (!aa_unpack_array(e, NULL, &size))
                        goto fail;

                ^^^ size is not set

                rules->secmark = kcalloc(size, sizeof(struct aa_secmark),
                                           GFP_KERNEL);
                if (!rules->secmark)
                        goto fail;

                rules->secmark_count = size;

                for (i = 0; i < size; i++) {
                        if (!unpack_u8(e, &rules->secmark[i].audit, NULL))
                                goto fail;
                        if (!unpack_u8(e, &rules->secmark[i].deny, NULL))
                                goto fail;
                        if (!aa_unpack_strdup(e, &rules->secmark[i].label, NULL))
                                goto fail;
                }
                if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
                        goto fail;
                if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
                        goto fail;
        }

        return true;

fail:
        if (rules->secmark) {
                for (i = 0; i < size; i++)
                        kfree(rules->secmark[i].label);

                ^^ for-loop on unbounded size

                kfree(rules->secmark);
                rules->secmark_count = 0;
                rules->secmark = NULL;
        }

        e->pos = pos;
        return false;
}

Changed in linux (Ubuntu):
importance: Undecided → High
assignee: nobody → John Johansen (jjohansen)
summary: - apparmor: access to uniniatliaed variable size may cause loop bounds
+ apparmor: access to uninitialized variable size may cause loop bounds
overflow
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.