aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor/match.c
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-08-08 12:10:50 -0700
committerJohn Johansen <john.johansen@canonical.com>2018-02-09 11:30:01 -0800
commit031dcc8f4e84fea37dc6f78fdc7288aa7f8386c3 (patch)
tree5631c0d1cd8a4be2b6baf3a6bf786a403655c43f /security/apparmor/match.c
parentapparmor: dfa move character match into a macro (diff)
downloadlinux-dev-031dcc8f4e84fea37dc6f78fdc7288aa7f8386c3.tar.xz
linux-dev-031dcc8f4e84fea37dc6f78fdc7288aa7f8386c3.zip
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>
Diffstat (limited to 'security/apparmor/match.c')
-rw-r--r--security/apparmor/match.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index aeac68c58689..70cdcb3c3b25 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -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]; \