mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 10:07:12 +00:00
Add LSS presentations about apparmor security model
This commit is contained in:
parent
75e3a212f1
commit
99322d3978
Binary file not shown.
@ -63,7 +63,7 @@ void aare_rules::add_to_rules(Node *tree, Node *perms)
|
|||||||
|
|
||||||
static Node *cat_with_null_seperator(Node *l, Node *r)
|
static Node *cat_with_null_seperator(Node *l, Node *r)
|
||||||
{
|
{
|
||||||
return new CatNode(new CatNode(l, new CharNode(0)), r);
|
return new CatNode(new CatNode(l, new CharSetNode(0)), r);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit,
|
bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit,
|
||||||
|
@ -232,12 +232,6 @@ void AltNode::normalize(int dir)
|
|||||||
} else if (dynamic_cast<AltNode *>(child[dir])) {
|
} else if (dynamic_cast<AltNode *>(child[dir])) {
|
||||||
// (a | b) | c -> a | (b | c)
|
// (a | b) | c -> a | (b | c)
|
||||||
rotate_node(this, dir);
|
rotate_node(this, dir);
|
||||||
} else if (dynamic_cast<CharSetNode *>(child[dir]) &&
|
|
||||||
dynamic_cast<CharNode *>(child[!dir])) {
|
|
||||||
// [a] | b -> b | [a]
|
|
||||||
Node *c = child[dir];
|
|
||||||
child[dir] = child[!dir];
|
|
||||||
child[!dir] = c;
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -252,76 +246,77 @@ void AltNode::normalize(int dir)
|
|||||||
//charset conversion is disabled for now,
|
//charset conversion is disabled for now,
|
||||||
//it hinders tree optimization in some cases, so it need to be either
|
//it hinders tree optimization in some cases, so it need to be either
|
||||||
//done post optimization, or have extra factoring rules added
|
//done post optimization, or have extra factoring rules added
|
||||||
#if 0
|
|
||||||
static Node *merge_charset(Node *a, Node *b)
|
static Node *merge_charset(Node *a, Node *b)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<CharNode *>(a) && dynamic_cast<CharNode *>(b)) {
|
Chars *from = &dynamic_cast<CharSetNode *>(b)->chars;
|
||||||
Chars chars;
|
Chars *to = &dynamic_cast<CharSetNode *>(a)->chars;
|
||||||
chars.insert(dynamic_cast<CharNode *>(a)->c);
|
|
||||||
chars.insert(dynamic_cast<CharNode *>(b)->c);
|
|
||||||
CharSetNode *n = new CharSetNode(chars);
|
|
||||||
return n;
|
|
||||||
} else if (dynamic_cast<CharNode *>(a) &&
|
|
||||||
dynamic_cast<CharSetNode *>(b)) {
|
|
||||||
Chars *chars = &dynamic_cast<CharSetNode *>(b)->chars;
|
|
||||||
chars->insert(dynamic_cast<CharNode *>(a)->c);
|
|
||||||
return b;
|
|
||||||
} else if (dynamic_cast<CharSetNode *>(a) &&
|
|
||||||
dynamic_cast<CharSetNode *>(b)) {
|
|
||||||
Chars *from = &dynamic_cast<CharSetNode *>(a)->chars;
|
|
||||||
Chars *to = &dynamic_cast<CharSetNode *>(b)->chars;
|
|
||||||
for (Chars::iterator i = from->begin(); i != from->end(); i++)
|
for (Chars::iterator i = from->begin(); i != from->end(); i++)
|
||||||
to->insert(*i);
|
to->insert(*i);
|
||||||
return b;
|
b->release();
|
||||||
}
|
return a;
|
||||||
//return ???;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node *alt_to_charsets(Node *t, int dir)
|
/* given a constructed alt vector do duplicate elimination and merging */
|
||||||
{
|
eliminate_dups_and_merge(vector<Node *> vec) {
|
||||||
/*
|
std::sort(vec->begin(), vec->end(), ???);
|
||||||
Node *first = NULL;
|
|
||||||
Node *p = t;
|
i = vec->begin();
|
||||||
Node *i = t;
|
if (vec->begin()->is_charset()) {
|
||||||
for (;dynamic_cast<AltNode *>(i);) {
|
for (j = i+1; *j->is_charset() && j != vec->end();
|
||||||
if (dynamic_cast<CharNode *>(i->child[dir]) ||
|
j++) {
|
||||||
dynamic_cast<CharNodeSet *>(i->child[dir])) {
|
merge_charset(*i, *j);
|
||||||
if (!first) {
|
*j = NULL;
|
||||||
first = i;
|
merge_count++;
|
||||||
p = i;
|
|
||||||
i = i->child[!dir];
|
|
||||||
} else {
|
|
||||||
first->child[dir] = merge_charset(first->child[dir],
|
|
||||||
i->child[dir]);
|
|
||||||
p->child[!dir] = i->child[!dir];
|
|
||||||
Node *tmp = i;
|
|
||||||
i = tmp->child[!dir];
|
|
||||||
tmp->child[!dir] = NULL;
|
|
||||||
tmp->release();
|
|
||||||
}
|
}
|
||||||
} else {
|
if (j != vec->end())
|
||||||
p = i;
|
i = j;
|
||||||
i = i->child[!dir];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// last altnode of chain check other dir as well
|
/* merged charsets, now eliminate other dups */
|
||||||
if (first && (dynamic_cast<charNode *>(i) ||
|
for (j = i + 1; ??; ???) {
|
||||||
dynamic_cast<charNodeSet *>(i))) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (dynamic_cast<CharNode *>(t->child[dir]) ||
|
|
||||||
dynamic_cast<CharSetNode *>(t->child[dir]))
|
|
||||||
char_test = true;
|
|
||||||
(char_test &&
|
|
||||||
(dynamic_cast<CharNode *>(i->child[dir]) ||
|
|
||||||
dynamic_cast<CharSetNode *>(i->child[dir])))) {
|
|
||||||
*/
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
flatten_altnode(Node *t) {
|
||||||
|
|
||||||
|
/* flatten tree */
|
||||||
|
elimintated_alt_nodes++;
|
||||||
|
|
||||||
|
eliminate_dups_and_merge();
|
||||||
|
}
|
||||||
|
|
||||||
|
flatten_catnode(Node *t) {
|
||||||
|
|
||||||
|
/* flatten tree */
|
||||||
|
eliminated_cat_nodes++;
|
||||||
|
|
||||||
|
/* only elimination to be done is accept nodes */
|
||||||
|
}
|
||||||
|
|
||||||
|
factor() {
|
||||||
|
|
||||||
|
factor everything from right, then left
|
||||||
|
|
||||||
|
factor longest/most - look at both left and right, which is most?
|
||||||
|
to determine which dir to factor first
|
||||||
|
|
||||||
|
ab | abc | abcd | abcde
|
||||||
|
|
||||||
|
a (b | bc | bcd | bcde)
|
||||||
|
|
||||||
|
a ( b (E | c | cd | cde))
|
||||||
|
|
||||||
|
a ( b (E | c (E | d | de))
|
||||||
|
|
||||||
|
a ( b (E | c (E | d (E | e))))
|
||||||
|
|
||||||
|
so once flattened, work top to bottom
|
||||||
|
|
||||||
|
may actually want to flatten charsets into single chars in altnode
|
||||||
|
to make it easier to factor them
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static Node *basic_alt_factor(Node *t, int dir)
|
static Node *basic_alt_factor(Node *t, int dir)
|
||||||
{
|
{
|
||||||
@ -335,6 +330,13 @@ static Node *basic_alt_factor(Node *t, int dir)
|
|||||||
t->release();
|
t->release();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
if (dynamic_cast<CharSetNode *>(t->child[dir]) &&
|
||||||
|
dynamic_cast<CharSetNode *>(t->child[!dir])) {
|
||||||
|
Node *res = merge_charset(t->child[dir], t->child[!dir]);
|
||||||
|
t->child[dir] = t->child[!dir] = NULL;
|
||||||
|
t->release();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
// (ab) | (ac) -> a(b|c)
|
// (ab) | (ac) -> a(b|c)
|
||||||
if (dynamic_cast<CatNode *>(t->child[dir]) &&
|
if (dynamic_cast<CatNode *>(t->child[dir]) &&
|
||||||
dynamic_cast<CatNode *>(t->child[!dir]) &&
|
dynamic_cast<CatNode *>(t->child[!dir]) &&
|
||||||
@ -534,8 +536,6 @@ static void count_tree_nodes(Node *t, struct node_counts *counts)
|
|||||||
} else if (dynamic_cast<StarNode *>(t)) {
|
} else if (dynamic_cast<StarNode *>(t)) {
|
||||||
counts->star++;
|
counts->star++;
|
||||||
count_tree_nodes(t->child[0], counts);
|
count_tree_nodes(t->child[0], counts);
|
||||||
} else if (dynamic_cast<CharNode *>(t)) {
|
|
||||||
counts->charnode++;
|
|
||||||
} else if (dynamic_cast<AnyCharNode *>(t)) {
|
} else if (dynamic_cast<AnyCharNode *>(t)) {
|
||||||
counts->any++;
|
counts->any++;
|
||||||
} else if (dynamic_cast<CharSetNode *>(t)) {
|
} else if (dynamic_cast<CharSetNode *>(t)) {
|
||||||
@ -554,11 +554,11 @@ Node *simplify_tree(Node *t, dfaflags_t flags)
|
|||||||
bool update;
|
bool update;
|
||||||
|
|
||||||
if (flags & DFA_DUMP_TREE_STATS) {
|
if (flags & DFA_DUMP_TREE_STATS) {
|
||||||
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0 };
|
||||||
count_tree_nodes(t, &counts);
|
count_tree_nodes(t, &counts);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"expr tree: c %d, [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n",
|
"expr tree: [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n",
|
||||||
counts.charnode, counts.charset, counts.notcharset,
|
counts.charset, counts.notcharset,
|
||||||
counts.alt, counts.plus, counts.star, counts.any,
|
counts.alt, counts.plus, counts.star, counts.any,
|
||||||
counts.cat);
|
counts.cat);
|
||||||
}
|
}
|
||||||
@ -590,11 +590,11 @@ Node *simplify_tree(Node *t, dfaflags_t flags)
|
|||||||
}
|
}
|
||||||
} while (update);
|
} while (update);
|
||||||
if (flags & DFA_DUMP_TREE_STATS) {
|
if (flags & DFA_DUMP_TREE_STATS) {
|
||||||
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0 };
|
||||||
count_tree_nodes(t, &counts);
|
count_tree_nodes(t, &counts);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"simplified expr tree: c %d, [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n",
|
"simplified expr tree: [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n",
|
||||||
counts.charnode, counts.charset, counts.notcharset,
|
counts.charset, counts.notcharset,
|
||||||
counts.alt, counts.plus, counts.star, counts.any,
|
counts.alt, counts.plus, counts.star, counts.any,
|
||||||
counts.cat);
|
counts.cat);
|
||||||
}
|
}
|
||||||
|
@ -229,41 +229,11 @@ public:
|
|||||||
int is_postprocess(void) { return false; }
|
int is_postprocess(void) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Match one specific character (/c/). */
|
|
||||||
class CharNode: public CNode {
|
|
||||||
public:
|
|
||||||
CharNode(uchar c): c(c) { }
|
|
||||||
void follow(Cases &cases)
|
|
||||||
{
|
|
||||||
NodeSet **x = &cases.cases[c];
|
|
||||||
if (!*x) {
|
|
||||||
if (cases.otherwise)
|
|
||||||
*x = new NodeSet(*cases.otherwise);
|
|
||||||
else
|
|
||||||
*x = new NodeSet;
|
|
||||||
}
|
|
||||||
(*x)->insert(followpos.begin(), followpos.end());
|
|
||||||
}
|
|
||||||
int eq(Node *other)
|
|
||||||
{
|
|
||||||
CharNode *o = dynamic_cast<CharNode *>(other);
|
|
||||||
if (o) {
|
|
||||||
return c == o->c;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ostream &dump(ostream &os)
|
|
||||||
{
|
|
||||||
return os << c;
|
|
||||||
}
|
|
||||||
|
|
||||||
uchar c;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Match a set of characters (/[abc]/). */
|
/* Match a set of characters (/[abc]/). */
|
||||||
class CharSetNode: public CNode {
|
class CharSetNode: public CNode {
|
||||||
public:
|
public:
|
||||||
CharSetNode(Chars &chars): chars(chars) { }
|
CharSetNode(Chars &chars): chars(chars) { }
|
||||||
|
CharSetNode(uchar c): chars() { chars.insert(c); }
|
||||||
void follow(Cases &cases)
|
void follow(Cases &cases)
|
||||||
{
|
{
|
||||||
for (Chars::iterator i = chars.begin(); i != chars.end(); i++) {
|
for (Chars::iterator i = chars.begin(); i != chars.end(); i++) {
|
||||||
@ -591,7 +561,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct node_counts {
|
struct node_counts {
|
||||||
int charnode;
|
|
||||||
int charset;
|
int charset;
|
||||||
int notcharset;
|
int notcharset;
|
||||||
int alt;
|
int alt;
|
||||||
|
@ -102,7 +102,7 @@ qterm : term
|
|||||||
;
|
;
|
||||||
|
|
||||||
term : '.' { $$ = new AnyCharNode; }
|
term : '.' { $$ = new AnyCharNode; }
|
||||||
| regex_char { $$ = new CharNode($1); }
|
| regex_char { $$ = new CharSetNode($1); }
|
||||||
| '[' charset ']' { $$ = new CharSetNode(*$2);
|
| '[' charset ']' { $$ = new CharSetNode(*$2);
|
||||||
delete $2; }
|
delete $2; }
|
||||||
| '[' '^' charset ']'
|
| '[' '^' charset ']'
|
||||||
|
BIN
presentations/LSS_apparmor-labeling-2013.odp
Normal file
BIN
presentations/LSS_apparmor-labeling-2013.odp
Normal file
Binary file not shown.
BIN
presentations/LSS_apparmor-userspace-2013.odp
Normal file
BIN
presentations/LSS_apparmor-userspace-2013.odp
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user