[apparmor] [PATCH 03/10] Make sure that state always has otherwise set

John Johansen john.johansen at canonical.com
Fri Oct 28 19:19:30 UTC 2011


Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 parser/libapparmor_re/hfa.cc |   34 ++++++++++++++++++----------------
 parser/libapparmor_re/hfa.h  |   13 ++++++++-----
 2 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/parser/libapparmor_re/hfa.cc b/parser/libapparmor_re/hfa.cc
index 79bcac7..1247089 100644
--- a/parser/libapparmor_re/hfa.cc
+++ b/parser/libapparmor_re/hfa.cc
@@ -46,9 +46,9 @@ ostream &operator<<(ostream &os, const State &state)
 
 State *DFA::add_new_state(NodeMap &nodemap,
 			  pair<unsigned long, NodeSet *> index,
-			  NodeSet *nodes, dfa_stats_t &stats)
+			  NodeSet *nodes, State *other, dfa_stats_t &stats)
 {
-	State *state = new State(nodemap.size(), nodes);
+	State *state = new State(nodemap.size(), nodes, other);
 	states.push_back(state);
 	nodemap.insert(make_pair(index, state));
 	stats.proto_sum += nodes->size();
@@ -70,7 +70,8 @@ State *DFA::find_target_state(NodeMap &nodemap, list<State *> &work_queue,
 		/* set of nodes isn't known so create new state, and nodes to
 		 * state mapping
 		 */
-		target = add_new_state(nodemap, index, nodes, stats);
+		target = add_new_state(nodemap, index, nodes, nonmatching,
+				       stats);
 		work_queue.push_back(target);
 	} else {
 		/* set of nodes already has a mapping so free this one */
@@ -104,8 +105,9 @@ void DFA::update_state_transitions(NodeMap &nodemap, list<State *> &work_queue,
 	/* check the default transition first */
 	if (cases.otherwise)
 		state->otherwise = find_target_state(nodemap, work_queue,
-							   cases.otherwise,
-							   stats);;
+						     cases.otherwise, stats);
+	else
+		state->otherwise = nonmatching;
 
 	/* For each transition from *from, check if the set of nodes it
 	 * transitions to already has been mapped to a state
@@ -161,11 +163,11 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root)
 	NodeSet *emptynode = new NodeSet;
 	nonmatching = add_new_state(nodemap,
 				    make_pair(hash_NodeSet(emptynode), emptynode),
-				    emptynode, stats);
+				    emptynode, NULL, stats);
 
 	NodeSet *first = new NodeSet(root->firstpos);
 	start = add_new_state(nodemap, make_pair(hash_NodeSet(first), first),
-			      first, stats);
+			      first, nonmatching, stats);
 
 	/* the work_queue contains the states that need to have their
 	 * transitions computed.  This could be done with a recursive
@@ -254,8 +256,8 @@ void DFA::remove_unreachable(dfaflags_t flags)
 		work_queue.pop_front();
 		reachable.insert(from);
 
-		if (from->otherwise &&
-		    (reachable.find(from->otherwise) == reachable.end()))
+		if (from->otherwise != nonmatching &&
+		    reachable.find(from->otherwise) == reachable.end())
 			work_queue.push_back(from->otherwise);
 
 		for (StateTrans::iterator j = from->trans.begin(); j != from->trans.end(); j++) {
@@ -301,14 +303,14 @@ void DFA::remove_unreachable(dfaflags_t flags)
 /* test if two states have the same transitions under partition_map */
 bool DFA::same_mappings(State *s1, State *s2)
 {
-	if (s1->otherwise && s1->otherwise != nonmatching) {
-		if (!s2->otherwise || s2->otherwise == nonmatching)
+	if (s1->otherwise != nonmatching) {
+		if (s2->otherwise == nonmatching)
 			return false;
 		Partition *p1 = s1->otherwise->partition;
 		Partition *p2 = s2->otherwise->partition;
 		if (p1 != p2)
 			return false;
-	} else if (s2->otherwise && s2->otherwise != nonmatching) {
+	} else if (s2->otherwise != nonmatching) {
 		return false;
 	}
 
@@ -344,7 +346,7 @@ size_t DFA::hash_trans(State *s)
 		hash = ((hash << 5) + hash) + k->trans.size();
 	}
 
-	if (s->otherwise && s->otherwise != nonmatching) {
+	if (s->otherwise != nonmatching) {
 		hash = ((hash << 5) + hash) + 5381;
 		State *k = s->otherwise;
 		hash = ((hash << 5) + hash) + k->trans.size();
@@ -487,7 +489,7 @@ void DFA::minimize(dfaflags_t flags)
 			cerr << *rep << " : ";
 
 		/* update representative state's transitions */
-		if (rep->otherwise) {
+		if (rep->otherwise != nonmatching) {
 			Partition *partition = rep->otherwise->partition;
 			rep->otherwise = *partition->begin();
 		}
@@ -577,7 +579,7 @@ void DFA::dump(ostream & os)
 	os << "\n";
 
 	for (Partition::iterator i = states.begin(); i != states.end(); i++) {
-		if ((*i)->otherwise)
+		if ((*i)->otherwise != nonmatching)
 			os << **i << " -> " << (*i)->otherwise << "\n";
 		for (StateTrans::iterator j = (*i)->trans.begin();
 		     j != (*i)->trans.end(); j++) {
@@ -623,7 +625,7 @@ void DFA::dump_dot_graph(ostream & os)
 				os << "\t]" << "\n";
 			}
 		}
-		if ((*i)->otherwise && (*i)->otherwise != nonmatching) {
+		if ((*i)->otherwise != nonmatching) {
 		  os << "\t\"" << **i << "\" -> \"" << *(*i)->otherwise
 			   << "\" [" << "\n";
 			if (!excluded.empty()) {
diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h
index ee63d21..b425011 100644
--- a/parser/libapparmor_re/hfa.h
+++ b/parser/libapparmor_re/hfa.h
@@ -56,13 +56,16 @@ uint32_t accept_perms(NodeSet *state, uint32_t *audit_ctl, int *error);
  */
 class State {
 public:
-	State(): label(0), audit(0), accept(0), trans(), otherwise(NULL), nodes(NULL) { };
-	State(int l): label(l), audit(0), accept(0), trans(), otherwise(NULL), nodes(NULL) { };
-	State(int l, NodeSet * n) throw(int):
-		label(l), audit(0), accept(0), trans(), otherwise(NULL), nodes(n)
+	State(int l, NodeSet * n, State *other) throw(int):
+		label(l), audit(0), accept(0), trans(), nodes(n)
 	{
 		int error;
 
+		if (other)
+			otherwise = other;
+		else
+			otherwise = this;
+
 		/* Compute permissions associated with the State. */
 		accept = accept_perms(nodes, &audit, &error);
 		if (error) {
@@ -100,7 +103,7 @@ class DFA {
 	void dump_node_to_dfa(void);
 	State *add_new_state(NodeMap &nodemap,
 			     pair<unsigned long, NodeSet *> index,
-			     NodeSet *nodes, dfa_stats_t &stats);
+			     NodeSet *nodes, State *other, dfa_stats_t &stats);
 	void update_state_transitions(NodeMap &nodemap,
 				      list<State *> &work_queue,
 				      State *state, dfa_stats_t &stats);
-- 
1.7.5.4




More information about the AppArmor mailing list