2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 14:25:52 +00:00

parser: cleanup and rework optimization and dump flag handling

In preparation for more flags (not all of the backend dfa based),
rework the optimization and dump flag handling which has been exclusively
around the dfa up to this point.

- split dfa control and dump flags into separate fields. This gives more
  room for new flags in the existing DFA set
- rename DFA_DUMP, and DFA_CONTROL to CONTROL_DFA and DUMP_DFA as
  this will provide more uniform naming for none dfa flags
- group dump and control flags into a structure so they can be passed
  together.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen
2023-07-06 16:41:56 -07:00
parent c5f2fcbb95
commit e84e481263
25 changed files with 303 additions and 258 deletions

View File

@@ -45,9 +45,9 @@ aare_rules::~aare_rules(void)
}
bool aare_rules::add_rule(const char *rule, int deny, uint32_t perms,
uint32_t audit, dfaflags_t flags)
uint32_t audit, optflags const &opts)
{
return add_rule_vec(deny, perms, audit, 1, &rule, flags, false);
return add_rule_vec(deny, perms, audit, 1, &rule, opts, false);
}
void aare_rules::add_to_rules(Node *tree, Node *perms)
@@ -72,7 +72,7 @@ static Node *cat_with_oob_separator(Node *l, Node *r)
}
bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit,
int count, const char **rulev, dfaflags_t flags,
int count, const char **rulev, optflags const &opts,
bool oob)
{
Node *tree = NULL, *accept;
@@ -110,7 +110,7 @@ bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit,
accept = unique_perms.insert(deny, perms, audit, exact_match);
if (flags & DFA_DUMP_RULE_EXPR) {
if (opts.dfadump & DUMP_DFA_RULE_EXPR) {
const char *separator;
if (oob)
separator = "\\-x01";
@@ -152,13 +152,13 @@ err:
* advanced by a null character for each xattr.
*/
bool aare_rules::append_rule(const char *rule, bool oob, bool with_perm,
dfaflags_t flags)
optflags const &opts)
{
Node *tree = NULL;
if (regex_parse(&tree, rule))
return false;
if (flags & DFA_DUMP_RULE_EXPR) {
if (opts.dfadump & DUMP_DFA_RULE_EXPR) {
cerr << "rule: ";
cerr << rule;
cerr << " -> ";
@@ -195,7 +195,7 @@ bool aare_rules::append_rule(const char *rule, bool oob, bool with_perm,
* else NULL on failure, @min_match_len set to the shortest string
* that can match the dfa for determining xmatch priority.
*/
void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
void *aare_rules::create_dfa(size_t *size, int *min_match_len, optflags const &opts,
bool filedfa)
{
char *buffer = NULL;
@@ -204,15 +204,15 @@ void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
* set nodes */
PermExprMap::iterator i = expr_map.begin();
if (i != expr_map.end()) {
if (flags & DFA_CONTROL_TREE_SIMPLE) {
Node *tmp = simplify_tree(i->second, flags);
if (opts.dfaflags & CONTROL_DFA_TREE_SIMPLE) {
Node *tmp = simplify_tree(i->second, opts);
root = new CatNode(tmp, i->first);
} else
root = new CatNode(i->second, i->first);
for (i++; i != expr_map.end(); i++) {
Node *tmp;
if (flags & DFA_CONTROL_TREE_SIMPLE) {
tmp = simplify_tree(i->second, flags);
if (opts.dfaflags & CONTROL_DFA_TREE_SIMPLE) {
tmp = simplify_tree(i->second, opts);
} else
tmp = i->second;
root = new AltNode(root, new CatNode(tmp, i->first));
@@ -226,22 +226,22 @@ void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
* this debug dump.
*/
label_nodes(root);
if (flags & DFA_DUMP_TREE) {
if (opts.dfadump & DUMP_DFA_TREE) {
cerr << "\nDFA: Expression Tree\n";
root->dump(cerr);
cerr << "\n\n";
}
if (flags & DFA_CONTROL_TREE_SIMPLE) {
if (opts.dfaflags & CONTROL_DFA_TREE_SIMPLE) {
/* This is old total tree, simplification point
* For now just do simplification up front. It gets most
* of the benefit running on the smaller chains, and is
* overall faster because there are less nodes. Reevaluate
* once tree simplification is rewritten
*/
//root = simplify_tree(root, flags);
//root = simplify_tree(root, opts);
if (flags & DFA_DUMP_SIMPLE_TREE) {
if (opts.dfadump & DUMP_DFA_SIMPLE_TREE) {
cerr << "\nDFA: Simplified Expression Tree\n";
root->dump(cerr);
cerr << "\n\n";
@@ -250,19 +250,19 @@ void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
stringstream stream;
try {
DFA dfa(root, flags, filedfa);
if (flags & DFA_DUMP_UNIQ_PERMS)
DFA dfa(root, opts, filedfa);
if (opts.dfadump & DUMP_DFA_UNIQ_PERMS)
dfa.dump_uniq_perms("dfa");
if (flags & DFA_CONTROL_MINIMIZE) {
dfa.minimize(flags);
if (opts.dfaflags & CONTROL_DFA_MINIMIZE) {
dfa.minimize(opts);
if (flags & DFA_DUMP_MIN_UNIQ_PERMS)
if (opts.dfadump & DUMP_DFA_MIN_UNIQ_PERMS)
dfa.dump_uniq_perms("minimized dfa");
}
if (flags & DFA_CONTROL_FILTER_DENY &&
flags & DFA_CONTROL_MINIMIZE &&
if (opts.dfaflags & CONTROL_DFA_FILTER_DENY &&
opts.dfaflags & CONTROL_DFA_MINIMIZE &&
dfa.apply_and_clear_deny()) {
/* Do a second minimization pass as removal of deny
* information has moved some states from accepting
@@ -271,42 +271,42 @@ void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
* TODO: add this as a tail pass to minimization
* so we don't need to do a full second pass
*/
dfa.minimize(flags);
dfa.minimize(opts);
if (flags & DFA_DUMP_MIN_UNIQ_PERMS)
if (opts.dfadump & DUMP_DFA_MIN_UNIQ_PERMS)
dfa.dump_uniq_perms("minimized dfa");
}
if (flags & DFA_CONTROL_REMOVE_UNREACHABLE)
dfa.remove_unreachable(flags);
if (opts.dfaflags & CONTROL_DFA_REMOVE_UNREACHABLE)
dfa.remove_unreachable(opts);
if (flags & DFA_DUMP_STATES)
if (opts.dfadump & DUMP_DFA_STATES)
dfa.dump(cerr);
if (flags & DFA_DUMP_GRAPH)
if (opts.dfadump & DUMP_DFA_GRAPH)
dfa.dump_dot_graph(cerr);
map<transchar, transchar> eq;
if (flags & DFA_CONTROL_EQUIV) {
eq = dfa.equivalence_classes(flags);
if (opts.dfaflags & CONTROL_DFA_EQUIV) {
eq = dfa.equivalence_classes(opts);
dfa.apply_equivalence_classes(eq);
if (flags & DFA_DUMP_EQUIV) {
if (opts.dfadump & DUMP_DFA_EQUIV) {
cerr << "\nDFA equivalence class\n";
dump_equivalence_classes(cerr, eq);
}
} else if (flags & DFA_DUMP_EQUIV)
} else if (opts.dfadump & DUMP_DFA_EQUIV)
cerr << "\nDFA did not generate an equivalence class\n";
if (flags & DFA_CONTROL_DIFF_ENCODE) {
dfa.diff_encode(flags);
if (opts.dfaflags & CONTROL_DFA_DIFF_ENCODE) {
dfa.diff_encode(opts);
if (flags & DFA_DUMP_DIFF_ENCODE)
if (opts.dfadump & DUMP_DFA_DIFF_ENCODE)
dfa.dump_diff_encode(cerr);
}
CHFA chfa(dfa, eq, flags);
if (flags & DFA_DUMP_TRANS_TABLE)
CHFA chfa(dfa, eq, opts);
if (opts.dfadump & DUMP_DFA_TRANS_TABLE)
chfa.dump(cerr);
chfa.flex_table(stream, "");
}