[apparmor] [Patch] Bug 888077 - aliases being partially applied
John Johansen
john.johansen at canonical.com
Mon Jul 8 09:06:42 UTC 2013
Below is a mostly complete patch for https://bugs.launchpad.net/apparmor/+bug/888077
It is currently missing support for link and mount rules. This patch is
done against the 2.8 branch, and the question is, is this something we
want in 2.8.2/3. It is rather large, and I want to rework it some before
it goes to the 2.9/3.0 branch. So the two branch will differ on this
point if we pull it into 2.8
---
diff --git a/parser/libapparmor_re/aare_rules.cc b/parser/libapparmor_re/aare_rules.cc
index 45664c0..5e6d652 100644
--- a/parser/libapparmor_re/aare_rules.cc
+++ b/parser/libapparmor_re/aare_rules.cc
@@ -76,6 +76,9 @@ DenyMatchFlag *deny_flags[FLAGS_WIDTH][MATCH_FLAGS_SIZE];
MatchFlag *exec_match_flags[FLAGS_WIDTH][EXEC_MATCH_FLAGS_SIZE]; /* mods + unsafe + ix + pux * u::o */
ExactMatchFlag *exact_match_flags[FLAGS_WIDTH][EXEC_MATCH_FLAGS_SIZE]; /* mods + unsafe + ix + pux *u::o */
+typedef map<pair<const char *, const char *>, AliasToNode *> AliasMap;
+AliasMap alias_map;
+
extern "C" void aare_reset_matchflags(void)
{
uint32_t i, j;
@@ -92,6 +95,42 @@ extern "C" void aare_reset_matchflags(void)
RESET_FLAGS(exec_match_flags, EXEC_MATCH_FLAGS_SIZE);
RESET_FLAGS(exact_match_flags, EXEC_MATCH_FLAGS_SIZE);
#undef RESET_FLAGS
+ alias_map.clear();
+}
+
+extern "C" int aare_add_alias(aare_ruleset_t *rules, const char *from,
+ const char *to)
+{
+ Node *tree_from = NULL, *tree_to = NULL;
+ AliasToNode *node = NULL;
+
+ AliasMap::iterator i = alias_map.find(make_pair(from, to));
+ if (i == alias_map.end()) {
+ node = new AliasToNode();
+ alias_map.insert(make_pair(make_pair(from, to), node));
+ } else {
+ node = i->second;
+ }
+
+ if (regex_parse(&tree_from, from))
+ return 0;
+ if (rules->reverse)
+ flip_tree(tree_from);
+ if (rules->root)
+ rules->root = new AltNode(rules->root, new CatNode(tree_from, &node->from));
+ else
+ rules->root = new CatNode(tree_from, &node->from);
+
+ if (regex_parse(&tree_to, to))
+ return 0;
+ if (rules->reverse)
+ flip_tree(tree_to);
+ if (rules->root)
+ rules->root = new AltNode(rules->root, new CatNode(tree_to, node));
+ else
+ rules->root = new CatNode(tree_to, node);
+
+ return 1;
}
extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, int deny,
diff --git a/parser/libapparmor_re/aare_rules.h b/parser/libapparmor_re/aare_rules.h
index 33e554c..c053530 100644
--- a/parser/libapparmor_re/aare_rules.h
+++ b/parser/libapparmor_re/aare_rules.h
@@ -40,6 +40,7 @@ int aare_add_rule(aare_ruleset_t *rules, char *rule, int deny, uint32_t perms,
int aare_add_rule_vec(aare_ruleset_t *rules, int deny, uint32_t perms,
uint32_t audit, int count, char **rulev,
dfaflags_t flags);
+int aare_add_alias(aare_ruleset_t *rules, const char *from, const char *to);
void *aare_create_dfa(aare_ruleset_t *rules, size_t *size, dfaflags_t flags);
void aare_reset_matchflags(void);
diff --git a/parser/libapparmor_re/apparmor_re.h b/parser/libapparmor_re/apparmor_re.h
index 186899c..1fdb915 100644
--- a/parser/libapparmor_re/apparmor_re.h
+++ b/parser/libapparmor_re/apparmor_re.h
@@ -30,6 +30,10 @@ typedef enum dfaflags {
DFA_CONTROL_REMOVE_UNREACHABLE = 1 << 7,
DFA_CONTROL_TRANS_HIGH = 1 << 8,
+ DFA_COMPAT_OLD_ALIAS = 1 << 10,
+
+ DFA_DUMP_ALIAS_INFO = 1 << 11,
+ DFA_DUMP_PRE_ALIAS = 1 << 12,
DFA_DUMP_MIN_PARTS = 1 << 13,
DFA_DUMP_UNIQ_PERMS = 1 << 14,
DFA_DUMP_MIN_UNIQ_PERMS = 1 << 15,
diff --git a/parser/libapparmor_re/expr-tree.h b/parser/libapparmor_re/expr-tree.h
index 29c2ded..651a02d 100644
--- a/parser/libapparmor_re/expr-tree.h
+++ b/parser/libapparmor_re/expr-tree.h
@@ -205,6 +205,7 @@ public:
void compute_lastpos() { lastpos.insert(this); }
virtual void follow(Cases &cases) = 0;
virtual int is_accept(void) = 0;
+ virtual int is_postprocess(void) = 0;
};
/* common base class for all the different classes that contain
@@ -214,6 +215,7 @@ class CNode: public ImportantNode {
public:
CNode(): ImportantNode() { }
int is_accept(void) { return false; }
+ int is_postprocess(void) { return false; }
};
/* Match one specific character (/c/). */
@@ -358,35 +360,6 @@ public:
ostream &dump(ostream &os) { return os << "."; }
};
-/**
- * Indicate that a regular expression matches. An AcceptNode itself
- * doesn't match anything, so it will never generate any transitions.
- */
-class AcceptNode: public ImportantNode {
-public:
- AcceptNode() { }
- int is_accept(void) { return true; }
- void release(void)
- {
- /* don't delete AcceptNode via release as they are shared, and
- * will be deleted when the table the are stored in is deleted
- */
- }
-
- void follow(Cases &cases __attribute__ ((unused)))
- {
- /* Nothing to follow. */
- }
-
- /* requires accept nodes to be common by pointer */
- int eq(Node *other)
- {
- if (dynamic_cast<AcceptNode *>(other))
- return (this == other);
- return 0;
- }
-};
-
/* Match a node zero or more times. (This is a unary operator.) */
class StarNode: public OneChildNode {
public:
@@ -523,6 +496,55 @@ public:
}
};
+class SharedNode: public ImportantNode {
+public:
+ SharedNode() { }
+ void release(void)
+ {
+ /* don't delete SharedNodes via release as they are shared, and
+ * will be deleted when the table they are stored in is deleted
+ */
+ }
+
+ void follow(Cases &cases __attribute__ ((unused)))
+ {
+ /* Nothing to follow. */
+ }
+
+ /* requires shared nodes to be common by pointer */
+ int eq(Node *other) { return (this == other); }
+};
+
+/**
+ * Indicate that a regular expression matches. An AcceptNode itself
+ * doesn't match anything, so it will never generate any transitions.
+ */
+class AcceptNode: public SharedNode {
+public:
+ AcceptNode() { }
+ int is_accept(void) { return true; }
+ int is_postprocess(void) { return false; }
+};
+
+class MatchFlag: public AcceptNode {
+public:
+ MatchFlag(uint32_t flag, uint32_t audit): flag(flag), audit(audit) { }
+ ostream &dump(ostream &os) { return os << '<' << flag << '>'; }
+
+ uint32_t flag;
+ uint32_t audit;
+};
+
+class ExactMatchFlag: public MatchFlag {
+public:
+ ExactMatchFlag(uint32_t flag, uint32_t audit): MatchFlag(flag, audit) {}
+};
+
+class DenyMatchFlag: public MatchFlag {
+public:
+ DenyMatchFlag(uint32_t flag, uint32_t quiet): MatchFlag(flag, quiet) {}
+};
+
/* Traverse the syntax tree depth-first in an iterator-like manner. */
class depth_first_traversal {
stack<Node *>pos;
@@ -574,24 +596,4 @@ void label_nodes(Node *root);
unsigned long hash_NodeSet(NodeSet *ns);
void flip_tree(Node *node);
-
-class MatchFlag: public AcceptNode {
-public:
- MatchFlag(uint32_t flag, uint32_t audit): flag(flag), audit(audit) { }
- ostream &dump(ostream &os) { return os << '<' << flag << '>'; }
-
- uint32_t flag;
- uint32_t audit;
-};
-
-class ExactMatchFlag: public MatchFlag {
-public:
- ExactMatchFlag(uint32_t flag, uint32_t audit): MatchFlag(flag, audit) {}
-};
-
-class DenyMatchFlag: public MatchFlag {
-public:
- DenyMatchFlag(uint32_t flag, uint32_t quiet): MatchFlag(flag, quiet) {}
-};
-
#endif /* __LIBAA_RE_EXPR */
diff --git a/parser/libapparmor_re/hfa.cc b/parser/libapparmor_re/hfa.cc
index e779dd3..34a18d9 100644
--- a/parser/libapparmor_re/hfa.cc
+++ b/parser/libapparmor_re/hfa.cc
@@ -73,10 +73,13 @@ ostream &operator<<(ostream &os, const State &state)
return os;
}
-static void split_node_types(NodeSet *nodes, NodeSet **anodes, NodeSet **nnodes
-)
+typedef set<PostProcessNode *> PostNodeSet;
+
+static void split_node_types(NodeSet *nodes, NodeSet **anodes, NodeSet **nnodes,
+ PostNodeSet **postnodes)
{
*anodes = *nnodes = NULL;
+ *postnodes = NULL;
for (NodeSet::iterator i = nodes->begin(); i != nodes->end(); ) {
if ((*i)->is_accept()) {
if (!*anodes)
@@ -84,20 +87,21 @@ static void split_node_types(NodeSet *nodes, NodeSet **anodes, NodeSet **nnodes
(*anodes)->insert(*i);
NodeSet::iterator k = i++;
nodes->erase(k);
+ } else if ((*i)->is_postprocess()) {
+ if (!*postnodes)
+ *postnodes = new PostNodeSet;
+ (*postnodes)->insert((PostProcessNode *) *i);
+ NodeSet::iterator k = i++;
+ nodes->erase(k);
} else
i++;
}
*nnodes = nodes;
}
-State *DFA::add_new_state(NodeSet *nodes, State *other)
+State *DFA::add_new_state(NodeSet *anodes, NodeSet *nnodes, State *other)
{
- /* The splitting of nodes should probably get pushed down into
- * follow(), ie. put in separate lists from the start
- */
- NodeSet *anodes, *nnodes;
hashedNodeVec *nnodev;
- split_node_types(nodes, &anodes, &nnodes);
nnodev = nnodes_cache.insert(nnodes);
anodes = anodes_cache.insert(anodes);
@@ -115,6 +119,30 @@ State *DFA::add_new_state(NodeSet *nodes, State *other)
return x.first->second;
}
+State *DFA::add_new_state(NodeSet *nodes, State *other)
+{
+ /* The splitting of nodes should probably get pushed down into
+ * follow(), ie. put in separate lists from the start
+ */
+ NodeSet *anodes, *nnodes;
+ PostNodeSet *postnodes;
+ split_node_types(nodes, &anodes, &nnodes, &postnodes);
+
+ State *state = add_new_state(anodes, nnodes, other);
+
+ /* add state to each unique post process node */
+ if (postnodes && state != nonmatching) {
+ for (PostNodeSet::iterator i = postnodes->begin();
+ i != postnodes->end(); i++) {
+//cerr << "adding state " << *state << " to postnode " << *i << "\n";
+ (*i)->states.insert(state);
+ }
+ dfa_postnodes.insert(postnodes->begin(), postnodes->end());
+ }
+
+ return state;
+}
+
void DFA::update_state_transitions(State *state)
{
/* Compute possible transitions for state->nodes. This is done by
@@ -169,13 +197,138 @@ void DFA::dump_node_to_dfa(void)
cerr << " " << (*i)->label << " <= " << (*i)->proto << "\n";
}
+class NodeSetPair {
+public:
+ NodeSet *anodes;
+ NodeSet *nnodes;
+
+ NodeSetPair(void) { anodes = nnodes = NULL; }
+ NodeSetPair(NodeSet *a, NodeSet *n) { anodes = a; nnodes = n; }
+
+ void insert(ProtoState &proto) {
+ if (proto.nnodes) {
+ if (!nnodes)
+ nnodes = new NodeSet();
+ nnodes->insert(proto.nnodes->begin(), proto.nnodes->end());
+ }
+ if (proto.anodes) {
+ if (!anodes)
+ anodes = new NodeSet();
+ anodes->insert(proto.anodes->begin(), proto.anodes->end());
+ }
+ }
+};
+//typedef pair<NodeSet *, NodeSet *> NodeSetPair;
+typedef map<uchar, NodeSetPair> NodeSetPairMap;
+
+
+void alias_add_transitions(State &state, NodeSetPair &otherwise,
+ NodeSetPairMap &trans)
+{
+ otherwise.insert(state.otherwise->proto);
+
+ for (StateTrans::iterator k = state.trans.begin(); k != state.trans.end(); k++) {
+ trans[k->first].insert(k->second->proto);
+ }
+}
+
+void DFA::update_state_for_alias(State &state, set<State *> &from,
+ dfaflags_t flags)
+{
+ NodeSetPairMap trans;
+ NodeSetPair otherwise(NULL, NULL);
+ State *target;
+
+ if (flags & DFA_DUMP_ALIAS_INFO) {
+ cerr << "Updating state " << state << " for alias from ";
+ for (set<State *>::iterator i = from.begin(); i != from.end(); i++) {
+ if ((*i) == nonmatching)
+ continue;
+ cerr << (**i) << " ";
+ }
+ cerr << "\n";
+ }
+
+ alias_add_transitions(state, otherwise, trans);
+ for (set<State *>::iterator i = from.begin(); i != from.end(); i++) {
+ if ((*i) == nonmatching)
+ continue;
+ alias_add_transitions(**i, otherwise, trans);
+ }
+
+ /* now update state transitions, to the updated transitions */
+ if (otherwise.nnodes || otherwise.anodes) {
+ target = add_new_state(otherwise.anodes, otherwise.nnodes, nonmatching);
+ if (target != state.otherwise) {
+ if (flags & DFA_DUMP_ALIAS_INFO) {
+ cerr << " updating trans otherwise from ";
+ if (state.otherwise)
+ cerr << *state.otherwise;
+ else
+ cerr << "<null>";
+ cerr << " to " << *target << "\n";
+ }
+ state.otherwise = target;
+ }
+ }
+
+ for (NodeSetPairMap::iterator i = trans.begin(); i != trans.end(); i++) {
+ target = add_new_state(i->second.anodes, i->second.nnodes, nonmatching);
+ if (target == state.otherwise) {
+ if (flags & DFA_DUMP_ALIAS_INFO) {
+ cerr << " removing trans " << i->first << " to ";
+ if (state.trans[i->first])
+ cerr << state.trans[i->first];
+ else
+ cerr << "<null>";
+ cerr << "\n";
+ }
+ state.trans.erase(i->first);
+ } else if (target != state.trans[i->first]) {
+ if (flags & DFA_DUMP_ALIAS_INFO) {
+ cerr << " updating trans " << i->first << " from ";
+ if (state.trans[i->first])
+ cerr << *state.trans[i->first];
+ else
+ cerr << "<null>";
+ cerr << " to " << *target << "\n";
+ }
+ state.trans[i->first] = target;
+ }
+ }
+}
+
+void DFA::process_work_queue(const char *header, dfaflags_t flags)
+{
+ int i = 0;
+
+ while (!work_queue.empty()) {
+ if (i % 1000 == 0 && (flags & DFA_DUMP_PROGRESS)) {
+ cerr << "\033[2K" << header << ": queue "
+ << work_queue.size()
+ << "\tstates "
+ << states.size()
+ << "\teliminated duplicates "
+ << node_map.dup
+ << "\r";
+ }
+ i++;
+
+ State *from = work_queue.front();
+ work_queue.pop_front();
+
+ /* Update 'from's transitions, and if it transitions to any
+ * unknown State create it and add it to the work_queue
+ */
+ update_state_transitions(from);
+ } /* while (!work_queue.empty()) */
+}
+
/**
* Construct a DFA from a syntax tree.
*/
DFA::DFA(Node *root, dfaflags_t flags): root(root)
{
- int i = 0;
-
if (flags & DFA_DUMP_PROGRESS)
fprintf(stderr, "Creating dfa:\r");
@@ -205,28 +358,28 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root)
* work_queue at any given time, thus reducing peak memory use.
*/
work_queue.push_back(start);
+ process_work_queue("Creating dfa", flags);
- while (!work_queue.empty()) {
- if (i % 1000 == 0 && (flags & DFA_DUMP_PROGRESS)) {
- cerr << "\033[2KCreating dfa: queue "
- << work_queue.size()
- << "\tstates "
- << states.size()
- << "\teliminated duplicates "
- << node_map.dup
- << "\r";
- }
- i++;
+ /* apply post process nodes before minimization. This lets us remove
+ * nodes/states in minimization that are made no longer reachable
+ * by post processing
+ */
- State *from = work_queue.front();
- work_queue.pop_front();
+ if (!dfa_postnodes.empty()) {
+ if (flags & DFA_DUMP_PRE_ALIAS) {
+ cerr << "DFA before alias rewrite\n";
+ this->dump(cerr);
+ }
+ for (set<PostProcessNode *>::iterator i = dfa_postnodes.begin();
+ i != dfa_postnodes.end(); i++) {
+ (*i)->apply(*this, flags);
+ }
- /* Update 'from's transitions, and if it transitions to any
- * unknown State create it and add it to the work_queue
+ /* post processing could have added new states that need
+ * transitions created. So reprocess work_queue
*/
- update_state_transitions(from);
-
- } /* while (!work_queue.empty()) */
+ process_work_queue("Postprocessing dfa", flags);
+ }
/* cleanup Sets of nodes used computing the DFA as they are no longer
* needed.
@@ -256,6 +409,7 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root)
* Do not clear out uniq_anodes, as we need them for minimizations
* diffs, unions, ...
*/
+ dfa_postnodes.clear();
nnodes_cache.clear();
node_map.clear();
}
@@ -264,6 +418,7 @@ DFA::~DFA()
{
anodes_cache.clear();
nnodes_cache.clear();
+ dfa_postnodes.clear();
for (Partition::iterator i = states.begin(); i != states.end(); i++)
delete *i;
diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h
index cbcb46f..f73dca8 100644
--- a/parser/libapparmor_re/hfa.h
+++ b/parser/libapparmor_re/hfa.h
@@ -429,18 +429,23 @@ public:
}
};
+class PostProcessNode;
+
/* Transitions in the DFA. */
class DFA {
void dump_node_to_dfa(void);
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);
/* temporary values used during computations */
NodeCache anodes_cache;
NodeVecCache nnodes_cache;
NodeMap node_map;
list<State *> work_queue;
+ set<PostProcessNode *> dfa_postnodes;
public:
DFA(Node *root, dfaflags_t flags);
@@ -460,6 +465,8 @@ public:
void dump_uniq_perms(const char *s);
map<uchar, uchar> equivalence_classes(dfaflags_t flags);
void apply_equivalence_classes(map<uchar, uchar> &eq);
+ void update_state_for_alias(State &state, set<State *> &from,
+ dfaflags_t flags);
Node *root;
State *nonmatching, *start;
Partition states;
@@ -467,4 +474,47 @@ public:
void dump_equivalence_classes(ostream &os, map<uchar, uchar> &eq);
+
+/* special post dfa construction nodes that can rewrite parts of the dfa
+ * and or cause more dfa construction. These nodes are removed as they
+ * are processed. We use these for operations like alias and set operations
+ * on regular expressions.
+ */
+
+class PostProcessNode: public SharedNode {
+public:
+ PostProcessNode(): states() { }
+ int is_accept(void) { return false; }
+ int is_postprocess(void) { return true; }
+ virtual void apply(DFA &dfa, dfaflags_t flags) = 0;
+ ostream &dump(ostream &os) { return os << "<<" << this << ">>"; }
+
+ set<State *> states;
+};
+
+/* Alias does nothing but store a list of states that it tags, is always
+ * paired with an AliasToNode
+ */
+class AliasFromNode: public PostProcessNode {
+public:
+ AliasFromNode(): PostProcessNode() { }
+ virtual void apply(DFA &dfa, dfaflags_t flags) { }
+};
+
+/* Handle actual processing of an alias */
+class AliasToNode: public PostProcessNode {
+public:
+ AliasToNode(): PostProcessNode() { }
+ virtual void apply(DFA &dfa, dfaflags_t flags)
+ {
+ /* For each alias_to state update its transitions */
+ for (set<State *>::iterator i = states.begin();
+ i != states.end(); i++) {
+ dfa.update_state_for_alias(**i, from.states, flags);
+ }
+ }
+
+ AliasFromNode from;
+};
+
#endif /* __LIBAA_RE_HFA_H */
diff --git a/parser/parser.h b/parser/parser.h
index 8199f43..38198f2 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -362,7 +362,8 @@ void free_symtabs(void);
/* parser_alias.c */
extern int new_alias(const char *from, const char *to);
-extern void replace_aliases(struct codomain *cod);
+extern void setup_name_aliases(struct codomain *cod);
+extern void replace_aliases(aare_ruleset_t *rules, struct codomain *cod);
extern void free_aliases(void);
/* parser_merge.c */
diff --git a/parser/parser_alias.c b/parser/parser_alias.c
index 00a4ced..d7d0c5c 100644
--- a/parser/parser_alias.c
+++ b/parser/parser_alias.c
@@ -152,7 +152,6 @@ static void process_entries(const void *nodep, VISIT value, int __unused level)
}
}
-static struct codomain *target_cod;
static void process_name(const void *nodep, VISIT value, int __unused level)
{
struct alias_rule **t = (struct alias_rule **) nodep;
@@ -185,15 +184,42 @@ static void process_name(const void *nodep, VISIT value, int __unused level)
}
}
-void replace_aliases(struct codomain *cod)
+static aare_ruleset_t *target_rules;
+static void process_new_alias(const void *nodep, VISIT value, int __unused level)
+{
+ struct alias_rule **t = (struct alias_rule **) nodep;
+
+ if (!aare_add_alias(target_rules, (*t)->from, (*t)->to))
+ return;
+
+ return;
+}
+
+void setup_name_aliases(struct codomain *cod)
{
target_cod = cod;
twalk(alias_table, process_name);
+}
- if (cod->entries) {
- target_list = cod->entries;
- target_cod = cod;
- twalk(alias_table, process_entries);
+void replace_aliases(aare_ruleset_t *rules, struct codomain *cod)
+{
+ target_cod = cod;
+ if (!(dfaflags & DFA_COMPAT_OLD_ALIAS)) {
+ /* forces creation of xmatch dfa if it finds an alias
+ * this does not catch all alias possibilities but
+ * the dfa alias handling in process_profile_name_xmatch
+ * handles all cases taht are missing.
+ * Probably should go to always just having an xmatch
+ */
+
+ target_rules = rules;
+ twalk(alias_table, process_new_alias);
+ } else {
+ if (cod->entries) {
+ target_list = cod->entries;
+ target_cod = cod;
+ twalk(alias_table, process_entries);
+ }
}
}
diff --git a/parser/parser_main.c b/parser/parser_main.c
index 9cbfccf..6ac25f9 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -219,6 +219,9 @@ optflag_table_t dumpflag_table[] = {
{ 1, "equiv-stats", "Dump equivance class stats",
DFA_DUMP_EQUIV_STATS },
{ 1, "equiv", "Dump equivance class", DFA_DUMP_EQUIV },
+ { 1, "dfa-prealias", "Dump dfa before alias rewrite",
+ DFA_DUMP_PRE_ALIAS },
+ { 1, "alias-info", "Dump alias info", DFA_DUMP_ALIAS_INFO },
{ 0, NULL, NULL, 0 },
};
@@ -248,6 +251,7 @@ optflag_table_t optflag_table[] = {
DFA_CONTROL_TRANS_HIGH },
{ 2, "compress-fast", "do faster dfa transition table compression",
DFA_CONTROL_TRANS_HIGH },
+ { 0, "old-alias", "use old alias processesing", DFA_COMPAT_OLD_ALIAS },
{ 0, NULL, NULL, 0 },
};
diff --git a/parser/parser_policy.c b/parser/parser_policy.c
index dce1b0d..4f5bb54 100644
--- a/parser/parser_policy.c
+++ b/parser/parser_policy.c
@@ -328,7 +328,6 @@ static void __process_regex(const void *nodep, const VISIT value,
if (value == preorder || value == endorder)
return;
-
if (process_regex(*t) != 0) {
PERROR(_("ERROR processing regexs for profile %s, failed to load\n"),
(*t)->name);
@@ -411,7 +410,7 @@ static void __process_alias(const void *nodep, const VISIT value,
if (value == preorder || value == endorder)
return;
- replace_aliases((*t));
+ replace_aliases(NULL, (*t));
if ((*t)->hat_table)
twalk((*t)->hat_table, __process_alias);
@@ -764,11 +763,14 @@ int post_process_policy(int debug_only)
return retval;
}
- retval = post_process_alias();
- if (retval != 0) {
- PERROR(_("%s: Errors found during postprocess. Aborting.\n"),
- progname);
- return retval;
+ /* only use old alias technique if new aliasing is disabled */
+ if (dfaflags & DFA_COMPAT_OLD_ALIAS) {
+ retval = post_process_alias();
+ if (retval != 0) {
+ PERROR(_("%s: Errors found during postprocess. Aborting.\n"),
+ progname);
+ return retval;
+ }
}
retval = post_merge_rules();
diff --git a/parser/parser_regex.c b/parser/parser_regex.c
index 0ba8114..77be150 100644
--- a/parser/parser_regex.c
+++ b/parser/parser_regex.c
@@ -389,6 +389,8 @@ static int process_profile_name_xmatch(struct codomain *cod)
pattern_t ptype;
const char *name;
+ setup_name_aliases(cod);
+
/* don't filter_slashes for profile names */
if (cod->attachment)
name = cod->attachment;
@@ -434,6 +436,12 @@ static int process_profile_name_xmatch(struct codomain *cod)
}
}
}
+
+ /* create aliases if there is an xmatch - alias ensures */
+ if (!(dfaflags & DFA_COMPAT_OLD_ALIAS)) {
+ replace_aliases(rule, cod);
+ }
+
cod->xmatch = aare_create_dfa(rule, &cod->xmatch_size,
dfaflags);
aare_delete_ruleset(rule);
@@ -570,14 +578,20 @@ int process_regex(struct codomain *cod)
{
int error = -1;
- if (regex_type == AARE_DFA) {
- if (!process_profile_name_xmatch(cod))
- goto out;
+ if (!process_profile_name_xmatch(cod))
+ goto out;
+ if (regex_type == AARE_DFA) {
cod->dfarules = aare_new_ruleset(0);
if (!cod->dfarules)
goto out;
}
+
+ if (!(dfaflags & DFA_COMPAT_OLD_ALIAS)) {
+ replace_aliases(cod->dfarules, cod);
+/* TODO: alias for link rules*/
+ }
+
if (!post_process_entries(cod))
goto out;
@@ -1075,6 +1089,8 @@ int process_policydb(struct codomain *cod)
if (!post_process_policydb_ents(cod))
goto out;
+ /* TODO: alias processing for mount rules */
+
if (regex_type == AARE_DFA && cod->policy_rule_count > 0) {
cod->policy_dfa = aare_create_dfa(cod->policy_rules,
&cod->policy_dfa_size,
More information about the AppArmor
mailing list