2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 18:17:09 +00:00

Add basic controls for dfa optimization

This commit is contained in:
John Johansen 2010-01-08 04:30:56 -08:00
parent 926b0c72e8
commit dce395e7ad
4 changed files with 73 additions and 17 deletions

View File

@ -12,6 +12,11 @@
#define APPARMOR_RE_H #define APPARMOR_RE_H
typedef enum dfaflags { typedef enum dfaflags {
DFA_CONTROL_EQUIV = 1 << 0,
DFA_CONTROL_NO_TREE_NORMAL = 1 << 1,
DFA_CONTROL_NO_TREE_SIMPLE = 1 << 2,
DFA_CONTROL_TREE_LEFT = 1 << 3,
DFA_DUMP_TREE_STATS = 1 << 8, DFA_DUMP_TREE_STATS = 1 << 8,
DFA_DUMP_TREE = 1 << 9, DFA_DUMP_TREE = 1 << 9,
DFA_DUMP_SIMPLE_TREE = 1 << 10, DFA_DUMP_SIMPLE_TREE = 1 << 10,
@ -40,8 +45,7 @@ int aare_add_rule(aare_ruleset_t *rules, char *rule, int deny,
uint32_t perms, uint32_t audit); uint32_t perms, uint32_t audit);
int aare_add_rule_vec(aare_ruleset_t *rules, int deny, uint32_t perms, int aare_add_rule_vec(aare_ruleset_t *rules, int deny, uint32_t perms,
uint32_t audit, int count, char **rulev); uint32_t audit, int count, char **rulev);
void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes, size_t *size, void *aare_create_dfa(aare_ruleset_t *rules, size_t *size, dfaflags_t flags);
dfaflags_t flags);
void aare_reset_matchflags(void); void aare_reset_matchflags(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -858,21 +858,29 @@ Node *simplify_tree(Node *t, dfaflags_t flags)
} }
do { do {
update = false; update = false;
//do right normalize first as this reduces the number //default to right normalize first as this reduces the number
//of trailing nodes which might follow an internal * //of trailing nodes which might follow an internal *
//or **, which is where state explosion can happen //or **, which is where state explosion can happen
//eg. in one test this makes the difference between //eg. in one test this makes the difference between
// the dfa having about 7 thousands states, // the dfa having about 7 thousands states,
// and it having about 1.25 million states // and it having about 1.25 million states
for (int dir = 1; dir >= 0 ; dir--) { int dir = 1;
if (flags & DFA_CONTROL_TREE_LEFT)
dir = 0;
for (int count = 0; count < 2; count++) {
bool modified; bool modified;
do { do {
modified = false; modified = false;
if (!(flags & DFA_CONTROL_NO_TREE_NORMAL))
normalize_tree(t, dir); normalize_tree(t, dir);
t = simplify_tree_base(t, dir, modified); t = simplify_tree_base(t, dir, modified);
if (modified) if (modified)
update = true; update = true;
} while (modified); } while (modified);
if (flags & DFA_CONTROL_TREE_LEFT)
dir++;
else
dir--;
} }
} while(update); } while(update);
if (flags & DFA_DUMP_TREE_STATS) { if (flags & DFA_DUMP_TREE_STATS) {
@ -2308,8 +2316,7 @@ extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, int deny,
* returns: buffer contain dfa tables, @size set to the size of the tables * returns: buffer contain dfa tables, @size set to the size of the tables
* else NULL on failure * else NULL on failure
*/ */
extern "C" void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes, extern "C" void *aare_create_dfa(aare_ruleset_t *rules, size_t *size, dfaflags_t flags)
size_t *size, dfaflags_t flags)
{ {
char *buffer = NULL; char *buffer = NULL;
@ -2320,6 +2327,7 @@ extern "C" void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes,
cerr << "\n\n"; cerr << "\n\n";
} }
if (!(flags & DFA_CONTROL_NO_TREE_SIMPLE)) {
rules->root = simplify_tree(rules->root, flags); rules->root = simplify_tree(rules->root, flags);
if (flags & DFA_DUMP_SIMPLE_TREE) { if (flags & DFA_DUMP_SIMPLE_TREE) {
@ -2327,6 +2335,7 @@ extern "C" void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes,
rules->root->dump(cerr); rules->root->dump(cerr);
cerr << "\n\n"; cerr << "\n\n";
} }
}
DFA dfa(rules->root, flags); DFA dfa(rules->root, flags);
@ -2337,13 +2346,14 @@ extern "C" void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes,
dfa.dump_dot_graph(cerr); dfa.dump_dot_graph(cerr);
map<uchar, uchar> eq; map<uchar, uchar> eq;
if (equiv_classes) { if (flags & DFA_CONTROL_EQUIV) {
eq = dfa.equivalence_classes(flags); eq = dfa.equivalence_classes(flags);
dfa.apply_equivalence_classes(eq); dfa.apply_equivalence_classes(eq);
if (flags & DFA_DUMP_EQUIV) if (flags & DFA_DUMP_EQUIV) {
cerr << "\nDFA equivalence class\n"; cerr << "\nDFA equivalence class\n";
dump_equivalence_classes(cerr, eq); dump_equivalence_classes(cerr, eq);
}
} else if (flags & DFA_DUMP_EQUIV) } else if (flags & DFA_DUMP_EQUIV)
cerr << "\nDFA did not generate an equivalence class\n"; cerr << "\nDFA did not generate an equivalence class\n";

View File

@ -159,6 +159,7 @@ static void display_usage(char *command)
"-V, --version Display version info and exit\n" "-V, --version Display version info and exit\n"
"-d, --debug Debug apparmor definitions\n" "-d, --debug Debug apparmor definitions\n"
"-D [n], --dump Dump internal info for debugging\n" "-D [n], --dump Dump internal info for debugging\n"
"-O [n], --Optimize Control dfa optimizations\n"
"-h [command], --help Display this text or info about command\n" "-h [command], --help Display this text or info about command\n"
,command); ,command);
} }
@ -187,6 +188,24 @@ static void display_dump(char *command)
,command); ,command);
} }
static void display_optimize(char *command)
{
display_version();
printf("\n%s: -O [Option]\n\n"
"Options:\n"
"--------\n"
"0 no optimizations\n"
"equiv use equivalent classes\n"
"no-equiv don't use equivalent classes\n"
"expr-normalize do expr normalization\n"
"expr-simplify do expr tree simplification\n"
"no-expr-normalize don't do expr normalization\n"
"no-expr-simplify don't do expr tree simplification\n"
"expr-left-simplify do left simplification first\n"
"expr-right-simplify do right simplification first\n"
,command);
}
void pwarn(char *fmt, ...) void pwarn(char *fmt, ...)
{ {
va_list arg; va_list arg;
@ -216,7 +235,7 @@ static int process_args(int argc, char *argv[])
int count = 0; int count = 0;
option = OPTION_ADD; option = OPTION_ADD;
while ((c = getopt_long(argc, argv, "adf:h::rRVvI:b:BCD:NSm:qQn:XKTWk", long_options, &o)) != -1) while ((c = getopt_long(argc, argv, "adf:h::rRVvI:b:BCD:NSm:qQn:XKTWkO:", long_options, &o)) != -1)
{ {
switch (c) { switch (c) {
case 0: case 0:
@ -319,6 +338,29 @@ static int process_args(int argc, char *argv[])
exit(1); exit(1);
} }
break; break;
case 'O':
skip_cache = 1;
if (strcmp(optarg, "0") == 0) {
dfaflags |= DFA_CONTROL_NO_TREE_NORMAL |
DFA_CONTROL_NO_TREE_SIMPLE;
} else if (strcmp(optarg, "equiv") == 0) {
dfaflags |= DFA_CONTROL_EQUIV;
} else if (strcmp(optarg, "no-equiv") == 0) {
dfaflags &= ~DFA_CONTROL_EQUIV;
} else if (strcmp(optarg, "expr-normalize") == 0) {
dfaflags &= ~DFA_CONTROL_NO_TREE_NORMAL;
} else if (strcmp(optarg, "no-expr-normalize") == 0) {
dfaflags |= DFA_CONTROL_NO_TREE_NORMAL;
} else if (strcmp(optarg, "expr-simplify") == 0) {
dfaflags &= ~DFA_CONTROL_NO_TREE_SIMPLE;
} else if (strcmp(optarg, "no-expr-simplify") == 0) {
dfaflags |= DFA_CONTROL_NO_TREE_SIMPLE;
} else if (strcmp(optarg, "expr-left-simplify") == 0) {
dfaflags |= DFA_CONTROL_TREE_LEFT;
} else if (strcmp(optarg, "expr-right-simplify") == 0) {
dfaflags &= ~DFA_CONTROL_TREE_LEFT;
}
break;
case 'm': case 'm':
match_string = strdup(optarg); match_string = strdup(optarg);
break; break;

View File

@ -523,7 +523,7 @@ static int process_profile_name_xmatch(struct codomain *cod)
aare_delete_ruleset(rule); aare_delete_ruleset(rule);
return FALSE; return FALSE;
} }
cod->xmatch = aare_create_dfa(rule, 0, &cod->xmatch_size, cod->xmatch = aare_create_dfa(rule, &cod->xmatch_size,
dfaflags); dfaflags);
aare_delete_ruleset(rule); aare_delete_ruleset(rule);
if (!cod->xmatch) if (!cod->xmatch)
@ -667,7 +667,7 @@ int process_regex(struct codomain *cod)
goto out; goto out;
if (regex_type == AARE_DFA && cod->dfarule_count > 0) { if (regex_type == AARE_DFA && cod->dfarule_count > 0) {
cod->dfa = aare_create_dfa(cod->dfarules, 0, &cod->dfa_size, cod->dfa = aare_create_dfa(cod->dfarules, &cod->dfa_size,
dfaflags); dfaflags);
aare_delete_ruleset(cod->dfarules); aare_delete_ruleset(cod->dfarules);
cod->dfarules = NULL; cod->dfarules = NULL;