2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-01 06:45:38 +00:00

Replace usage of NodeSet with ProtoState in dfa creation.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Kees Cook <kees@ubuntu.com>
This commit is contained in:
John Johansen
2011-12-15 05:12:30 -08:00
parent bd10235397
commit 8bc30c8851
3 changed files with 36 additions and 18 deletions

View File

@@ -4,7 +4,7 @@
TARGET=libapparmor_re.a TARGET=libapparmor_re.a
CFLAGS ?= -g -Wall -O2 ${EXTRA_CFLAGS} CFLAGS ?= -g -Wall -O2 ${EXTRA_CFLAGS}
CXXFLAGS := ${CFLAGS} CXXFLAGS := ${CFLAGS} -std=c++0x
ARFLAGS=-rcs ARFLAGS=-rcs

View File

@@ -35,6 +35,15 @@
#include "hfa.h" #include "hfa.h"
#include "../immunix.h" #include "../immunix.h"
ostream &operator<<(ostream &os, const ProtoState &proto)
{
/* dump the state label */
os << '{';
os << proto.nodes;
os << '}';
return os;
}
ostream &operator<<(ostream &os, const State &state) ostream &operator<<(ostream &os, const State &state)
{ {
/* dump the state label */ /* dump the state label */
@@ -44,15 +53,15 @@ ostream &operator<<(ostream &os, const State &state)
return os; return os;
} }
State *DFA::add_new_state(NodeMap &nodemap, State *DFA::add_new_state(NodeMap &nodemap, ProtoState &proto,
NodeSet *nodes, State *other, dfa_stats_t &stats) State *other, dfa_stats_t &stats)
{ {
State *state = new State(nodemap.size(), nodes, other); State *state = new State(nodemap.size(), proto, other);
states.push_back(state); states.push_back(state);
nodemap.insert(make_pair(ProtoState(nodes), state)); nodemap.insert(make_pair(proto, state));
stats.proto_sum += nodes->size(); stats.proto_sum += proto.size();
if (nodes->size() > stats.proto_max) if (proto.size() > stats.proto_max)
stats.proto_max = nodes->size(); stats.proto_max = proto.size();
return state; return state;
} }
@@ -75,7 +84,7 @@ State *DFA::find_target_state(NodeMap &nodemap, list<State *> &work_queue,
/* set of nodes isn't known so create new state, and nodes to /* set of nodes isn't known so create new state, and nodes to
* state mapping * state mapping
*/ */
target = add_new_state(nodemap, nodes, nonmatching, stats); target = add_new_state(nodemap, index, nonmatching, stats);
work_queue.push_back(target); work_queue.push_back(target);
} else { } else {
/* set of nodes already has a mapping so free this one */ /* set of nodes already has a mapping so free this one */
@@ -97,7 +106,7 @@ void DFA::update_state_transitions(NodeMap &nodemap, list<State *> &work_queue,
* sets of nodes. * sets of nodes.
*/ */
Cases cases; Cases cases;
for (NodeSet::iterator i = state->nodes->begin(); i != state->nodes->end(); i++) for (ProtoState::iterator i = state->proto.begin(); i != state->proto.end(); i++)
(*i)->follow(cases); (*i)->follow(cases);
/* Now for each set of nodes in the computed transitions, make /* Now for each set of nodes in the computed transitions, make
@@ -136,7 +145,7 @@ void DFA::dump_node_to_dfa(void)
" State <= Nodes\n" " State <= Nodes\n"
"-------------------\n"; "-------------------\n";
for (Partition::iterator i = states.begin(); i != states.end(); i++) for (Partition::iterator i = states.begin(); i != states.end(); i++)
cerr << " " << (*i)->label << " <= " << *(*i)->nodes << "\n"; cerr << " " << (*i)->label << " <= " << (*i)->proto << "\n";
} }
/** /**
@@ -163,10 +172,10 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root)
} }
NodeMap nodemap; NodeMap nodemap;
NodeSet *emptynode = new NodeSet; ProtoState emptynode = ProtoState(new NodeSet);
nonmatching = add_new_state(nodemap, emptynode, NULL, stats); nonmatching = add_new_state(nodemap, emptynode, NULL, stats);
NodeSet *first = new NodeSet(root->firstpos); ProtoState first = ProtoState(new NodeSet(root->firstpos));
start = add_new_state(nodemap, first, nonmatching, stats); start = add_new_state(nodemap, first, nonmatching, stats);
/* the work_queue contains the states that need to have their /* the work_queue contains the states that need to have their

View File

@@ -70,6 +70,10 @@ public:
*/ */
class ProtoState { class ProtoState {
public: public:
typedef NodeSet::iterator iterator;
iterator begin() { return nodes->begin(); }
iterator end() { return nodes->end(); }
NodeSet *nodes; NodeSet *nodes;
ProtoState(NodeSet *n): nodes(n) { }; ProtoState(NodeSet *n): nodes(n) { };
@@ -78,6 +82,7 @@ public:
return nodes < rhs.nodes; return nodes < rhs.nodes;
} }
unsigned long size(void) { return nodes->size(); }
}; };
/* /*
@@ -97,8 +102,8 @@ public:
*/ */
class State { class State {
public: public:
State(int l, NodeSet * n, State *other) throw(int): State(int l, ProtoState &n, State *other) throw(int):
label(l), audit(0), accept(0), trans(), nodes(n) label(l), audit(0), accept(0), trans()
{ {
int error; int error;
@@ -107,8 +112,10 @@ public:
else else
otherwise = this; otherwise = this;
proto = n;
/* Compute permissions associated with the State. */ /* Compute permissions associated with the State. */
accept = accept_perms(nodes, &audit, &error); accept = accept_perms(n.nodes, &audit, &error);
if (error) { if (error) {
//cerr << "Failing on accept perms " << error << "\n"; //cerr << "Failing on accept perms " << error << "\n";
throw error; throw error;
@@ -119,9 +126,11 @@ public:
uint32_t audit, accept; uint32_t audit, accept;
StateTrans trans; StateTrans trans;
State *otherwise; State *otherwise;
/* temp storage for State construction */
union { union {
Partition *partition; Partition *partition;
NodeSet *nodes; ProtoState proto;
}; };
}; };
@@ -144,7 +153,7 @@ typedef struct dfa_stats {
class DFA { class DFA {
void dump_node_to_dfa(void); void dump_node_to_dfa(void);
State *add_new_state(NodeMap &nodemap, State *add_new_state(NodeMap &nodemap,
NodeSet *nodes, State *other, dfa_stats_t &stats); ProtoState &proto, State *other, dfa_stats_t &stats);
void update_state_transitions(NodeMap &nodemap, void update_state_transitions(NodeMap &nodemap,
list<State *> &work_queue, list<State *> &work_queue,
State *state, dfa_stats_t &stats); State *state, dfa_stats_t &stats);