Commit 9063d7e2 authored by Massimiliano Pellizzer's avatar Massimiliano Pellizzer Committed by John Johansen
Browse files

apparmor: validate DFA start states are in bounds in unpack_pdb



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: ad5ff3db ("AppArmor: Add ability to load extended policy")
Reported-by: default avatarQualys Security Advisory <qsa@qualys.com>
Tested-by: default avatarSalvatore Bonaccorso <carnil@debian.org>
Reviewed-by: default avatarGeorgia Garcia <georgia.garcia@canonical.com>
Reviewed-by: default avatarCengiz Can <cengiz.can@canonical.com>
Signed-off-by: default avatarMassimiliano Pellizzer <massimiliano.pellizzer@canonical.com>
Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent 1f318b96
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -1010,7 +1010,17 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy,
		if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) {
			/* default start state for xmatch and file dfa */
			pdb->start[AA_CLASS_FILE] = DFA_START;
		}	/* setup class index */
		}

		size_t state_count = pdb->dfa->tables[YYTD_ID_BASE]->td_lolen;

		if (pdb->start[0] >= state_count ||
		    pdb->start[AA_CLASS_FILE] >= state_count) {
			*info = "invalid dfa start state";
			goto fail;
		}

		/* setup class index */
		for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
			pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0],
						    i);