apparmor: validate default DFA states are in bounds

Some backports of commit 9063d7e2615f ("apparmor: validate DFA start
states are in bounds in unpack_pdb") limited the bounds checks on DFA
start states to the case where the start state was explicit in the
policy.  However, the default DFA start state (DFA_START = 1) could
also be out-of-bounds.

Move these checks out of the else-branches so that they are applied
regardless of how the start state was initialised.

Fixes: f43eea8ae010 ("apparmor: validate DFA start states are in bounds in unpack_pdb")
Signed-off-by: Ben Hutchings <benh@debian.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ulrich Hecht <uli@kernel.org>
This commit is contained in:
Ben Hutchings
2026-05-28 17:15:26 +02:00
committed by Ulrich Hecht
parent 17cb2b5a83
commit 147fa180c9

View File

@ -758,6 +758,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
}
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
size_t state_count;
/* generic policy dfa - optional and may be NULL */
info = "failed to unpack policydb";
profile->policy.dfa = unpack_dfa(e);
@ -772,13 +774,12 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
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;
}
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 */
@ -801,16 +802,18 @@ 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) {
size_t state_count;
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;
}
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]) {