diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 93fcafdaa548..e4f079a19388 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -841,9 +841,18 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) error = -EPROTO; goto fail; } - if (!unpack_u32(e, &profile->policy.start[0], "start")) + if (!unpack_u32(e, &profile->policy.start[0], "start")) { /* default start state */ profile->policy.start[0] = DFA_START; + } else { + size_t state_count = profile->policy.dfa->tables[YYTD_ID_BASE]->td_lolen; + + if (profile->policy.start[0] >= state_count) { + info = "invalid dfa start state"; + goto fail; + } + } + /* setup class index */ for (i = AA_CLASS_FILE; i <= AA_CLASS_LAST; i++) { profile->policy.start[i] = @@ -864,9 +873,17 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) info = "failed to unpack profile file rules"; goto fail; } else if (profile->file.dfa) { - if (!unpack_u32(e, &profile->file.start, "dfa_start")) + if (!unpack_u32(e, &profile->file.start, "dfa_start")) { /* default start state */ profile->file.start = DFA_START; + } else { + size_t state_count = profile->file.dfa->tables[YYTD_ID_BASE]->td_lolen; + + if (profile->file.start >= state_count) { + info = "invalid dfa start state"; + goto fail; + } + } } else if (profile->policy.dfa && profile->policy.start[AA_CLASS_FILE]) { profile->file.dfa = aa_get_dfa(profile->policy.dfa);