mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-07-08 18:13:59 +02:00
apparmor: validate DFA start states are in bounds in unpack_pdb
commit9063d7e261upstream. Backport for conflicts caused byad596ea74e("apparmor: group dfa policydb unpacking") - rearrange and consolidated the unpack.b11e51dd70("apparmor: test: make static symbols visible during kunit testing") - rename function and make it visible to kunit tests Start states are read from untrusted data and used as indexes into the DFA state tables. The aa_dfa_next() function call in unpack_pdb() will access dfa->tables[YYTD_ID_BASE][start], and if the start state exceeds the number of states in the DFA, this results in an out-of-bound read. ================================================================== BUG: KASAN: slab-out-of-bounds in aa_dfa_next+0x2a1/0x360 Read of size 4 at addr ffff88811956fb90 by task su/1097 ... Reject policies with out-of-bounds start states during unpacking to prevent the issue. Fixes:ad5ff3db53("AppArmor: Add ability to load extended policy") Reported-by: Qualys Security Advisory <qsa@qualys.com> Tested-by: Salvatore Bonaccorso <carnil@debian.org> Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com> Reviewed-by: Cengiz Can <cengiz.can@canonical.com> Signed-off-by: Massimiliano Pellizzer <massimiliano.pellizzer@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
6495204f82
commit
f43eea8ae0
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user