diff --git a/parser/libapparmor_re/apparmor_re.h b/parser/libapparmor_re/apparmor_re.h index 07231157e..de59e41f6 100644 --- a/parser/libapparmor_re/apparmor_re.h +++ b/parser/libapparmor_re/apparmor_re.h @@ -15,6 +15,11 @@ extern "C" { #endif +typedef enum dfaflags { + DFA_DUMP_TREE = 1, + DFA_DUMP_SIMPLE_TREE = 2, +} dfaflags_t; + struct aare_ruleset; typedef struct aare_ruleset aare_ruleset_t; @@ -25,7 +30,8 @@ int aare_add_rule(aare_ruleset_t *rules, char *rule, int deny, uint32_t perms, uint32_t audit); int aare_add_rule_vec(aare_ruleset_t *rules, int deny, uint32_t perms, 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, int equiv_classes, size_t *size, + dfaflags_t flags); void aare_reset_matchflags(void); #ifdef __cplusplus diff --git a/parser/libapparmor_re/regexp.y b/parser/libapparmor_re/regexp.y index 5a5b9c80a..83ed5977a 100644 --- a/parser/libapparmor_re/regexp.y +++ b/parser/libapparmor_re/regexp.y @@ -2214,20 +2214,25 @@ extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, int deny, * else NULL on failure */ extern "C" void *aare_create_dfa(aare_ruleset_t *rules, int equiv_classes, - size_t *size) + size_t *size, dfaflags_t flags) { char *buffer = NULL; label_nodes(rules->root); -#ifdef DEBUG_TREE - cerr << "pre opt tree\n"; - rules->root->dump(cerr); -#endif + if (flags & DFA_DUMP_TREE) { + cerr << "\nDFA: Expression Tree\n"; + rules->root->dump(cerr); + cerr << "\n\n"; + } + rules->root = simplify_tree(rules->root); -#ifdef DEBUG_TREE - cerr << "post opt tree\n"; - rules->root->dump(cerr); -#endif + + if (flags & DFA_DUMP_SIMPLE_TREE) { + cerr << "\nDFA: Simplified Expression Tree\n"; + rules->root->dump(cerr); + cerr << "\n\n"; + } + DFA dfa(rules->root); map eq; diff --git a/parser/parser.h b/parser/parser.h index e2bb58715..a571f4c0a 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -168,6 +168,7 @@ struct var_string { #define FLAG_CHANGEHAT_1_5 3 extern int flag_changehat_version; extern int read_implies_exec; +extern dfaflags_t dfaflags; #ifdef DEBUG #define PDEBUG(fmt, args...) printf("parser: " fmt, ## args) diff --git a/parser/parser_main.c b/parser/parser_main.c index 59e7c622a..551f11449 100644 --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -38,6 +38,7 @@ #include "parser.h" #include "parser_version.h" #include "parser_include.h" +#include "libapparmor_re/apparmor_re.h" #define MODULE_NAME "apparmor" #define OLD_MODULE_NAME "subdomain" @@ -62,6 +63,7 @@ int binary_input = 0; int names_only = 0; int dump_vars = 0; int dump_expanded_vars = 0; +dfaflags_t dfaflags = 0; int conf_verbose = 0; int conf_quiet = 0; int kernel_load = 1; @@ -93,16 +95,13 @@ struct option long_options[] = { {"add", 0, 0, 'a'}, {"binary", 0, 0, 'B'}, {"base", 1, 0, 'b'}, - {"debug", 0, 0, 'd'}, {"subdomainfs", 0, 0, 'f'}, - {"help", 0, 0, 'h'}, + {"help", 2, 0, 'h'}, {"replace", 0, 0, 'r'}, {"reload", 0, 0, 'r'}, /* undocumented reload option == replace */ {"version", 0, 0, 'V'}, {"complain", 0, 0, 'C'}, {"Complain", 0, 0, 'C'}, /* Erk, apparently documented as --Complain */ - {"dump-variables", 0, 0, 'D'}, - {"dump-expanded-variables", 0, 0, 'E'}, {"Include", 1, 0, 'I'}, {"remove", 0, 0, 'R'}, {"names", 0, 0, 'N'}, @@ -117,6 +116,9 @@ struct option long_options[] = { {"skip-read-cache", 0, 0, 'T'}, {"write-cache", 0, 0, 'W'}, {"show-cache", 0, 0, 'k'}, + {"debug", 0, 0, 'd'}, + {"dump", 1, 0, 'D'}, + {"Dump", 1, 0, 'D'}, {NULL, 0, 0, 0}, }; @@ -156,7 +158,22 @@ static void display_usage(char *command) "-Q, --skip-kernel-load Do everything except loading into kernel\n" "-V, --version Display version info and exit\n" "-d, --debug Debug apparmor definitions\n" - "-h, --help Display this text and exit\n" + "-D [n], --dump Dump internal info for debugging\n" + "-h [command], --help Display this text or info about command\n" + ,command); +} + +static void display_dump(char *command) +{ + display_version(); + printf("\n%s: --dump [Option]\n\n" + "Options:\n" + "--------\n" + "no option specified Dump variables\n" + "variables Dump variables\n" + "expanded-variables Dump expanded variables\n" + "dfa-tree Dump expression tree\n" + "dfa-simple-tree Dump simplified expression tree\n" ,command); } @@ -189,7 +206,7 @@ static int process_args(int argc, char *argv[]) int count = 0; option = OPTION_ADD; - while ((c = getopt_long(argc, argv, "adf:hrRVvI:b:BCDENSm:qQn:XKTWk", long_options, &o)) != -1) + while ((c = getopt_long(argc, argv, "adf:h::rRVvI:b:BCD:NSm:qQn:XKTWk", long_options, &o)) != -1) { switch (c) { case 0: @@ -206,7 +223,15 @@ static int process_args(int argc, char *argv[]) skip_cache = 1; break; case 'h': - display_usage(progname); + if (!optarg) { + display_usage(progname); + } else if (strcmp(optarg, "dump") == 0) { + display_dump(progname); + } else { + PERROR("%s: Invalid --help option %s\n", + progname, optarg); + exit(1); + } exit(0); break; case 'r': @@ -246,12 +271,22 @@ static int process_args(int argc, char *argv[]) subdomainbase = strndup(optarg, PATH_MAX); break; case 'D': - dump_vars = 1; - skip_cache = 1; - break; - case 'E': - dump_expanded_vars = 1; skip_cache = 1; + if (!optarg) { + dump_vars = 1; + } else if (strcmp(optarg, "variables") == 0) { + dump_vars = 1; + } else if (strcmp(optarg, "expanded-variables") == 0) { + dump_expanded_vars = 1; + } else if (strcmp(optarg, "dfa-tree") == 0) { + dfaflags |= DFA_DUMP_TREE; + } else if (strcmp(optarg, "dfa-simple-tree") == 0) { + dfaflags |= DFA_DUMP_SIMPLE_TREE; + } else { + PERROR("%s: Invalid --Dump option %s\n", + progname, optarg); + exit(1); + } break; case 'm': match_string = strdup(optarg); diff --git a/parser/parser_regex.c b/parser/parser_regex.c index 7e0531e69..9f9708ae4 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -523,7 +523,8 @@ static int process_profile_name_xmatch(struct codomain *cod) aare_delete_ruleset(rule); return FALSE; } - cod->xmatch = aare_create_dfa(rule, 0, &cod->xmatch_size); + cod->xmatch = aare_create_dfa(rule, 0, &cod->xmatch_size, + dfaflags); aare_delete_ruleset(rule); if (!cod->xmatch) return FALSE; @@ -666,7 +667,8 @@ int process_regex(struct codomain *cod) goto out; 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, 0, &cod->dfa_size, + dfaflags); aare_delete_ruleset(cod->dfarules); cod->dfarules = NULL; if (!cod->dfa)