Loading security/apparmor/include/match.h +4 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ */ #define YYTH_MAGIC 0x1B5E783D #define YYTH_FLAG_DIFF_ENCODE 1 struct table_set_header { u32 th_magic; /* YYTH_MAGIC */ Loading Loading @@ -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 */ security/apparmor/match.c +25 −1 Original line number Diff line number Diff line Loading @@ -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 " Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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]; \ Loading Loading
security/apparmor/include/match.h +4 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ */ #define YYTH_MAGIC 0x1B5E783D #define YYTH_FLAG_DIFF_ENCODE 1 struct table_set_header { u32 th_magic; /* YYTH_MAGIC */ Loading Loading @@ -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 */
security/apparmor/match.c +25 −1 Original line number Diff line number Diff line Loading @@ -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 " Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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]; \ Loading