mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-17 18:56:24 +00:00
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: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
074c1cd798
commit
031dcc8f4e
@ -40,6 +40,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define YYTH_MAGIC 0x1B5E783D
|
#define YYTH_MAGIC 0x1B5E783D
|
||||||
|
#define YYTH_FLAG_DIFF_ENCODE 1
|
||||||
|
|
||||||
struct table_set_header {
|
struct table_set_header {
|
||||||
u32 th_magic; /* YYTH_MAGIC */
|
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);
|
kref_put(&dfa->count, aa_dfa_free_kref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MATCH_FLAG_DIFF_ENCODE 0x80000000
|
||||||
|
#define MARK_DIFF_ENCODE 0x40000000
|
||||||
|
|
||||||
#endif /* __AA_MATCH_H */
|
#endif /* __AA_MATCH_H */
|
||||||
|
@ -185,7 +185,8 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
|
|||||||
|
|
||||||
if (flags & DFA_FLAG_VERIFY_STATES) {
|
if (flags & DFA_FLAG_VERIFY_STATES) {
|
||||||
for (i = 0; i < state_count; i++) {
|
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;
|
goto out;
|
||||||
if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
|
if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
|
||||||
printk(KERN_ERR "AppArmor DFA next/check upper "
|
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;
|
error = 0;
|
||||||
out:
|
out:
|
||||||
return error;
|
return error;
|
||||||
@ -274,6 +293,9 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
dfa->flags = ntohs(*(__be16 *) (data + 12));
|
dfa->flags = ntohs(*(__be16 *) (data + 12));
|
||||||
|
if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
data += hsize;
|
data += hsize;
|
||||||
size -= hsize;
|
size -= hsize;
|
||||||
|
|
||||||
@ -335,6 +357,8 @@ do { \
|
|||||||
unsigned int pos = base_idx(b) + (C); \
|
unsigned int pos = base_idx(b) + (C); \
|
||||||
if ((check)[pos] != (state)) { \
|
if ((check)[pos] != (state)) { \
|
||||||
(state) = (def)[(state)]; \
|
(state) = (def)[(state)]; \
|
||||||
|
if (b & MATCH_FLAG_DIFF_ENCODE) \
|
||||||
|
continue; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
(state) = (next)[pos]; \
|
(state) = (next)[pos]; \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user