add ability to use out of band transitions

Currently the NULL character is used as an out of band transition
for string/path elements. This works for them as the NULL character
is not valid for this data. However this does not work for binary
data that can contain a NULL character.

So far we have only dealt with fixed length fields of binary data
making the NULL separator either unnecessary.

However binary data like in the xattr match and mount data field are
variable length and can contain NULL characters. To deal with this
add the ability to specify out of band transitions, that can only
be triggered by code not input data.

The out of band transition can be used to separate variable length
data fields just as the NULL transition has been used to separate
variable length strings.

In the compressed hfa out of band transitions are expressed as a
negative offset from the states base. This leaves us room to expand
the character match range in the future if desired and on average
makes the range between the out of band transition and the input
transitions smaller than would be had if the out of band transition
had been stored after the valid input transitions.

Out of band transitions in the dfa will not break old kernels
that don't know about them, but they won't be able to trigger
the out of band transition match. So they should not be used unless
the kernel indicates that it supports them.

It should be noted that this patch only adds support for a single
out of band transition. If multiple out of band transitions are
required. It is trivial to extend.
- Add a tag indicating support in the kernel
- add a oob max range field to the dfa header so the kernel knows
  what the max range that needs verifying is.
- extend oob generation fns to generate oob based on value instead
  of a fixed -1.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2019-08-11 06:18:27 -07:00
parent 6062262ccd
commit 16b67ddbd6
11 changed files with 186 additions and 74 deletions

View file

@ -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;
}

View file

@ -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 << " -> ";

View file

@ -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);
};

View file

@ -54,10 +54,11 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &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<transchar, transchar> &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<transchar, transchar> &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<pair<size_t, size_t> > &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<pair<size_t, size_t> > &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<pair<size_t, size_t> > &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));

View file

@ -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<const State *, size_t> num;
map<transchar, transchar> &eq;
transchar max_eq;
size_t first_free;
ssize_t first_free;
unsigned int chfaflags;
};

View file

@ -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)
{

View file

@ -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 */

View file

@ -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<State *, int> 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<transchar, transchar> 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<const State *, Chars> 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<const State *, Chars>::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<transchar, transchar> &eq)
for (Partition::iterator i = states.begin(); i != states.end(); i++) {
map<transchar, State *> 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));
}
}
}

View file

@ -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<transchar, transchar> &eq);
unsigned int diffcount;
int oob_range;
int max_range;
int ord_range;
int upper_bound;
Node *root;
State *nonmatching, *start;
Partition states;

View file

@ -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++;
}

View file

@ -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;