diff --git a/parser/common_optarg.c b/parser/common_optarg.c index 5ddd25da2..a9dc13fdb 100644 --- a/parser/common_optarg.c +++ b/parser/common_optarg.c @@ -44,6 +44,7 @@ optflag_table_t dumpflag_table[] = { DUMP_DFA_PROGRESS | DUMP_DFA_STATS }, { 1, "dfa-stats", "Dump dfa creation stats", DUMP_DFA_STATS }, { 1, "dfa-states", "Dump final dfa state information", DUMP_DFA_STATES }, + { 1, "dfa-compressed-states", "Dump compressed dfa state information", DUMP_DFA_COMPTRESSED_STATES }, { 1, "dfa-states-initial", "Dump dfa state immediately after initial build", DUMP_DFA_STATES_INIT }, { 1, "dfa-states-post-filter", "Dump dfa state immediately after filtering deny", DUMP_DFA_STATES_POST_FILTER }, { 1, "dfa-states-post-minimize", "Dump dfa state immediately after initial build", DUMP_DFA_STATES_POST_MINIMIZE }, diff --git a/parser/libapparmor_re/aare_rules.cc b/parser/libapparmor_re/aare_rules.cc index f6ce6832e..d5546dde4 100644 --- a/parser/libapparmor_re/aare_rules.cc +++ b/parser/libapparmor_re/aare_rules.cc @@ -259,7 +259,7 @@ CHFA *aare_rules::create_chfa(int *min_match_len, dfa.dump_uniq_perms("dfa"); if (opts.dump & DUMP_DFA_STATES_INIT) - dfa.dump(cerr); + dfa.dump(cerr, NULL); /* since we are building a chfa, use the info about * whether the chfa supports extended perms to help @@ -271,23 +271,23 @@ CHFA *aare_rules::create_chfa(int *min_match_len, ((opts.control & CONTROL_DFA_FILTER_DENY))) { dfa.apply_and_clear_deny(); if (opts.dump & DUMP_DFA_STATES_POST_FILTER) - dfa.dump(cerr); + dfa.dump(cerr, NULL); } if (opts.control & CONTROL_DFA_MINIMIZE) { dfa.minimize(opts); if (opts.dump & DUMP_DFA_MIN_UNIQ_PERMS) dfa.dump_uniq_perms("minimized dfa"); if (opts.dump & DUMP_DFA_STATES_POST_MINIMIZE) - dfa.dump(cerr); + dfa.dump(cerr, NULL); } if (opts.control & CONTROL_DFA_REMOVE_UNREACHABLE) { dfa.remove_unreachable(opts); if (opts.dump & DUMP_DFA_STATES_POST_UNREACHABLE) - dfa.dump(cerr); + dfa.dump(cerr, NULL); } if (opts.dump & DUMP_DFA_STATES) - dfa.dump(cerr); + dfa.dump(cerr, NULL); if (opts.dump & DUMP_DFA_GRAPH) dfa.dump_dot_graph(cerr); @@ -331,6 +331,8 @@ CHFA *aare_rules::create_chfa(int *min_match_len, chfa = new CHFA(dfa, eq, opts, extended_perms, prompt); if (opts.dump & DUMP_DFA_TRANS_TABLE) chfa->dump(cerr); + if (opts.dump & DUMP_DFA_COMPTRESSED_STATES) + dfa.dump(cerr, &chfa->num); } catch(int error) { return NULL; diff --git a/parser/libapparmor_re/apparmor_re.h b/parser/libapparmor_re/apparmor_re.h index 843400c48..edd29aafe 100644 --- a/parser/libapparmor_re/apparmor_re.h +++ b/parser/libapparmor_re/apparmor_re.h @@ -64,5 +64,6 @@ #define DUMP_DFA_STATES_POST_FILTER (1 << 26) #define DUMP_DFA_STATES_POST_MINIMIZE (1 << 27) #define DUMP_DFA_STATES_POST_UNREACHABLE (1 << 28) +#define DUMP_DFA_COMPTRESSED_STATES (1 << 29) #endif /* APPARMOR_RE_H */ diff --git a/parser/libapparmor_re/chfa.h b/parser/libapparmor_re/chfa.h index fe621bd9f..cc36e8580 100644 --- a/parser/libapparmor_re/chfa.h +++ b/parser/libapparmor_re/chfa.h @@ -63,7 +63,7 @@ class CHFA { DefaultBase default_base; NextCheck next_check; const State *start; - map num; + Renumber_Map num; map eq; unsigned int chfaflags; private: diff --git a/parser/libapparmor_re/hfa.cc b/parser/libapparmor_re/hfa.cc index 93d4d3480..2a89ab9ad 100644 --- a/parser/libapparmor_re/hfa.cc +++ b/parser/libapparmor_re/hfa.cc @@ -83,6 +83,21 @@ ostream &operator<<(ostream &os, State &state) return os; } +ostream &operator<<(ostream &os, + const std::pair &p) +{ + /* dump the state label */ + if (p.second && (*p.second)[p.first] != (size_t) p.first->label) { + os << '{'; + os << (*p.second)[p.first]; + os << " == " << *(p.first); + os << '}'; + } else { + os << *(p.first); + } + return os; +} + /** * diff_weight - Find differential compression distance between @rel and @this * @rel: State to compare too @@ -1082,11 +1097,11 @@ void DFA::dump_diff_encode(ostream &os) /** * text-dump the DFA (for debugging). */ -void DFA::dump(ostream & os) +void DFA::dump(ostream &os, Renumber_Map *renum) { for (Partition::iterator i = states.begin(); i != states.end(); i++) { if (*i == start || (*i)->perms.is_accept()) { - os << **i; + os << make_pair(*i, renum); if (*i == start) { os << " <== "; (*i)->perms.dump_header(os); @@ -1109,7 +1124,7 @@ void DFA::dump(ostream & os) } else { if (first) { first = false; - os << **i << " perms: "; + os << make_pair(*i, renum) << " perms: "; if ((*i)->perms.is_accept()) (*i)->perms.dump(os); else @@ -1117,7 +1132,7 @@ void DFA::dump(ostream & os) os << "\n"; } os << " "; j->first.dump(os) << " -> " << - *(j)->second; + make_pair(j->second, renum); if ((j)->second->perms.is_accept()) os << " ", (j->second)->perms.dump(os); os << "\n"; @@ -1127,7 +1142,7 @@ void DFA::dump(ostream & os) if ((*i)->otherwise != nonmatching) { if (first) { first = false; - os << **i << " perms: "; + os << make_pair(*i, renum) << " perms: "; if ((*i)->perms.is_accept()) (*i)->perms.dump(os); else @@ -1142,7 +1157,7 @@ void DFA::dump(ostream & os) os << *k; } } - os << "] -> " << *(*i)->otherwise; + os << "] -> " << make_pair((*i)->otherwise, renum); if ((*i)->otherwise->perms.is_accept()) os << " ", (*i)->otherwise->perms.dump(os); os << "\n"; diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h index ba0edeabf..79cc0ede1 100644 --- a/parser/libapparmor_re/hfa.h +++ b/parser/libapparmor_re/hfa.h @@ -349,6 +349,8 @@ public: } }; +typedef map Renumber_Map; + /* Transitions in the DFA. */ class DFA { void dump_node_to_dfa(void); @@ -385,7 +387,7 @@ public: void undiff_encode(void); void dump_diff_encode(ostream &os); - void dump(ostream &os); + void dump(ostream &os, Renumber_Map *renum); void dump_dot_graph(ostream &os); void dump_uniq_perms(const char *s);