2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 18:17:09 +00:00
John Johansen 91dd7527d9 Dfa minimization and unreachable state removal
Add basic Hopcroft based dfa minimization.  It currently does a simple
straight state comparison that can be quadratic in time to split partitions.
This is offset however by using hashing to setup the initial partitions so
that the number of states within a partition are relative few.

The hashing of states for initial partition setup is linear in time.  This
means the closer the initial partition set is to the final set, the closer
the algorithm is to completing in a linear time.  The hashing works as
follows:  For each state we know the number of transitions that are not
the default transition.  For each of of these we hash the set of letters
it can transition on using a simple djb2 hash algorithm.  This creates
a unique hash based on the number of transitions and the input it can
transition on.  If a state does not have the same hash we know it can not
the same as another because it either has a different number of transitions
or or transitions on a different set.

To further distiguish states, the number of transitions of each transitions
target state are added into the hash.  This serves to further distiguish
states as a transition to a state with a different number of transitions
can not possibly be reduced to an equivalent state.

A further distinction of states is made for accepting states in that
we know each state with a unique set of accept permissions must be in
its own partition to ensure the unique accept permissions are in the
final dfa.

The unreachable state removal is a basic walk of the dfa from the start
state marking all states that are reached.  It then sweeps any state not
reached away.  This does not do dead state removal where a non accepting
state gets into a loop that will never result in an accepting state.
2010-01-20 03:32:34 -08:00

61 lines
1.6 KiB
C

/* $Id$
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007 Novell, Inc.
* (All rights reserved)
*
* The libapparmor library is licensed under the terms of the GNU
* Lesser General Public License, version 2.1. Please see the file
* COPYING.LGPL.
*/
#ifndef APPARMOR_RE_H
#define APPARMOR_RE_H
typedef enum dfaflags {
DFA_CONTROL_EQUIV = 1 << 0,
DFA_CONTROL_NO_TREE_NORMAL = 1 << 1,
DFA_CONTROL_NO_TREE_SIMPLE = 1 << 2,
DFA_CONTROL_TREE_LEFT = 1 << 3,
DFA_CONTROL_NO_MINIMIZE = 1 << 4,
DFA_CONTROL_NO_HASH_PART = 1 << 5,
DFA_CONTROL_NO_UNREACHABLE = 1 << 6,
DFA_DUMP_TREE_STATS = 1 << 8,
DFA_DUMP_TREE = 1 << 9,
DFA_DUMP_SIMPLE_TREE = 1 << 10,
DFA_DUMP_PROGRESS = 1 << 11,
DFA_DUMP_STATS = 1 << 12,
DFA_DUMP_STATES = 1 << 13,
DFA_DUMP_GRAPH = 1 << 14,
DFA_DUMP_TRANS_PROGRESS = 1 << 15,
DFA_DUMP_TRANS_STATS = 1 << 16,
DFA_DUMP_TRANS_TABLE = 1 << 17,
DFA_DUMP_EQUIV = 1 << 18,
DFA_DUMP_EQUIV_STATS = 1 << 19,
DFA_DUMP_MINIMIZE = 1 << 20,
DFA_DUMP_UNREACHABLE = 1 << 22,
} dfaflags_t;
#ifdef __cplusplus
extern "C" {
#endif
struct aare_ruleset;
typedef struct aare_ruleset aare_ruleset_t;
aare_ruleset_t *aare_new_ruleset(int reverse);
void aare_delete_ruleset(aare_ruleset_t *rules);
int aare_add_rule(aare_ruleset_t *rules, char *rule, int deny,
uint32_t perms, uint32_t audit);
int aare_add_rule_vec(aare_ruleset_t *rules, int deny, uint32_t perms,
uint32_t audit, int count, char **rulev);
void *aare_create_dfa(aare_ruleset_t *rules, size_t *size, dfaflags_t flags);
void aare_reset_matchflags(void);
#ifdef __cplusplus
}
#endif
#endif /* APPARMOR_RE_H */