mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-01 14:55:10 +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:
@@ -106,7 +106,8 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \
|
||||
STATIC_HDRS = af_rule.h af_unix.h capability.h common_optarg.h dbus.h \
|
||||
file_cache.h immunix.h lib.h mount.h network.h parser.h \
|
||||
parser_include.h parser_version.h policy_cache.h policydb.h \
|
||||
profile.h ptrace.h rule.h signal.h userns.h mqueue.h io_uring.h
|
||||
profile.h ptrace.h rule.h signal.h userns.h mqueue.h io_uring.h \
|
||||
common_flags.h
|
||||
|
||||
SPECIAL_HDRS = parser_yacc.h unit_test.h base_cap_names.h
|
||||
GENERATED_HDRS = af_names.h generated_af_names.h \
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "common_optarg.h"
|
||||
#include "network.h"
|
||||
#include "parser.h"
|
||||
#include "profile.h"
|
||||
@@ -203,7 +204,7 @@ void unix_rule::downgrade_rule(Profile &prof) {
|
||||
* restrictive and may end up denying accesses that might be
|
||||
* allowed by the profile.
|
||||
*/
|
||||
if (warnflags & WARN_RULE_NOT_ENFORCED)
|
||||
if (parseopts.warn & WARN_RULE_NOT_ENFORCED)
|
||||
rule_t::warn_once(prof.name, "deny unix socket rule not enforced, can't be downgraded to generic network rule\n");
|
||||
}
|
||||
}
|
||||
@@ -321,7 +322,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
if (features_supports_network || features_supports_networkv8) {
|
||||
/* only warn if we are building against a kernel
|
||||
* that requires downgrading */
|
||||
if (warnflags & WARN_RULE_DOWNGRADED)
|
||||
if (parseopts.warn & WARN_RULE_DOWNGRADED)
|
||||
rule_t::warn_once(prof.name, "downgrading extended network unix socket rule to generic network rule\n");
|
||||
/* TODO: add ability to abort instead of downgrade */
|
||||
return RULE_OK;
|
||||
@@ -337,7 +338,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||
map_perms(AA_NET_CREATE),
|
||||
map_perms(audit == AUDIT_FORCE ? AA_NET_CREATE : 0),
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
mask &= ~AA_NET_CREATE;
|
||||
}
|
||||
@@ -362,7 +363,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||
map_perms(AA_NET_BIND),
|
||||
map_perms(audit == AUDIT_FORCE ? AA_NET_BIND : 0),
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
/* clear if auto, else generic need to generate addr below */
|
||||
if (addr)
|
||||
@@ -387,7 +388,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||
map_perms(mask & local_mask),
|
||||
map_perms(audit == AUDIT_FORCE ? mask & local_mask : 0),
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -401,7 +402,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||
map_perms(AA_NET_LISTEN),
|
||||
map_perms(audit == AUDIT_FORCE ? AA_NET_LISTEN : 0),
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
}
|
||||
if ((mask & AA_NET_OPT) && !has_peer_conds()) {
|
||||
@@ -414,7 +415,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||
map_perms(AA_NET_OPT),
|
||||
map_perms(audit == AUDIT_FORCE ? AA_NET_OPT : 0),
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
}
|
||||
mask &= ~AA_LOCAL_NET_PERMS | AA_NET_ACCEPT;
|
||||
@@ -432,7 +433,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
goto fail;
|
||||
|
||||
buf = buffer.str();
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), dfaflags))
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), parseopts))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
31
parser/common_flags.h
Normal file
31
parser/common_flags.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2023
|
||||
* Canonical Ltd. (All rights reserved)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public
|
||||
* License published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc. or Canonical
|
||||
* Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __AA_COMMON_FLAGS_H
|
||||
#define __AA_COMMON_FLAGS_H
|
||||
|
||||
typedef int optflags_t;
|
||||
|
||||
typedef struct optflags {
|
||||
optflags_t dfaflags;
|
||||
optflags_t dfadump;
|
||||
optflags_t warn;
|
||||
optflags_t Werror;
|
||||
} optflags;
|
||||
|
||||
#endif /* __AA_COMMON_FLAGS_H */
|
@@ -27,82 +27,90 @@
|
||||
#include "common_optarg.h"
|
||||
#include "parser.h"
|
||||
|
||||
optflag_table_t dumpflag_table[] = {
|
||||
optflag_table_t dfadumpflag_table[] = {
|
||||
{ 1, "rule-exprs", "Dump rule to expr tree conversions",
|
||||
DFA_DUMP_RULE_EXPR },
|
||||
{ 1, "expr-stats", "Dump stats on expr tree", DFA_DUMP_TREE_STATS },
|
||||
{ 1, "expr-tree", "Dump expression tree", DFA_DUMP_TREE },
|
||||
DUMP_DFA_RULE_EXPR },
|
||||
{ 1, "expr-stats", "Dump stats on expr tree", DUMP_DFA_TREE_STATS },
|
||||
{ 1, "expr-tree", "Dump expression tree", DUMP_DFA_TREE },
|
||||
{ 1, "expr-simplified", "Dump simplified expression tree",
|
||||
DFA_DUMP_SIMPLE_TREE },
|
||||
DUMP_DFA_SIMPLE_TREE },
|
||||
{ 1, "stats", "Dump all compile stats",
|
||||
DFA_DUMP_TREE_STATS | DFA_DUMP_STATS | DFA_DUMP_TRANS_STATS |
|
||||
DFA_DUMP_EQUIV_STATS | DFA_DUMP_DIFF_STATS },
|
||||
DUMP_DFA_TREE_STATS | DUMP_DFA_STATS | DUMP_DFA_TRANS_STATS |
|
||||
DUMP_DFA_EQUIV_STATS | DUMP_DFA_DIFF_STATS },
|
||||
{ 1, "progress", "Dump progress for all compile phases",
|
||||
DFA_DUMP_PROGRESS | DFA_DUMP_STATS | DFA_DUMP_TRANS_PROGRESS |
|
||||
DFA_DUMP_TRANS_STATS | DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS },
|
||||
DUMP_DFA_PROGRESS | DUMP_DFA_STATS | DUMP_DFA_TRANS_PROGRESS |
|
||||
DUMP_DFA_TRANS_STATS | DUMP_DFA_DIFF_PROGRESS | DUMP_DFA_DIFF_STATS },
|
||||
{ 1, "dfa-progress", "Dump dfa creation as in progress",
|
||||
DFA_DUMP_PROGRESS | DFA_DUMP_STATS },
|
||||
{ 1, "dfa-stats", "Dump dfa creation stats", DFA_DUMP_STATS },
|
||||
{ 1, "dfa-states", "Dump dfa state diagram", DFA_DUMP_STATES },
|
||||
{ 1, "dfa-graph", "Dump dfa dot (graphviz) graph", DFA_DUMP_GRAPH },
|
||||
{ 1, "dfa-minimize", "Dump dfa minimization", DFA_DUMP_MINIMIZE },
|
||||
DUMP_DFA_PROGRESS | DUMP_DFA_STATS },
|
||||
{ 1, "dfa-stats", "Dump dfa creation stats", DUMP_DFA_STATS },
|
||||
{ 1, "dfa-states", "Dump dfa state diagram", DUMP_DFA_STATES },
|
||||
{ 1, "dfa-graph", "Dump dfa dot (graphviz) graph", DUMP_DFA_GRAPH },
|
||||
{ 1, "dfa-minimize", "Dump dfa minimization", DUMP_DFA_MINIMIZE },
|
||||
{ 1, "dfa-unreachable", "Dump dfa unreachable states",
|
||||
DFA_DUMP_UNREACHABLE },
|
||||
DUMP_DFA_UNREACHABLE },
|
||||
{ 1, "dfa-node-map", "Dump expr node set to state mapping",
|
||||
DFA_DUMP_NODE_TO_DFA },
|
||||
DUMP_DFA_NODE_TO_DFA },
|
||||
{ 1, "dfa-uniq-perms", "Dump unique perms",
|
||||
DFA_DUMP_UNIQ_PERMS },
|
||||
DUMP_DFA_UNIQ_PERMS },
|
||||
{ 1, "dfa-minimize-uniq-perms", "Dump unique perms post minimization",
|
||||
DFA_DUMP_MIN_UNIQ_PERMS },
|
||||
DUMP_DFA_MIN_UNIQ_PERMS },
|
||||
{ 1, "dfa-minimize-partitions", "Dump dfa minimization partitions",
|
||||
DFA_DUMP_MIN_PARTS },
|
||||
DUMP_DFA_MIN_PARTS },
|
||||
{ 1, "compress-progress", "Dump progress of compression",
|
||||
DFA_DUMP_TRANS_PROGRESS | DFA_DUMP_TRANS_STATS },
|
||||
DUMP_DFA_TRANS_PROGRESS | DUMP_DFA_TRANS_STATS },
|
||||
{ 1, "compress-stats", "Dump stats on compression",
|
||||
DFA_DUMP_TRANS_STATS },
|
||||
{ 1, "compressed-dfa", "Dump compressed dfa", DFA_DUMP_TRANS_TABLE },
|
||||
DUMP_DFA_TRANS_STATS },
|
||||
{ 1, "compressed-dfa", "Dump compressed dfa", DUMP_DFA_TRANS_TABLE },
|
||||
{ 1, "equiv-stats", "Dump equivalence class stats",
|
||||
DFA_DUMP_EQUIV_STATS },
|
||||
{ 1, "equiv", "Dump equivalence class", DFA_DUMP_EQUIV },
|
||||
DUMP_DFA_EQUIV_STATS },
|
||||
{ 1, "equiv", "Dump equivalence class", DUMP_DFA_EQUIV },
|
||||
{ 1, "diff-encode", "Dump differential encoding",
|
||||
DFA_DUMP_DIFF_ENCODE },
|
||||
DUMP_DFA_DIFF_ENCODE },
|
||||
{ 1, "diff-stats", "Dump differential encoding stats",
|
||||
DFA_DUMP_DIFF_STATS },
|
||||
DUMP_DFA_DIFF_STATS },
|
||||
{ 1, "diff-progress", "Dump progress of differential encoding",
|
||||
DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS },
|
||||
DUMP_DFA_DIFF_PROGRESS | DUMP_DFA_DIFF_STATS },
|
||||
{ 0, NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
optflag_table_t optflag_table[] = {
|
||||
optflag_table_t dfaoptflag_table[] = {
|
||||
{ 2, "0", "no optimizations",
|
||||
DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE |
|
||||
DFA_CONTROL_MINIMIZE | DFA_CONTROL_REMOVE_UNREACHABLE |
|
||||
DFA_CONTROL_DIFF_ENCODE
|
||||
CONTROL_DFA_TREE_NORMAL | CONTROL_DFA_TREE_SIMPLE |
|
||||
CONTROL_DFA_MINIMIZE | CONTROL_DFA_REMOVE_UNREACHABLE |
|
||||
CONTROL_DFA_DIFF_ENCODE
|
||||
},
|
||||
{ 1, "equiv", "use equivalent classes", DFA_CONTROL_EQUIV },
|
||||
{ 1, "equiv", "use equivalent classes", CONTROL_DFA_EQUIV },
|
||||
{ 1, "expr-normalize", "expression tree normalization",
|
||||
DFA_CONTROL_TREE_NORMAL },
|
||||
CONTROL_DFA_TREE_NORMAL },
|
||||
{ 1, "expr-simplify", "expression tree simplification",
|
||||
DFA_CONTROL_TREE_SIMPLE },
|
||||
CONTROL_DFA_TREE_SIMPLE },
|
||||
{ 0, "expr-left-simplify", "left simplification first",
|
||||
DFA_CONTROL_TREE_LEFT },
|
||||
CONTROL_DFA_TREE_LEFT },
|
||||
{ 2, "expr-right-simplify", "right simplification first",
|
||||
DFA_CONTROL_TREE_LEFT },
|
||||
{ 1, "minimize", "dfa state minimization", DFA_CONTROL_MINIMIZE },
|
||||
CONTROL_DFA_TREE_LEFT },
|
||||
{ 1, "minimize", "dfa state minimization", CONTROL_DFA_MINIMIZE },
|
||||
{ 1, "filter-deny", "filter out deny information from final dfa",
|
||||
DFA_CONTROL_FILTER_DENY },
|
||||
CONTROL_DFA_FILTER_DENY },
|
||||
{ 1, "remove-unreachable", "dfa unreachable state removal",
|
||||
DFA_CONTROL_REMOVE_UNREACHABLE },
|
||||
CONTROL_DFA_REMOVE_UNREACHABLE },
|
||||
{ 0, "compress-small",
|
||||
"do slower dfa transition table compression",
|
||||
DFA_CONTROL_TRANS_HIGH },
|
||||
CONTROL_DFA_TRANS_HIGH },
|
||||
{ 2, "compress-fast", "do faster dfa transition table compression",
|
||||
DFA_CONTROL_TRANS_HIGH },
|
||||
CONTROL_DFA_TRANS_HIGH },
|
||||
{ 1, "diff-encode", "Differentially encode transitions",
|
||||
DFA_CONTROL_DIFF_ENCODE },
|
||||
CONTROL_DFA_DIFF_ENCODE },
|
||||
{ 0, NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
optflags parseopts = {
|
||||
.dfaflags = (optflags_t)(CONTROL_DFA_TREE_NORMAL | CONTROL_DFA_TREE_SIMPLE | CONTROL_DFA_MINIMIZE | CONTROL_DFA_DIFF_ENCODE),
|
||||
.dfadump = 0,
|
||||
.warn = DEFAULT_WARNINGS,
|
||||
.Werror = 0
|
||||
};
|
||||
|
||||
|
||||
void print_flag_table(optflag_table_t *table)
|
||||
{
|
||||
int i;
|
||||
@@ -114,12 +122,14 @@ void print_flag_table(optflag_table_t *table)
|
||||
|
||||
printf("%-*s \t%s\n", longest, " show", "show flags that have been set and exit");
|
||||
for (i = 0; table[i].option; i++) {
|
||||
printf("%5s%-*s \t%s\n", (table[i].control & 1) ? "[no-]" : "",
|
||||
printf("%5s%-*s \t%s\n",
|
||||
(table[i].control & OPT_FLAG_CONTROL_PREFIX_NO) ? "[no-]" : "",
|
||||
longest, table[i].option, table[i].desc);
|
||||
}
|
||||
}
|
||||
|
||||
void print_flags(const char *prefix, optflag_table_t *table, dfaflags_t flags)
|
||||
void print_flags(const char *prefix, optflag_table_t *table,
|
||||
optflags_t flags)
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
@@ -137,7 +147,7 @@ void print_flags(const char *prefix, optflag_table_t *table, dfaflags_t flags)
|
||||
}
|
||||
|
||||
int handle_flag_table(optflag_table_t *table, const char *optarg,
|
||||
dfaflags_t *flags)
|
||||
optflags_t *flags)
|
||||
{
|
||||
const char *arg = optarg;
|
||||
int i, invert = 0;
|
||||
|
@@ -21,25 +21,33 @@
|
||||
#ifndef __AA_COMMON_OPTARG_H
|
||||
#define __AA_COMMON_OPTARG_H
|
||||
|
||||
#include "common_flags.h"
|
||||
#include "libapparmor_re/apparmor_re.h"
|
||||
|
||||
|
||||
/*
|
||||
* flag: 1 - allow no- inversion
|
||||
* flag: 2 - flags specified should be masked off
|
||||
*/
|
||||
#define OPT_FLAG_CONTROL_PREFIX_NO 1
|
||||
#define OPT_FLAG_CONTROL_MASK 2
|
||||
typedef struct {
|
||||
int control;
|
||||
const char *option;
|
||||
const char *desc;
|
||||
dfaflags_t flags;
|
||||
optflags_t flags;
|
||||
} optflag_table_t;
|
||||
|
||||
extern optflag_table_t dumpflag_table[];
|
||||
extern optflag_table_t optflag_table[];
|
||||
extern optflag_table_t dfadumpflag_table[];
|
||||
extern optflag_table_t dfaoptflag_table[];
|
||||
|
||||
void print_flags(const char *prefix, optflag_table_t *table, dfaflags_t flags);
|
||||
extern optflags parseopts;
|
||||
|
||||
|
||||
void print_flags(const char *prefix, optflag_table_t *table,
|
||||
optflags_t flags);
|
||||
int handle_flag_table(optflag_table_t *table, const char *optarg,
|
||||
dfaflags_t *flags);
|
||||
optflags_t *flags);
|
||||
void flagtable_help(const char *name, const char *header, const char *command,
|
||||
optflag_table_t *table);
|
||||
|
||||
|
@@ -276,21 +276,21 @@ int dbus_rule::gen_policy_re(Profile &prof)
|
||||
if (perms & AA_DBUS_BIND) {
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms & AA_DBUS_BIND,
|
||||
audit == AUDIT_FORCE ? perms & AA_DBUS_BIND : 0,
|
||||
2, vec, dfaflags, false))
|
||||
2, vec, parseopts, false))
|
||||
goto fail;
|
||||
}
|
||||
if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) {
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
|
||||
perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
|
||||
audit == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0,
|
||||
6, vec, dfaflags, false))
|
||||
6, vec, parseopts, false))
|
||||
goto fail;
|
||||
}
|
||||
if (perms & AA_DBUS_EAVESDROP) {
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
|
||||
perms & AA_DBUS_EAVESDROP,
|
||||
audit == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0,
|
||||
1, vec, dfaflags, false))
|
||||
1, vec, parseopts, false))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@@ -123,14 +123,14 @@ int io_uring_rule::gen_policy_re(Profile &prof)
|
||||
if (perms & AA_VALID_IO_URING_PERMS) {
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
|
||||
audit == AUDIT_FORCE ? perms : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
|
||||
if (perms & AA_IO_URING_OVERRIDE_CREDS) {
|
||||
buf = buffer.str(); /* update buf to have label */
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||
perms, audit == AUDIT_FORCE ? perms : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@@ -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, "");
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../common_optarg.h"
|
||||
#include "apparmor_re.h"
|
||||
#include "expr-tree.h"
|
||||
|
||||
@@ -101,11 +102,11 @@ class aare_rules {
|
||||
~aare_rules();
|
||||
|
||||
bool add_rule(const char *rule, int deny, uint32_t perms,
|
||||
uint32_t audit, dfaflags_t flags);
|
||||
uint32_t audit, optflags const &opts);
|
||||
bool add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count,
|
||||
const char **rulev, dfaflags_t flags, bool oob);
|
||||
bool append_rule(const char *rule, bool oob, bool with_perm, dfaflags_t flags);
|
||||
void *create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
|
||||
const char **rulev, optflags const &opts, bool oob);
|
||||
bool append_rule(const char *rule, bool oob, bool with_perm, optflags const &opts);
|
||||
void *create_dfa(size_t *size, int *min_match_len, optflags const &opts,
|
||||
bool filedfa);
|
||||
};
|
||||
|
||||
|
@@ -19,40 +19,39 @@
|
||||
#ifndef APPARMOR_RE_H
|
||||
#define APPARMOR_RE_H
|
||||
|
||||
typedef int dfaflags_t;
|
||||
#include "../common_flags.h"
|
||||
|
||||
#define CONTROL_DFA_EQUIV (1 << 0)
|
||||
#define CONTROL_DFA_TREE_NORMAL (1 << 1)
|
||||
#define CONTROL_DFA_TREE_SIMPLE (1 << 2)
|
||||
#define CONTROL_DFA_TREE_LEFT (1 << 3)
|
||||
#define CONTROL_DFA_MINIMIZE (1 << 4)
|
||||
#define CONTROL_DFA_FILTER_DENY (1 << 6)
|
||||
#define CONTROL_DFA_REMOVE_UNREACHABLE (1 << 7)
|
||||
#define CONTROL_DFA_TRANS_HIGH (1 << 8)
|
||||
#define CONTROL_DFA_DIFF_ENCODE (1 << 9)
|
||||
|
||||
#define DFA_CONTROL_EQUIV (1 << 0)
|
||||
#define DFA_CONTROL_TREE_NORMAL (1 << 1)
|
||||
#define DFA_CONTROL_TREE_SIMPLE (1 << 2)
|
||||
#define DFA_CONTROL_TREE_LEFT (1 << 3)
|
||||
#define DFA_CONTROL_MINIMIZE (1 << 4)
|
||||
#define DFA_CONTROL_FILTER_DENY (1 << 6)
|
||||
#define DFA_CONTROL_REMOVE_UNREACHABLE (1 << 7)
|
||||
#define DFA_CONTROL_TRANS_HIGH (1 << 8)
|
||||
#define DFA_CONTROL_DIFF_ENCODE (1 << 9)
|
||||
|
||||
#define DFA_DUMP_DIFF_PROGRESS (1 << 10)
|
||||
#define DFA_DUMP_DIFF_ENCODE (1 << 11)
|
||||
#define DFA_DUMP_DIFF_STATS (1 << 12)
|
||||
#define DFA_DUMP_MIN_PARTS (1 << 13)
|
||||
#define DFA_DUMP_UNIQ_PERMS (1 << 14)
|
||||
#define DFA_DUMP_MIN_UNIQ_PERMS (1 << 15)
|
||||
#define DFA_DUMP_TREE_STATS (1 << 16)
|
||||
#define DFA_DUMP_TREE (1 << 17)
|
||||
#define DFA_DUMP_SIMPLE_TREE (1 << 18)
|
||||
#define DFA_DUMP_PROGRESS (1 << 19)
|
||||
#define DFA_DUMP_STATS (1 << 20)
|
||||
#define DFA_DUMP_STATES (1 << 21)
|
||||
#define DFA_DUMP_GRAPH (1 << 22)
|
||||
#define DFA_DUMP_TRANS_PROGRESS (1 << 23)
|
||||
#define DFA_DUMP_TRANS_STATS (1 << 24)
|
||||
#define DFA_DUMP_TRANS_TABLE (1 << 25)
|
||||
#define DFA_DUMP_EQUIV (1 << 26)
|
||||
#define DFA_DUMP_EQUIV_STATS (1 << 27)
|
||||
#define DFA_DUMP_MINIMIZE (1 << 28)
|
||||
#define DFA_DUMP_UNREACHABLE (1 << 29)
|
||||
#define DFA_DUMP_RULE_EXPR (1 << 30)
|
||||
#define DFA_DUMP_NODE_TO_DFA (1 << 31)
|
||||
#define DUMP_DFA_DIFF_PROGRESS (1 << 0)
|
||||
#define DUMP_DFA_DIFF_ENCODE (1 << 1)
|
||||
#define DUMP_DFA_DIFF_STATS (1 << 2)
|
||||
#define DUMP_DFA_MIN_PARTS (1 << 3)
|
||||
#define DUMP_DFA_UNIQ_PERMS (1 << 4)
|
||||
#define DUMP_DFA_MIN_UNIQ_PERMS (1 << 5)
|
||||
#define DUMP_DFA_TREE_STATS (1 << 6)
|
||||
#define DUMP_DFA_TREE (1 << 7)
|
||||
#define DUMP_DFA_SIMPLE_TREE (1 << 8)
|
||||
#define DUMP_DFA_PROGRESS (1 << 9)
|
||||
#define DUMP_DFA_STATS (1 << 10)
|
||||
#define DUMP_DFA_STATES (1 << 11)
|
||||
#define DUMP_DFA_GRAPH (1 << 12)
|
||||
#define DUMP_DFA_TRANS_PROGRESS (1 << 13)
|
||||
#define DUMP_DFA_TRANS_STATS (1 << 14)
|
||||
#define DUMP_DFA_TRANS_TABLE (1 << 15)
|
||||
#define DUMP_DFA_EQUIV (1 << 16)
|
||||
#define DUMP_DFA_EQUIV_STATS (1 << 17)
|
||||
#define DUMP_DFA_MINIMIZE (1 << 18)
|
||||
#define DUMP_DFA_UNREACHABLE (1 << 19)
|
||||
#define DUMP_DFA_RULE_EXPR (1 << 20)
|
||||
#define DUMP_DFA_NODE_TO_DFA (1 << 21)
|
||||
|
||||
#endif /* APPARMOR_RE_H */
|
||||
|
@@ -49,9 +49,10 @@ void CHFA::init_free_list(vector<pair<size_t, size_t> > &free_list,
|
||||
/**
|
||||
* new Construct the transition table.
|
||||
*/
|
||||
CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags): eq(eq)
|
||||
CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts):
|
||||
eq(eq)
|
||||
{
|
||||
if (flags & DFA_DUMP_TRANS_PROGRESS)
|
||||
if (opts.dfadump & DUMP_DFA_TRANS_PROGRESS)
|
||||
fprintf(stderr, "Compressing HFA:\r");
|
||||
|
||||
chfaflags = 0;
|
||||
@@ -82,7 +83,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags): eq(eq)
|
||||
if (*i == dfa.start || *i == dfa.nonmatching)
|
||||
continue;
|
||||
optimal += (*i)->trans.size();
|
||||
if (flags & DFA_CONTROL_TRANS_HIGH) {
|
||||
if (opts.dfaflags & CONTROL_DFA_TRANS_HIGH) {
|
||||
size_t range = 0;
|
||||
if ((*i)->trans.size())
|
||||
range =
|
||||
@@ -116,7 +117,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags): eq(eq)
|
||||
|
||||
int count = 2;
|
||||
|
||||
if (!(flags & DFA_CONTROL_TRANS_HIGH)) {
|
||||
if (!(opts.dfaflags & CONTROL_DFA_TRANS_HIGH)) {
|
||||
for (Partition::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) {
|
||||
if (*i != dfa.nonmatching && *i != dfa.start) {
|
||||
insert_state(free_list, *i, dfa);
|
||||
@@ -124,7 +125,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags): eq(eq)
|
||||
accept2[num.size()] = PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny);
|
||||
num.insert(make_pair(*i, num.size()));
|
||||
}
|
||||
if (flags & (DFA_DUMP_TRANS_PROGRESS)) {
|
||||
if (opts.dfadump & (DUMP_DFA_TRANS_PROGRESS)) {
|
||||
count++;
|
||||
if (count % 100 == 0)
|
||||
fprintf(stderr, "\033[2KCompressing trans table: insert state: %d/%zd\r",
|
||||
@@ -141,7 +142,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags): eq(eq)
|
||||
accept2[num.size()] = PACK_AUDIT_CTL(i->second->perms.audit, i->second->perms.quiet & i->second->perms.deny);
|
||||
num.insert(make_pair(i->second, num.size()));
|
||||
}
|
||||
if (flags & (DFA_DUMP_TRANS_PROGRESS)) {
|
||||
if (opts.dfadump & (DUMP_DFA_TRANS_PROGRESS)) {
|
||||
count++;
|
||||
if (count % 100 == 0)
|
||||
fprintf(stderr, "\033[2KCompressing trans table: insert state: %d/%zd\r",
|
||||
@@ -150,7 +151,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags): eq(eq)
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & (DFA_DUMP_TRANS_STATS | DFA_DUMP_TRANS_PROGRESS)) {
|
||||
if (opts.dfadump & (DUMP_DFA_TRANS_STATS | DUMP_DFA_TRANS_PROGRESS)) {
|
||||
ssize_t size = 4 * next_check.size() + 6 * dfa.states.size();
|
||||
fprintf(stderr, "\033[2KCompressed trans table: states %zd, next/check %zd, optimal next/check %zd avg/state %.2f, compression %zd/%zd = %.2f %%\n",
|
||||
dfa.states.size(), next_check.size(), optimal,
|
||||
|
@@ -37,7 +37,7 @@ class CHFA {
|
||||
typedef vector<pair<const State *, size_t> > DefaultBase;
|
||||
typedef vector<pair<const State *, const State *> > NextCheck;
|
||||
public:
|
||||
CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags);
|
||||
CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts);
|
||||
void dump(ostream & os);
|
||||
void flex_table(ostream &os, const char *name);
|
||||
void init_free_list(vector<pair<size_t, size_t> > &free_list,
|
||||
|
@@ -575,12 +575,12 @@ static void count_tree_nodes(Node *t, struct node_counts *counts)
|
||||
// simplification passes. Simplification may exit sooner if no changes
|
||||
// are made.
|
||||
#define MAX_PASSES 1
|
||||
Node *simplify_tree(Node *t, dfaflags_t flags)
|
||||
Node *simplify_tree(Node *t, optflags const &opts)
|
||||
{
|
||||
bool update = true;
|
||||
int i;
|
||||
|
||||
if (flags & DFA_DUMP_TREE_STATS) {
|
||||
if (opts.dfadump & DUMP_DFA_TREE_STATS) {
|
||||
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
count_tree_nodes(t, &counts);
|
||||
fprintf(stderr,
|
||||
@@ -598,25 +598,25 @@ Node *simplify_tree(Node *t, dfaflags_t flags)
|
||||
// the dfa having about 7 thousands states,
|
||||
// and it having about 1.25 million states
|
||||
int dir = 1;
|
||||
if (flags & DFA_CONTROL_TREE_LEFT)
|
||||
if (opts.dfaflags & CONTROL_DFA_TREE_LEFT)
|
||||
dir = 0;
|
||||
for (int count = 0; count < 2; count++) {
|
||||
bool modified;
|
||||
do {
|
||||
modified = false;
|
||||
if (flags & DFA_CONTROL_TREE_NORMAL)
|
||||
if (opts.dfaflags & CONTROL_DFA_TREE_NORMAL)
|
||||
t->normalize(dir);
|
||||
t = simplify_tree_base(t, dir, modified);
|
||||
if (modified)
|
||||
update = true;
|
||||
} while (modified);
|
||||
if (flags & DFA_CONTROL_TREE_LEFT)
|
||||
if (opts.dfaflags & CONTROL_DFA_TREE_LEFT)
|
||||
dir++;
|
||||
else
|
||||
dir--;
|
||||
}
|
||||
}
|
||||
if (flags & DFA_DUMP_TREE_STATS) {
|
||||
if (opts.dfadump & DUMP_DFA_TREE_STATS) {
|
||||
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
count_tree_nodes(t, &counts);
|
||||
fprintf(stderr,
|
||||
|
@@ -958,7 +958,7 @@ struct node_counts {
|
||||
extern EpsNode epsnode;
|
||||
|
||||
int debug_tree(Node *t);
|
||||
Node *simplify_tree(Node *t, dfaflags_t flags);
|
||||
Node *simplify_tree(Node *t, optflags const &opts);
|
||||
void label_nodes(Node *root);
|
||||
unsigned long hash_NodeSet(NodeSet *ns);
|
||||
void flip_tree(Node *node);
|
||||
|
@@ -391,12 +391,12 @@ void DFA::dump_node_to_dfa(void)
|
||||
cerr << " " << (*i)->label << " <= " << (*i)->proto << "\n";
|
||||
}
|
||||
|
||||
void DFA::process_work_queue(const char *header, dfaflags_t flags)
|
||||
void DFA::process_work_queue(const char *header, optflags const &opts)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (!work_queue.empty()) {
|
||||
if (i % 1000 == 0 && (flags & DFA_DUMP_PROGRESS)) {
|
||||
if (i % 1000 == 0 && (opts.dfadump & DUMP_DFA_PROGRESS)) {
|
||||
cerr << "\033[2K" << header << ": queue "
|
||||
<< work_queue.size()
|
||||
<< "\tstates "
|
||||
@@ -420,7 +420,7 @@ void DFA::process_work_queue(const char *header, dfaflags_t flags)
|
||||
/**
|
||||
* Construct a DFA from a syntax tree.
|
||||
*/
|
||||
DFA::DFA(Node *root, dfaflags_t flags, bool buildfiledfa): root(root), filedfa(buildfiledfa)
|
||||
DFA::DFA(Node *root, optflags const &opts, bool buildfiledfa): root(root), filedfa(buildfiledfa)
|
||||
{
|
||||
diffcount = 0; /* set by diff_encode */
|
||||
max_range = 256;
|
||||
@@ -428,7 +428,7 @@ DFA::DFA(Node *root, dfaflags_t flags, bool buildfiledfa): root(root), filedfa(b
|
||||
oob_range = 0;
|
||||
ord_range = 8;
|
||||
|
||||
if (flags & DFA_DUMP_PROGRESS)
|
||||
if (opts.dfadump & DUMP_DFA_PROGRESS)
|
||||
fprintf(stderr, "Creating dfa:\r");
|
||||
|
||||
for (depth_first_traversal i(root); i; i++) {
|
||||
@@ -437,7 +437,7 @@ DFA::DFA(Node *root, dfaflags_t flags, bool buildfiledfa): root(root), filedfa(b
|
||||
(*i)->compute_lastpos();
|
||||
}
|
||||
|
||||
if (flags & DFA_DUMP_PROGRESS)
|
||||
if (opts.dfadump & DUMP_DFA_PROGRESS)
|
||||
fprintf(stderr, "Creating dfa: followpos\r");
|
||||
for (depth_first_traversal i(root); i; i++) {
|
||||
(*i)->compute_followpos();
|
||||
@@ -457,7 +457,7 @@ DFA::DFA(Node *root, dfaflags_t flags, bool buildfiledfa): root(root), filedfa(b
|
||||
* work_queue at any given time, thus reducing peak memory use.
|
||||
*/
|
||||
work_queue.push_back(start);
|
||||
process_work_queue("Creating dfa", flags);
|
||||
process_work_queue("Creating dfa", opts);
|
||||
max_range += oob_range;
|
||||
/* if oob_range is ever greater than 256 need to move to computing this */
|
||||
if (oob_range)
|
||||
@@ -471,10 +471,10 @@ DFA::DFA(Node *root, dfaflags_t flags, bool buildfiledfa): root(root), filedfa(b
|
||||
(*i)->followpos.clear();
|
||||
}
|
||||
|
||||
if (flags & DFA_DUMP_NODE_TO_DFA)
|
||||
if (opts.dfadump & DUMP_DFA_NODE_TO_DFA)
|
||||
dump_node_to_dfa();
|
||||
|
||||
if (flags & (DFA_DUMP_STATS)) {
|
||||
if (opts.dfadump & (DUMP_DFA_STATS)) {
|
||||
cerr << "\033[2KCreated dfa: states "
|
||||
<< states.size()
|
||||
<< " proto { "
|
||||
@@ -540,7 +540,7 @@ void DFA::dump_uniq_perms(const char *s)
|
||||
}
|
||||
|
||||
/* Remove dead or unreachable states */
|
||||
void DFA::remove_unreachable(dfaflags_t flags)
|
||||
void DFA::remove_unreachable(optflags const &opts)
|
||||
{
|
||||
set<State *> reachable;
|
||||
|
||||
@@ -571,7 +571,7 @@ void DFA::remove_unreachable(dfaflags_t flags)
|
||||
next = i;
|
||||
next++;
|
||||
if (reachable.find(*i) == reachable.end()) {
|
||||
if (flags & DFA_DUMP_UNREACHABLE) {
|
||||
if (opts.dfadump & DUMP_DFA_UNREACHABLE) {
|
||||
cerr << "unreachable: " << **i;
|
||||
if (*i == start)
|
||||
cerr << " <==";
|
||||
@@ -586,7 +586,7 @@ void DFA::remove_unreachable(dfaflags_t flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (count && (flags & DFA_DUMP_STATS))
|
||||
if (count && (opts.dfadump & DUMP_DFA_STATS))
|
||||
cerr << "DFA: states " << states.size() << " removed "
|
||||
<< count << " unreachable states\n";
|
||||
}
|
||||
@@ -645,7 +645,7 @@ int DFA::apply_and_clear_deny(void)
|
||||
}
|
||||
|
||||
/* minimize the number of dfa states */
|
||||
void DFA::minimize(dfaflags_t flags)
|
||||
void DFA::minimize(optflags const &opts)
|
||||
{
|
||||
map<pair<uint64_t, size_t>, Partition *> perm_map;
|
||||
list<Partition *> partitions;
|
||||
@@ -680,7 +680,7 @@ void DFA::minimize(dfaflags_t flags)
|
||||
p->second->push_back(*i);
|
||||
}
|
||||
|
||||
if ((flags & DFA_DUMP_PROGRESS) && (partitions.size() % 1000 == 0))
|
||||
if ((opts.dfadump & DUMP_DFA_PROGRESS) && (partitions.size() % 1000 == 0))
|
||||
cerr << "\033[2KMinimize dfa: partitions "
|
||||
<< partitions.size() << "\tinit " << partitions.size()
|
||||
<< " (accept " << accept_count << ")\r";
|
||||
@@ -692,7 +692,7 @@ void DFA::minimize(dfaflags_t flags)
|
||||
perm_map.clear();
|
||||
|
||||
int init_count = partitions.size();
|
||||
if (flags & DFA_DUMP_PROGRESS)
|
||||
if (opts.dfadump & DUMP_DFA_PROGRESS)
|
||||
cerr << "\033[2KMinimize dfa: partitions " << partitions.size()
|
||||
<< "\tinit " << init_count << " (accept "
|
||||
<< accept_count << ")\r";
|
||||
@@ -734,7 +734,7 @@ void DFA::minimize(dfaflags_t flags)
|
||||
(*m)->partition = new_part;
|
||||
}
|
||||
}
|
||||
if ((flags & DFA_DUMP_PROGRESS) && (partitions.size() % 100 == 0))
|
||||
if ((opts.dfadump & DUMP_DFA_PROGRESS) && (partitions.size() % 100 == 0))
|
||||
cerr << "\033[2KMinimize dfa: partitions "
|
||||
<< partitions.size() << "\tinit "
|
||||
<< init_count << " (accept "
|
||||
@@ -743,7 +743,7 @@ void DFA::minimize(dfaflags_t flags)
|
||||
} while (new_part_count);
|
||||
|
||||
if (partitions.size() == states.size()) {
|
||||
if (flags & DFA_DUMP_STATS)
|
||||
if (opts.dfadump & DUMP_DFA_STATS)
|
||||
cerr << "\033[2KDfa minimization no states removed: partitions "
|
||||
<< partitions.size() << "\tinit " << init_count
|
||||
<< " (accept " << accept_count << ")\n";
|
||||
@@ -757,13 +757,13 @@ void DFA::minimize(dfaflags_t flags)
|
||||
* to states within the same partitions, however this can slow
|
||||
* down compressed dfa compression as there are more states,
|
||||
*/
|
||||
if (flags & DFA_DUMP_MIN_PARTS)
|
||||
if (opts.dfadump & DUMP_DFA_MIN_PARTS)
|
||||
cerr << "Partitions after minimization\n";
|
||||
for (list<Partition *>::iterator p = partitions.begin();
|
||||
p != partitions.end(); p++) {
|
||||
/* representative state for this partition */
|
||||
State *rep = *((*p)->begin());
|
||||
if (flags & DFA_DUMP_MIN_PARTS)
|
||||
if (opts.dfadump & DUMP_DFA_MIN_PARTS)
|
||||
cerr << *rep << " : ";
|
||||
|
||||
/* update representative state's transitions */
|
||||
@@ -782,17 +782,17 @@ void DFA::minimize(dfaflags_t flags)
|
||||
/* clear the state label for all non representative states,
|
||||
* and accumulate permissions */
|
||||
for (Partition::iterator i = ++(*p)->begin(); i != (*p)->end(); i++) {
|
||||
if (flags & DFA_DUMP_MIN_PARTS)
|
||||
if (opts.dfadump & DUMP_DFA_MIN_PARTS)
|
||||
cerr << **i << ", ";
|
||||
(*i)->label = -1;
|
||||
rep->perms.add((*i)->perms, filedfa);
|
||||
}
|
||||
if (rep->perms.is_accept())
|
||||
final_accept++;
|
||||
if (flags & DFA_DUMP_MIN_PARTS)
|
||||
if (opts.dfadump & DUMP_DFA_MIN_PARTS)
|
||||
cerr << "\n";
|
||||
}
|
||||
if (flags & DFA_DUMP_STATS)
|
||||
if (opts.dfadump & DUMP_DFA_STATS)
|
||||
cerr << "\033[2KMinimized dfa: final partitions "
|
||||
<< partitions.size() << " (accept " << final_accept
|
||||
<< ")" << "\tinit " << init_count << " (accept "
|
||||
@@ -875,7 +875,7 @@ static int diff_partition(State *state, Partition &part, int max_range, int uppe
|
||||
|
||||
/**
|
||||
* diff_encode - compress dfa by differentially encoding state transitions
|
||||
* @dfa_flags: flags controlling dfa creation
|
||||
* @opts: flags controlling dfa creation
|
||||
*
|
||||
* This function reduces the number of transitions that need to be stored
|
||||
* by encoding transitions as the difference between the state and a
|
||||
@@ -910,7 +910,7 @@ static int diff_partition(State *state, Partition &part, int max_range, int uppe
|
||||
* the state transition at most will only move 1 deeper into the DAG so for
|
||||
* the next state the maximum number of states traversed is 2*7.
|
||||
*/
|
||||
void DFA::diff_encode(dfaflags_t flags)
|
||||
void DFA::diff_encode(optflags const &opts)
|
||||
{
|
||||
DiffDag *dag;
|
||||
unsigned int xcount = 0, xweight = 0, transitions = 0, depth = 0;
|
||||
@@ -965,7 +965,7 @@ void DFA::diff_encode(dfaflags_t flags)
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & DFA_DUMP_DIFF_PROGRESS) && (i % 100 == 0))
|
||||
if ((opts.dfadump & DUMP_DFA_DIFF_PROGRESS) && (i % 100 == 0))
|
||||
cerr << "\033[2KDiff Encode: " << i << " of "
|
||||
<< tail << ". Diff states " << xcount
|
||||
<< " Savings " << xweight << "\r";
|
||||
@@ -992,7 +992,7 @@ void DFA::diff_encode(dfaflags_t flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & DFA_DUMP_DIFF_STATS)
|
||||
if (opts.dfadump & DUMP_DFA_DIFF_STATS)
|
||||
cerr << "Diff encode states: " << diffcount << " of "
|
||||
<< tail << " reached @ depth " << depth << ". "
|
||||
<< aweight << " trans removed\n";
|
||||
@@ -1194,7 +1194,7 @@ void DFA::dump_dot_graph(ostream & os)
|
||||
* Compute character equivalence classes in the DFA to save space in the
|
||||
* transition table.
|
||||
*/
|
||||
map<transchar, transchar> DFA::equivalence_classes(dfaflags_t flags)
|
||||
map<transchar, transchar> DFA::equivalence_classes(optflags const &opts)
|
||||
{
|
||||
map<transchar, transchar> classes;
|
||||
transchar next_class = 1;
|
||||
@@ -1251,7 +1251,7 @@ map<transchar, transchar> DFA::equivalence_classes(dfaflags_t flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & DFA_DUMP_EQUIV_STATS)
|
||||
if (opts.dfadump & DUMP_DFA_EQUIV_STATS)
|
||||
fprintf(stderr, "Equiv class reduces to %d classes\n",
|
||||
next_class.c - 1);
|
||||
return classes;
|
||||
|
@@ -305,7 +305,7 @@ class DFA {
|
||||
State *add_new_state(NodeSet *nodes, State *other);
|
||||
State *add_new_state(NodeSet *anodes, NodeSet *nnodes, State *other);
|
||||
void update_state_transitions(State *state);
|
||||
void process_work_queue(const char *header, dfaflags_t);
|
||||
void process_work_queue(const char *header, optflags const &);
|
||||
void dump_diff_chain(ostream &os, map<State *, Partition> &relmap,
|
||||
Partition &chain, State *state,
|
||||
unsigned int &count, unsigned int &total,
|
||||
@@ -318,19 +318,19 @@ class DFA {
|
||||
list<State *> work_queue;
|
||||
|
||||
public:
|
||||
DFA(Node *root, dfaflags_t flags, bool filedfa);
|
||||
DFA(Node *root, optflags const &flags, bool filedfa);
|
||||
virtual ~DFA();
|
||||
|
||||
State *match_len(State *state, const char *str, size_t len);
|
||||
State *match_until(State *state, const char *str, const char term);
|
||||
State *match(const char *str);
|
||||
|
||||
void remove_unreachable(dfaflags_t flags);
|
||||
void remove_unreachable(optflags const &flags);
|
||||
bool same_mappings(State *s1, State *s2);
|
||||
void minimize(dfaflags_t flags);
|
||||
void minimize(optflags const &flags);
|
||||
int apply_and_clear_deny(void);
|
||||
|
||||
void diff_encode(dfaflags_t flags);
|
||||
void diff_encode(optflags const &flags);
|
||||
void undiff_encode(void);
|
||||
void dump_diff_encode(ostream &os);
|
||||
|
||||
@@ -338,7 +338,7 @@ public:
|
||||
void dump_dot_graph(ostream &os);
|
||||
void dump_uniq_perms(const char *s);
|
||||
|
||||
map<transchar, transchar> equivalence_classes(dfaflags_t flags);
|
||||
map<transchar, transchar> equivalence_classes(optflags const &flags);
|
||||
void apply_equivalence_classes(map<transchar, transchar> &eq);
|
||||
|
||||
unsigned int diffcount;
|
||||
|
@@ -798,7 +798,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count,
|
||||
* else it has full perms
|
||||
*/
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
|
||||
vec, dfaflags, false))
|
||||
vec, parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
|
||||
@@ -810,7 +810,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count,
|
||||
vec[4] = optsbuf.c_str();
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||
(audit == AUDIT_FORCE ? perms : 0),
|
||||
5, vec, dfaflags, false))
|
||||
5, vec, parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
}
|
||||
@@ -852,7 +852,7 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count,
|
||||
vec[3] = flagsbuf;
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||
4, vec,
|
||||
dfaflags, false))
|
||||
parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
|
||||
@@ -909,7 +909,7 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count,
|
||||
vec[3] = flagsbuf;
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||
4, vec,
|
||||
dfaflags, false))
|
||||
parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
|
||||
@@ -952,7 +952,7 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count,
|
||||
vec[3] = flagsbuf;
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||
4, vec,
|
||||
dfaflags, false))
|
||||
parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
|
||||
@@ -1003,7 +1003,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count,
|
||||
}
|
||||
/* rule for match without required data || data MATCH_CONT */
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
|
||||
vec, dfaflags, false))
|
||||
vec, parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
|
||||
@@ -1015,7 +1015,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count,
|
||||
vec[4] = optsbuf.c_str();
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||
audit == AUDIT_FORCE ? perms : 0,
|
||||
5, vec, dfaflags, false))
|
||||
5, vec, parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
}
|
||||
@@ -1107,7 +1107,7 @@ int mnt_rule::gen_policy_re(Profile &prof)
|
||||
vec[0] = mntbuf.c_str();
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||
(audit == AUDIT_FORCE ? perms : 0), 1, vec,
|
||||
dfaflags, false))
|
||||
parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
}
|
||||
@@ -1122,7 +1122,7 @@ int mnt_rule::gen_policy_re(Profile &prof)
|
||||
vec[1] = devbuf.c_str();
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||
(audit == AUDIT_FORCE ? perms : 0), 2, vec,
|
||||
dfaflags, false))
|
||||
parseopts, false))
|
||||
goto fail;
|
||||
count++;
|
||||
}
|
||||
|
@@ -231,10 +231,10 @@ int mqueue_rule::gen_policy_re(Profile &prof)
|
||||
/* store perms at name match so label doesn't need
|
||||
* to be checked
|
||||
*/
|
||||
if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false))
|
||||
if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, parseopts, false))
|
||||
goto fail;
|
||||
/* also provide label match with perm */
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false))
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, parseopts, false))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@@ -266,10 +266,10 @@ int mqueue_rule::gen_policy_re(Profile &prof)
|
||||
}
|
||||
|
||||
if (perms & AA_VALID_SYSV_MQ_PERMS) {
|
||||
if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false))
|
||||
if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, parseopts, false))
|
||||
goto fail;
|
||||
/* also provide label match with perm */
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false))
|
||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, parseopts, false))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@@ -82,9 +82,6 @@ extern int parser_token;
|
||||
WARN_UNEXPECTED | WARN_FORMAT | WARN_MISSING | \
|
||||
WARN_OVERRIDE | WARN_INCLUDE)
|
||||
|
||||
extern dfaflags_t warnflags;
|
||||
extern dfaflags_t werrflags;
|
||||
|
||||
|
||||
typedef enum pattern_t pattern_t;
|
||||
|
||||
@@ -362,7 +359,6 @@ extern int conf_quiet;
|
||||
extern int names_only;
|
||||
extern int option;
|
||||
extern int current_lineno;
|
||||
extern dfaflags_t dfaflags;
|
||||
extern const char *progname;
|
||||
extern char *profilename;
|
||||
extern char *profile_ns;
|
||||
@@ -374,7 +370,7 @@ extern IncludeCache_t *g_includecache;
|
||||
extern void pwarnf(bool werr, const char *fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
|
||||
extern void common_warn_once(const char *name, const char *msg, const char **warned_name);
|
||||
|
||||
#define pwarn(F, args...) do { if (warnflags & (F)) pwarnf((werrflags & (F)), ## args); } while (0)
|
||||
#define pwarn(F, args...) do { if (parseopts.warn & (F)) pwarnf((parseopts.Werror & (F)), ## args); } while (0)
|
||||
|
||||
/* from parser_main (cannot be used in tst builds) */
|
||||
extern int force_complain;
|
||||
|
@@ -89,9 +89,6 @@ int names_only = 0;
|
||||
int current_lineno = 1;
|
||||
int option = OPTION_ADD;
|
||||
|
||||
dfaflags_t dfaflags = (dfaflags_t)(DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE | DFA_CONTROL_DIFF_ENCODE);
|
||||
dfaflags_t warnflags = DEFAULT_WARNINGS;
|
||||
dfaflags_t werrflags = 0;
|
||||
|
||||
const char *progname = __FILE__;
|
||||
char *profile_ns = NULL;
|
||||
@@ -140,8 +137,8 @@ void pwarnf(bool werr, const char *fmt, ...)
|
||||
/* do we want to warn once/profile or just once per compile?? */
|
||||
void common_warn_once(const char *name, const char *msg, const char **warned_name)
|
||||
{
|
||||
if ((warnflags & WARN_RULE_NOT_ENFORCED) && *warned_name != name) {
|
||||
if (werrflags & WARN_RULE_NOT_ENFORCED)
|
||||
if ((parseopts.warn & WARN_RULE_NOT_ENFORCED) && *warned_name != name) {
|
||||
if (parseopts.Werror & WARN_RULE_NOT_ENFORCED)
|
||||
cerr << "Warning converted to Error";
|
||||
else
|
||||
cerr << "Warning";
|
||||
@@ -154,6 +151,6 @@ void common_warn_once(const char *name, const char *msg, const char **warned_nam
|
||||
*warned_name = name;
|
||||
}
|
||||
|
||||
if (werrflags & WARN_RULE_NOT_ENFORCED)
|
||||
if (parseopts.Werror & WARN_RULE_NOT_ENFORCED)
|
||||
exit(1);
|
||||
}
|
||||
|
@@ -493,11 +493,11 @@ static int process_arg(int c, char *optarg)
|
||||
strcmp(optarg, "dump") == 0 ||
|
||||
strcmp(optarg, "D") == 0) {
|
||||
flagtable_help("--dump=", DUMP_HEADER, progname,
|
||||
dumpflag_table);
|
||||
dfadumpflag_table);
|
||||
} else if (strcmp(optarg, "Optimize") == 0 ||
|
||||
strcmp(optarg, "optimize") == 0 ||
|
||||
strcmp(optarg, "O") == 0) {
|
||||
flagtable_help("-O ", "", progname, optflag_table);
|
||||
flagtable_help("-O ", "", progname, dfaoptflag_table);
|
||||
} else if (strcmp(optarg, "warn") == 0) {
|
||||
flagtable_help("--warn=", "", progname, warnflag_table);
|
||||
} else if (strcmp(optarg, "Werror") == 0) {
|
||||
@@ -568,13 +568,13 @@ static int process_arg(int c, char *optarg)
|
||||
if (!optarg) {
|
||||
dump_vars = 1;
|
||||
} else if (strcmp(optarg, "show") == 0) {
|
||||
print_flags("dump", dumpflag_table, dfaflags);
|
||||
print_flags("dump", dfadumpflag_table, parseopts.dfadump);
|
||||
} else if (strcmp(optarg, "variables") == 0) {
|
||||
dump_vars = 1;
|
||||
} else if (strcmp(optarg, "expanded-variables") == 0) {
|
||||
dump_expanded_vars = 1;
|
||||
} else if (!handle_flag_table(dumpflag_table, optarg,
|
||||
&dfaflags)) {
|
||||
} else if (!handle_flag_table(dfadumpflag_table, optarg,
|
||||
&parseopts.dfadump)) {
|
||||
PERROR("%s: Invalid --Dump option %s\n",
|
||||
progname, optarg);
|
||||
exit(1);
|
||||
@@ -582,9 +582,9 @@ static int process_arg(int c, char *optarg)
|
||||
break;
|
||||
case 'O':
|
||||
if (strcmp(optarg, "show") == 0) {
|
||||
print_flags("Optimize", optflag_table, dfaflags);
|
||||
} else if (!handle_flag_table(optflag_table, optarg,
|
||||
&dfaflags)) {
|
||||
print_flags("Optimize", dfaoptflag_table, parseopts.dfaflags);
|
||||
} else if (!handle_flag_table(dfaoptflag_table, optarg,
|
||||
&parseopts.dfaflags)) {
|
||||
PERROR("%s: Invalid --Optimize option %s\n",
|
||||
progname, optarg);
|
||||
exit(1);
|
||||
@@ -665,7 +665,7 @@ static int process_arg(int c, char *optarg)
|
||||
case 'q':
|
||||
conf_verbose = 0;
|
||||
conf_quiet = 1;
|
||||
warnflags = 0;
|
||||
parseopts.warn = 0;
|
||||
break;
|
||||
case 'v':
|
||||
conf_verbose = 1;
|
||||
@@ -723,9 +723,9 @@ static int process_arg(int c, char *optarg)
|
||||
break;
|
||||
case ARG_WARN:
|
||||
if (strcmp(optarg, "show") == 0) {
|
||||
print_flags("warn", warnflag_table, warnflags);
|
||||
print_flags("warn", warnflag_table, parseopts.warn);
|
||||
} else if (!handle_flag_table(warnflag_table, optarg,
|
||||
&warnflags)) {
|
||||
&parseopts.warn)) {
|
||||
PERROR("%s: Invalid --warn option %s\n",
|
||||
progname, optarg);
|
||||
exit(1);
|
||||
@@ -733,18 +733,18 @@ static int process_arg(int c, char *optarg)
|
||||
break;
|
||||
case ARG_WERROR:
|
||||
if (!optarg) {
|
||||
werrflags = -1;
|
||||
parseopts.Werror = -1;
|
||||
} else if (strcmp(optarg, "show") == 0) {
|
||||
print_flags("Werror", warnflag_table, werrflags);
|
||||
print_flags("Werror", warnflag_table, parseopts.Werror);
|
||||
} else if (optarg && !handle_flag_table(warnflag_table, optarg,
|
||||
&werrflags)) {
|
||||
&parseopts.Werror)) {
|
||||
PERROR("%s: Invalid --Werror option %s\n",
|
||||
progname, optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case ARG_DEBUG_CACHE:
|
||||
warnflags |= WARN_DEBUG_CACHE;
|
||||
parseopts.warn |= WARN_DEBUG_CACHE;
|
||||
break;
|
||||
case 'j':
|
||||
jobs = process_jobs_arg("-j", optarg);
|
||||
@@ -1530,7 +1530,7 @@ static bool get_kernel_features(struct aa_features **features)
|
||||
|
||||
if (!kernel_supports_diff_encode)
|
||||
/* clear diff_encode because it is not supported */
|
||||
dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
|
||||
parseopts.dfaflags &= ~CONTROL_DFA_DIFF_ENCODE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include "common_optarg.h"
|
||||
#include "lib.h"
|
||||
#include "parser.h"
|
||||
#include "profile.h"
|
||||
@@ -128,7 +128,7 @@ pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, int glob,
|
||||
|
||||
sptr = aare;
|
||||
|
||||
if (dfaflags & DFA_DUMP_RULE_EXPR)
|
||||
if (parseopts.dfadump & DUMP_DFA_RULE_EXPR)
|
||||
fprintf(stderr, "aare: %s -> ", aare);
|
||||
|
||||
if (anchor)
|
||||
@@ -427,7 +427,7 @@ out:
|
||||
if (ret == FALSE)
|
||||
ptype = ePatternInvalid;
|
||||
|
||||
if (dfaflags & DFA_DUMP_RULE_EXPR)
|
||||
if (parseopts.dfadump & DUMP_DFA_RULE_EXPR)
|
||||
fprintf(stderr, "%s\n", pcre.c_str());
|
||||
|
||||
return ptype;
|
||||
@@ -507,7 +507,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
||||
aare_rules *rules = new aare_rules();
|
||||
if (!rules)
|
||||
return FALSE;
|
||||
if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) {
|
||||
if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, parseopts)) {
|
||||
delete rules;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -520,7 +520,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
||||
ptype = convert_aaregex_to_pcre(alt->name, 0,
|
||||
glob_default,
|
||||
tbuf, &len);
|
||||
if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) {
|
||||
if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, parseopts)) {
|
||||
delete rules;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -562,14 +562,14 @@ static int process_profile_name_xmatch(Profile *prof)
|
||||
convert_aaregex_to_pcre(xattr_value, 0,
|
||||
glob_null, tbuf,
|
||||
&len);
|
||||
if (!rules->append_rule(tbuf.c_str(), true, true, dfaflags)) {
|
||||
if (!rules->append_rule(tbuf.c_str(), true, true, parseopts)) {
|
||||
delete rules;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
build:
|
||||
prof->xmatch = rules->create_dfa(&prof->xmatch_size, &prof->xmatch_len, dfaflags, true);
|
||||
prof->xmatch = rules->create_dfa(&prof->xmatch_size, &prof->xmatch_len, parseopts, true);
|
||||
delete rules;
|
||||
if (!prof->xmatch)
|
||||
return FALSE;
|
||||
@@ -638,13 +638,13 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
|
||||
!dfarules->add_rule(tbuf.c_str(), entry->rule_mode == RULE_DENY,
|
||||
entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
|
||||
entry->audit == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
return FALSE;
|
||||
} else if (!is_change_profile_perms(entry->perms)) {
|
||||
if (!dfarules->add_rule(tbuf.c_str(),
|
||||
entry->rule_mode == RULE_DENY, entry->perms,
|
||||
entry->audit == AUDIT_FORCE ? entry->perms : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -667,7 +667,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
|
||||
perms |= LINK_TO_LINK_SUBSET(perms);
|
||||
vec[1] = "/[^/].*";
|
||||
}
|
||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, perms, entry->audit == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false))
|
||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, perms, entry->audit == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, parseopts, false))
|
||||
return FALSE;
|
||||
}
|
||||
if (is_change_profile_perms(entry->perms)) {
|
||||
@@ -678,7 +678,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
|
||||
int index = 1;
|
||||
uint32_t onexec_perms = AA_ONEXEC;
|
||||
|
||||
if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit == AUDIT_FORCE && warn_change_profile) {
|
||||
if ((parseopts.warn & WARN_RULE_DOWNGRADED) && entry->audit == AUDIT_FORCE && warn_change_profile) {
|
||||
/* don't have profile name here, so until this code
|
||||
* gets refactored just throw out a generic warning
|
||||
*/
|
||||
@@ -720,12 +720,12 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
|
||||
/* regular change_profile rule */
|
||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY,
|
||||
AA_CHANGE_PROFILE | onexec_perms,
|
||||
0, index - 1, &vec[1], dfaflags, false))
|
||||
0, index - 1, &vec[1], parseopts, false))
|
||||
return FALSE;
|
||||
|
||||
/* onexec rules - both rules are needed for onexec */
|
||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms,
|
||||
0, 1, vec, dfaflags, false))
|
||||
0, 1, vec, parseopts, false))
|
||||
return FALSE;
|
||||
|
||||
/**
|
||||
@@ -734,7 +734,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
|
||||
*/
|
||||
onexec_perms |= (entry->perms & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE));
|
||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms,
|
||||
0, index, vec, dfaflags, false))
|
||||
0, index, vec, parseopts, false))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@@ -770,7 +770,7 @@ int process_profile_regex(Profile *prof)
|
||||
if (prof->dfa.rules->rule_count > 0) {
|
||||
int xmatch_len = 0;
|
||||
prof->dfa.dfa = prof->dfa.rules->create_dfa(&prof->dfa.size,
|
||||
&xmatch_len, dfaflags, true);
|
||||
&xmatch_len, parseopts, true);
|
||||
delete prof->dfa.rules;
|
||||
prof->dfa.rules = NULL;
|
||||
if (!prof->dfa.dfa)
|
||||
@@ -875,7 +875,7 @@ static bool gen_net_rule(Profile *prof, u16 family, unsigned int type_mask,
|
||||
buf = buffer.str();
|
||||
if (!prof->policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_VALID_NET_PERMS),
|
||||
audit ? map_perms(AA_VALID_NET_PERMS) : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -969,44 +969,44 @@ int process_profile_policydb(Profile *prof)
|
||||
|
||||
/* note: this activates fs based unix domain sockets mediation on connect */
|
||||
if (kernel_abi_version > 5 &&
|
||||
!prof->policy.rules->add_rule(mediates_file, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_file, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_mount &&
|
||||
!prof->policy.rules->add_rule(mediates_mount, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_mount, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_dbus &&
|
||||
!prof->policy.rules->add_rule(mediates_dbus, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_dbus, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_signal &&
|
||||
!prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_ptrace &&
|
||||
!prof->policy.rules->add_rule(mediates_ptrace, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_ptrace, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_networkv8 &&
|
||||
!prof->policy.rules->add_rule(mediates_netv8, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_netv8, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_unix &&
|
||||
(!prof->policy.rules->add_rule(mediates_extended_net, 0, AA_MAY_READ, 0, dfaflags) ||
|
||||
!prof->policy.rules->add_rule(mediates_net_unix, 0, AA_MAY_READ, 0, dfaflags)))
|
||||
(!prof->policy.rules->add_rule(mediates_extended_net, 0, AA_MAY_READ, 0, parseopts) ||
|
||||
!prof->policy.rules->add_rule(mediates_net_unix, 0, AA_MAY_READ, 0, parseopts)))
|
||||
goto out;
|
||||
if (features_supports_userns &&
|
||||
!prof->policy.rules->add_rule(mediates_ns, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_ns, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_posix_mqueue &&
|
||||
!prof->policy.rules->add_rule(mediates_posix_mqueue, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_posix_mqueue, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_sysv_mqueue &&
|
||||
!prof->policy.rules->add_rule(mediates_sysv_mqueue, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_sysv_mqueue, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
if (features_supports_io_uring &&
|
||||
!prof->policy.rules->add_rule(mediates_io_uring, 0, AA_MAY_READ, 0, dfaflags))
|
||||
!prof->policy.rules->add_rule(mediates_io_uring, 0, AA_MAY_READ, 0, parseopts))
|
||||
goto out;
|
||||
|
||||
if (prof->policy.rules->rule_count > 0) {
|
||||
int xmatch_len = 0;
|
||||
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size,
|
||||
&xmatch_len, dfaflags, false);
|
||||
&xmatch_len, parseopts, false);
|
||||
delete prof->policy.rules;
|
||||
|
||||
prof->policy.rules = NULL;
|
||||
|
@@ -134,7 +134,7 @@ int ptrace_rule::gen_policy_re(Profile &prof)
|
||||
buf = buffer.str();
|
||||
if (perms & AA_VALID_PTRACE_PERMS) {
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@@ -317,7 +317,7 @@ int signal_rule::gen_policy_re(Profile &prof)
|
||||
buf = buffer.str();
|
||||
if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@@ -97,7 +97,7 @@ int userns_rule::gen_policy_re(Profile &prof)
|
||||
if (perms & AA_VALID_USERNS_PERMS) {
|
||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
|
||||
audit == AUDIT_FORCE ? perms : 0,
|
||||
dfaflags))
|
||||
parseopts))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user