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 \
|
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 \
|
file_cache.h immunix.h lib.h mount.h network.h parser.h \
|
||||||
parser_include.h parser_version.h policy_cache.h policydb.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
|
SPECIAL_HDRS = parser_yacc.h unit_test.h base_cap_names.h
|
||||||
GENERATED_HDRS = af_names.h generated_af_names.h \
|
GENERATED_HDRS = af_names.h generated_af_names.h \
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "common_optarg.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "profile.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
|
* restrictive and may end up denying accesses that might be
|
||||||
* allowed by the profile.
|
* 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");
|
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) {
|
if (features_supports_network || features_supports_networkv8) {
|
||||||
/* only warn if we are building against a kernel
|
/* only warn if we are building against a kernel
|
||||||
* that requires downgrading */
|
* 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");
|
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 */
|
/* TODO: add ability to abort instead of downgrade */
|
||||||
return RULE_OK;
|
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,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||||
map_perms(AA_NET_CREATE),
|
map_perms(AA_NET_CREATE),
|
||||||
map_perms(audit == AUDIT_FORCE ? AA_NET_CREATE : 0),
|
map_perms(audit == AUDIT_FORCE ? AA_NET_CREATE : 0),
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
mask &= ~AA_NET_CREATE;
|
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,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||||
map_perms(AA_NET_BIND),
|
map_perms(AA_NET_BIND),
|
||||||
map_perms(audit == AUDIT_FORCE ? AA_NET_BIND : 0),
|
map_perms(audit == AUDIT_FORCE ? AA_NET_BIND : 0),
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
/* clear if auto, else generic need to generate addr below */
|
/* clear if auto, else generic need to generate addr below */
|
||||||
if (addr)
|
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,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||||
map_perms(mask & local_mask),
|
map_perms(mask & local_mask),
|
||||||
map_perms(audit == AUDIT_FORCE ? mask & local_mask : 0),
|
map_perms(audit == AUDIT_FORCE ? mask & local_mask : 0),
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
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,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||||
map_perms(AA_NET_LISTEN),
|
map_perms(AA_NET_LISTEN),
|
||||||
map_perms(audit == AUDIT_FORCE ? AA_NET_LISTEN : 0),
|
map_perms(audit == AUDIT_FORCE ? AA_NET_LISTEN : 0),
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if ((mask & AA_NET_OPT) && !has_peer_conds()) {
|
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,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||||
map_perms(AA_NET_OPT),
|
map_perms(AA_NET_OPT),
|
||||||
map_perms(audit == AUDIT_FORCE ? AA_NET_OPT : 0),
|
map_perms(audit == AUDIT_FORCE ? AA_NET_OPT : 0),
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
mask &= ~AA_LOCAL_NET_PERMS | AA_NET_ACCEPT;
|
mask &= ~AA_LOCAL_NET_PERMS | AA_NET_ACCEPT;
|
||||||
@@ -432,7 +433,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
buf = buffer.str();
|
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;
|
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 "common_optarg.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
optflag_table_t dumpflag_table[] = {
|
optflag_table_t dfadumpflag_table[] = {
|
||||||
{ 1, "rule-exprs", "Dump rule to expr tree conversions",
|
{ 1, "rule-exprs", "Dump rule to expr tree conversions",
|
||||||
DFA_DUMP_RULE_EXPR },
|
DUMP_DFA_RULE_EXPR },
|
||||||
{ 1, "expr-stats", "Dump stats on expr tree", DFA_DUMP_TREE_STATS },
|
{ 1, "expr-stats", "Dump stats on expr tree", DUMP_DFA_TREE_STATS },
|
||||||
{ 1, "expr-tree", "Dump expression tree", DFA_DUMP_TREE },
|
{ 1, "expr-tree", "Dump expression tree", DUMP_DFA_TREE },
|
||||||
{ 1, "expr-simplified", "Dump simplified expression tree",
|
{ 1, "expr-simplified", "Dump simplified expression tree",
|
||||||
DFA_DUMP_SIMPLE_TREE },
|
DUMP_DFA_SIMPLE_TREE },
|
||||||
{ 1, "stats", "Dump all compile stats",
|
{ 1, "stats", "Dump all compile stats",
|
||||||
DFA_DUMP_TREE_STATS | DFA_DUMP_STATS | DFA_DUMP_TRANS_STATS |
|
DUMP_DFA_TREE_STATS | DUMP_DFA_STATS | DUMP_DFA_TRANS_STATS |
|
||||||
DFA_DUMP_EQUIV_STATS | DFA_DUMP_DIFF_STATS },
|
DUMP_DFA_EQUIV_STATS | DUMP_DFA_DIFF_STATS },
|
||||||
{ 1, "progress", "Dump progress for all compile phases",
|
{ 1, "progress", "Dump progress for all compile phases",
|
||||||
DFA_DUMP_PROGRESS | DFA_DUMP_STATS | DFA_DUMP_TRANS_PROGRESS |
|
DUMP_DFA_PROGRESS | DUMP_DFA_STATS | DUMP_DFA_TRANS_PROGRESS |
|
||||||
DFA_DUMP_TRANS_STATS | DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS },
|
DUMP_DFA_TRANS_STATS | DUMP_DFA_DIFF_PROGRESS | DUMP_DFA_DIFF_STATS },
|
||||||
{ 1, "dfa-progress", "Dump dfa creation as in progress",
|
{ 1, "dfa-progress", "Dump dfa creation as in progress",
|
||||||
DFA_DUMP_PROGRESS | DFA_DUMP_STATS },
|
DUMP_DFA_PROGRESS | DUMP_DFA_STATS },
|
||||||
{ 1, "dfa-stats", "Dump dfa creation stats", DFA_DUMP_STATS },
|
{ 1, "dfa-stats", "Dump dfa creation stats", DUMP_DFA_STATS },
|
||||||
{ 1, "dfa-states", "Dump dfa state diagram", DFA_DUMP_STATES },
|
{ 1, "dfa-states", "Dump dfa state diagram", DUMP_DFA_STATES },
|
||||||
{ 1, "dfa-graph", "Dump dfa dot (graphviz) graph", DFA_DUMP_GRAPH },
|
{ 1, "dfa-graph", "Dump dfa dot (graphviz) graph", DUMP_DFA_GRAPH },
|
||||||
{ 1, "dfa-minimize", "Dump dfa minimization", DFA_DUMP_MINIMIZE },
|
{ 1, "dfa-minimize", "Dump dfa minimization", DUMP_DFA_MINIMIZE },
|
||||||
{ 1, "dfa-unreachable", "Dump dfa unreachable states",
|
{ 1, "dfa-unreachable", "Dump dfa unreachable states",
|
||||||
DFA_DUMP_UNREACHABLE },
|
DUMP_DFA_UNREACHABLE },
|
||||||
{ 1, "dfa-node-map", "Dump expr node set to state mapping",
|
{ 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",
|
{ 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",
|
{ 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",
|
{ 1, "dfa-minimize-partitions", "Dump dfa minimization partitions",
|
||||||
DFA_DUMP_MIN_PARTS },
|
DUMP_DFA_MIN_PARTS },
|
||||||
{ 1, "compress-progress", "Dump progress of compression",
|
{ 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",
|
{ 1, "compress-stats", "Dump stats on compression",
|
||||||
DFA_DUMP_TRANS_STATS },
|
DUMP_DFA_TRANS_STATS },
|
||||||
{ 1, "compressed-dfa", "Dump compressed dfa", DFA_DUMP_TRANS_TABLE },
|
{ 1, "compressed-dfa", "Dump compressed dfa", DUMP_DFA_TRANS_TABLE },
|
||||||
{ 1, "equiv-stats", "Dump equivalence class stats",
|
{ 1, "equiv-stats", "Dump equivalence class stats",
|
||||||
DFA_DUMP_EQUIV_STATS },
|
DUMP_DFA_EQUIV_STATS },
|
||||||
{ 1, "equiv", "Dump equivalence class", DFA_DUMP_EQUIV },
|
{ 1, "equiv", "Dump equivalence class", DUMP_DFA_EQUIV },
|
||||||
{ 1, "diff-encode", "Dump differential encoding",
|
{ 1, "diff-encode", "Dump differential encoding",
|
||||||
DFA_DUMP_DIFF_ENCODE },
|
DUMP_DFA_DIFF_ENCODE },
|
||||||
{ 1, "diff-stats", "Dump differential encoding stats",
|
{ 1, "diff-stats", "Dump differential encoding stats",
|
||||||
DFA_DUMP_DIFF_STATS },
|
DUMP_DFA_DIFF_STATS },
|
||||||
{ 1, "diff-progress", "Dump progress of differential encoding",
|
{ 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 },
|
{ 0, NULL, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
optflag_table_t optflag_table[] = {
|
optflag_table_t dfaoptflag_table[] = {
|
||||||
{ 2, "0", "no optimizations",
|
{ 2, "0", "no optimizations",
|
||||||
DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE |
|
CONTROL_DFA_TREE_NORMAL | CONTROL_DFA_TREE_SIMPLE |
|
||||||
DFA_CONTROL_MINIMIZE | DFA_CONTROL_REMOVE_UNREACHABLE |
|
CONTROL_DFA_MINIMIZE | CONTROL_DFA_REMOVE_UNREACHABLE |
|
||||||
DFA_CONTROL_DIFF_ENCODE
|
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",
|
{ 1, "expr-normalize", "expression tree normalization",
|
||||||
DFA_CONTROL_TREE_NORMAL },
|
CONTROL_DFA_TREE_NORMAL },
|
||||||
{ 1, "expr-simplify", "expression tree simplification",
|
{ 1, "expr-simplify", "expression tree simplification",
|
||||||
DFA_CONTROL_TREE_SIMPLE },
|
CONTROL_DFA_TREE_SIMPLE },
|
||||||
{ 0, "expr-left-simplify", "left simplification first",
|
{ 0, "expr-left-simplify", "left simplification first",
|
||||||
DFA_CONTROL_TREE_LEFT },
|
CONTROL_DFA_TREE_LEFT },
|
||||||
{ 2, "expr-right-simplify", "right simplification first",
|
{ 2, "expr-right-simplify", "right simplification first",
|
||||||
DFA_CONTROL_TREE_LEFT },
|
CONTROL_DFA_TREE_LEFT },
|
||||||
{ 1, "minimize", "dfa state minimization", DFA_CONTROL_MINIMIZE },
|
{ 1, "minimize", "dfa state minimization", CONTROL_DFA_MINIMIZE },
|
||||||
{ 1, "filter-deny", "filter out deny information from final dfa",
|
{ 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",
|
{ 1, "remove-unreachable", "dfa unreachable state removal",
|
||||||
DFA_CONTROL_REMOVE_UNREACHABLE },
|
CONTROL_DFA_REMOVE_UNREACHABLE },
|
||||||
{ 0, "compress-small",
|
{ 0, "compress-small",
|
||||||
"do slower dfa transition table compression",
|
"do slower dfa transition table compression",
|
||||||
DFA_CONTROL_TRANS_HIGH },
|
CONTROL_DFA_TRANS_HIGH },
|
||||||
{ 2, "compress-fast", "do faster dfa transition table compression",
|
{ 2, "compress-fast", "do faster dfa transition table compression",
|
||||||
DFA_CONTROL_TRANS_HIGH },
|
CONTROL_DFA_TRANS_HIGH },
|
||||||
{ 1, "diff-encode", "Differentially encode transitions",
|
{ 1, "diff-encode", "Differentially encode transitions",
|
||||||
DFA_CONTROL_DIFF_ENCODE },
|
CONTROL_DFA_DIFF_ENCODE },
|
||||||
{ 0, NULL, NULL, 0 },
|
{ 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)
|
void print_flag_table(optflag_table_t *table)
|
||||||
{
|
{
|
||||||
int i;
|
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");
|
printf("%-*s \t%s\n", longest, " show", "show flags that have been set and exit");
|
||||||
for (i = 0; table[i].option; i++) {
|
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);
|
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;
|
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,
|
int handle_flag_table(optflag_table_t *table, const char *optarg,
|
||||||
dfaflags_t *flags)
|
optflags_t *flags)
|
||||||
{
|
{
|
||||||
const char *arg = optarg;
|
const char *arg = optarg;
|
||||||
int i, invert = 0;
|
int i, invert = 0;
|
||||||
|
@@ -21,25 +21,33 @@
|
|||||||
#ifndef __AA_COMMON_OPTARG_H
|
#ifndef __AA_COMMON_OPTARG_H
|
||||||
#define __AA_COMMON_OPTARG_H
|
#define __AA_COMMON_OPTARG_H
|
||||||
|
|
||||||
|
#include "common_flags.h"
|
||||||
#include "libapparmor_re/apparmor_re.h"
|
#include "libapparmor_re/apparmor_re.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flag: 1 - allow no- inversion
|
* flag: 1 - allow no- inversion
|
||||||
* flag: 2 - flags specified should be masked off
|
* flag: 2 - flags specified should be masked off
|
||||||
*/
|
*/
|
||||||
|
#define OPT_FLAG_CONTROL_PREFIX_NO 1
|
||||||
|
#define OPT_FLAG_CONTROL_MASK 2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int control;
|
int control;
|
||||||
const char *option;
|
const char *option;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
dfaflags_t flags;
|
optflags_t flags;
|
||||||
} optflag_table_t;
|
} optflag_table_t;
|
||||||
|
|
||||||
extern optflag_table_t dumpflag_table[];
|
extern optflag_table_t dfadumpflag_table[];
|
||||||
extern optflag_table_t optflag_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,
|
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,
|
void flagtable_help(const char *name, const char *header, const char *command,
|
||||||
optflag_table_t *table);
|
optflag_table_t *table);
|
||||||
|
|
||||||
|
@@ -276,21 +276,21 @@ int dbus_rule::gen_policy_re(Profile &prof)
|
|||||||
if (perms & AA_DBUS_BIND) {
|
if (perms & AA_DBUS_BIND) {
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, 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,
|
audit == AUDIT_FORCE ? perms & AA_DBUS_BIND : 0,
|
||||||
2, vec, dfaflags, false))
|
2, vec, parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) {
|
if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) {
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
|
||||||
perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
|
perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
|
||||||
audit == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0,
|
audit == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0,
|
||||||
6, vec, dfaflags, false))
|
6, vec, parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (perms & AA_DBUS_EAVESDROP) {
|
if (perms & AA_DBUS_EAVESDROP) {
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY,
|
||||||
perms & AA_DBUS_EAVESDROP,
|
perms & AA_DBUS_EAVESDROP,
|
||||||
audit == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0,
|
audit == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0,
|
||||||
1, vec, dfaflags, false))
|
1, vec, parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -123,14 +123,14 @@ int io_uring_rule::gen_policy_re(Profile &prof)
|
|||||||
if (perms & AA_VALID_IO_URING_PERMS) {
|
if (perms & AA_VALID_IO_URING_PERMS) {
|
||||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
|
||||||
audit == AUDIT_FORCE ? perms : 0,
|
audit == AUDIT_FORCE ? perms : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (perms & AA_IO_URING_OVERRIDE_CREDS) {
|
if (perms & AA_IO_URING_OVERRIDE_CREDS) {
|
||||||
buf = buffer.str(); /* update buf to have label */
|
buf = buffer.str(); /* update buf to have label */
|
||||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY,
|
||||||
perms, audit == AUDIT_FORCE ? perms : 0,
|
perms, audit == AUDIT_FORCE ? perms : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,9 +45,9 @@ aare_rules::~aare_rules(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool aare_rules::add_rule(const char *rule, int deny, uint32_t perms,
|
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)
|
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,
|
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)
|
bool oob)
|
||||||
{
|
{
|
||||||
Node *tree = NULL, *accept;
|
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);
|
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;
|
const char *separator;
|
||||||
if (oob)
|
if (oob)
|
||||||
separator = "\\-x01";
|
separator = "\\-x01";
|
||||||
@@ -152,13 +152,13 @@ err:
|
|||||||
* advanced by a null character for each xattr.
|
* advanced by a null character for each xattr.
|
||||||
*/
|
*/
|
||||||
bool aare_rules::append_rule(const char *rule, bool oob, bool with_perm,
|
bool aare_rules::append_rule(const char *rule, bool oob, bool with_perm,
|
||||||
dfaflags_t flags)
|
optflags const &opts)
|
||||||
{
|
{
|
||||||
Node *tree = NULL;
|
Node *tree = NULL;
|
||||||
if (regex_parse(&tree, rule))
|
if (regex_parse(&tree, rule))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (flags & DFA_DUMP_RULE_EXPR) {
|
if (opts.dfadump & DUMP_DFA_RULE_EXPR) {
|
||||||
cerr << "rule: ";
|
cerr << "rule: ";
|
||||||
cerr << rule;
|
cerr << rule;
|
||||||
cerr << " -> ";
|
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
|
* else NULL on failure, @min_match_len set to the shortest string
|
||||||
* that can match the dfa for determining xmatch priority.
|
* 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)
|
bool filedfa)
|
||||||
{
|
{
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
@@ -204,15 +204,15 @@ void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
|
|||||||
* set nodes */
|
* set nodes */
|
||||||
PermExprMap::iterator i = expr_map.begin();
|
PermExprMap::iterator i = expr_map.begin();
|
||||||
if (i != expr_map.end()) {
|
if (i != expr_map.end()) {
|
||||||
if (flags & DFA_CONTROL_TREE_SIMPLE) {
|
if (opts.dfaflags & CONTROL_DFA_TREE_SIMPLE) {
|
||||||
Node *tmp = simplify_tree(i->second, flags);
|
Node *tmp = simplify_tree(i->second, opts);
|
||||||
root = new CatNode(tmp, i->first);
|
root = new CatNode(tmp, i->first);
|
||||||
} else
|
} else
|
||||||
root = new CatNode(i->second, i->first);
|
root = new CatNode(i->second, i->first);
|
||||||
for (i++; i != expr_map.end(); i++) {
|
for (i++; i != expr_map.end(); i++) {
|
||||||
Node *tmp;
|
Node *tmp;
|
||||||
if (flags & DFA_CONTROL_TREE_SIMPLE) {
|
if (opts.dfaflags & CONTROL_DFA_TREE_SIMPLE) {
|
||||||
tmp = simplify_tree(i->second, flags);
|
tmp = simplify_tree(i->second, opts);
|
||||||
} else
|
} else
|
||||||
tmp = i->second;
|
tmp = i->second;
|
||||||
root = new AltNode(root, new CatNode(tmp, i->first));
|
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.
|
* this debug dump.
|
||||||
*/
|
*/
|
||||||
label_nodes(root);
|
label_nodes(root);
|
||||||
if (flags & DFA_DUMP_TREE) {
|
if (opts.dfadump & DUMP_DFA_TREE) {
|
||||||
cerr << "\nDFA: Expression Tree\n";
|
cerr << "\nDFA: Expression Tree\n";
|
||||||
root->dump(cerr);
|
root->dump(cerr);
|
||||||
cerr << "\n\n";
|
cerr << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DFA_CONTROL_TREE_SIMPLE) {
|
if (opts.dfaflags & CONTROL_DFA_TREE_SIMPLE) {
|
||||||
/* This is old total tree, simplification point
|
/* This is old total tree, simplification point
|
||||||
* For now just do simplification up front. It gets most
|
* For now just do simplification up front. It gets most
|
||||||
* of the benefit running on the smaller chains, and is
|
* of the benefit running on the smaller chains, and is
|
||||||
* overall faster because there are less nodes. Reevaluate
|
* overall faster because there are less nodes. Reevaluate
|
||||||
* once tree simplification is rewritten
|
* 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";
|
cerr << "\nDFA: Simplified Expression Tree\n";
|
||||||
root->dump(cerr);
|
root->dump(cerr);
|
||||||
cerr << "\n\n";
|
cerr << "\n\n";
|
||||||
@@ -250,19 +250,19 @@ void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
|
|||||||
|
|
||||||
stringstream stream;
|
stringstream stream;
|
||||||
try {
|
try {
|
||||||
DFA dfa(root, flags, filedfa);
|
DFA dfa(root, opts, filedfa);
|
||||||
if (flags & DFA_DUMP_UNIQ_PERMS)
|
if (opts.dfadump & DUMP_DFA_UNIQ_PERMS)
|
||||||
dfa.dump_uniq_perms("dfa");
|
dfa.dump_uniq_perms("dfa");
|
||||||
|
|
||||||
if (flags & DFA_CONTROL_MINIMIZE) {
|
if (opts.dfaflags & CONTROL_DFA_MINIMIZE) {
|
||||||
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");
|
dfa.dump_uniq_perms("minimized dfa");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DFA_CONTROL_FILTER_DENY &&
|
if (opts.dfaflags & CONTROL_DFA_FILTER_DENY &&
|
||||||
flags & DFA_CONTROL_MINIMIZE &&
|
opts.dfaflags & CONTROL_DFA_MINIMIZE &&
|
||||||
dfa.apply_and_clear_deny()) {
|
dfa.apply_and_clear_deny()) {
|
||||||
/* Do a second minimization pass as removal of deny
|
/* Do a second minimization pass as removal of deny
|
||||||
* information has moved some states from accepting
|
* 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
|
* TODO: add this as a tail pass to minimization
|
||||||
* so we don't need to do a full second pass
|
* 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");
|
dfa.dump_uniq_perms("minimized dfa");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DFA_CONTROL_REMOVE_UNREACHABLE)
|
if (opts.dfaflags & CONTROL_DFA_REMOVE_UNREACHABLE)
|
||||||
dfa.remove_unreachable(flags);
|
dfa.remove_unreachable(opts);
|
||||||
|
|
||||||
if (flags & DFA_DUMP_STATES)
|
if (opts.dfadump & DUMP_DFA_STATES)
|
||||||
dfa.dump(cerr);
|
dfa.dump(cerr);
|
||||||
|
|
||||||
if (flags & DFA_DUMP_GRAPH)
|
if (opts.dfadump & DUMP_DFA_GRAPH)
|
||||||
dfa.dump_dot_graph(cerr);
|
dfa.dump_dot_graph(cerr);
|
||||||
|
|
||||||
map<transchar, transchar> eq;
|
map<transchar, transchar> eq;
|
||||||
if (flags & DFA_CONTROL_EQUIV) {
|
if (opts.dfaflags & CONTROL_DFA_EQUIV) {
|
||||||
eq = dfa.equivalence_classes(flags);
|
eq = dfa.equivalence_classes(opts);
|
||||||
dfa.apply_equivalence_classes(eq);
|
dfa.apply_equivalence_classes(eq);
|
||||||
|
|
||||||
if (flags & DFA_DUMP_EQUIV) {
|
if (opts.dfadump & DUMP_DFA_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 (opts.dfadump & DUMP_DFA_EQUIV)
|
||||||
cerr << "\nDFA did not generate an equivalence class\n";
|
cerr << "\nDFA did not generate an equivalence class\n";
|
||||||
|
|
||||||
if (flags & DFA_CONTROL_DIFF_ENCODE) {
|
if (opts.dfaflags & CONTROL_DFA_DIFF_ENCODE) {
|
||||||
dfa.diff_encode(flags);
|
dfa.diff_encode(opts);
|
||||||
|
|
||||||
if (flags & DFA_DUMP_DIFF_ENCODE)
|
if (opts.dfadump & DUMP_DFA_DIFF_ENCODE)
|
||||||
dfa.dump_diff_encode(cerr);
|
dfa.dump_diff_encode(cerr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHFA chfa(dfa, eq, flags);
|
CHFA chfa(dfa, eq, opts);
|
||||||
if (flags & DFA_DUMP_TRANS_TABLE)
|
if (opts.dfadump & DUMP_DFA_TRANS_TABLE)
|
||||||
chfa.dump(cerr);
|
chfa.dump(cerr);
|
||||||
chfa.flex_table(stream, "");
|
chfa.flex_table(stream, "");
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../common_optarg.h"
|
||||||
#include "apparmor_re.h"
|
#include "apparmor_re.h"
|
||||||
#include "expr-tree.h"
|
#include "expr-tree.h"
|
||||||
|
|
||||||
@@ -101,11 +102,11 @@ class aare_rules {
|
|||||||
~aare_rules();
|
~aare_rules();
|
||||||
|
|
||||||
bool add_rule(const char *rule, int deny, uint32_t perms,
|
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,
|
bool add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count,
|
||||||
const char **rulev, dfaflags_t flags, bool oob);
|
const char **rulev, optflags const &opts, bool oob);
|
||||||
bool append_rule(const char *rule, bool oob, bool with_perm, dfaflags_t flags);
|
bool append_rule(const char *rule, bool oob, bool with_perm, optflags const &opts);
|
||||||
void *create_dfa(size_t *size, int *min_match_len, dfaflags_t flags,
|
void *create_dfa(size_t *size, int *min_match_len, optflags const &opts,
|
||||||
bool filedfa);
|
bool filedfa);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -19,40 +19,39 @@
|
|||||||
#ifndef APPARMOR_RE_H
|
#ifndef APPARMOR_RE_H
|
||||||
#define 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 DUMP_DFA_DIFF_PROGRESS (1 << 0)
|
||||||
#define DFA_CONTROL_TREE_NORMAL (1 << 1)
|
#define DUMP_DFA_DIFF_ENCODE (1 << 1)
|
||||||
#define DFA_CONTROL_TREE_SIMPLE (1 << 2)
|
#define DUMP_DFA_DIFF_STATS (1 << 2)
|
||||||
#define DFA_CONTROL_TREE_LEFT (1 << 3)
|
#define DUMP_DFA_MIN_PARTS (1 << 3)
|
||||||
#define DFA_CONTROL_MINIMIZE (1 << 4)
|
#define DUMP_DFA_UNIQ_PERMS (1 << 4)
|
||||||
#define DFA_CONTROL_FILTER_DENY (1 << 6)
|
#define DUMP_DFA_MIN_UNIQ_PERMS (1 << 5)
|
||||||
#define DFA_CONTROL_REMOVE_UNREACHABLE (1 << 7)
|
#define DUMP_DFA_TREE_STATS (1 << 6)
|
||||||
#define DFA_CONTROL_TRANS_HIGH (1 << 8)
|
#define DUMP_DFA_TREE (1 << 7)
|
||||||
#define DFA_CONTROL_DIFF_ENCODE (1 << 9)
|
#define DUMP_DFA_SIMPLE_TREE (1 << 8)
|
||||||
|
#define DUMP_DFA_PROGRESS (1 << 9)
|
||||||
#define DFA_DUMP_DIFF_PROGRESS (1 << 10)
|
#define DUMP_DFA_STATS (1 << 10)
|
||||||
#define DFA_DUMP_DIFF_ENCODE (1 << 11)
|
#define DUMP_DFA_STATES (1 << 11)
|
||||||
#define DFA_DUMP_DIFF_STATS (1 << 12)
|
#define DUMP_DFA_GRAPH (1 << 12)
|
||||||
#define DFA_DUMP_MIN_PARTS (1 << 13)
|
#define DUMP_DFA_TRANS_PROGRESS (1 << 13)
|
||||||
#define DFA_DUMP_UNIQ_PERMS (1 << 14)
|
#define DUMP_DFA_TRANS_STATS (1 << 14)
|
||||||
#define DFA_DUMP_MIN_UNIQ_PERMS (1 << 15)
|
#define DUMP_DFA_TRANS_TABLE (1 << 15)
|
||||||
#define DFA_DUMP_TREE_STATS (1 << 16)
|
#define DUMP_DFA_EQUIV (1 << 16)
|
||||||
#define DFA_DUMP_TREE (1 << 17)
|
#define DUMP_DFA_EQUIV_STATS (1 << 17)
|
||||||
#define DFA_DUMP_SIMPLE_TREE (1 << 18)
|
#define DUMP_DFA_MINIMIZE (1 << 18)
|
||||||
#define DFA_DUMP_PROGRESS (1 << 19)
|
#define DUMP_DFA_UNREACHABLE (1 << 19)
|
||||||
#define DFA_DUMP_STATS (1 << 20)
|
#define DUMP_DFA_RULE_EXPR (1 << 20)
|
||||||
#define DFA_DUMP_STATES (1 << 21)
|
#define DUMP_DFA_NODE_TO_DFA (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)
|
|
||||||
|
|
||||||
#endif /* APPARMOR_RE_H */
|
#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.
|
* 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");
|
fprintf(stderr, "Compressing HFA:\r");
|
||||||
|
|
||||||
chfaflags = 0;
|
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)
|
if (*i == dfa.start || *i == dfa.nonmatching)
|
||||||
continue;
|
continue;
|
||||||
optimal += (*i)->trans.size();
|
optimal += (*i)->trans.size();
|
||||||
if (flags & DFA_CONTROL_TRANS_HIGH) {
|
if (opts.dfaflags & CONTROL_DFA_TRANS_HIGH) {
|
||||||
size_t range = 0;
|
size_t range = 0;
|
||||||
if ((*i)->trans.size())
|
if ((*i)->trans.size())
|
||||||
range =
|
range =
|
||||||
@@ -116,7 +117,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, dfaflags_t flags): eq(eq)
|
|||||||
|
|
||||||
int count = 2;
|
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++) {
|
for (Partition::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) {
|
||||||
if (*i != dfa.nonmatching && *i != dfa.start) {
|
if (*i != dfa.nonmatching && *i != dfa.start) {
|
||||||
insert_state(free_list, *i, dfa);
|
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);
|
accept2[num.size()] = PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny);
|
||||||
num.insert(make_pair(*i, num.size()));
|
num.insert(make_pair(*i, num.size()));
|
||||||
}
|
}
|
||||||
if (flags & (DFA_DUMP_TRANS_PROGRESS)) {
|
if (opts.dfadump & (DUMP_DFA_TRANS_PROGRESS)) {
|
||||||
count++;
|
count++;
|
||||||
if (count % 100 == 0)
|
if (count % 100 == 0)
|
||||||
fprintf(stderr, "\033[2KCompressing trans table: insert state: %d/%zd\r",
|
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);
|
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()));
|
num.insert(make_pair(i->second, num.size()));
|
||||||
}
|
}
|
||||||
if (flags & (DFA_DUMP_TRANS_PROGRESS)) {
|
if (opts.dfadump & (DUMP_DFA_TRANS_PROGRESS)) {
|
||||||
count++;
|
count++;
|
||||||
if (count % 100 == 0)
|
if (count % 100 == 0)
|
||||||
fprintf(stderr, "\033[2KCompressing trans table: insert state: %d/%zd\r",
|
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();
|
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",
|
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,
|
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 *, size_t> > DefaultBase;
|
||||||
typedef vector<pair<const State *, const State *> > NextCheck;
|
typedef vector<pair<const State *, const State *> > NextCheck;
|
||||||
public:
|
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 dump(ostream & os);
|
||||||
void flex_table(ostream &os, const char *name);
|
void flex_table(ostream &os, const char *name);
|
||||||
void init_free_list(vector<pair<size_t, size_t> > &free_list,
|
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
|
// simplification passes. Simplification may exit sooner if no changes
|
||||||
// are made.
|
// are made.
|
||||||
#define MAX_PASSES 1
|
#define MAX_PASSES 1
|
||||||
Node *simplify_tree(Node *t, dfaflags_t flags)
|
Node *simplify_tree(Node *t, optflags const &opts)
|
||||||
{
|
{
|
||||||
bool update = true;
|
bool update = true;
|
||||||
int i;
|
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 };
|
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
count_tree_nodes(t, &counts);
|
count_tree_nodes(t, &counts);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -598,25 +598,25 @@ Node *simplify_tree(Node *t, dfaflags_t flags)
|
|||||||
// 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
|
||||||
int dir = 1;
|
int dir = 1;
|
||||||
if (flags & DFA_CONTROL_TREE_LEFT)
|
if (opts.dfaflags & CONTROL_DFA_TREE_LEFT)
|
||||||
dir = 0;
|
dir = 0;
|
||||||
for (int count = 0; count < 2; count++) {
|
for (int count = 0; count < 2; count++) {
|
||||||
bool modified;
|
bool modified;
|
||||||
do {
|
do {
|
||||||
modified = false;
|
modified = false;
|
||||||
if (flags & DFA_CONTROL_TREE_NORMAL)
|
if (opts.dfaflags & CONTROL_DFA_TREE_NORMAL)
|
||||||
t->normalize(dir);
|
t->normalize(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)
|
if (opts.dfaflags & CONTROL_DFA_TREE_LEFT)
|
||||||
dir++;
|
dir++;
|
||||||
else
|
else
|
||||||
dir--;
|
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 };
|
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
count_tree_nodes(t, &counts);
|
count_tree_nodes(t, &counts);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@@ -958,7 +958,7 @@ struct node_counts {
|
|||||||
extern EpsNode epsnode;
|
extern EpsNode epsnode;
|
||||||
|
|
||||||
int debug_tree(Node *t);
|
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);
|
void label_nodes(Node *root);
|
||||||
unsigned long hash_NodeSet(NodeSet *ns);
|
unsigned long hash_NodeSet(NodeSet *ns);
|
||||||
void flip_tree(Node *node);
|
void flip_tree(Node *node);
|
||||||
|
@@ -391,12 +391,12 @@ void DFA::dump_node_to_dfa(void)
|
|||||||
cerr << " " << (*i)->label << " <= " << (*i)->proto << "\n";
|
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;
|
int i = 0;
|
||||||
|
|
||||||
while (!work_queue.empty()) {
|
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 "
|
cerr << "\033[2K" << header << ": queue "
|
||||||
<< work_queue.size()
|
<< work_queue.size()
|
||||||
<< "\tstates "
|
<< "\tstates "
|
||||||
@@ -420,7 +420,7 @@ void DFA::process_work_queue(const char *header, dfaflags_t flags)
|
|||||||
/**
|
/**
|
||||||
* Construct a DFA from a syntax tree.
|
* 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 */
|
diffcount = 0; /* set by diff_encode */
|
||||||
max_range = 256;
|
max_range = 256;
|
||||||
@@ -428,7 +428,7 @@ DFA::DFA(Node *root, dfaflags_t flags, bool buildfiledfa): root(root), filedfa(b
|
|||||||
oob_range = 0;
|
oob_range = 0;
|
||||||
ord_range = 8;
|
ord_range = 8;
|
||||||
|
|
||||||
if (flags & DFA_DUMP_PROGRESS)
|
if (opts.dfadump & DUMP_DFA_PROGRESS)
|
||||||
fprintf(stderr, "Creating dfa:\r");
|
fprintf(stderr, "Creating dfa:\r");
|
||||||
|
|
||||||
for (depth_first_traversal i(root); i; i++) {
|
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();
|
(*i)->compute_lastpos();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DFA_DUMP_PROGRESS)
|
if (opts.dfadump & DUMP_DFA_PROGRESS)
|
||||||
fprintf(stderr, "Creating dfa: followpos\r");
|
fprintf(stderr, "Creating dfa: followpos\r");
|
||||||
for (depth_first_traversal i(root); i; i++) {
|
for (depth_first_traversal i(root); i; i++) {
|
||||||
(*i)->compute_followpos();
|
(*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 at any given time, thus reducing peak memory use.
|
||||||
*/
|
*/
|
||||||
work_queue.push_back(start);
|
work_queue.push_back(start);
|
||||||
process_work_queue("Creating dfa", flags);
|
process_work_queue("Creating dfa", opts);
|
||||||
max_range += oob_range;
|
max_range += oob_range;
|
||||||
/* if oob_range is ever greater than 256 need to move to computing this */
|
/* if oob_range is ever greater than 256 need to move to computing this */
|
||||||
if (oob_range)
|
if (oob_range)
|
||||||
@@ -471,10 +471,10 @@ DFA::DFA(Node *root, dfaflags_t flags, bool buildfiledfa): root(root), filedfa(b
|
|||||||
(*i)->followpos.clear();
|
(*i)->followpos.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DFA_DUMP_NODE_TO_DFA)
|
if (opts.dfadump & DUMP_DFA_NODE_TO_DFA)
|
||||||
dump_node_to_dfa();
|
dump_node_to_dfa();
|
||||||
|
|
||||||
if (flags & (DFA_DUMP_STATS)) {
|
if (opts.dfadump & (DUMP_DFA_STATS)) {
|
||||||
cerr << "\033[2KCreated dfa: states "
|
cerr << "\033[2KCreated dfa: states "
|
||||||
<< states.size()
|
<< states.size()
|
||||||
<< " proto { "
|
<< " proto { "
|
||||||
@@ -540,7 +540,7 @@ void DFA::dump_uniq_perms(const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove dead or unreachable states */
|
/* Remove dead or unreachable states */
|
||||||
void DFA::remove_unreachable(dfaflags_t flags)
|
void DFA::remove_unreachable(optflags const &opts)
|
||||||
{
|
{
|
||||||
set<State *> reachable;
|
set<State *> reachable;
|
||||||
|
|
||||||
@@ -571,7 +571,7 @@ void DFA::remove_unreachable(dfaflags_t flags)
|
|||||||
next = i;
|
next = i;
|
||||||
next++;
|
next++;
|
||||||
if (reachable.find(*i) == reachable.end()) {
|
if (reachable.find(*i) == reachable.end()) {
|
||||||
if (flags & DFA_DUMP_UNREACHABLE) {
|
if (opts.dfadump & DUMP_DFA_UNREACHABLE) {
|
||||||
cerr << "unreachable: " << **i;
|
cerr << "unreachable: " << **i;
|
||||||
if (*i == start)
|
if (*i == start)
|
||||||
cerr << " <==";
|
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 "
|
cerr << "DFA: states " << states.size() << " removed "
|
||||||
<< count << " unreachable states\n";
|
<< count << " unreachable states\n";
|
||||||
}
|
}
|
||||||
@@ -645,7 +645,7 @@ int DFA::apply_and_clear_deny(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* minimize the number of dfa states */
|
/* 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;
|
map<pair<uint64_t, size_t>, Partition *> perm_map;
|
||||||
list<Partition *> partitions;
|
list<Partition *> partitions;
|
||||||
@@ -680,7 +680,7 @@ void DFA::minimize(dfaflags_t flags)
|
|||||||
p->second->push_back(*i);
|
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 "
|
cerr << "\033[2KMinimize dfa: partitions "
|
||||||
<< partitions.size() << "\tinit " << partitions.size()
|
<< partitions.size() << "\tinit " << partitions.size()
|
||||||
<< " (accept " << accept_count << ")\r";
|
<< " (accept " << accept_count << ")\r";
|
||||||
@@ -692,7 +692,7 @@ void DFA::minimize(dfaflags_t flags)
|
|||||||
perm_map.clear();
|
perm_map.clear();
|
||||||
|
|
||||||
int init_count = partitions.size();
|
int init_count = partitions.size();
|
||||||
if (flags & DFA_DUMP_PROGRESS)
|
if (opts.dfadump & DUMP_DFA_PROGRESS)
|
||||||
cerr << "\033[2KMinimize dfa: partitions " << partitions.size()
|
cerr << "\033[2KMinimize dfa: partitions " << partitions.size()
|
||||||
<< "\tinit " << init_count << " (accept "
|
<< "\tinit " << init_count << " (accept "
|
||||||
<< accept_count << ")\r";
|
<< accept_count << ")\r";
|
||||||
@@ -734,7 +734,7 @@ void DFA::minimize(dfaflags_t flags)
|
|||||||
(*m)->partition = new_part;
|
(*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 "
|
cerr << "\033[2KMinimize dfa: partitions "
|
||||||
<< partitions.size() << "\tinit "
|
<< partitions.size() << "\tinit "
|
||||||
<< init_count << " (accept "
|
<< init_count << " (accept "
|
||||||
@@ -743,7 +743,7 @@ void DFA::minimize(dfaflags_t flags)
|
|||||||
} while (new_part_count);
|
} while (new_part_count);
|
||||||
|
|
||||||
if (partitions.size() == states.size()) {
|
if (partitions.size() == states.size()) {
|
||||||
if (flags & DFA_DUMP_STATS)
|
if (opts.dfadump & DUMP_DFA_STATS)
|
||||||
cerr << "\033[2KDfa minimization no states removed: partitions "
|
cerr << "\033[2KDfa minimization no states removed: partitions "
|
||||||
<< partitions.size() << "\tinit " << init_count
|
<< partitions.size() << "\tinit " << init_count
|
||||||
<< " (accept " << accept_count << ")\n";
|
<< " (accept " << accept_count << ")\n";
|
||||||
@@ -757,13 +757,13 @@ void DFA::minimize(dfaflags_t flags)
|
|||||||
* to states within the same partitions, however this can slow
|
* to states within the same partitions, however this can slow
|
||||||
* down compressed dfa compression as there are more states,
|
* 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";
|
cerr << "Partitions after minimization\n";
|
||||||
for (list<Partition *>::iterator p = partitions.begin();
|
for (list<Partition *>::iterator p = partitions.begin();
|
||||||
p != partitions.end(); p++) {
|
p != partitions.end(); p++) {
|
||||||
/* representative state for this partition */
|
/* representative state for this partition */
|
||||||
State *rep = *((*p)->begin());
|
State *rep = *((*p)->begin());
|
||||||
if (flags & DFA_DUMP_MIN_PARTS)
|
if (opts.dfadump & DUMP_DFA_MIN_PARTS)
|
||||||
cerr << *rep << " : ";
|
cerr << *rep << " : ";
|
||||||
|
|
||||||
/* update representative state's transitions */
|
/* update representative state's transitions */
|
||||||
@@ -782,17 +782,17 @@ void DFA::minimize(dfaflags_t flags)
|
|||||||
/* clear the state label for all non representative states,
|
/* clear the state label for all non representative states,
|
||||||
* and accumulate permissions */
|
* and accumulate permissions */
|
||||||
for (Partition::iterator i = ++(*p)->begin(); i != (*p)->end(); i++) {
|
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 << ", ";
|
cerr << **i << ", ";
|
||||||
(*i)->label = -1;
|
(*i)->label = -1;
|
||||||
rep->perms.add((*i)->perms, filedfa);
|
rep->perms.add((*i)->perms, filedfa);
|
||||||
}
|
}
|
||||||
if (rep->perms.is_accept())
|
if (rep->perms.is_accept())
|
||||||
final_accept++;
|
final_accept++;
|
||||||
if (flags & DFA_DUMP_MIN_PARTS)
|
if (opts.dfadump & DUMP_DFA_MIN_PARTS)
|
||||||
cerr << "\n";
|
cerr << "\n";
|
||||||
}
|
}
|
||||||
if (flags & DFA_DUMP_STATS)
|
if (opts.dfadump & DUMP_DFA_STATS)
|
||||||
cerr << "\033[2KMinimized dfa: final partitions "
|
cerr << "\033[2KMinimized dfa: final partitions "
|
||||||
<< partitions.size() << " (accept " << final_accept
|
<< partitions.size() << " (accept " << final_accept
|
||||||
<< ")" << "\tinit " << init_count << " (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
|
* 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
|
* This function reduces the number of transitions that need to be stored
|
||||||
* by encoding transitions as the difference between the state and a
|
* 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 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.
|
* 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;
|
DiffDag *dag;
|
||||||
unsigned int xcount = 0, xweight = 0, transitions = 0, depth = 0;
|
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 "
|
cerr << "\033[2KDiff Encode: " << i << " of "
|
||||||
<< tail << ". Diff states " << xcount
|
<< tail << ". Diff states " << xcount
|
||||||
<< " Savings " << xweight << "\r";
|
<< " 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 "
|
cerr << "Diff encode states: " << diffcount << " of "
|
||||||
<< tail << " reached @ depth " << depth << ". "
|
<< tail << " reached @ depth " << depth << ". "
|
||||||
<< aweight << " trans removed\n";
|
<< 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
|
* Compute character equivalence classes in the DFA to save space in the
|
||||||
* transition table.
|
* transition table.
|
||||||
*/
|
*/
|
||||||
map<transchar, transchar> DFA::equivalence_classes(dfaflags_t flags)
|
map<transchar, transchar> DFA::equivalence_classes(optflags const &opts)
|
||||||
{
|
{
|
||||||
map<transchar, transchar> classes;
|
map<transchar, transchar> classes;
|
||||||
transchar next_class = 1;
|
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",
|
fprintf(stderr, "Equiv class reduces to %d classes\n",
|
||||||
next_class.c - 1);
|
next_class.c - 1);
|
||||||
return classes;
|
return classes;
|
||||||
|
@@ -305,7 +305,7 @@ class DFA {
|
|||||||
State *add_new_state(NodeSet *nodes, State *other);
|
State *add_new_state(NodeSet *nodes, State *other);
|
||||||
State *add_new_state(NodeSet *anodes, NodeSet *nnodes, State *other);
|
State *add_new_state(NodeSet *anodes, NodeSet *nnodes, State *other);
|
||||||
void update_state_transitions(State *state);
|
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,
|
void dump_diff_chain(ostream &os, map<State *, Partition> &relmap,
|
||||||
Partition &chain, State *state,
|
Partition &chain, State *state,
|
||||||
unsigned int &count, unsigned int &total,
|
unsigned int &count, unsigned int &total,
|
||||||
@@ -318,19 +318,19 @@ class DFA {
|
|||||||
list<State *> work_queue;
|
list<State *> work_queue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DFA(Node *root, dfaflags_t flags, bool filedfa);
|
DFA(Node *root, optflags const &flags, bool filedfa);
|
||||||
virtual ~DFA();
|
virtual ~DFA();
|
||||||
|
|
||||||
State *match_len(State *state, const char *str, size_t len);
|
State *match_len(State *state, const char *str, size_t len);
|
||||||
State *match_until(State *state, const char *str, const char term);
|
State *match_until(State *state, const char *str, const char term);
|
||||||
State *match(const char *str);
|
State *match(const char *str);
|
||||||
|
|
||||||
void remove_unreachable(dfaflags_t flags);
|
void remove_unreachable(optflags const &flags);
|
||||||
bool same_mappings(State *s1, State *s2);
|
bool same_mappings(State *s1, State *s2);
|
||||||
void minimize(dfaflags_t flags);
|
void minimize(optflags const &flags);
|
||||||
int apply_and_clear_deny(void);
|
int apply_and_clear_deny(void);
|
||||||
|
|
||||||
void diff_encode(dfaflags_t flags);
|
void diff_encode(optflags const &flags);
|
||||||
void undiff_encode(void);
|
void undiff_encode(void);
|
||||||
void dump_diff_encode(ostream &os);
|
void dump_diff_encode(ostream &os);
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ public:
|
|||||||
void dump_dot_graph(ostream &os);
|
void dump_dot_graph(ostream &os);
|
||||||
void dump_uniq_perms(const char *s);
|
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);
|
void apply_equivalence_classes(map<transchar, transchar> &eq);
|
||||||
|
|
||||||
unsigned int diffcount;
|
unsigned int diffcount;
|
||||||
|
@@ -798,7 +798,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count,
|
|||||||
* else it has full perms
|
* else it has full perms
|
||||||
*/
|
*/
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
|
||||||
vec, dfaflags, false))
|
vec, parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
@@ -810,7 +810,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count,
|
|||||||
vec[4] = optsbuf.c_str();
|
vec[4] = optsbuf.c_str();
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||||
(audit == AUDIT_FORCE ? perms : 0),
|
(audit == AUDIT_FORCE ? perms : 0),
|
||||||
5, vec, dfaflags, false))
|
5, vec, parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -852,7 +852,7 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count,
|
|||||||
vec[3] = flagsbuf;
|
vec[3] = flagsbuf;
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||||
4, vec,
|
4, vec,
|
||||||
dfaflags, false))
|
parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
@@ -909,7 +909,7 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count,
|
|||||||
vec[3] = flagsbuf;
|
vec[3] = flagsbuf;
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||||
4, vec,
|
4, vec,
|
||||||
dfaflags, false))
|
parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
@@ -952,7 +952,7 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count,
|
|||||||
vec[3] = flagsbuf;
|
vec[3] = flagsbuf;
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||||
4, vec,
|
4, vec,
|
||||||
dfaflags, false))
|
parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
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 */
|
/* rule for match without required data || data MATCH_CONT */
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4,
|
||||||
vec, dfaflags, false))
|
vec, parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
@@ -1015,7 +1015,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count,
|
|||||||
vec[4] = optsbuf.c_str();
|
vec[4] = optsbuf.c_str();
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||||
audit == AUDIT_FORCE ? perms : 0,
|
audit == AUDIT_FORCE ? perms : 0,
|
||||||
5, vec, dfaflags, false))
|
5, vec, parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1107,7 @@ int mnt_rule::gen_policy_re(Profile &prof)
|
|||||||
vec[0] = mntbuf.c_str();
|
vec[0] = mntbuf.c_str();
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||||
(audit == AUDIT_FORCE ? perms : 0), 1, vec,
|
(audit == AUDIT_FORCE ? perms : 0), 1, vec,
|
||||||
dfaflags, false))
|
parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -1122,7 +1122,7 @@ int mnt_rule::gen_policy_re(Profile &prof)
|
|||||||
vec[1] = devbuf.c_str();
|
vec[1] = devbuf.c_str();
|
||||||
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms,
|
||||||
(audit == AUDIT_FORCE ? perms : 0), 2, vec,
|
(audit == AUDIT_FORCE ? perms : 0), 2, vec,
|
||||||
dfaflags, false))
|
parseopts, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@@ -231,10 +231,10 @@ int mqueue_rule::gen_policy_re(Profile &prof)
|
|||||||
/* store perms at name match so label doesn't need
|
/* store perms at name match so label doesn't need
|
||||||
* to be checked
|
* 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;
|
goto fail;
|
||||||
/* also provide label match with perm */
|
/* 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;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,10 +266,10 @@ int mqueue_rule::gen_policy_re(Profile &prof)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (perms & AA_VALID_SYSV_MQ_PERMS) {
|
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;
|
goto fail;
|
||||||
/* also provide label match with perm */
|
/* 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;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -82,9 +82,6 @@ extern int parser_token;
|
|||||||
WARN_UNEXPECTED | WARN_FORMAT | WARN_MISSING | \
|
WARN_UNEXPECTED | WARN_FORMAT | WARN_MISSING | \
|
||||||
WARN_OVERRIDE | WARN_INCLUDE)
|
WARN_OVERRIDE | WARN_INCLUDE)
|
||||||
|
|
||||||
extern dfaflags_t warnflags;
|
|
||||||
extern dfaflags_t werrflags;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum pattern_t pattern_t;
|
typedef enum pattern_t pattern_t;
|
||||||
|
|
||||||
@@ -362,7 +359,6 @@ extern int conf_quiet;
|
|||||||
extern int names_only;
|
extern int names_only;
|
||||||
extern int option;
|
extern int option;
|
||||||
extern int current_lineno;
|
extern int current_lineno;
|
||||||
extern dfaflags_t dfaflags;
|
|
||||||
extern const char *progname;
|
extern const char *progname;
|
||||||
extern char *profilename;
|
extern char *profilename;
|
||||||
extern char *profile_ns;
|
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 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);
|
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) */
|
/* from parser_main (cannot be used in tst builds) */
|
||||||
extern int force_complain;
|
extern int force_complain;
|
||||||
|
@@ -89,9 +89,6 @@ int names_only = 0;
|
|||||||
int current_lineno = 1;
|
int current_lineno = 1;
|
||||||
int option = OPTION_ADD;
|
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__;
|
const char *progname = __FILE__;
|
||||||
char *profile_ns = NULL;
|
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?? */
|
/* 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)
|
void common_warn_once(const char *name, const char *msg, const char **warned_name)
|
||||||
{
|
{
|
||||||
if ((warnflags & WARN_RULE_NOT_ENFORCED) && *warned_name != name) {
|
if ((parseopts.warn & WARN_RULE_NOT_ENFORCED) && *warned_name != name) {
|
||||||
if (werrflags & WARN_RULE_NOT_ENFORCED)
|
if (parseopts.Werror & WARN_RULE_NOT_ENFORCED)
|
||||||
cerr << "Warning converted to Error";
|
cerr << "Warning converted to Error";
|
||||||
else
|
else
|
||||||
cerr << "Warning";
|
cerr << "Warning";
|
||||||
@@ -154,6 +151,6 @@ void common_warn_once(const char *name, const char *msg, const char **warned_nam
|
|||||||
*warned_name = name;
|
*warned_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (werrflags & WARN_RULE_NOT_ENFORCED)
|
if (parseopts.Werror & WARN_RULE_NOT_ENFORCED)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@@ -493,11 +493,11 @@ static int process_arg(int c, char *optarg)
|
|||||||
strcmp(optarg, "dump") == 0 ||
|
strcmp(optarg, "dump") == 0 ||
|
||||||
strcmp(optarg, "D") == 0) {
|
strcmp(optarg, "D") == 0) {
|
||||||
flagtable_help("--dump=", DUMP_HEADER, progname,
|
flagtable_help("--dump=", DUMP_HEADER, progname,
|
||||||
dumpflag_table);
|
dfadumpflag_table);
|
||||||
} else if (strcmp(optarg, "Optimize") == 0 ||
|
} else if (strcmp(optarg, "Optimize") == 0 ||
|
||||||
strcmp(optarg, "optimize") == 0 ||
|
strcmp(optarg, "optimize") == 0 ||
|
||||||
strcmp(optarg, "O") == 0) {
|
strcmp(optarg, "O") == 0) {
|
||||||
flagtable_help("-O ", "", progname, optflag_table);
|
flagtable_help("-O ", "", progname, dfaoptflag_table);
|
||||||
} else if (strcmp(optarg, "warn") == 0) {
|
} else if (strcmp(optarg, "warn") == 0) {
|
||||||
flagtable_help("--warn=", "", progname, warnflag_table);
|
flagtable_help("--warn=", "", progname, warnflag_table);
|
||||||
} else if (strcmp(optarg, "Werror") == 0) {
|
} else if (strcmp(optarg, "Werror") == 0) {
|
||||||
@@ -568,13 +568,13 @@ static int process_arg(int c, char *optarg)
|
|||||||
if (!optarg) {
|
if (!optarg) {
|
||||||
dump_vars = 1;
|
dump_vars = 1;
|
||||||
} else if (strcmp(optarg, "show") == 0) {
|
} 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) {
|
} else if (strcmp(optarg, "variables") == 0) {
|
||||||
dump_vars = 1;
|
dump_vars = 1;
|
||||||
} else if (strcmp(optarg, "expanded-variables") == 0) {
|
} else if (strcmp(optarg, "expanded-variables") == 0) {
|
||||||
dump_expanded_vars = 1;
|
dump_expanded_vars = 1;
|
||||||
} else if (!handle_flag_table(dumpflag_table, optarg,
|
} else if (!handle_flag_table(dfadumpflag_table, optarg,
|
||||||
&dfaflags)) {
|
&parseopts.dfadump)) {
|
||||||
PERROR("%s: Invalid --Dump option %s\n",
|
PERROR("%s: Invalid --Dump option %s\n",
|
||||||
progname, optarg);
|
progname, optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -582,9 +582,9 @@ static int process_arg(int c, char *optarg)
|
|||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
if (strcmp(optarg, "show") == 0) {
|
if (strcmp(optarg, "show") == 0) {
|
||||||
print_flags("Optimize", optflag_table, dfaflags);
|
print_flags("Optimize", dfaoptflag_table, parseopts.dfaflags);
|
||||||
} else if (!handle_flag_table(optflag_table, optarg,
|
} else if (!handle_flag_table(dfaoptflag_table, optarg,
|
||||||
&dfaflags)) {
|
&parseopts.dfaflags)) {
|
||||||
PERROR("%s: Invalid --Optimize option %s\n",
|
PERROR("%s: Invalid --Optimize option %s\n",
|
||||||
progname, optarg);
|
progname, optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -665,7 +665,7 @@ static int process_arg(int c, char *optarg)
|
|||||||
case 'q':
|
case 'q':
|
||||||
conf_verbose = 0;
|
conf_verbose = 0;
|
||||||
conf_quiet = 1;
|
conf_quiet = 1;
|
||||||
warnflags = 0;
|
parseopts.warn = 0;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
conf_verbose = 1;
|
conf_verbose = 1;
|
||||||
@@ -723,9 +723,9 @@ static int process_arg(int c, char *optarg)
|
|||||||
break;
|
break;
|
||||||
case ARG_WARN:
|
case ARG_WARN:
|
||||||
if (strcmp(optarg, "show") == 0) {
|
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,
|
} else if (!handle_flag_table(warnflag_table, optarg,
|
||||||
&warnflags)) {
|
&parseopts.warn)) {
|
||||||
PERROR("%s: Invalid --warn option %s\n",
|
PERROR("%s: Invalid --warn option %s\n",
|
||||||
progname, optarg);
|
progname, optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -733,18 +733,18 @@ static int process_arg(int c, char *optarg)
|
|||||||
break;
|
break;
|
||||||
case ARG_WERROR:
|
case ARG_WERROR:
|
||||||
if (!optarg) {
|
if (!optarg) {
|
||||||
werrflags = -1;
|
parseopts.Werror = -1;
|
||||||
} else if (strcmp(optarg, "show") == 0) {
|
} 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,
|
} else if (optarg && !handle_flag_table(warnflag_table, optarg,
|
||||||
&werrflags)) {
|
&parseopts.Werror)) {
|
||||||
PERROR("%s: Invalid --Werror option %s\n",
|
PERROR("%s: Invalid --Werror option %s\n",
|
||||||
progname, optarg);
|
progname, optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_DEBUG_CACHE:
|
case ARG_DEBUG_CACHE:
|
||||||
warnflags |= WARN_DEBUG_CACHE;
|
parseopts.warn |= WARN_DEBUG_CACHE;
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
jobs = process_jobs_arg("-j", optarg);
|
jobs = process_jobs_arg("-j", optarg);
|
||||||
@@ -1530,7 +1530,7 @@ static bool get_kernel_features(struct aa_features **features)
|
|||||||
|
|
||||||
if (!kernel_supports_diff_encode)
|
if (!kernel_supports_diff_encode)
|
||||||
/* clear diff_encode because it is not supported */
|
/* clear diff_encode because it is not supported */
|
||||||
dfaflags &= ~DFA_CONTROL_DIFF_ENCODE;
|
parseopts.dfaflags &= ~CONTROL_DFA_DIFF_ENCODE;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
|
#include "common_optarg.h"
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
@@ -128,7 +128,7 @@ pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, int glob,
|
|||||||
|
|
||||||
sptr = aare;
|
sptr = aare;
|
||||||
|
|
||||||
if (dfaflags & DFA_DUMP_RULE_EXPR)
|
if (parseopts.dfadump & DUMP_DFA_RULE_EXPR)
|
||||||
fprintf(stderr, "aare: %s -> ", aare);
|
fprintf(stderr, "aare: %s -> ", aare);
|
||||||
|
|
||||||
if (anchor)
|
if (anchor)
|
||||||
@@ -427,7 +427,7 @@ out:
|
|||||||
if (ret == FALSE)
|
if (ret == FALSE)
|
||||||
ptype = ePatternInvalid;
|
ptype = ePatternInvalid;
|
||||||
|
|
||||||
if (dfaflags & DFA_DUMP_RULE_EXPR)
|
if (parseopts.dfadump & DUMP_DFA_RULE_EXPR)
|
||||||
fprintf(stderr, "%s\n", pcre.c_str());
|
fprintf(stderr, "%s\n", pcre.c_str());
|
||||||
|
|
||||||
return ptype;
|
return ptype;
|
||||||
@@ -507,7 +507,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||||||
aare_rules *rules = new aare_rules();
|
aare_rules *rules = new aare_rules();
|
||||||
if (!rules)
|
if (!rules)
|
||||||
return FALSE;
|
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;
|
delete rules;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -520,7 +520,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||||||
ptype = convert_aaregex_to_pcre(alt->name, 0,
|
ptype = convert_aaregex_to_pcre(alt->name, 0,
|
||||||
glob_default,
|
glob_default,
|
||||||
tbuf, &len);
|
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;
|
delete rules;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -562,14 +562,14 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||||||
convert_aaregex_to_pcre(xattr_value, 0,
|
convert_aaregex_to_pcre(xattr_value, 0,
|
||||||
glob_null, tbuf,
|
glob_null, tbuf,
|
||||||
&len);
|
&len);
|
||||||
if (!rules->append_rule(tbuf.c_str(), true, true, dfaflags)) {
|
if (!rules->append_rule(tbuf.c_str(), true, true, parseopts)) {
|
||||||
delete rules;
|
delete rules;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
build:
|
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;
|
delete rules;
|
||||||
if (!prof->xmatch)
|
if (!prof->xmatch)
|
||||||
return FALSE;
|
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,
|
!dfarules->add_rule(tbuf.c_str(), entry->rule_mode == RULE_DENY,
|
||||||
entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
|
entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
|
||||||
entry->audit == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0,
|
entry->audit == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (!is_change_profile_perms(entry->perms)) {
|
} else if (!is_change_profile_perms(entry->perms)) {
|
||||||
if (!dfarules->add_rule(tbuf.c_str(),
|
if (!dfarules->add_rule(tbuf.c_str(),
|
||||||
entry->rule_mode == RULE_DENY, entry->perms,
|
entry->rule_mode == RULE_DENY, entry->perms,
|
||||||
entry->audit == AUDIT_FORCE ? entry->perms : 0,
|
entry->audit == AUDIT_FORCE ? entry->perms : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,7 +667,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
|
|||||||
perms |= LINK_TO_LINK_SUBSET(perms);
|
perms |= LINK_TO_LINK_SUBSET(perms);
|
||||||
vec[1] = "/[^/].*";
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (is_change_profile_perms(entry->perms)) {
|
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;
|
int index = 1;
|
||||||
uint32_t onexec_perms = AA_ONEXEC;
|
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
|
/* don't have profile name here, so until this code
|
||||||
* gets refactored just throw out a generic warning
|
* 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 */
|
/* regular change_profile rule */
|
||||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY,
|
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY,
|
||||||
AA_CHANGE_PROFILE | onexec_perms,
|
AA_CHANGE_PROFILE | onexec_perms,
|
||||||
0, index - 1, &vec[1], dfaflags, false))
|
0, index - 1, &vec[1], parseopts, false))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* onexec rules - both rules are needed for onexec */
|
/* onexec rules - both rules are needed for onexec */
|
||||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms,
|
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms,
|
||||||
0, 1, vec, dfaflags, false))
|
0, 1, vec, parseopts, false))
|
||||||
return 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));
|
onexec_perms |= (entry->perms & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE));
|
||||||
if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms,
|
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 FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -770,7 +770,7 @@ int process_profile_regex(Profile *prof)
|
|||||||
if (prof->dfa.rules->rule_count > 0) {
|
if (prof->dfa.rules->rule_count > 0) {
|
||||||
int xmatch_len = 0;
|
int xmatch_len = 0;
|
||||||
prof->dfa.dfa = prof->dfa.rules->create_dfa(&prof->dfa.size,
|
prof->dfa.dfa = prof->dfa.rules->create_dfa(&prof->dfa.size,
|
||||||
&xmatch_len, dfaflags, true);
|
&xmatch_len, parseopts, true);
|
||||||
delete prof->dfa.rules;
|
delete prof->dfa.rules;
|
||||||
prof->dfa.rules = NULL;
|
prof->dfa.rules = NULL;
|
||||||
if (!prof->dfa.dfa)
|
if (!prof->dfa.dfa)
|
||||||
@@ -875,7 +875,7 @@ static bool gen_net_rule(Profile *prof, u16 family, unsigned int type_mask,
|
|||||||
buf = buffer.str();
|
buf = buffer.str();
|
||||||
if (!prof->policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_VALID_NET_PERMS),
|
if (!prof->policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_VALID_NET_PERMS),
|
||||||
audit ? map_perms(AA_VALID_NET_PERMS) : 0,
|
audit ? map_perms(AA_VALID_NET_PERMS) : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -969,44 +969,44 @@ int process_profile_policydb(Profile *prof)
|
|||||||
|
|
||||||
/* note: this activates fs based unix domain sockets mediation on connect */
|
/* note: this activates fs based unix domain sockets mediation on connect */
|
||||||
if (kernel_abi_version > 5 &&
|
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;
|
goto out;
|
||||||
if (features_supports_mount &&
|
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;
|
goto out;
|
||||||
if (features_supports_dbus &&
|
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;
|
goto out;
|
||||||
if (features_supports_signal &&
|
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;
|
goto out;
|
||||||
if (features_supports_ptrace &&
|
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;
|
goto out;
|
||||||
if (features_supports_networkv8 &&
|
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;
|
goto out;
|
||||||
if (features_supports_unix &&
|
if (features_supports_unix &&
|
||||||
(!prof->policy.rules->add_rule(mediates_extended_net, 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, dfaflags)))
|
!prof->policy.rules->add_rule(mediates_net_unix, 0, AA_MAY_READ, 0, parseopts)))
|
||||||
goto out;
|
goto out;
|
||||||
if (features_supports_userns &&
|
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;
|
goto out;
|
||||||
if (features_supports_posix_mqueue &&
|
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;
|
goto out;
|
||||||
if (features_supports_sysv_mqueue &&
|
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;
|
goto out;
|
||||||
if (features_supports_io_uring &&
|
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;
|
goto out;
|
||||||
|
|
||||||
if (prof->policy.rules->rule_count > 0) {
|
if (prof->policy.rules->rule_count > 0) {
|
||||||
int xmatch_len = 0;
|
int xmatch_len = 0;
|
||||||
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size,
|
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size,
|
||||||
&xmatch_len, dfaflags, false);
|
&xmatch_len, parseopts, false);
|
||||||
delete prof->policy.rules;
|
delete prof->policy.rules;
|
||||||
|
|
||||||
prof->policy.rules = NULL;
|
prof->policy.rules = NULL;
|
||||||
|
@@ -134,7 +134,7 @@ int ptrace_rule::gen_policy_re(Profile &prof)
|
|||||||
buf = buffer.str();
|
buf = buffer.str();
|
||||||
if (perms & AA_VALID_PTRACE_PERMS) {
|
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,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -317,7 +317,7 @@ int signal_rule::gen_policy_re(Profile &prof)
|
|||||||
buf = buffer.str();
|
buf = buffer.str();
|
||||||
if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
|
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,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -97,7 +97,7 @@ int userns_rule::gen_policy_re(Profile &prof)
|
|||||||
if (perms & AA_VALID_USERNS_PERMS) {
|
if (perms & AA_VALID_USERNS_PERMS) {
|
||||||
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
|
if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms,
|
||||||
audit == AUDIT_FORCE ? perms : 0,
|
audit == AUDIT_FORCE ? perms : 0,
|
||||||
dfaflags))
|
parseopts))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user