diff --git a/parser/dbus.cc b/parser/dbus.cc index eef291693..56bc2a3f9 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -291,21 +291,21 @@ int dbus_rule::gen_policy_re(Profile &prof) if (mode & AA_DBUS_BIND) { if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_BIND, audit & AA_DBUS_BIND, - 2, vec, dfaflags)) + 2, vec, dfaflags, false)) goto fail; } if (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { if (!prof.policy.rules->add_rule_vec(deny, mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE), audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - 6, vec, dfaflags)) + 6, vec, dfaflags, false)) goto fail; } if (mode & AA_DBUS_EAVESDROP) { if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_EAVESDROP, audit & AA_DBUS_EAVESDROP, - 1, vec, dfaflags)) + 1, vec, dfaflags, false)) goto fail; } diff --git a/parser/libapparmor_re/aare_rules.cc b/parser/libapparmor_re/aare_rules.cc index a869756f6..11f396464 100644 --- a/parser/libapparmor_re/aare_rules.cc +++ b/parser/libapparmor_re/aare_rules.cc @@ -47,7 +47,7 @@ aare_rules::~aare_rules(void) bool aare_rules::add_rule(const char *rule, int deny, uint32_t perms, uint32_t audit, dfaflags_t flags) { - return add_rule_vec(deny, perms, audit, 1, &rule, flags); + return add_rule_vec(deny, perms, audit, 1, &rule, flags, false); } void aare_rules::add_to_rules(Node *tree, Node *perms) @@ -66,8 +66,14 @@ static Node *cat_with_null_seperator(Node *l, Node *r) return new CatNode(new CatNode(l, new CharNode(0)), r); } +static Node *cat_with_oob_seperator(Node *l, Node *r) +{ + return new CatNode(new CatNode(l, new CharNode(transchar(-1, true))), r); +} + bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit, - int count, const char **rulev, dfaflags_t flags) + int count, const char **rulev, dfaflags_t flags, + bool oob) { Node *tree = NULL, *accept; int exact_match; @@ -78,7 +84,10 @@ bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit, Node *subtree = NULL; if (regex_parse(&subtree, rulev[i])) return false; - tree = cat_with_null_seperator(tree, subtree); + if (oob) + tree = cat_with_oob_seperator(tree, subtree); + else + tree = cat_with_null_seperator(tree, subtree); } /* @@ -102,10 +111,15 @@ bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit, accept = unique_perms.insert(deny, perms, audit, exact_match); if (flags & DFA_DUMP_RULE_EXPR) { + const char *seperator; + if (oob) + seperator = "\\-x01"; + else + seperator = "\\x00"; cerr << "rule: "; cerr << rulev[0]; for (int i = 1; i < count; i++) { - cerr << "\\x00"; + cerr << seperator; cerr << rulev[i]; } cerr << " -> "; diff --git a/parser/libapparmor_re/aare_rules.h b/parser/libapparmor_re/aare_rules.h index ac0fba5d3..459a17376 100644 --- a/parser/libapparmor_re/aare_rules.h +++ b/parser/libapparmor_re/aare_rules.h @@ -103,7 +103,7 @@ class aare_rules { bool add_rule(const char *rule, int deny, uint32_t perms, uint32_t audit, dfaflags_t flags); bool add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count, - const char **rulev, dfaflags_t flags); + const char **rulev, dfaflags_t flags, bool oob); bool append_rule(const char *rule, dfaflags_t flags); void *create_dfa(size_t *size, int *min_match_len, dfaflags_t flags); }; diff --git a/parser/libapparmor_re/chfa.cc b/parser/libapparmor_re/chfa.cc index 130c35adc..a6b09222a 100644 --- a/parser/libapparmor_re/chfa.cc +++ b/parser/libapparmor_re/chfa.cc @@ -54,10 +54,11 @@ CHFA::CHFA(DFA &dfa, map &eq, dfaflags_t flags): eq(eq) if (flags & DFA_DUMP_TRANS_PROGRESS) fprintf(stderr, "Compressing HFA:\r"); + chfaflags = 0; if (dfa.diffcount) - chfaflags = YYTH_FLAG_DIFF_ENCODE; - else - chfaflags = 0; + chfaflags |= YYTH_FLAG_DIFF_ENCODE; + if (dfa.oob_range) + chfaflags |= YYTH_FLAG_OOB_TRANS; if (eq.empty()) max_eq = 255; @@ -87,7 +88,7 @@ CHFA::CHFA(DFA &dfa, map &eq, dfaflags_t flags): eq(eq) range = (*i)->trans.rbegin()->first.c - (*i)->trans.begin()->first.c; - size_t ord = ((256 - (*i)->trans.size()) << 8) | (256 - range); + size_t ord = ((dfa.max_range - (*i)->trans.size()) << dfa.ord_range) | (dfa.max_range - range); /* reverse sort by entry count, most entries first */ order.insert(make_pair(ord, *i)); } @@ -100,7 +101,7 @@ CHFA::CHFA(DFA &dfa, map &eq, dfaflags_t flags): eq(eq) accept.resize(max(dfa.states.size(), (size_t) 2)); accept2.resize(max(dfa.states.size(), (size_t) 2)); - next_check.resize(max(optimal, (size_t) 256)); + next_check.resize(max(optimal, (size_t) dfa.max_range)); free_list.resize(next_check.size()); accept[0] = 0; @@ -166,12 +167,15 @@ bool CHFA::fits_in(vector > &free_list __attribute__ ((unused)), size_t pos, StateTrans &trans) { - size_t c, base = pos - trans.begin()->first.c; + ssize_t c, base = pos - trans.begin()->first.c; + + if (base < 0) + return false; for (StateTrans::iterator i = trans.begin(); i != trans.end(); i++) { c = base + i->first.c; /* if it overflows the next_check array it fits in as we will * resize */ - if (c >= next_check.size()) + if (c >= (ssize_t) next_check.size()) return true; if (next_check[c].second) return false; @@ -187,13 +191,13 @@ void CHFA::insert_state(vector > &free_list, State *from, DFA &dfa) { State *default_state = dfa.nonmatching; - size_t base = 0; + ssize_t base = 0; int resize; StateTrans &trans = from->trans; - size_t c = trans.begin()->first.c; - size_t prev = 0; - size_t x = first_free; + ssize_t c = trans.begin()->first.c; + ssize_t prev = 0; + ssize_t x = first_free; if (from->otherwise) default_state = from->otherwise; @@ -203,7 +207,7 @@ void CHFA::insert_state(vector > &free_list, repeat: resize = 0; /* get the first free entry that won't underflow */ - while (x && (x < c)) { + while (x && ((x < c) || (x + c < 0))) { prev = x; x = free_list[x].second; } @@ -214,17 +218,17 @@ repeat: x = free_list[x].second; } if (!x) { - resize = 256 - trans.begin()->first.c; + resize = dfa.upper_bound - c; x = free_list.size(); /* set prev to last free */ - } else if (x + 255 - trans.begin()->first.c >= next_check.size()) { - resize = (255 - trans.begin()->first.c - (next_check.size() - 1 - x)); + } else if (x + (dfa.upper_bound - 1) - c >= (ssize_t) next_check.size()) { + resize = ((dfa.upper_bound -1) - c - (next_check.size() - 1 - x)); for (size_t y = x; y; y = free_list[y].second) prev = y; } if (resize) { /* expand next_check and free_list */ - size_t old_size = free_list.size(); + ssize_t old_size = free_list.size(); next_check.resize(next_check.size() + resize); free_list.resize(free_list.size() + resize); init_free_list(free_list, prev, old_size); @@ -248,6 +252,9 @@ repeat: } do_insert: + if (c < 0) { + base |= MATCH_FLAG_OOB_TRANSITION; + } if (from->flags & DiffEncodeFlag) base |= DiffEncodeBit32; default_base.push_back(make_pair(default_state, base)); diff --git a/parser/libapparmor_re/chfa.h b/parser/libapparmor_re/chfa.h index 445987f19..0577215dc 100644 --- a/parser/libapparmor_re/chfa.h +++ b/parser/libapparmor_re/chfa.h @@ -28,6 +28,7 @@ #define BASE32_FLAGS 0xff000000 #define DiffEncodeBit32 0x80000000 +#define MATCH_FLAG_OOB_TRANSITION 0x20000000 #define base_mask_size(X) ((X) & ~BASE32_FLAGS) using namespace std; @@ -54,7 +55,7 @@ class CHFA { map num; map &eq; transchar max_eq; - size_t first_free; + ssize_t first_free; unsigned int chfaflags; }; diff --git a/parser/libapparmor_re/expr-tree.h b/parser/libapparmor_re/expr-tree.h index 069811d32..846f8121d 100644 --- a/parser/libapparmor_re/expr-tree.h +++ b/parser/libapparmor_re/expr-tree.h @@ -45,11 +45,69 @@ using namespace std; +/* + * transchar - representative input character for state transitions + * + * the transchar is used as the leaf node in the expr tree created + * by parsing an input regex (parse.y), and is used to build both the + * states and the transitions for a state machine (hfa.{h,cc}) built + * from the expression tree. + * + * While the state machine is currently based on byte inputs the + * transchar abstraction allows for flexibility and the option of + * moving to a larger input in the future. It also allows the ability + * to specify out of band transitions. + * + * Out of band transitions allow for code to specify special transitions + * that can not be triggered by an input byte stream. As such out of + * band transitions can be used to separate logical units of a match. + * + * eg. + * you need to allow an arbitrary data match (.*) followed by an arbitrary + * string match ([^\x00]*), and make an acceptance dission based + * on both matches. + * + * One way to do this is to chain the two matches in a single state + * machine. However without an out of band transition, the matche pattern + * for the data match (.*) could also consume the input for the string match. + * To ensure the data pattern match cannot consume characters for the second + * match a special character is used. This prevents state machine + * generation from intermixing the two expressions. For string matches + * this can be achieved with the pattern. + * ([^\x00]*)\x00([\x00]*) + * since \x00 can not be matched by the first expression (and is not a + * valid character in a C string), the nul character can be used to + * separate the string match. This however is not possible when matching + * arbitrary data that can have any input character. + * + * Out of band transitions replace the \x00 transition in the string + * example with a new input transition that comes from the driver + * code. Once the first match is done, the driver supplies the non-input + * character, causing the state machine to transition to the second + * match pattern. + * + * Out of band transitions are specified using negative integers + * (-1..-32k). They llow for different transitions if needed (currently + * only -1 is used). + * + * Negative integers were chosen to represent out of band transitions + * because it makes the run time match simple, and also keeps the + * upper positive integer range open for future input character + * expansion. + * + * When a chfa is built, the out of band transition is encoded as + * a negative offset of the same value specified in the transchar from the + * state base base value. The check value at the negative offset will + * contain the owning state value. The chfa state machine is constructed + * in such a way that this value will always be in bounds, and only an + * unpack time verification is needed. + */ class transchar { public: short c; transchar(unsigned char a): c((unsigned short) a) {} + transchar(short a, bool oob __attribute__((unused))): c(a) {} transchar(const transchar &a): c(a.c) {} transchar(): c(0) {} @@ -341,7 +399,7 @@ public: { NodeSet **x = &cases.cases[c]; if (!*x) { - if (cases.otherwise) + if (cases.otherwise && c.c >= 0) *x = new NodeSet(*cases.otherwise); else *x = new NodeSet; @@ -384,7 +442,7 @@ public: for (Chars::iterator i = chars.begin(); i != chars.end(); i++) { NodeSet **x = &cases.cases[*i]; if (!*x) { - if (cases.otherwise) + if (cases.otherwise && i->c >= 0) *x = new NodeSet(*cases.otherwise); else *x = new NodeSet; @@ -453,7 +511,8 @@ public: cases.otherwise->insert(followpos.begin(), followpos.end()); for (Cases::iterator i = cases.begin(); i != cases.end(); i++) { - if (chars.find(i->first) == chars.end()) + /* does not match oob transition chars */ + if (i->first.c >=0 && chars.find(i->first) == chars.end()) i->second->insert(followpos.begin(), followpos.end()); } @@ -511,7 +570,9 @@ public: cases.otherwise->insert(followpos.begin(), followpos.end()); for (Cases::iterator i = cases.begin(); i != cases.end(); i++) - i->second->insert(followpos.begin(), followpos.end()); + /* does not match oob transition chars */ + if (i->first.c >= 0) + i->second->insert(followpos.begin(), followpos.end()); } int eq(Node *other) { diff --git a/parser/libapparmor_re/flex-tables.h b/parser/libapparmor_re/flex-tables.h index efd05ac9a..6cd2959a1 100644 --- a/parser/libapparmor_re/flex-tables.h +++ b/parser/libapparmor_re/flex-tables.h @@ -6,6 +6,7 @@ #define YYTH_MAGIC 0xF13C57B1 #define YYTH_FLAG_DIFF_ENCODE 1 +#define YYTH_FLAG_OOB_TRANS 2 struct table_set_header { uint32_t th_magic; /* TH_MAGIC */ diff --git a/parser/libapparmor_re/hfa.cc b/parser/libapparmor_re/hfa.cc index c013595f6..500275654 100644 --- a/parser/libapparmor_re/hfa.cc +++ b/parser/libapparmor_re/hfa.cc @@ -100,9 +100,10 @@ ostream &operator<<(ostream &os, State &state) * * Should be applied after state minimization */ -int State::diff_weight(State *rel) +int State::diff_weight(State *rel, int max_range, int upper_bound) { int weight = 0; + int first = 0; if (this == rel) return 0; @@ -117,8 +118,10 @@ int State::diff_weight(State *rel) } else if (rel->diff->depth >= this->diff->depth) return 0; + if (rel->trans.begin()->first.c < first) + first = rel->trans.begin()->first.c; if (rel->flags & DiffEncodeFlag) { - for (int i = 0; i < 256; i++) { + for (int i = first; i < upper_bound; i++) { State *state = rel->next(i); StateTrans::iterator j = trans.find(i); if (j != trans.end()) { @@ -184,7 +187,7 @@ int State::diff_weight(State *rel) /* rel default transitions have to be masked with transitions * This covers all transitions not covered above */ - weight -= 256 - (rel->trans.size() + this_count); + weight -= (max_range) - (rel->trans.size() + this_count); } return weight; @@ -193,12 +196,14 @@ int State::diff_weight(State *rel) /** * make_relative - Make this state relative to @rel * @rel: state to make this state relative too + * @upper_bound: the largest value for an input transition (256 for a byte). * * @rel can be a relative (differentially compressed state) */ -int State::make_relative(State *rel) +int State::make_relative(State *rel, int upper_bound) { int weight = 0; + int first = 0; if (this == rel || !rel) return 0; @@ -206,9 +211,12 @@ int State::make_relative(State *rel) if (flags & DiffEncodeFlag) return 0; + if (rel->trans.begin()->first.c < 0) + first = rel->trans.begin()->first.c; + flags |= DiffEncodeFlag; - for (int i = 0; i < 256 ; i++) { + for (int i = first; i < upper_bound ; i++) { State *next = rel->next(i); StateTrans::iterator j = trans.find(i); @@ -236,27 +244,33 @@ int State::make_relative(State *rel) /** * flatten_differential - remove differential encode from this state + * @nonmatching: the nonmatching state for the state machine + * @upper_bound: the largest value for an input transition (256 for a byte). */ -void State::flatten_relative(void) +void State::flatten_relative(State *nonmatching, int upper_bound) { if (!(flags & DiffEncodeFlag)) return; map count; - for (int i = 0; i < 256; i++) + int first = 0; + if (next(-1) != nonmatching) + first = -1; + + for (int i = first; i < upper_bound; i++) count[next(i)] += 1; - int j = 0; - State *def = next(0); - for (int i = 1; i < 256; i++) { + int j = first; + State *def = next(first); + for (int i = first + 1; i < upper_bound; i++) { if (count[next(i)] > count[next(j)]) { j = i; def = next(i); } } - for (int i = 0; i < 256; i++) { + for (int i = first; i < upper_bound; i++) { if (trans.find(i) != trans.end()) { if (trans[i] == def) trans.erase(i); @@ -357,8 +371,11 @@ void DFA::update_state_transitions(State *state) /* Don't insert transition that the otherwise transition * already covers */ - if (target != state->otherwise) + if (target != state->otherwise) { state->trans[j->first] = target; + if (j->first.c < 0 && -j->first.c > oob_range) + oob_range = -j->first.c; + } } } @@ -406,6 +423,10 @@ void DFA::process_work_queue(const char *header, dfaflags_t flags) DFA::DFA(Node *root, dfaflags_t flags): root(root) { diffcount = 0; /* set by diff_encode */ + max_range = 256; + upper_bound = 256; + oob_range = 0; + ord_range = 8; if (flags & DFA_DUMP_PROGRESS) fprintf(stderr, "Creating dfa:\r"); @@ -437,7 +458,10 @@ DFA::DFA(Node *root, dfaflags_t flags): root(root) */ work_queue.push_back(start); process_work_queue("Creating dfa", flags); - + max_range += oob_range; + /* if oob_range is ever greater than 256 need to move to computing this */ + if (oob_range) + ord_range = 9; /* cleanup Sets of nodes used computing the DFA as they are no longer * needed. */ @@ -755,12 +779,9 @@ void DFA::minimize(dfaflags_t flags) c = rep->trans.erase(c); } -//if ((*p)->size() > 1) -//cerr << rep->label << ": "; /* clear the state label for all non representative states, * and accumulate permissions */ for (Partition::iterator i = ++(*p)->begin(); i != (*p)->end(); i++) { -//cerr << " " << (*i)->label; if (flags & DFA_DUMP_MIN_PARTS) cerr << **i << ", "; (*i)->label = -1; @@ -768,8 +789,6 @@ void DFA::minimize(dfaflags_t flags) } if (rep->perms.is_accept()) final_accept++; -//if ((*p)->size() > 1) -//cerr << "\n"; if (flags & DFA_DUMP_MIN_PARTS) cerr << "\n"; } @@ -836,7 +855,7 @@ static unsigned int add_to_dag(DiffDag *dag, State *state, return rc; } -static int diff_partition(State *state, Partition &part, State **candidate) +static int diff_partition(State *state, Partition &part, int max_range, int upper_bound, State **candidate) { int weight = 0; *candidate = NULL; @@ -845,7 +864,7 @@ static int diff_partition(State *state, Partition &part, State **candidate) if (*i == state) continue; - int tmp = state->diff_weight(*i); + int tmp = state->diff_weight(*i, max_range, upper_bound); if (tmp > weight) { weight = tmp; *candidate = *i; @@ -932,14 +951,14 @@ void DFA::diff_encode(dfaflags_t flags) State *candidate = NULL; int weight = diff_partition(state, - state->otherwise->diff->parents, - &candidate); + state->otherwise->diff->parents, max_range, + upper_bound, &candidate); for (StateTrans::iterator j = state->trans.begin(); j != state->trans.end(); j++) { State *tmp_candidate; int tmp = diff_partition(state, - j->second->diff->parents, - &tmp_candidate); + j->second->diff->parents, max_range, + upper_bound, &tmp_candidate); if (tmp > weight) { weight = tmp; candidate = tmp_candidate; @@ -967,7 +986,7 @@ void DFA::diff_encode(dfaflags_t flags) diffcount = 0; for (int i = tail - 1; i > 1; i--) { if (dag[i].rel) { - int weight = dag[i].state->make_relative(dag[i].rel); + int weight = dag[i].state->make_relative(dag[i].rel, upper_bound); aweight += weight; diffcount++; } @@ -1000,7 +1019,7 @@ void DFA::diff_encode(dfaflags_t flags) void DFA::undiff_encode(void) { for (Partition::iterator i = states.begin(); i != states.end(); i++) - (*i)->flatten_relative(); + (*i)->flatten_relative(nonmatching, upper_bound); diffcount = 0; } @@ -1183,9 +1202,11 @@ map DFA::equivalence_classes(dfaflags_t flags) for (Partition::iterator i = states.begin(); i != states.end(); i++) { /* Group edges to the same next state together */ map node_sets; - for (StateTrans::iterator j = (*i)->trans.begin(); j != (*i)->trans.end(); j++) + for (StateTrans::iterator j = (*i)->trans.begin(); j != (*i)->trans.end(); j++) { + if (j->first.c < 0) + continue; node_sets[j->second].insert(j->first); - + } for (map::iterator j = node_sets.begin(); j != node_sets.end(); j++) { /* Group edges to the same next state together by class */ @@ -1271,8 +1292,11 @@ void DFA::apply_equivalence_classes(map &eq) for (Partition::iterator i = states.begin(); i != states.end(); i++) { map tmp; tmp.swap((*i)->trans); - for (StateTrans::iterator j = tmp.begin(); j != tmp.end(); j++) + for (StateTrans::iterator j = tmp.begin(); j != tmp.end(); j++) { + if (j->first.c < 0) + continue; (*i)->trans.insert(make_pair(eq[j->first], j->second)); + } } } diff --git a/parser/libapparmor_re/hfa.h b/parser/libapparmor_re/hfa.h index fd96e5b47..7de4e88c1 100644 --- a/parser/libapparmor_re/hfa.h +++ b/parser/libapparmor_re/hfa.h @@ -241,9 +241,9 @@ public: return os; } - int diff_weight(State *rel); - int make_relative(State *rel); - void flatten_relative(void); + int diff_weight(State *rel, int max_range, int upper_bound); + int make_relative(State *rel, int upper_bound); + void flatten_relative(State *, int upper_bound); int apply_and_clear_deny(void) { return perms.apply_and_clear_deny(); } @@ -340,6 +340,10 @@ public: void apply_equivalence_classes(map &eq); unsigned int diffcount; + int oob_range; + int max_range; + int ord_range; + int upper_bound; Node *root; State *nonmatching, *start; Partition states; diff --git a/parser/mount.cc b/parser/mount.cc index 2181ccc0e..e02a7dc2b 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -643,7 +643,7 @@ int mnt_rule::gen_policy_re(Profile &prof) /* rule for match without required data || data MATCH_CONT */ if (!prof.policy.rules->add_rule_vec(deny, tmpallow, audit | AA_AUDIT_MNT_DATA, 4, - vec, dfaflags)) + vec, dfaflags, false)) goto fail; count++; @@ -655,7 +655,7 @@ int mnt_rule::gen_policy_re(Profile &prof) vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, allow, audit | AA_AUDIT_MNT_DATA, - 5, vec, dfaflags)) + 5, vec, dfaflags, false)) goto fail; count++; } @@ -684,7 +684,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[3] = flagsbuf; if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, - dfaflags)) + dfaflags, false)) goto fail; count++; } @@ -713,7 +713,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[3] = flagsbuf; if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, - dfaflags)) + dfaflags, false)) goto fail; count++; } @@ -743,7 +743,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[3] = flagsbuf; if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, - dfaflags)) + dfaflags, false)) goto fail; count++; } @@ -784,7 +784,7 @@ int mnt_rule::gen_policy_re(Profile &prof) /* rule for match without required data || data MATCH_CONT */ if (!prof.policy.rules->add_rule_vec(deny, tmpallow, audit | AA_AUDIT_MNT_DATA, 4, - vec, dfaflags)) + vec, dfaflags, false)) goto fail; count++; @@ -796,7 +796,7 @@ int mnt_rule::gen_policy_re(Profile &prof) vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, allow, audit | AA_AUDIT_MNT_DATA, - 5, vec, dfaflags)) + 5, vec, dfaflags, false)) goto fail; count++; } @@ -808,7 +808,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[0] = mntbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 1, vec, - dfaflags)) + dfaflags, false)) goto fail; count++; } @@ -822,7 +822,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[1] = devbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 2, vec, - dfaflags)) + dfaflags, false)) goto fail; count++; } diff --git a/parser/parser_regex.c b/parser/parser_regex.c index 1b3c2b659..77b96e467 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -613,7 +613,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } - if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags)) + if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags, false)) return FALSE; } if (is_change_profile_mode(entry->mode)) { @@ -666,12 +666,12 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) /* regular change_profile rule */ if (!dfarules->add_rule_vec(entry->deny, AA_CHANGE_PROFILE | onexec_perms, - 0, index - 1, &vec[1], dfaflags)) + 0, index - 1, &vec[1], dfaflags, false)) return FALSE; /* onexec rules - both rules are needed for onexec */ if (!dfarules->add_rule_vec(entry->deny, onexec_perms, - 0, 1, vec, dfaflags)) + 0, 1, vec, dfaflags, false)) return FALSE; /** @@ -680,7 +680,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) */ onexec_perms |= (entry->mode & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE)); if (!dfarules->add_rule_vec(entry->deny, onexec_perms, - 0, index, vec, dfaflags)) + 0, index, vec, dfaflags, false)) return FALSE; } return TRUE;