Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 031dcc8f authored by John Johansen's avatar John Johansen
Browse files

apparmor: dfa add support for state differential encoding



State differential encoding can provide better compression for
apparmor policy, without having significant impact on match time.

Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent 074c1cd7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
 */

#define YYTH_MAGIC	0x1B5E783D
#define YYTH_FLAG_DIFF_ENCODE	1

struct table_set_header {
	u32 th_magic;		/* YYTH_MAGIC */
@@ -164,4 +165,7 @@ static inline void aa_put_dfa(struct aa_dfa *dfa)
		kref_put(&dfa->count, aa_dfa_free_kref);
}

#define MATCH_FLAG_DIFF_ENCODE 0x80000000
#define MARK_DIFF_ENCODE 0x40000000

#endif /* __AA_MATCH_H */
+25 −1
Original line number Diff line number Diff line
@@ -185,7 +185,8 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)

	if (flags & DFA_FLAG_VERIFY_STATES) {
		for (i = 0; i < state_count; i++) {
			if (DEFAULT_TABLE(dfa)[i] >= state_count)
			if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) &&
			    (DEFAULT_TABLE(dfa)[i] >= state_count))
				goto out;
			if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
				printk(KERN_ERR "AppArmor DFA next/check upper "
@@ -202,6 +203,24 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
		}
	}

	/* Now that all the other tables are verified, verify diffencoding */
	if (flags & DFA_FLAG_VERIFY_STATES) {
		size_t j, k;

		for (i = 0; i < state_count; i++) {
			for (j = i;
			     (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) &&
			      !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE);
			     j = k) {
				k = DEFAULT_TABLE(dfa)[j];
				if (j == k)
					goto out;
				if (k < j)
					break;		/* already verified */
				BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE;
			}
		}
	}
	error = 0;
out:
	return error;
@@ -274,6 +293,9 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
		goto fail;

	dfa->flags = ntohs(*(__be16 *) (data + 12));
	if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE)
		goto fail;

	data += hsize;
	size -= hsize;

@@ -335,6 +357,8 @@ do { \
	unsigned int pos = base_idx(b) + (C);		\
	if ((check)[pos] != (state)) {			\
		(state) = (def)[(state)];		\
		if (b & MATCH_FLAG_DIFF_ENCODE)		\
			continue;			\
		break;					\
	}						\
	(state) = (next)[pos];				\