mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-30 13:58:22 +00:00
Make sure that state always has otherwise set
Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Kees Cook <kees@ubuntu.com>
This commit is contained in:
@@ -46,9 +46,9 @@ ostream &operator<<(ostream &os, const State &state)
|
|||||||
|
|
||||||
State *DFA::add_new_state(NodeMap &nodemap,
|
State *DFA::add_new_state(NodeMap &nodemap,
|
||||||
pair<unsigned long, NodeSet *> index,
|
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);
|
states.push_back(state);
|
||||||
nodemap.insert(make_pair(index, state));
|
nodemap.insert(make_pair(index, state));
|
||||||
stats.proto_sum += nodes->size();
|
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
|
/* set of nodes isn't known so create new state, and nodes to
|
||||||
* state mapping
|
* state mapping
|
||||||
*/
|
*/
|
||||||
target = add_new_state(nodemap, index, nodes, stats);
|
target = add_new_state(nodemap, index, nodes, 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 */
|
||||||
@@ -104,8 +105,9 @@ void DFA::update_state_transitions(NodeMap &nodemap, list<State *> &work_queue,
|
|||||||
/* check the default transition first */
|
/* check the default transition first */
|
||||||
if (cases.otherwise)
|
if (cases.otherwise)
|
||||||
state->otherwise = find_target_state(nodemap, work_queue,
|
state->otherwise = find_target_state(nodemap, work_queue,
|
||||||
cases.otherwise,
|
cases.otherwise, stats);
|
||||||
stats);;
|
else
|
||||||
|
state->otherwise = nonmatching;
|
||||||
|
|
||||||
/* For each transition from *from, check if the set of nodes it
|
/* For each transition from *from, check if the set of nodes it
|
||||||
* transitions to already has been mapped to a state
|
* 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;
|
NodeSet *emptynode = new NodeSet;
|
||||||
nonmatching = add_new_state(nodemap,
|
nonmatching = add_new_state(nodemap,
|
||||||
make_pair(hash_NodeSet(emptynode), emptynode),
|
make_pair(hash_NodeSet(emptynode), emptynode),
|
||||||
emptynode, stats);
|
emptynode, NULL, stats);
|
||||||
|
|
||||||
NodeSet *first = new NodeSet(root->firstpos);
|
NodeSet *first = new NodeSet(root->firstpos);
|
||||||
start = add_new_state(nodemap, make_pair(hash_NodeSet(first), first),
|
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
|
/* the work_queue contains the states that need to have their
|
||||||
* transitions computed. This could be done with a recursive
|
* transitions computed. This could be done with a recursive
|
||||||
@@ -254,8 +256,8 @@ void DFA::remove_unreachable(dfaflags_t flags)
|
|||||||
work_queue.pop_front();
|
work_queue.pop_front();
|
||||||
reachable.insert(from);
|
reachable.insert(from);
|
||||||
|
|
||||||
if (from->otherwise &&
|
if (from->otherwise != nonmatching &&
|
||||||
(reachable.find(from->otherwise) == reachable.end()))
|
reachable.find(from->otherwise) == reachable.end())
|
||||||
work_queue.push_back(from->otherwise);
|
work_queue.push_back(from->otherwise);
|
||||||
|
|
||||||
for (StateTrans::iterator j = from->trans.begin(); j != from->trans.end(); j++) {
|
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 */
|
/* test if two states have the same transitions under partition_map */
|
||||||
bool DFA::same_mappings(State *s1, State *s2)
|
bool DFA::same_mappings(State *s1, State *s2)
|
||||||
{
|
{
|
||||||
if (s1->otherwise && s1->otherwise != nonmatching) {
|
if (s1->otherwise != nonmatching) {
|
||||||
if (!s2->otherwise || s2->otherwise == nonmatching)
|
if (s2->otherwise == nonmatching)
|
||||||
return false;
|
return false;
|
||||||
Partition *p1 = s1->otherwise->partition;
|
Partition *p1 = s1->otherwise->partition;
|
||||||
Partition *p2 = s2->otherwise->partition;
|
Partition *p2 = s2->otherwise->partition;
|
||||||
if (p1 != p2)
|
if (p1 != p2)
|
||||||
return false;
|
return false;
|
||||||
} else if (s2->otherwise && s2->otherwise != nonmatching) {
|
} else if (s2->otherwise != nonmatching) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,7 +346,7 @@ size_t DFA::hash_trans(State *s)
|
|||||||
hash = ((hash << 5) + hash) + k->trans.size();
|
hash = ((hash << 5) + hash) + k->trans.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->otherwise && s->otherwise != nonmatching) {
|
if (s->otherwise != nonmatching) {
|
||||||
hash = ((hash << 5) + hash) + 5381;
|
hash = ((hash << 5) + hash) + 5381;
|
||||||
State *k = s->otherwise;
|
State *k = s->otherwise;
|
||||||
hash = ((hash << 5) + hash) + k->trans.size();
|
hash = ((hash << 5) + hash) + k->trans.size();
|
||||||
@@ -487,7 +489,7 @@ void DFA::minimize(dfaflags_t flags)
|
|||||||
cerr << *rep << " : ";
|
cerr << *rep << " : ";
|
||||||
|
|
||||||
/* update representative state's transitions */
|
/* update representative state's transitions */
|
||||||
if (rep->otherwise) {
|
if (rep->otherwise != nonmatching) {
|
||||||
Partition *partition = rep->otherwise->partition;
|
Partition *partition = rep->otherwise->partition;
|
||||||
rep->otherwise = *partition->begin();
|
rep->otherwise = *partition->begin();
|
||||||
}
|
}
|
||||||
@@ -577,7 +579,7 @@ void DFA::dump(ostream & os)
|
|||||||
os << "\n";
|
os << "\n";
|
||||||
|
|
||||||
for (Partition::iterator i = states.begin(); i != states.end(); i++) {
|
for (Partition::iterator i = states.begin(); i != states.end(); i++) {
|
||||||
if ((*i)->otherwise)
|
if ((*i)->otherwise != nonmatching)
|
||||||
os << **i << " -> " << (*i)->otherwise << "\n";
|
os << **i << " -> " << (*i)->otherwise << "\n";
|
||||||
for (StateTrans::iterator j = (*i)->trans.begin();
|
for (StateTrans::iterator j = (*i)->trans.begin();
|
||||||
j != (*i)->trans.end(); j++) {
|
j != (*i)->trans.end(); j++) {
|
||||||
@@ -623,7 +625,7 @@ void DFA::dump_dot_graph(ostream & os)
|
|||||||
os << "\t]" << "\n";
|
os << "\t]" << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((*i)->otherwise && (*i)->otherwise != nonmatching) {
|
if ((*i)->otherwise != nonmatching) {
|
||||||
os << "\t\"" << **i << "\" -> \"" << *(*i)->otherwise
|
os << "\t\"" << **i << "\" -> \"" << *(*i)->otherwise
|
||||||
<< "\" [" << "\n";
|
<< "\" [" << "\n";
|
||||||
if (!excluded.empty()) {
|
if (!excluded.empty()) {
|
||||||
|
@@ -56,13 +56,16 @@ uint32_t accept_perms(NodeSet *state, uint32_t *audit_ctl, int *error);
|
|||||||
*/
|
*/
|
||||||
class State {
|
class State {
|
||||||
public:
|
public:
|
||||||
State(): label(0), audit(0), accept(0), trans(), otherwise(NULL), nodes(NULL) { };
|
State(int l, NodeSet * n, State *other) throw(int):
|
||||||
State(int l): label(l), audit(0), accept(0), trans(), otherwise(NULL), nodes(NULL) { };
|
label(l), audit(0), accept(0), trans(), nodes(n)
|
||||||
State(int l, NodeSet * n) throw(int):
|
|
||||||
label(l), audit(0), accept(0), trans(), otherwise(NULL), nodes(n)
|
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if (other)
|
||||||
|
otherwise = other;
|
||||||
|
else
|
||||||
|
otherwise = this;
|
||||||
|
|
||||||
/* Compute permissions associated with the State. */
|
/* Compute permissions associated with the State. */
|
||||||
accept = accept_perms(nodes, &audit, &error);
|
accept = accept_perms(nodes, &audit, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -100,7 +103,7 @@ 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,
|
||||||
pair<unsigned long, NodeSet *> index,
|
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,
|
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);
|
||||||
|
Reference in New Issue
Block a user