mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-21 17:47:10 +00:00
Merge branch 'master' into 'override'
# Conflicts: # parser/libapparmor_re/expr-tree.h
This commit is contained in:
commit
330d202586
@ -17,6 +17,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "profile.h"
|
||||
#include "af_unix.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* See unix(7) for autobind address definition */
|
||||
#define autobind_address_pattern "\\x00[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]";
|
||||
|
||||
|
@ -1196,17 +1196,17 @@ using inode access times. Matches only:
|
||||
|
||||
=item B<< mount options=(ro, atime) options in (nodev, user) /dev/foo -E<gt> /mnt/, >>
|
||||
|
||||
allow mounting /dev/foo on /mmt/ read only and using inode access times or
|
||||
allow mounting /dev/foo on /mnt/ with some combination of 'nodev' and 'user'.
|
||||
allow mounting /dev/foo on /mnt/ read only and using inode access times, in
|
||||
addition to allowing some combination of 'nodev' and 'user' to be added on top.
|
||||
Matches only:
|
||||
|
||||
$ mount -o ro,atime /dev/foo /mnt
|
||||
|
||||
$ mount -o nodev /dev/foo /mnt
|
||||
$ mount -o ro,atime,nodev /dev/foo /mnt
|
||||
|
||||
$ mount -o user /dev/foo /mnt
|
||||
$ mount -o ro,atime,user /dev/foo /mnt
|
||||
|
||||
$ mount -o nodev,user /dev/foo /mnt
|
||||
$ mount -o ro,atime,nodev,user /dev/foo /mnt
|
||||
|
||||
=back
|
||||
|
||||
|
@ -21,14 +21,12 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* TODO: have includecache be a frontend for file cache, don't just
|
||||
* store name.
|
||||
*/
|
||||
class IncludeCache_t {
|
||||
public:
|
||||
set<string> cache;
|
||||
std::set<std::string> cache;
|
||||
|
||||
IncludeCache_t() = default;
|
||||
virtual ~IncludeCache_t() = default;
|
||||
@ -39,7 +37,7 @@ public:
|
||||
}
|
||||
|
||||
bool insert(const char *name) {
|
||||
pair<set<string>::iterator,bool> res = cache.insert(name);
|
||||
std::pair<std::set<std::string>::iterator,bool> res = cache.insert(name);
|
||||
if (res.second == false) {
|
||||
return false;
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "lib.h"
|
||||
#include "parser.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int dirat_for_each(int dirfd, const char *name, void *data,
|
||||
int (* cb)(int, const char *, struct stat *, void *))
|
||||
{
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "chfa.h"
|
||||
#include "../immunix.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
aare_rules::~aare_rules(void)
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
|
||||
class UniquePermsCache {
|
||||
public:
|
||||
typedef map<UniquePerm, Node*> UniquePermMap;
|
||||
typedef std::map<UniquePerm, Node*> UniquePermMap;
|
||||
typedef UniquePermMap::iterator iterator;
|
||||
UniquePermMap nodes;
|
||||
|
||||
@ -89,7 +89,7 @@ public:
|
||||
node = new ExactMatchFlag(priority, perms, audit);
|
||||
else
|
||||
node = new MatchFlag(priority, perms, audit);
|
||||
pair<iterator, bool> val = nodes.insert(make_pair(tmp, node));
|
||||
std::pair<iterator, bool> val = nodes.insert(std::make_pair(tmp, node));
|
||||
if (val.second == false) {
|
||||
delete node;
|
||||
return val.first->second;
|
||||
@ -121,17 +121,17 @@ class aare_rules {
|
||||
optflags const &opts, bool oob);
|
||||
bool append_rule(const char *rule, bool oob, bool with_perm, optflags const &opts);
|
||||
CHFA *create_chfa(int *min_match_len,
|
||||
vector <aa_perms> &perms_table,
|
||||
std::vector <aa_perms> &perms_table,
|
||||
optflags const &opts, bool filedfa,
|
||||
bool extended_perms, bool prompt);
|
||||
void *create_dfablob(size_t *size, int *min_match_len,
|
||||
vector <aa_perms> &perms_table,
|
||||
std::vector <aa_perms> &perms_table,
|
||||
optflags const &opts,
|
||||
bool filedfa, bool extended_perms, bool prompt);
|
||||
void *create_welded_dfablob(aare_rules *file_rules,
|
||||
size_t *size, int *min_match_len,
|
||||
size_t *new_start,
|
||||
vector <aa_perms> &perms_table,
|
||||
std::vector <aa_perms> &perms_table,
|
||||
optflags const &opts,
|
||||
bool extended_perms, bool prompt);
|
||||
};
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "../policydb.h"
|
||||
#include "flex-tables.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void CHFA::init_free_list(vector<pair<size_t, size_t> > &free_list,
|
||||
size_t prev, size_t start)
|
||||
{
|
||||
|
@ -32,39 +32,37 @@
|
||||
#define MATCH_FLAG_OOB_TRANSITION 0x20000000
|
||||
#define base_mask_size(X) ((X) & ~BASE32_FLAGS)
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef vector<pair<const State *, size_t> > DefaultBase;
|
||||
typedef vector<pair<const State *, const State *> > NextCheck;
|
||||
typedef std::vector<std::pair<const State *, size_t> > DefaultBase;
|
||||
typedef std::vector<std::pair<const State *, const State *> > NextCheck;
|
||||
|
||||
class CHFA {
|
||||
public:
|
||||
CHFA(void);
|
||||
CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts,
|
||||
CHFA(DFA &dfa, std::map<transchar, transchar> &eq, optflags const &opts,
|
||||
bool permindex, bool prompt);
|
||||
void dump(ostream & os);
|
||||
void flex_table(ostream &os, optflags const &opts);
|
||||
void init_free_list(vector<pair<size_t, size_t> > &free_list,
|
||||
void init_free_list(std::vector<std::pair<size_t, size_t> > &free_list,
|
||||
size_t prev, size_t start);
|
||||
bool fits_in(vector<pair<size_t, size_t> > &free_list, size_t base,
|
||||
bool fits_in(std::vector<std::pair<size_t, size_t> > &free_list, size_t base,
|
||||
StateTrans &cases);
|
||||
void insert_state(vector<pair<size_t, size_t> > &free_list,
|
||||
void insert_state(std::vector<std::pair<size_t, size_t> > &free_list,
|
||||
State *state, DFA &dfa);
|
||||
void weld_file_to_policy(CHFA &file_chfa, size_t &new_start,
|
||||
bool accept_idx, bool prompt,
|
||||
vector <aa_perms> &policy_perms,
|
||||
vector <aa_perms> &file_perms);
|
||||
std::vector <aa_perms> &policy_perms,
|
||||
std::vector <aa_perms> &file_perms);
|
||||
|
||||
// private:
|
||||
// sigh templates suck, friend declaration does not work so for now
|
||||
// make these public
|
||||
vector<uint32_t> accept;
|
||||
vector<uint32_t> accept2;
|
||||
std::vector<uint32_t> accept;
|
||||
std::vector<uint32_t> accept2;
|
||||
DefaultBase default_base;
|
||||
NextCheck next_check;
|
||||
const State *start;
|
||||
Renumber_Map num;
|
||||
map<transchar, transchar> eq;
|
||||
std::map<transchar, transchar> eq;
|
||||
unsigned int chfaflags;
|
||||
private:
|
||||
transchar max_eq;
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "expr-tree.h"
|
||||
#include "apparmor_re.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* Use a single static EpsNode as it carries no node specific information */
|
||||
EpsNode epsnode;
|
||||
|
||||
|
@ -44,8 +44,6 @@
|
||||
#include "../perms.h"
|
||||
#include "apparmor_re.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
* transchar - representative input character for state transitions
|
||||
*
|
||||
@ -146,9 +144,9 @@ public:
|
||||
|
||||
class Chars {
|
||||
public:
|
||||
set<transchar> chars;
|
||||
std::set<transchar> chars;
|
||||
|
||||
typedef set<transchar>::iterator iterator;
|
||||
typedef std::set<transchar>::iterator iterator;
|
||||
iterator begin() { return chars.begin(); }
|
||||
iterator end() { return chars.end(); }
|
||||
|
||||
@ -166,11 +164,11 @@ public:
|
||||
{
|
||||
return chars.find(key);
|
||||
}
|
||||
pair<iterator,bool> insert(transchar c)
|
||||
std::pair<iterator,bool> insert(transchar c)
|
||||
{
|
||||
return chars.insert(c);
|
||||
}
|
||||
pair<iterator,bool> insert(char c)
|
||||
std::pair<iterator,bool> insert(char c)
|
||||
{
|
||||
transchar tmp(c);
|
||||
return chars.insert(tmp);
|
||||
@ -181,9 +179,9 @@ public:
|
||||
ostream &operator<<(ostream &os, transchar c);
|
||||
|
||||
/* Compute the union of two sets. */
|
||||
template<class T> set<T> operator+(const set<T> &a, const set<T> &b)
|
||||
template<class T> std::set<T> operator+(const std::set<T> &a, const std::set<T> &b)
|
||||
{
|
||||
set<T> c(a);
|
||||
std::set<T> c(a);
|
||||
c.insert(b.begin(), b.end());
|
||||
return c;
|
||||
}
|
||||
@ -196,7 +194,7 @@ template<class T> set<T> operator+(const set<T> &a, const set<T> &b)
|
||||
*/
|
||||
class Node;
|
||||
class ImportantNode;
|
||||
typedef set<ImportantNode *> NodeSet;
|
||||
typedef std::set<ImportantNode *> NodeSet;
|
||||
|
||||
/**
|
||||
* Text-dump a state (for debugging).
|
||||
@ -212,12 +210,12 @@ ostream &operator<<(ostream &os, const NodeSet &state);
|
||||
* enumerating all the explicit tranitions for default matches.
|
||||
*/
|
||||
typedef struct Cases {
|
||||
typedef map<transchar, NodeSet *>::iterator iterator;
|
||||
typedef std::map<transchar, NodeSet *>::iterator iterator;
|
||||
iterator begin() { return cases.begin(); }
|
||||
iterator end() { return cases.end(); }
|
||||
|
||||
Cases(): otherwise(0) { }
|
||||
map<transchar, NodeSet *> cases;
|
||||
std::map<transchar, NodeSet *> cases;
|
||||
NodeSet *otherwise;
|
||||
} Cases;
|
||||
|
||||
@ -891,7 +889,8 @@ public:
|
||||
{
|
||||
type_flags |= NODE_TYPE_MATCHFLAG;
|
||||
}
|
||||
ostream &dump(ostream &os) override { return os << "< 0x" << hex << perms << std::dec << '>'; }
|
||||
|
||||
ostream &dump(ostream &os) override { return os << "< 0x" << std::hex << perms << std::dec << '>'; }
|
||||
|
||||
int priority;
|
||||
perm32_t perms;
|
||||
@ -925,7 +924,7 @@ public:
|
||||
|
||||
/* Traverse the syntax tree depth-first in an iterator-like manner. */
|
||||
class depth_first_traversal {
|
||||
stack<Node *>pos;
|
||||
std::stack<Node *>pos;
|
||||
void push_left(Node *node) {
|
||||
pos.push(node);
|
||||
|
||||
@ -1051,7 +1050,7 @@ struct deref_less_than {
|
||||
|
||||
class NodeVecCache: public CacheStats {
|
||||
public:
|
||||
set<NodeVec *, deref_less_than> cache;
|
||||
std::set<NodeVec *, deref_less_than> cache;
|
||||
|
||||
NodeVecCache(void): cache() { };
|
||||
~NodeVecCache() override { clear(); };
|
||||
@ -1060,7 +1059,7 @@ public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (set<NodeVec *>::iterator i = cache.begin();
|
||||
for (std::set<NodeVec *>::iterator i = cache.begin();
|
||||
i != cache.end(); i++) {
|
||||
delete *i;
|
||||
}
|
||||
@ -1072,7 +1071,7 @@ public:
|
||||
{
|
||||
if (!nodes)
|
||||
return NULL;
|
||||
pair<set<NodeVec *>::iterator,bool> uniq;
|
||||
std::pair<std::set<NodeVec *>::iterator,bool> uniq;
|
||||
NodeVec *nv = new NodeVec(nodes);
|
||||
uniq = cache.insert(nv);
|
||||
if (uniq.second == false) {
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "../immunix.h"
|
||||
#include "../perms.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ostream &operator<<(ostream &os, const CacheStats &cache)
|
||||
{
|
||||
/* dump the state label */
|
||||
@ -1443,9 +1445,31 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
MatchFlag *match, perms_t &perms, perms_t &exact,
|
||||
bool filedfa)
|
||||
{
|
||||
if (priority[i] > match->priority) {
|
||||
// scaling priority *4
|
||||
int pri = match->priority<<2;
|
||||
|
||||
/* use priority to get proper ordering and application of the type
|
||||
* of match flag.
|
||||
*
|
||||
* Note: this is the last use of priority, it is dropped and not
|
||||
* used in the backend.
|
||||
*/
|
||||
if (match->is_type(NODE_TYPE_DENYMATCHFLAG))
|
||||
pri += 3;
|
||||
// exact match must be same priority as allow as its audit
|
||||
// flags has the same priority.
|
||||
// current no ALLOWMATCHFLAG it is just absence of other flags
|
||||
// so it has to be second last in this list, using !last
|
||||
// until this gets fixed
|
||||
else if (match->is_type(NODE_TYPE_EXACTMATCHFLAG) ||
|
||||
(!match->is_type(NODE_TYPE_PROMPTMATCHFLAG)))
|
||||
pri += 2;
|
||||
else if (match->is_type(NODE_TYPE_PROMPTMATCHFLAG))
|
||||
pri += 1;
|
||||
|
||||
if (priority[i] > pri) {
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " > " << match->priority << " SKIPPING " << hex << (match->perms) << "/" << (match->audit) << dec << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " > " << pri << " SKIPPING " << hex << (match->perms) << "/" << (match->audit) << dec << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1461,8 +1485,8 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
if (match->perms & AA_EXEC_INHERIT) {
|
||||
xmask |= AA_USER_EXEC_MMAP;
|
||||
//USER_EXEC_MAP = 6
|
||||
if (priority[6] < match->priority)
|
||||
priority[6] = match->priority;
|
||||
if (priority[6] < pri)
|
||||
priority[6] = pri;
|
||||
}
|
||||
amask = mask | xmask;
|
||||
} else if (mask & AA_OTHER_EXEC) {
|
||||
@ -1471,8 +1495,8 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
if (match->perms & AA_OTHER_EXEC_INHERIT) {
|
||||
xmask |= AA_OTHER_EXEC_MMAP;
|
||||
//OTHER_EXEC_MAP = 20
|
||||
if (priority[20] < match->priority)
|
||||
priority[20] = match->priority;
|
||||
if (priority[20] < pri)
|
||||
priority[20] = pri;
|
||||
}
|
||||
amask = mask | xmask;
|
||||
} else if (((mask & AA_USER_EXEC_MMAP) &&
|
||||
@ -1481,17 +1505,17 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
(match->perms & AA_OTHER_EXEC_INHERIT))) {
|
||||
// if exec && ix we handled mmp above
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " SKIPPING mmap unmasked " << hex << match->perms << "/" << match->audit << " masked " << (match->perms & amask) << "/" << (match->audit & amask) << " data " << (perms.allow & mask) << "/" << (perms.audit & mask) << " exact " << (exact.allow & mask) << "/" << (exact.audit & mask) << dec << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " SKIPPING mmap unmasked " << hex << match->perms << "/" << match->audit << " masked " << (match->perms & amask) << "/" << (match->audit & amask) << " data " << (perms.allow & mask) << "/" << (perms.audit & mask) << " exact " << (exact.allow & mask) << "/" << (exact.audit & mask) << dec << "\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " vs. " << match->priority << " mask: " << hex << mask << " xmask: " << xmask << " amask: " << amask << dec << "\n";
|
||||
if (priority[i] < match->priority) {
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " vs. " << pri << " mask: " << hex << mask << " xmask: " << xmask << " amask: " << amask << dec << "\n";
|
||||
if (priority[i] < pri) {
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " < " << match->priority << " clearing " << hex << (perms.allow & amask) << "/" << (perms.audit & amask) << " -> " << dec;
|
||||
priority[i] = match->priority;
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " < " << pri << " clearing " << hex << (perms.allow & amask) << "/" << (perms.audit & amask) << " -> " << dec;
|
||||
priority[i] = pri;
|
||||
perms.clear_bits(amask);
|
||||
exact.clear_bits(amask);
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
@ -1501,7 +1525,7 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
// the if conditions in order of permission priority
|
||||
if (match->is_type(NODE_TYPE_DENYMATCHFLAG)) {
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " deny " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " deny " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
perms.deny |= match->perms & amask;
|
||||
perms.quiet |= match->audit & amask;
|
||||
|
||||
@ -1511,11 +1535,11 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
} else if (match->is_type(NODE_TYPE_EXACTMATCHFLAG)) {
|
||||
/* exact match only asserts dominance on the XTYPE */
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " exact " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " exact " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
if (filedfa &&
|
||||
!is_merged_x_consistent(exact.allow, match->perms & amask)) {
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " exact match conflict" << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " exact match conflict" << "\n";
|
||||
return 1;
|
||||
}
|
||||
exact.allow |= match->perms & amask;
|
||||
@ -1536,11 +1560,11 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
// allow perms, if exact has been encountered will already be set
|
||||
// if overlaps x here, don't conflict, because exact will override
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " allow " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " allow " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
if (filedfa && !(exact.allow & mask) &&
|
||||
!is_merged_x_consistent(perms.allow, match->perms & amask)) {
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " allow match conflict" << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " allow match conflict" << "\n";
|
||||
return 1;
|
||||
}
|
||||
// mask off if XTYPE in xmatch
|
||||
@ -1554,11 +1578,11 @@ static int pri_update_perm(optflags const &opts, vector<int> &priority, int i,
|
||||
}
|
||||
} else { // if (match->is_type(NODE_TYPE_PROMPTMATCHFLAG)) {
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " prompt " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " prompt " << hex << (match->perms & amask) << "/" << (match->audit & amask) << dec << "\n";
|
||||
if (filedfa && !((exact.allow | perms.allow) & mask) &&
|
||||
!is_merged_x_consistent(perms.allow, match->perms & amask)) {
|
||||
if (opts.dump & DUMP_DFA_PERMS)
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << match->priority << " prompt match conflict" << "\n";
|
||||
cerr << " " << match << "[" << i << "]=" << priority[i] << " <= " << pri << " prompt match conflict" << "\n";
|
||||
return 1;
|
||||
}
|
||||
if ((exact.allow | exact.audit | perms.allow | perms.audit) & mask) {
|
||||
@ -1584,7 +1608,8 @@ int accept_perms(optflags const &opts, NodeVec *state, perms_t &perms,
|
||||
{
|
||||
int error = 0;
|
||||
perms_t exact;
|
||||
std::vector<int> priority(sizeof(perm32_t)*8, MIN_INTERNAL_PRIORITY); // 32 but wan't tied to perm32_t
|
||||
// scaling priority by *4
|
||||
std::vector<int> priority(sizeof(perm32_t)*8, MIN_INTERNAL_PRIORITY<<2); // 32 but wan't tied to perm32_t
|
||||
perms.clear();
|
||||
|
||||
if (!state)
|
||||
|
@ -42,8 +42,8 @@ extern int prompt_compat_mode;
|
||||
|
||||
class State;
|
||||
|
||||
typedef map<transchar, State *> StateTrans;
|
||||
typedef list<State *> Partition;
|
||||
typedef std::map<transchar, State *> StateTrans;
|
||||
typedef std::list<State *> Partition;
|
||||
|
||||
#include "../immunix.h"
|
||||
|
||||
@ -62,9 +62,9 @@ public:
|
||||
}
|
||||
ostream &dump(ostream &os)
|
||||
{
|
||||
os << "(0x " << hex
|
||||
os << "(0x " << std::hex
|
||||
<< allow << "/" << deny << "/" << "/" << prompt << "/" << audit << "/" << quiet
|
||||
<< ')' << dec;
|
||||
<< ')' << std::dec;
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -317,11 +317,11 @@ public:
|
||||
class NodeMap: public CacheStats
|
||||
{
|
||||
public:
|
||||
typedef map<ProtoState, State *>::iterator iterator;
|
||||
typedef std::map<ProtoState, State *>::iterator iterator;
|
||||
iterator begin() { return cache.begin(); }
|
||||
iterator end() { return cache.end(); }
|
||||
|
||||
map<ProtoState, State *> cache;
|
||||
std::map<ProtoState, State *> cache;
|
||||
|
||||
NodeMap(void): cache() { };
|
||||
~NodeMap() override { clear(); };
|
||||
@ -334,10 +334,10 @@ public:
|
||||
CacheStats::clear();
|
||||
}
|
||||
|
||||
pair<iterator,bool> insert(ProtoState &proto, State *state)
|
||||
std::pair<iterator,bool> insert(ProtoState &proto, State *state)
|
||||
{
|
||||
pair<iterator,bool> uniq;
|
||||
uniq = cache.insert(make_pair(proto, state));
|
||||
std::pair<iterator,bool> uniq;
|
||||
uniq = cache.insert(std::make_pair(proto, state));
|
||||
if (uniq.second == false) {
|
||||
dup++;
|
||||
} else {
|
||||
@ -349,7 +349,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef map<const State *, size_t> Renumber_Map;
|
||||
typedef std::map<const State *, size_t> Renumber_Map;
|
||||
|
||||
/* Transitions in the DFA. */
|
||||
class DFA {
|
||||
@ -360,7 +360,7 @@ class DFA {
|
||||
NodeSet *nnodes, State *other);
|
||||
void update_state_transitions(optflags const &opts, State *state);
|
||||
void process_work_queue(const char *header, optflags const &);
|
||||
void dump_diff_chain(ostream &os, map<State *, Partition> &relmap,
|
||||
void dump_diff_chain(ostream &os, std::map<State *, Partition> &relmap,
|
||||
Partition &chain, State *state,
|
||||
unsigned int &count, unsigned int &total,
|
||||
unsigned int &max);
|
||||
@ -369,7 +369,7 @@ class DFA {
|
||||
NodeVecCache anodes_cache;
|
||||
NodeVecCache nnodes_cache;
|
||||
NodeMap node_map;
|
||||
list<State *> work_queue;
|
||||
std::list<State *> work_queue;
|
||||
|
||||
public:
|
||||
DFA(Node *root, optflags const &flags, bool filedfa);
|
||||
@ -394,14 +394,14 @@ public:
|
||||
void dump_uniq_perms(const char *s);
|
||||
ostream &dump_partition(ostream &os, Partition &p);
|
||||
ostream &dump_partitions(ostream &os, const char *description,
|
||||
list<Partition *> &partitions);
|
||||
map<transchar, transchar> equivalence_classes(optflags const &flags);
|
||||
void apply_equivalence_classes(map<transchar, transchar> &eq);
|
||||
std::list<Partition *> &partitions);
|
||||
std::map<transchar, transchar> equivalence_classes(optflags const &flags);
|
||||
void apply_equivalence_classes(std::map<transchar, transchar> &eq);
|
||||
|
||||
void compute_perms_table_ent(State *state, size_t pos,
|
||||
vector <aa_perms> &perms_table,
|
||||
std::vector <aa_perms> &perms_table,
|
||||
bool prompt);
|
||||
void compute_perms_table(vector <aa_perms> &perms_table,
|
||||
void compute_perms_table(std::vector <aa_perms> &perms_table,
|
||||
bool prompt);
|
||||
|
||||
unsigned int diffcount;
|
||||
@ -415,6 +415,6 @@ public:
|
||||
bool filedfa;
|
||||
};
|
||||
|
||||
void dump_equivalence_classes(ostream &os, map<transchar, transchar> &eq);
|
||||
void dump_equivalence_classes(ostream &os, std::map<transchar, transchar> &eq);
|
||||
|
||||
#endif /* __LIBAA_RE_HFA_H */
|
||||
|
@ -24,6 +24,8 @@
|
||||
/* #define DEBUG_TREE */
|
||||
#include "expr-tree.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
@ -60,7 +62,7 @@ static inline Chars* insert_char_range(Chars* cset, transchar a, transchar b)
|
||||
%lex-param {YYLEX_PARAM}
|
||||
%parse-param {Node **root}
|
||||
%parse-param {const char *text}
|
||||
%name-prefix "regex_"
|
||||
%define api.prefix {regex_}
|
||||
|
||||
%token <c> CHAR
|
||||
%type <c> regex_char cset_char1 cset_char cset_charN
|
||||
|
@ -228,6 +228,8 @@
|
||||
#include "profile.h"
|
||||
#include "mount.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct mnt_keyword_table {
|
||||
const char *keyword;
|
||||
unsigned int set;
|
||||
|
@ -41,8 +41,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <set>
|
||||
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#define SD_CODE_SIZE (sizeof(u8))
|
||||
#define SD_STR_LEN (sizeof(u16))
|
||||
|
||||
using namespace std;
|
||||
|
||||
int __sd_serialize_profile(int option, aa_kernel_interface *kernel_interface,
|
||||
Profile *prof, int cache_fd);
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "policy_cache.h"
|
||||
#include "file_cache.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef PDEBUG
|
||||
#undef PDEBUG
|
||||
#endif
|
||||
|
@ -66,6 +66,8 @@ void *reallocarray(void *ptr, size_t nmemb, size_t size)
|
||||
#define NULL nullptr
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
int is_blacklisted(const char *name, const char *path)
|
||||
{
|
||||
int retval = _aa_is_blacklisted(name);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#endif
|
||||
#define NPDEBUG(fmt, args...) /* Do nothing */
|
||||
|
||||
using namespace std;
|
||||
|
||||
ProfileList policy_list;
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define CIDR_32 htonl(0xffffffff)
|
||||
#define CIDR_24 htonl(0xffffff00)
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const char *profile_mode_table[] = {
|
||||
"",
|
||||
"enforce",
|
||||
|
@ -42,16 +42,16 @@ struct deref_profileptr_lt {
|
||||
|
||||
class ProfileList {
|
||||
public:
|
||||
set<Profile *, deref_profileptr_lt> list;
|
||||
std::set<Profile *, deref_profileptr_lt> list;
|
||||
|
||||
typedef set<Profile *, deref_profileptr_lt>::iterator iterator;
|
||||
typedef std::set<Profile *, deref_profileptr_lt>::iterator iterator;
|
||||
iterator begin() { return list.begin(); }
|
||||
iterator end() { return list.end(); }
|
||||
|
||||
ProfileList() { };
|
||||
virtual ~ProfileList() { clear(); }
|
||||
virtual bool empty(void) { return list.empty(); }
|
||||
virtual pair<ProfileList::iterator,bool> insert(Profile *);
|
||||
virtual std::pair<ProfileList::iterator,bool> insert(Profile *);
|
||||
virtual void erase(ProfileList::iterator pos);
|
||||
void clear(void);
|
||||
void dump(void);
|
||||
@ -368,7 +368,7 @@ struct dfa_stuff {
|
||||
void *dfa;
|
||||
size_t size;
|
||||
size_t file_start; /* special start in welded dfa */
|
||||
vector <aa_perms> perms_table;
|
||||
std::vector <aa_perms> perms_table;
|
||||
dfa_stuff(void): rules(NULL), dfa(NULL), size(0) { }
|
||||
};
|
||||
|
||||
@ -382,7 +382,7 @@ public:
|
||||
void *xmatch;
|
||||
size_t xmatch_size;
|
||||
int xmatch_len;
|
||||
vector <aa_perms> xmatch_perms_table;
|
||||
std::vector <aa_perms> xmatch_perms_table;
|
||||
struct cond_entry_list xattrs;
|
||||
|
||||
/* char *sub_name; */ /* subdomain name or NULL */
|
||||
@ -477,7 +477,7 @@ public:
|
||||
debug_cod_entries(entries);
|
||||
|
||||
for (RuleList::iterator i = rule_ents.begin(); i != rule_ents.end(); i++) {
|
||||
(*i)->dump(cout);
|
||||
(*i)->dump(std::cout);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
@ -511,7 +511,7 @@ public:
|
||||
|
||||
void dump_name(bool fqp)
|
||||
{
|
||||
cout << get_name(fqp);;
|
||||
std::cout << get_name(fqp);;
|
||||
}
|
||||
|
||||
void post_parse_profile(void);
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include "perms.h"
|
||||
#include "policydb.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define PROMPT_COMPAT_UNKNOWN 0
|
||||
#define PROMPT_COMPAT_IGNORE 1
|
||||
#define PROMPT_COMPAT_PERMSV2 2
|
||||
@ -436,9 +434,9 @@ public:
|
||||
class_rule_t::dump(os);
|
||||
|
||||
if (saved)
|
||||
os << "(0x" << hex << perms << "/orig " << saved << ") ";
|
||||
os << "(0x" << std::hex << perms << "/orig " << saved << ") ";
|
||||
else
|
||||
os << "(0x" << hex << perms << ") ";
|
||||
os << "(0x" << std::hex << perms << ") ";
|
||||
|
||||
return os;
|
||||
}
|
||||
@ -464,7 +462,7 @@ public:
|
||||
ostream &dump(ostream &os) override {
|
||||
class_rule_t::dump(os);
|
||||
|
||||
os << "(0x" << hex << perms << ") ";
|
||||
os << "(0x" << std::hex << perms << ") ";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "parser_yacc.h"
|
||||
#include "signal.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define MAXMAPPED_SIG 35
|
||||
#define MINRT_SIG 128 /* base of RT sigs */
|
||||
#define MAXRT_SIG 32 /* Max RT above MINRT_SIG */
|
||||
|
@ -29,7 +29,7 @@
|
||||
#define AA_VALID_SIGNAL_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE)
|
||||
|
||||
|
||||
typedef set<int> Signals;
|
||||
typedef std::set<int> Signals;
|
||||
|
||||
int find_signal_mapping(const char *sig);
|
||||
int parse_signal_perms(const char *str_perms, perm32_t *perms, int fail);
|
||||
|
@ -1223,7 +1223,7 @@ done
|
||||
|
||||
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
|
||||
|
||||
if [ $# -eq 0 -o -z $testtype] ; then
|
||||
if [ $# -eq 0 -o -z "$testtype" ] ; then
|
||||
run_tests "$@"
|
||||
exit $?
|
||||
fi
|
||||
|
@ -15,10 +15,5 @@
|
||||
priority=-1 file ux /foo3,
|
||||
priority=-1 file Ux /foo4,
|
||||
priority=-1 file ix /foo5,
|
||||
priority=-1 file unsafe px /foo6,
|
||||
priority=-1 file unsafe Px /foo7,
|
||||
priority=-1 file unsafe ux /foo8,
|
||||
priority=-1 file unsafe Ux /foo9,
|
||||
priority=-1 file unsafe ix /foo10,
|
||||
|
||||
}
|
||||
|
@ -15,10 +15,5 @@
|
||||
priority=-1 ux /foo3,
|
||||
priority=-1 Ux /foo4,
|
||||
priority=-1 ix /foo5,
|
||||
priority=-1 unsafe px /foo6,
|
||||
priority=-1 unsafe Px /foo7,
|
||||
priority=-1 unsafe ux /foo8,
|
||||
priority=-1 unsafe Ux /foo9,
|
||||
priority=-1 unsafe ix /foo10,
|
||||
|
||||
}
|
||||
|
12
parser/tst/simple_tests/file/priority/front_perms_ok_3.sd
Normal file
12
parser/tst/simple_tests/file/priority/front_perms_ok_3.sd
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
#=DESCRIPTION perms before pathname + unsafe keyword
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/usr/bin/foo {
|
||||
priority=-1 file unsafe px /foo6,
|
||||
priority=-1 file unsafe Px /foo7,
|
||||
priority=-1 file unsafe ux /foo8,
|
||||
priority=-1 file unsafe Ux /foo9,
|
||||
priority=-1 file unsafe ix /foo10,
|
||||
|
||||
}
|
13
parser/tst/simple_tests/file/priority/front_perms_ok_4.sd
Normal file
13
parser/tst/simple_tests/file/priority/front_perms_ok_4.sd
Normal file
@ -0,0 +1,13 @@
|
||||
#
|
||||
#=DESCRIPTION perms before pathname + unsafe keyword
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/usr/bin/foo {
|
||||
|
||||
priority=-1 unsafe px /foo6,
|
||||
priority=-1 unsafe Px /foo7,
|
||||
priority=-1 unsafe ux /foo8,
|
||||
priority=-1 unsafe Ux /foo9,
|
||||
priority=-1 unsafe ix /foo10,
|
||||
|
||||
}
|
30
profiles/apparmor.d/ssh-keyscan
Normal file
30
profiles/apparmor.d/ssh-keyscan
Normal file
@ -0,0 +1,30 @@
|
||||
#------------------------------------------------------------------
|
||||
# Copyright (C) 2025 Canonical Ltd.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#------------------------------------------------------------------
|
||||
# vim: ft=apparmor
|
||||
#
|
||||
abi <abi/4.0>,
|
||||
|
||||
include <tunables/global>
|
||||
|
||||
profile ssh-keyscan /usr/bin/ssh-keyscan {
|
||||
include <abstractions/base>
|
||||
include <abstractions/nameservice-strict>
|
||||
|
||||
network inet dgram,
|
||||
network inet6 dgram,
|
||||
network inet stream,
|
||||
network inet6 stream,
|
||||
network netlink raw,
|
||||
|
||||
# Allow executable mapping and read for the binary
|
||||
file mr /usr/bin/ssh-keyscan,
|
||||
|
||||
# Site-specific additions and overrides. See local/README for details.
|
||||
include if exists <local/ssh-keyscan>
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ from apparmor.translations import init_translation
|
||||
_ = init_translation()
|
||||
|
||||
# Profile parsing Regex
|
||||
RE_AUDIT_DENY = r'^\s*(?P<audit>audit\s+)?(?P<allow>allow\s+|deny\s+)?' # line start, optionally: leading whitespace, <audit> and <allow>/deny
|
||||
RE_PRIORITY_AUDIT_DENY = r'^\s*(priority\s*=\s*(?P<priority>[+-]?[0-9]*)\s+)?(?P<audit>audit\s+)?(?P<allow>allow\s+|deny\s+)?' # line start, optionally: leading whitespace, <priority> = number, <audit> and <allow>/deny
|
||||
RE_EOL = r'\s*(?P<comment>#.*?)?\s*$' # optional whitespace, optional <comment>, optional whitespace, end of the line
|
||||
RE_COMMA_EOL = r'\s*,' + RE_EOL # optional whitespace, comma + RE_EOL
|
||||
|
||||
@ -34,8 +34,8 @@ RE_XATTRS = r'(\s+xattrs\s*=\s*\((?P<xattrs>([^)=]+(=[^)=]+)?\s?)+)\)\s*)?'
|
||||
RE_FLAGS = r'(\s+(flags\s*=\s*)?\((?P<flags>[^)]+)\))?'
|
||||
|
||||
RE_PROFILE_END = re.compile(r'^\s*\}' + RE_EOL)
|
||||
RE_PROFILE_ALL = re.compile(RE_AUDIT_DENY + r'all' + RE_COMMA_EOL)
|
||||
RE_PROFILE_CAP = re.compile(RE_AUDIT_DENY + r'capability(?P<capability>(\s+\S+)+)?' + RE_COMMA_EOL)
|
||||
RE_PROFILE_ALL = re.compile(RE_PRIORITY_AUDIT_DENY + r'all' + RE_COMMA_EOL)
|
||||
RE_PROFILE_CAP = re.compile(RE_PRIORITY_AUDIT_DENY + r'capability(?P<capability>(\s+\S+)+)?' + RE_COMMA_EOL)
|
||||
RE_PROFILE_ALIAS = re.compile(r'^\s*alias\s+(?P<orig_path>"??.+?"??)\s+->\s*(?P<target>"??.+?"??)' + RE_COMMA_EOL)
|
||||
RE_PROFILE_RLIMIT = re.compile(r'^\s*set\s+rlimit\s+(?P<rlimit>[a-z]+)\s*<=\s*(?P<value>[^ ]+(\s+[a-zA-Z]+)?)' + RE_COMMA_EOL)
|
||||
RE_PROFILE_BOOLEAN = re.compile(r'^\s*(?P<varname>\$\{?\w*\}?)\s*=\s*(?P<value>true|false)\s*,?' + RE_EOL, flags=re.IGNORECASE)
|
||||
@ -43,18 +43,18 @@ RE_PROFILE_VARIABLE = re.compile(r'^\s*(?P<varname>@\{?\w+\}?)\s*(?P<mode>\+?=)\
|
||||
RE_PROFILE_CONDITIONAL = re.compile(r'^\s*if\s+(not\s+)?(\$\{?\w*\}?)\s*\{' + RE_EOL)
|
||||
RE_PROFILE_CONDITIONAL_VARIABLE = re.compile(r'^\s*if\s+(not\s+)?defined\s+(@\{?\w+\}?)\s*\{\s*(#.*)?$')
|
||||
RE_PROFILE_CONDITIONAL_BOOLEAN = re.compile(r'^\s*if\s+(not\s+)?defined\s+(\$\{?\w+\}?)\s*\{\s*(#.*)?$')
|
||||
RE_PROFILE_NETWORK = re.compile(RE_AUDIT_DENY + r'network(?P<details>\s+.*)?' + RE_COMMA_EOL)
|
||||
RE_PROFILE_NETWORK = re.compile(RE_PRIORITY_AUDIT_DENY + r'network(?P<details>\s+.*)?' + RE_COMMA_EOL)
|
||||
RE_PROFILE_CHANGE_HAT = re.compile(r'^\s*\^("??.+?"??)' + RE_COMMA_EOL)
|
||||
RE_PROFILE_HAT_DEF = re.compile(r'^(?P<leadingspace>\s*)(?P<hat_keyword>\^|hat\s+)(?P<hat>"??[^)]+?"??)' + RE_FLAGS + r'\s*\{' + RE_EOL)
|
||||
RE_PROFILE_DBUS = re.compile(RE_AUDIT_DENY + r'(dbus\s*,|dbus(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_MOUNT = re.compile(RE_AUDIT_DENY + r'((?P<operation>mount|remount|umount|unmount)(?P<details>\s+[^#]*)?\s*,)' + RE_EOL)
|
||||
RE_PROFILE_SIGNAL = re.compile(RE_AUDIT_DENY + r'(signal\s*,|signal(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_PTRACE = re.compile(RE_AUDIT_DENY + r'(ptrace\s*,|ptrace(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_PIVOT_ROOT = re.compile(RE_AUDIT_DENY + r'(pivot_root\s*,|pivot_root(?P<details>\s+[^#]*),)' + RE_EOL)
|
||||
RE_PROFILE_UNIX = re.compile(RE_AUDIT_DENY + r'(unix\s*,|unix(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_USERNS = re.compile(RE_AUDIT_DENY + r'(userns\s*,|userns(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_MQUEUE = re.compile(RE_AUDIT_DENY + r'(mqueue\s*,|mqueue(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_IO_URING = re.compile(RE_AUDIT_DENY + r'(io_uring\s*,|io_uring(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_DBUS = re.compile(RE_PRIORITY_AUDIT_DENY + r'(dbus\s*,|dbus(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_MOUNT = re.compile(RE_PRIORITY_AUDIT_DENY + r'((?P<operation>mount|remount|umount|unmount)(?P<details>\s+[^#]*)?\s*,)' + RE_EOL)
|
||||
RE_PROFILE_SIGNAL = re.compile(RE_PRIORITY_AUDIT_DENY + r'(signal\s*,|signal(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_PTRACE = re.compile(RE_PRIORITY_AUDIT_DENY + r'(ptrace\s*,|ptrace(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_PIVOT_ROOT = re.compile(RE_PRIORITY_AUDIT_DENY + r'(pivot_root\s*,|pivot_root(?P<details>\s+[^#]*),)' + RE_EOL)
|
||||
RE_PROFILE_UNIX = re.compile(RE_PRIORITY_AUDIT_DENY + r'(unix\s*,|unix(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_USERNS = re.compile(RE_PRIORITY_AUDIT_DENY + r'(userns\s*,|userns(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_MQUEUE = re.compile(RE_PRIORITY_AUDIT_DENY + r'(mqueue\s*,|mqueue(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
RE_PROFILE_IO_URING = re.compile(RE_PRIORITY_AUDIT_DENY + r'(io_uring\s*,|io_uring(?P<details>\s+[^#]*)\s*,)' + RE_EOL)
|
||||
|
||||
# match anything that's not " or #, or matching quotes with anything except quotes inside
|
||||
__re_no_or_quoted_hash = '([^#"]|"[^"]*")*'
|
||||
@ -81,7 +81,7 @@ RE_PROFILE_START = re.compile(
|
||||
|
||||
|
||||
RE_PROFILE_CHANGE_PROFILE = re.compile(
|
||||
RE_AUDIT_DENY
|
||||
RE_PRIORITY_AUDIT_DENY
|
||||
+ 'change_profile'
|
||||
+ r'(\s+' + RE_SAFE_OR_UNSAFE + ')?' # optionally exec mode
|
||||
+ r'(\s+' + RE_PROFILE_PATH_OR_VAR % 'execcond' + ')?' # optionally exec condition
|
||||
@ -94,7 +94,7 @@ RE_PROFILE_CHANGE_PROFILE = re.compile(
|
||||
RE_PATH_PERMS = '(?P<%s>[mrwalkPUCpucix]+)'
|
||||
|
||||
RE_PROFILE_FILE_ENTRY = re.compile(
|
||||
RE_AUDIT_DENY
|
||||
RE_PRIORITY_AUDIT_DENY
|
||||
+ r'(?P<owner>owner\s+)?' # optionally: <owner>
|
||||
+ '('
|
||||
+ '(?P<bare_file>file)' # bare 'file,' # noqa: E131
|
||||
|
@ -41,8 +41,10 @@ class BaseRule(metaclass=ABCMeta):
|
||||
_match_re = None
|
||||
|
||||
def __init__(self, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
"""initialize variables needed by all rule types"""
|
||||
|
||||
self._store_priority(priority)
|
||||
self.audit = audit
|
||||
self.deny = deny
|
||||
self.allow_keyword = allow_keyword
|
||||
@ -52,6 +54,21 @@ class BaseRule(metaclass=ABCMeta):
|
||||
# Set only in the parse() class method
|
||||
self.raw_rule = None
|
||||
|
||||
def _store_priority(self, priority):
|
||||
if priority is None: # default priority
|
||||
self.priority = None
|
||||
return
|
||||
|
||||
try:
|
||||
ipriority = int(priority)
|
||||
except ValueError:
|
||||
raise AppArmorException("Invalid value for priority '%s'" % priority)
|
||||
|
||||
if ipriority < -1000 or ipriority > 1000:
|
||||
raise AppArmorException('priority %d out of range' % (ipriority))
|
||||
|
||||
self.priority = ipriority
|
||||
|
||||
def _aare_or_all(self, rulepart, partname, is_path, log_event, empty_ok=False):
|
||||
"""checks rulepart and returns
|
||||
- (AARE, False) if rulepart is a (non-empty) string
|
||||
@ -233,7 +250,9 @@ class BaseRule(metaclass=ABCMeta):
|
||||
"""compare if rule_obj == self
|
||||
Calls _is_equal_localvars() to compare rule-specific variables"""
|
||||
|
||||
if self.audit != rule_obj.audit or self.deny != rule_obj.deny:
|
||||
if (self.priority != rule_obj.priority
|
||||
or self.audit != rule_obj.audit
|
||||
or self.deny != rule_obj.deny):
|
||||
return False
|
||||
|
||||
if strict and (
|
||||
@ -282,6 +301,9 @@ class BaseRule(metaclass=ABCMeta):
|
||||
headers = []
|
||||
qualifier = []
|
||||
|
||||
if self.priority:
|
||||
qualifier.append('priority=%s' % self.priority)
|
||||
|
||||
if self.audit:
|
||||
qualifier.append('audit')
|
||||
|
||||
@ -318,7 +340,12 @@ class BaseRule(metaclass=ABCMeta):
|
||||
raise NotImplementedError("'%s' needs to implement store_edit(), but didn't" % (str(self)))
|
||||
|
||||
def modifiers_str(self):
|
||||
"""return the allow/deny and audit keyword as string, including whitespace"""
|
||||
"""return priority, allow/deny, and audit keyword as string, including whitespace"""
|
||||
|
||||
if self.priority is not None:
|
||||
prioritystr = 'priority=%s ' % self.priority
|
||||
else:
|
||||
prioritystr = ''
|
||||
|
||||
if self.audit:
|
||||
auditstr = 'audit '
|
||||
@ -332,7 +359,17 @@ class BaseRule(metaclass=ABCMeta):
|
||||
else:
|
||||
allowstr = ''
|
||||
|
||||
return '%s%s' % (auditstr, allowstr)
|
||||
return '%s%s%s' % (prioritystr, auditstr, allowstr)
|
||||
|
||||
def ensure_modifiers_not_supported(self):
|
||||
if self.audit:
|
||||
raise AppArmorBug('Attempt to initialize %s with audit flag' % self.__class__.__name__)
|
||||
if self.deny:
|
||||
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
|
||||
if self.allow_keyword:
|
||||
raise AppArmorBug('Attempt to initialize %s with allow keyword' % self.__class__.__name__)
|
||||
if self.priority is not None:
|
||||
raise AppArmorBug('Attempt to initialize %s with priority' % self.__class__.__name__)
|
||||
|
||||
|
||||
class BaseRuleset:
|
||||
@ -565,9 +602,16 @@ def parse_comment(matches):
|
||||
|
||||
|
||||
def parse_modifiers(matches):
|
||||
"""returns audit, deny, allow_keyword and comment from the matches object
|
||||
"""returns priority, audit, deny, allow_keyword and comment from the
|
||||
matches object
|
||||
- priority is a number or None
|
||||
- audit, deny and allow_keyword are True/False
|
||||
- comment is the comment with a leading space"""
|
||||
|
||||
priority = None
|
||||
if matches.group('priority'):
|
||||
priority = int(matches.group('priority'))
|
||||
|
||||
audit = False
|
||||
if matches.group('audit'):
|
||||
audit = True
|
||||
@ -586,7 +630,7 @@ def parse_modifiers(matches):
|
||||
|
||||
comment = parse_comment(matches)
|
||||
|
||||
return (audit, deny, allow_keyword, comment)
|
||||
return (priority, audit, deny, allow_keyword, comment)
|
||||
|
||||
|
||||
def quote_if_needed(data):
|
||||
|
@ -29,11 +29,11 @@ class AbiRule(IncludeRule):
|
||||
_match_re = RE_ABI
|
||||
|
||||
def __init__(self, path, ifexists, ismagic, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(path, ifexists, ismagic,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
# abi doesn't support 'if exists'
|
||||
if ifexists:
|
||||
|
@ -27,16 +27,13 @@ class AliasRule(BaseRule):
|
||||
_match_re = RE_PROFILE_ALIAS
|
||||
|
||||
def __init__(self, orig_path, target, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
# aliases don't support audit or deny
|
||||
if audit:
|
||||
raise AppArmorBug('Attempt to initialize %s with audit flag' % self.__class__.__name__)
|
||||
if deny:
|
||||
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
|
||||
# aliases don't support priority, allow keyword, audit or deny
|
||||
self.ensure_modifiers_not_supported()
|
||||
|
||||
if not isinstance(orig_path, str):
|
||||
raise AppArmorBug('Passed unknown type for orig_path to %s: %s' % (self.__class__.__name__, orig_path))
|
||||
@ -65,7 +62,7 @@ class AliasRule(BaseRule):
|
||||
target = strip_quotes(matches.group('target').strip())
|
||||
|
||||
return cls(orig_path, target,
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment)
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment, priority=None)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -29,10 +29,10 @@ class AllRule(BaseRule):
|
||||
_match_re = RE_PROFILE_ALL
|
||||
|
||||
def __init__(self, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
# no localvars -> nothing more to do
|
||||
|
||||
@ -40,11 +40,11 @@ class AllRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
return cls(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment)
|
||||
comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -28,16 +28,13 @@ class BooleanRule(BaseRule):
|
||||
_match_re = RE_PROFILE_BOOLEAN
|
||||
|
||||
def __init__(self, varname, value, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
# boolean variables don't support audit or deny
|
||||
if audit:
|
||||
raise AppArmorBug('Attempt to initialize %s with audit flag' % self.__class__.__name__)
|
||||
if deny:
|
||||
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
|
||||
# boolean variables don't support priority, allow keyword, audit or deny
|
||||
self.ensure_modifiers_not_supported()
|
||||
|
||||
if not isinstance(varname, str):
|
||||
raise AppArmorBug('Passed unknown type for boolean variable to %s: %s' % (self.__class__.__name__, varname))
|
||||
@ -66,7 +63,7 @@ class BooleanRule(BaseRule):
|
||||
value = matches.group('value')
|
||||
|
||||
return cls(varname, value,
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment)
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment, priority=None)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -46,10 +46,10 @@ class CapabilityRule(BaseRule):
|
||||
_match_re = RE_PROFILE_CAP
|
||||
|
||||
def __init__(self, cap_list, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
# Because we support having multiple caps in one rule,
|
||||
# initializer needs to accept a list of caps.
|
||||
self.all_caps = False
|
||||
@ -78,7 +78,7 @@ class CapabilityRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
if matches.group('capability'):
|
||||
capability = matches.group('capability').strip()
|
||||
@ -88,7 +88,7 @@ class CapabilityRule(BaseRule):
|
||||
|
||||
return cls(capability, audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment)
|
||||
comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -37,11 +37,11 @@ class ChangeProfileRule(BaseRule):
|
||||
_match_re = RE_PROFILE_CHANGE_PROFILE
|
||||
|
||||
def __init__(self, execmode, execcond, targetprofile, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
"""CHANGE_PROFILE RULE = 'change_profile' [ [ EXEC MODE ] EXEC COND ] [ -> PROGRAMCHILD ]"""
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
if execmode:
|
||||
if execmode != 'safe' and execmode != 'unsafe':
|
||||
@ -80,7 +80,7 @@ class ChangeProfileRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
execmode = matches.group('execmode')
|
||||
|
||||
@ -95,7 +95,7 @@ class ChangeProfileRule(BaseRule):
|
||||
targetprofile = cls.ALL
|
||||
|
||||
return cls(execmode, execcond, targetprofile,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -80,10 +80,10 @@ class DbusRule(BaseRule):
|
||||
_match_re = RE_PROFILE_DBUS
|
||||
|
||||
def __init__(self, access, bus, path, name, interface, member, peername, peerlabel,
|
||||
audit=False, deny=False, allow_keyword=False, comment='', log_event=None):
|
||||
audit=False, deny=False, allow_keyword=False, comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, self.ALL, type(self).__name__, 'access')
|
||||
if unknown_items:
|
||||
@ -112,7 +112,7 @@ class DbusRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -186,7 +186,8 @@ class DbusRule(BaseRule):
|
||||
peerlabel = cls.ALL
|
||||
|
||||
return cls(access, bus, path, name, interface, member, peername, peerlabel,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment,
|
||||
priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -47,7 +47,7 @@ class FileRule(BaseRule):
|
||||
_match_re = RE_PROFILE_FILE_ENTRY
|
||||
|
||||
def __init__(self, path, perms, exec_perms, target, owner, file_keyword=False, leading_perms=False,
|
||||
audit=False, deny=False, allow_keyword=False, comment='', log_event=None):
|
||||
audit=False, deny=False, allow_keyword=False, comment='', log_event=None, priority=None):
|
||||
"""Initialize object
|
||||
|
||||
Parameters:
|
||||
@ -61,7 +61,7 @@ class FileRule(BaseRule):
|
||||
"""
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
# rulepart partperms is_path log_event
|
||||
self.path, self.all_paths = self._aare_or_all(path, 'path', True, log_event) # noqa: E221
|
||||
@ -138,7 +138,7 @@ class FileRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
owner = bool(matches.group('owner'))
|
||||
|
||||
@ -183,7 +183,7 @@ class FileRule(BaseRule):
|
||||
file_keyword = bool(matches.group('file_keyword'))
|
||||
|
||||
return cls(path, perms, exec_perms, target, owner, file_keyword, leading_perms,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -28,16 +28,13 @@ class IncludeRule(BaseRule):
|
||||
_match_re = RE_INCLUDE
|
||||
|
||||
def __init__(self, path, ifexists, ismagic, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
# include doesn't support audit or deny
|
||||
if audit:
|
||||
raise AppArmorBug('Attempt to initialize %s with audit flag' % self.__class__.__name__)
|
||||
if deny:
|
||||
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
|
||||
# include doesn't support priority, allow keyword, audit or deny
|
||||
self.ensure_modifiers_not_supported()
|
||||
|
||||
if not isinstance(ifexists, bool):
|
||||
raise AppArmorBug('Passed unknown type for ifexists to %s: %s' % (self.__class__.__name__, ifexists))
|
||||
@ -62,7 +59,7 @@ class IncludeRule(BaseRule):
|
||||
path, ifexists, ismagic = re_match_include_parse(raw_rule, cls.rule_name)
|
||||
|
||||
return cls(path, ifexists, ismagic,
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment)
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment, priority=None)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -51,12 +51,12 @@ class IOUringRule(BaseRule):
|
||||
_match_re = RE_PROFILE_IO_URING
|
||||
|
||||
def __init__(self, access, label, audit=False, deny=False,
|
||||
allow_keyword=False, comment='', log_event=None):
|
||||
allow_keyword=False, comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment,
|
||||
log_event=log_event)
|
||||
log_event=log_event, priority=priority)
|
||||
|
||||
self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, self.ALL, type(self).__name__, 'access')
|
||||
if unknown_items:
|
||||
@ -68,7 +68,7 @@ class IOUringRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
'''parse raw_rule and return instance of this class'''
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -96,7 +96,7 @@ class IOUringRule(BaseRule):
|
||||
label = cls.ALL
|
||||
|
||||
return cls(access, label, audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword, comment=comment)
|
||||
allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
'''return rule (in clean/default formatting)'''
|
||||
|
@ -112,12 +112,15 @@ class MountRule(BaseRule):
|
||||
rule_name = 'mount'
|
||||
_match_re = RE_PROFILE_MOUNT
|
||||
|
||||
def __init__(self, operation, fstype, options, source, dest, audit=False, deny=False, allow_keyword=False, comment='', log_event=None):
|
||||
def __init__(self, operation, fstype, options, source, dest,
|
||||
audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment,
|
||||
log_event=log_event)
|
||||
log_event=log_event,
|
||||
priority=priority)
|
||||
|
||||
self.operation = operation
|
||||
|
||||
@ -164,7 +167,7 @@ class MountRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
'''parse raw_rule and return instance of this class'''
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
operation = matches.group('operation')
|
||||
|
||||
@ -223,7 +226,9 @@ class MountRule(BaseRule):
|
||||
source = cls.ALL
|
||||
dest = cls.ALL
|
||||
|
||||
return cls(operation=operation, fstype=(is_fstype_equal, fstype), options=(is_options_equal, options), source=source, dest=dest, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
return cls(operation=operation, fstype=(is_fstype_equal, fstype), options=(is_options_equal, options),
|
||||
source=source, dest=dest, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment,
|
||||
priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
space = ' ' * depth
|
||||
|
@ -62,12 +62,13 @@ class MessageQueueRule(BaseRule):
|
||||
|
||||
def __init__(self, access, mqueue_type, label, mqueue_name,
|
||||
audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment,
|
||||
log_event=log_event)
|
||||
log_event=log_event,
|
||||
priority=priority)
|
||||
|
||||
self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, self.ALL, type(self).__name__, 'access')
|
||||
if unknown_items:
|
||||
@ -92,7 +93,7 @@ class MessageQueueRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
'''parse raw_rule and return instance of this class'''
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -132,7 +133,7 @@ class MessageQueueRule(BaseRule):
|
||||
mqueue_name = cls.ALL
|
||||
|
||||
return cls(access, mqueue_type, label, mqueue_name,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
'''return rule (in clean/default formatting)'''
|
||||
|
@ -92,10 +92,10 @@ class NetworkRule(BaseRule):
|
||||
_match_re = RE_PROFILE_NETWORK
|
||||
|
||||
def __init__(self, accesses, domain, type_or_protocol, local_expr, peer_expr, audit=False, deny=False,
|
||||
allow_keyword=False, comment='', log_event=None):
|
||||
allow_keyword=False, comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
if type(local_expr) is tuple:
|
||||
if accesses is None:
|
||||
@ -159,7 +159,7 @@ class NetworkRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -191,7 +191,7 @@ class NetworkRule(BaseRule):
|
||||
peer_expr = cls.ALL
|
||||
|
||||
return cls(accesses, domain, type_or_protocol, local_expr, peer_expr,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -47,12 +47,13 @@ class PivotRootRule(BaseRule):
|
||||
_match_re = RE_PROFILE_PIVOT_ROOT
|
||||
|
||||
# PIVOT ROOT RULE = [ QUALIFIERS ] pivot_root [ oldroot=OLD PUT FILEGLOB ] [ NEW ROOT FILEGLOB ] [ ’->’ PROFILE NAME ]
|
||||
def __init__(self, oldroot, newroot, profile_name, audit=False, deny=False, allow_keyword=False, comment='', log_event=None):
|
||||
def __init__(self, oldroot, newroot, profile_name, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment,
|
||||
log_event=log_event)
|
||||
log_event=log_event, priority=priority)
|
||||
|
||||
self.oldroot, self.all_oldroots = self._aare_or_all(oldroot, 'oldroot', True, log_event) # noqa: E221
|
||||
self.newroot, self.all_newroots = self._aare_or_all(newroot, 'newroot', True, log_event) # noqa: E221
|
||||
@ -66,7 +67,7 @@ class PivotRootRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
'''parse raw_rule and return instance of this class'''
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -100,7 +101,7 @@ class PivotRootRule(BaseRule):
|
||||
profile_name = cls.ALL
|
||||
|
||||
return cls(oldroot=oldroot, newroot=newroot, profile_name=profile_name,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
space = ' ' * depth
|
||||
|
@ -53,10 +53,10 @@ class PtraceRule(BaseRule):
|
||||
_match_re = RE_PROFILE_PTRACE
|
||||
|
||||
def __init__(self, access, peer, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
self.access, self.all_access, unknown_items = check_and_split_list(
|
||||
access, access_keywords, self.ALL, type(self).__name__, 'access')
|
||||
@ -69,7 +69,7 @@ class PtraceRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -98,7 +98,7 @@ class PtraceRule(BaseRule):
|
||||
peer = cls.ALL
|
||||
|
||||
return cls(access, peer,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -49,13 +49,13 @@ class RlimitRule(BaseRule):
|
||||
_match_re = RE_PROFILE_RLIMIT
|
||||
|
||||
def __init__(self, rlimit, value, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
if audit or deny or allow_keyword:
|
||||
raise AppArmorBug('The audit, allow or deny keywords are not allowed in rlimit rules.')
|
||||
# rlimit rules don't support priority, allow keyword, audit or deny
|
||||
self.ensure_modifiers_not_supported()
|
||||
|
||||
if isinstance(rlimit, str):
|
||||
if rlimit in rlimit_all:
|
||||
|
@ -78,10 +78,10 @@ class SignalRule(BaseRule):
|
||||
_match_re = RE_PROFILE_SIGNAL
|
||||
|
||||
def __init__(self, access, signal, peer, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
self.access, self.all_access, unknown_items = check_and_split_list(
|
||||
access, access_keywords, self.ALL, type(self).__name__, 'access')
|
||||
@ -103,7 +103,7 @@ class SignalRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
"""parse raw_rule and return instance of this class"""
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -141,7 +141,7 @@ class SignalRule(BaseRule):
|
||||
peer = cls.ALL
|
||||
|
||||
return cls(access, signal, peer,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -65,12 +65,14 @@ class UnixRule(BaseRule):
|
||||
rule_name = 'unix'
|
||||
_match_re = RE_PROFILE_UNIX
|
||||
|
||||
def __init__(self, accesses, rule_conds, local_expr, peer_expr, audit=False, deny=False, allow_keyword=False, comment='', log_event=None):
|
||||
def __init__(self, accesses, rule_conds, local_expr, peer_expr, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment,
|
||||
log_event=log_event)
|
||||
log_event=log_event,
|
||||
priority=priority)
|
||||
|
||||
if type(rule_conds) is tuple: # This comes from the logparser, we convert it to dicts
|
||||
accesses = strip_parenthesis(accesses).replace(',', ' ').split()
|
||||
@ -96,7 +98,7 @@ class UnixRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
'''parse raw_rule and return instance of this class'''
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -124,7 +126,8 @@ class UnixRule(BaseRule):
|
||||
local_expr = cls.ALL
|
||||
peer_expr = cls.ALL
|
||||
|
||||
return cls(accesses=accesses, rule_conds=rule_conds, local_expr=local_expr, peer_expr=peer_expr, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment)
|
||||
return cls(accesses=accesses, rule_conds=rule_conds, local_expr=local_expr, peer_expr=peer_expr,
|
||||
audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
space = ' ' * depth
|
||||
|
@ -44,12 +44,13 @@ class UserNamespaceRule(BaseRule):
|
||||
_match_re = RE_PROFILE_USERNS
|
||||
|
||||
def __init__(self, access, audit=False, deny=False,
|
||||
allow_keyword=False, comment='', log_event=None):
|
||||
allow_keyword=False, comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword,
|
||||
comment=comment,
|
||||
log_event=log_event)
|
||||
log_event=log_event,
|
||||
priority=priority)
|
||||
|
||||
self.access, self.all_access, unknown_items = check_and_split_list(access, access_keyword, self.ALL, type(self).__name__, 'access')
|
||||
if unknown_items:
|
||||
@ -59,7 +60,7 @@ class UserNamespaceRule(BaseRule):
|
||||
def _create_instance(cls, raw_rule, matches):
|
||||
'''parse raw_rule and return instance of this class'''
|
||||
|
||||
audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
priority, audit, deny, allow_keyword, comment = parse_modifiers(matches)
|
||||
|
||||
rule_details = ''
|
||||
if matches.group('details'):
|
||||
@ -75,7 +76,7 @@ class UserNamespaceRule(BaseRule):
|
||||
access = cls.ALL
|
||||
|
||||
return cls(access, audit=audit, deny=deny,
|
||||
allow_keyword=allow_keyword, comment=comment)
|
||||
allow_keyword=allow_keyword, comment=comment, priority=priority)
|
||||
|
||||
@staticmethod
|
||||
def hashlog_from_event(hl, e):
|
||||
|
@ -30,16 +30,13 @@ class VariableRule(BaseRule):
|
||||
_match_re = RE_PROFILE_VARIABLE
|
||||
|
||||
def __init__(self, varname, mode, values, audit=False, deny=False, allow_keyword=False,
|
||||
comment='', log_event=None):
|
||||
comment='', log_event=None, priority=None):
|
||||
|
||||
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
|
||||
comment=comment, log_event=log_event)
|
||||
comment=comment, log_event=log_event, priority=priority)
|
||||
|
||||
# variables don't support audit or deny
|
||||
if audit:
|
||||
raise AppArmorBug('Attempt to initialize %s with audit flag' % self.__class__.__name__)
|
||||
if deny:
|
||||
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
|
||||
# variables don't support priority, allow keyword, audit or deny
|
||||
self.ensure_modifiers_not_supported()
|
||||
|
||||
if not isinstance(varname, str):
|
||||
raise AppArmorBug('Passed unknown type for varname to %s: %s' % (self.__class__.__name__, varname))
|
||||
@ -73,7 +70,7 @@ class VariableRule(BaseRule):
|
||||
values = separate_vars(matches.group('values'))
|
||||
|
||||
return cls(varname, mode, values,
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment)
|
||||
audit=False, deny=False, allow_keyword=False, comment=comment, priority=None)
|
||||
|
||||
def get_clean(self, depth=0):
|
||||
"""return rule (in clean/default formatting)"""
|
||||
|
@ -30,10 +30,11 @@ exp = namedtuple('exp', ('comment', 'orig_path', 'target'))
|
||||
|
||||
class AliasTest(AATest):
|
||||
def _compare_obj(self, obj, expected):
|
||||
# aliases don't support the allow, audit or deny keyword
|
||||
# aliases don't support the allow, audit, deny, or priority keyword
|
||||
self.assertEqual(False, obj.allow_keyword)
|
||||
self.assertEqual(False, obj.audit)
|
||||
self.assertEqual(False, obj.deny)
|
||||
self.assertEqual(None, obj.priority)
|
||||
|
||||
self.assertEqual(expected.orig_path, obj.orig_path)
|
||||
self.assertEqual(expected.target, obj.target)
|
||||
@ -114,6 +115,14 @@ class InvalidAliasInit(AATest):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
AliasRule('/foo', '/bar', deny=True)
|
||||
|
||||
def test_invalid_priority_1(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
AliasRule('/foo', '/bar', priority=1)
|
||||
|
||||
def test_invalid_priority_2(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
AliasRule('/foo', '/bar', priority=0)
|
||||
|
||||
|
||||
class InvalidAliasTest(AATest):
|
||||
def _check_invalid_rawrule(self, rawrule, matches_regex=False):
|
||||
|
@ -116,6 +116,7 @@ class WriteAllTestAATest(AATest):
|
||||
(' deny all ,# foo bar', 'deny all, # foo bar'),
|
||||
(' allow all ,# foo bar', 'allow all, # foo bar'),
|
||||
(' allow all ,', 'allow all,'),
|
||||
(' priority = -2 allow all ,', 'priority=-2 allow all,'),
|
||||
)
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
|
@ -71,7 +71,7 @@ class TestBaserule(AATest):
|
||||
self.ValidSubclass.match('foo')
|
||||
|
||||
def test_parse_modifiers_invalid(self):
|
||||
regex = re.compile(r'^\s*(?P<audit>audit\s+)?(?P<allow>allow\s+|deny\s+|invalid\s+)?')
|
||||
regex = re.compile(r'^\s*(priority\s*=\s*(?P<priority>[+-]?[0-9]*)\s+)?(?P<audit>audit\s+)?(?P<allow>allow\s+|deny\s+|invalid\s+)?')
|
||||
matches = regex.search('audit invalid ')
|
||||
|
||||
with self.assertRaises(AppArmorBug):
|
||||
|
@ -30,10 +30,11 @@ exp = namedtuple('exp', ('comment', 'varname', 'value'))
|
||||
|
||||
class BooleanTest(AATest):
|
||||
def _compare_obj(self, obj, expected):
|
||||
# boolean variables don't support the allow, audit or deny keyword
|
||||
# boolean variables don't support the allow, audit, deny, or priority keyword
|
||||
self.assertEqual(False, obj.allow_keyword)
|
||||
self.assertEqual(False, obj.audit)
|
||||
self.assertEqual(False, obj.deny)
|
||||
self.assertEqual(None, obj.priority)
|
||||
|
||||
self.assertEqual(expected.varname, obj.varname)
|
||||
self.assertEqual(expected.value, obj.value)
|
||||
@ -122,6 +123,14 @@ class InvalidBooleanInit(AATest):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
BooleanRule('$foo', 'true', deny=True)
|
||||
|
||||
def test_invalid_priority_1(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
BooleanRule('$foo', 'true', priority=-100)
|
||||
|
||||
def test_invalid_priority_2(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
BooleanRule('$foo', 'true', priority=0)
|
||||
|
||||
|
||||
class InvalidBooleanTest(AATest):
|
||||
def _check_invalid_rawrule(self, rawrule, matches_regex=False):
|
||||
|
@ -314,6 +314,18 @@ class WriteCapabilityTest(AATest):
|
||||
self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule')
|
||||
self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule')
|
||||
|
||||
def test_write_priority_1(self):
|
||||
self._check_write_rule(' priority = 923 audit capability sys_admin,', 'priority=923 audit capability sys_admin,')
|
||||
|
||||
def test_write_priority_2(self):
|
||||
self._check_write_rule(' priority = 0 audit capability sys_admin,', 'priority=0 audit capability sys_admin,')
|
||||
|
||||
def test_write_priority_3(self):
|
||||
self._check_write_rule(' priority=-12 audit capability sys_admin,', 'priority=-12 audit capability sys_admin,')
|
||||
|
||||
def test_write_priority_4(self):
|
||||
self._check_write_rule(' priority=+99 audit capability sys_admin,', 'priority=99 audit capability sys_admin,')
|
||||
|
||||
|
||||
class CapabilityCoveredTest(AATest):
|
||||
def _is_covered(self, obj, rule_to_test):
|
||||
|
@ -225,6 +225,10 @@ class WriteChangeProfileTestAATest(AATest):
|
||||
(' allow change_profile -> /bar ,# foo bar', 'allow change_profile -> /bar, # foo bar'),
|
||||
(' allow change_profile unsafe /** -> /bar ,# foo bar', 'allow change_profile unsafe /** -> /bar, # foo bar'),
|
||||
(' allow change_profile "/fo o" -> "/b ar",', 'allow change_profile "/fo o" -> "/b ar",'),
|
||||
(' priority=9 audit deny change_profile /foo -> baz,', 'priority=9 audit deny change_profile /foo -> baz,'),
|
||||
(' priority = 0 audit deny change_profile /foo -> baz,', 'priority=0 audit deny change_profile /foo -> baz,'),
|
||||
(' priority=-54 audit deny change_profile /foo -> baz,', 'priority=-54 audit deny change_profile /foo -> baz,'),
|
||||
(' priority=+42 audit deny change_profile /foo -> baz,', 'priority=42 audit deny change_profile /foo -> baz,'),
|
||||
)
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
|
@ -419,6 +419,10 @@ class WriteDbusTest(AATest):
|
||||
('dbus receive peer=(label=foo),', 'dbus receive peer=(label=foo),'),
|
||||
('dbus (send receive) peer=(name=/usr/bin/bar),', 'dbus (receive send) peer=(name=/usr/bin/bar),'),
|
||||
('dbus (, receive ,,, send ,) interface=/sbin/baz,', 'dbus (receive send) interface=/sbin/baz,'), # XXX leading and trailing ',' inside (...) causes error
|
||||
(' priority=123 deny dbus send interface = ( foo ),', 'priority=123 deny dbus send interface=foo,'),
|
||||
(' priority=0 deny dbus send interface = ( foo ),', 'priority=0 deny dbus send interface=foo,'),
|
||||
(' priority=-72 deny dbus send interface = ( foo ),', 'priority=-72 deny dbus send interface=foo,'),
|
||||
(' priority=+834 deny dbus send interface = ( foo ),', 'priority=834 deny dbus send interface=foo,'),
|
||||
# XXX add more complex rules
|
||||
)
|
||||
|
||||
|
@ -415,6 +415,10 @@ class WriteFileTest(AATest):
|
||||
(' /foo r,', '/foo r,'),
|
||||
(' /foo lwr,', '/foo rwl,'),
|
||||
(' /foo Pxrm -> bar,', '/foo mrPx -> bar,'),
|
||||
(' priority=-1 /foo Pxrm -> bar,', 'priority=-1 /foo mrPx -> bar,'),
|
||||
(' priority=0 /foo Pxrm -> bar,', 'priority=0 /foo mrPx -> bar,'),
|
||||
(' priority=343 /foo Pxrm -> bar,', 'priority=343 /foo mrPx -> bar,'),
|
||||
(' priority=+65 /foo Pxrm -> bar,', 'priority=65 /foo mrPx -> bar,'),
|
||||
|
||||
# with leading permissions
|
||||
(' audit file r /foo,', 'audit file r /foo,'),
|
||||
@ -432,11 +436,19 @@ class WriteFileTest(AATest):
|
||||
(' r /foo ,', 'r /foo,'),
|
||||
(' klwr /foo ,', 'rwlk /foo,'),
|
||||
(' Pxrm /foo -> bar,', 'mrPx /foo -> bar,'),
|
||||
(' priority=1 Pxrm /foo -> bar,', 'priority=1 mrPx /foo -> bar,'),
|
||||
(' priority=0 Pxrm /foo -> bar,', 'priority=0 mrPx /foo -> bar,'),
|
||||
(' priority=-22 Pxrm /foo -> bar,', 'priority=-22 mrPx /foo -> bar,'),
|
||||
(' priority=+78 Pxrm /foo -> bar,', 'priority=78 mrPx /foo -> bar,'),
|
||||
|
||||
# link rules
|
||||
(' link /foo -> /bar,', 'link /foo -> /bar,'),
|
||||
(' audit deny owner link subset /foo -> /bar,', 'audit deny owner link subset /foo -> /bar,'),
|
||||
(' link subset /foo -> /bar,', 'link subset /foo -> /bar,')
|
||||
(' link subset /foo -> /bar,', 'link subset /foo -> /bar,'),
|
||||
(' priority=0 link /foo -> /bar,', 'priority=0 link /foo -> /bar,'),
|
||||
(' priority=12 link /foo -> /bar,', 'priority=12 link /foo -> /bar,'),
|
||||
(' priority=-1 link /foo -> /bar,', 'priority=-1 link /foo -> /bar,'),
|
||||
(' priority=+4 link /foo -> /bar,', 'priority=4 link /foo -> /bar,'),
|
||||
)
|
||||
|
||||
def test_write_manually_1(self):
|
||||
@ -844,21 +856,23 @@ class FileSeverityTest(AATest):
|
||||
class FileLogprofHeaderTest(AATest):
|
||||
tests = (
|
||||
# log event old perms ALL / owner
|
||||
(('file,', set(), set()), [ _('Path'), _('ALL'), _('New Mode'), _('ALL')]), # noqa: E201
|
||||
(('/foo r,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'r']), # noqa: E201
|
||||
(('file /bar Px -> foo,', set(), set()), [ _('Path'), '/bar', _('New Mode'), 'Px -> foo']), # noqa: E201
|
||||
(('deny file,', set(), set()), [_('Qualifier'), 'deny', _('Path'), _('ALL'), _('New Mode'), _('ALL')]),
|
||||
(('allow file /baz rwk,', set(), set()), [_('Qualifier'), 'allow', _('Path'), '/baz', _('New Mode'), 'rwk']),
|
||||
(('audit file /foo mr,', set(), set()), [_('Qualifier'), 'audit', _('Path'), '/foo', _('New Mode'), 'mr']),
|
||||
(('audit deny /foo wk,', set(), set()), [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'wk']),
|
||||
(('owner file /foo ix,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'owner ix']), # noqa: E201
|
||||
(('audit deny file /foo rlx -> /baz,', set(), set()), [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'rlx -> /baz']),
|
||||
(('/foo rw,', set('r'), set()), [ _('Path'), '/foo', _('Old Mode'), _('r'), _('New Mode'), 'rw']), # noqa: E201
|
||||
(('/foo rw,', set(), set('rw')), [ _('Path'), '/foo', _('Old Mode'), _('owner rw'), _('New Mode'), 'rw']), # noqa: E201
|
||||
(('/foo mrw,', set('r'), set('k')), [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), 'mrw']), # noqa: E201
|
||||
(('/foo mrw,', set('r'), set('rk')), [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), 'mrw']), # noqa: E201
|
||||
(('link /foo -> /bar,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'link -> /bar']), # noqa: E201
|
||||
(('link subset /foo -> /bar,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'link subset -> /bar']), # noqa: E201
|
||||
(('file,', set(), set()), [ _('Path'), _('ALL'), _('New Mode'), _('ALL')]), # noqa: E201
|
||||
(('/foo r,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'r']), # noqa: E201
|
||||
(('file /bar Px -> foo,', set(), set()), [ _('Path'), '/bar', _('New Mode'), 'Px -> foo']), # noqa: E201
|
||||
(('deny file,', set(), set()), [_('Qualifier'), 'deny', _('Path'), _('ALL'), _('New Mode'), _('ALL')]),
|
||||
(('allow file /baz rwk,', set(), set()), [_('Qualifier'), 'allow', _('Path'), '/baz', _('New Mode'), 'rwk']),
|
||||
(('audit file /foo mr,', set(), set()), [_('Qualifier'), 'audit', _('Path'), '/foo', _('New Mode'), 'mr']),
|
||||
(('audit deny /foo wk,', set(), set()), [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'wk']),
|
||||
(('priority=1 file,', set(), set()), [_('Qualifier'), 'priority=1', _('Path'), _('ALL'), _('New Mode'), _('ALL')]),
|
||||
(('priority=-1 audit file /foo mr,', set(), set()), [_('Qualifier'), 'priority=-1 audit', _('Path'), '/foo', _('New Mode'), 'mr']),
|
||||
(('owner file /foo ix,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'owner ix']), # noqa: E201
|
||||
(('audit deny file /foo rlx -> /baz,', set(), set()), [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'rlx -> /baz']),
|
||||
(('/foo rw,', set('r'), set()), [ _('Path'), '/foo', _('Old Mode'), _('r'), _('New Mode'), 'rw']), # noqa: E201
|
||||
(('/foo rw,', set(), set('rw')), [ _('Path'), '/foo', _('Old Mode'), _('owner rw'), _('New Mode'), 'rw']), # noqa: E201
|
||||
(('/foo mrw,', set('r'), set('k')), [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), 'mrw']), # noqa: E201
|
||||
(('/foo mrw,', set('r'), set('rk')), [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), 'mrw']), # noqa: E201
|
||||
(('link /foo -> /bar,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'link -> /bar']), # noqa: E201
|
||||
(('link subset /foo -> /bar,', set(), set()), [ _('Path'), '/foo', _('New Mode'), 'link subset -> /bar']), # noqa: E201
|
||||
)
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
|
@ -37,6 +37,7 @@ class IncludeTest(AATest):
|
||||
self.assertEqual(False, obj.allow_keyword) # not supported in include rules, expected to be always False
|
||||
self.assertEqual(False, obj.audit) # not supported in include rules, expected to be always False
|
||||
self.assertEqual(False, obj.deny) # not supported in include rules, expected to be always False
|
||||
self.assertEqual(None, obj.priority) # not supported in include rules, expected to be always None
|
||||
self.assertEqual(expected.comment, obj.comment)
|
||||
|
||||
self.assertEqual(expected.path, obj.path)
|
||||
@ -159,6 +160,10 @@ class InvalidIncludeInit(AATest):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
IncludeRule('foo', False, False, deny=True)
|
||||
|
||||
def test_priority_true(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
IncludeRule('foo', False, False, priority=0)
|
||||
|
||||
|
||||
class InvalidIncludeTest(AATest):
|
||||
def _check_invalid_rawrule(self, rawrule, matches_regex=False):
|
||||
|
@ -64,10 +64,10 @@ class IOUringTestParseInvalid(AATest):
|
||||
IOUringRule.create_instance('foo,')
|
||||
|
||||
def test_diff_non_iouringrule(self):
|
||||
exp = namedtuple('exp', ('audit', 'deny'))
|
||||
exp = namedtuple('exp', ('audit', 'deny', 'priority'))
|
||||
obj = IOUringRule(('sqpoll'), IOUringRule.ALL)
|
||||
with self.assertRaises(AppArmorBug):
|
||||
obj.is_equal(exp(False, False), False)
|
||||
obj.is_equal(exp(False, False, None), False)
|
||||
|
||||
def test_diff_access(self):
|
||||
obj1 = IOUringRule(IOUringRule.ALL, IOUringRule.ALL)
|
||||
@ -124,6 +124,10 @@ class WriteIOUringTestAATest(AATest):
|
||||
('io_uring sqpoll label="tst",', 'io_uring sqpoll label="tst",'),
|
||||
('io_uring (override_creds) label=bar,', 'io_uring override_creds label=bar,'),
|
||||
('io_uring (sqpoll override_creds) label=/foo,', 'io_uring (override_creds sqpoll) label=/foo,'),
|
||||
(' priority=1 deny io_uring override_creds ,# foo bar', 'priority=1 deny io_uring override_creds, # foo bar'),
|
||||
(' priority=0 deny io_uring override_creds ,# foo bar', 'priority=0 deny io_uring override_creds, # foo bar'),
|
||||
(' priority=-23 deny io_uring override_creds ,# foo bar', 'priority=-23 deny io_uring override_creds, # foo bar'),
|
||||
(' priority=+21 deny io_uring override_creds ,# foo bar', 'priority=21 deny io_uring override_creds, # foo bar'),
|
||||
)
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
|
90
utils/test/test-modifiers.py
Normal file
90
utils/test/test-modifiers.py
Normal file
@ -0,0 +1,90 @@
|
||||
#! /usr/bin/python3
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2025 Canonical Ltd.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
|
||||
from apparmor.common import AppArmorException
|
||||
from apparmor.rule.capability import CapabilityRule
|
||||
from apparmor.rule.change_profile import ChangeProfileRule
|
||||
from apparmor.rule.dbus import DbusRule
|
||||
from apparmor.rule.file import FileRule
|
||||
from apparmor.rule.io_uring import IOUringRule
|
||||
from apparmor.rule.mount import MountRule
|
||||
from apparmor.rule.mqueue import MessageQueueRule
|
||||
from apparmor.rule.network import NetworkRule
|
||||
from apparmor.rule.pivot_root import PivotRootRule
|
||||
from apparmor.rule.ptrace import PtraceRule
|
||||
from apparmor.rule.signal import SignalRule
|
||||
from apparmor.rule.unix import UnixRule
|
||||
from apparmor.rule.userns import UserNamespaceRule
|
||||
from apparmor.rule.all import AllRule
|
||||
from common_test import AATest, setup_all_loops
|
||||
|
||||
|
||||
class TestInvalid_parse_priority(AATest):
|
||||
tests = (
|
||||
((CapabilityRule, 'priority=a capability,'), AppArmorException),
|
||||
((DbusRule, 'priority=a dbus,'), AppArmorException),
|
||||
((MountRule, 'priority=a mount,'), AppArmorException),
|
||||
((MountRule, 'priority=a umount,'), AppArmorException),
|
||||
((MountRule, 'priority=a unmount,'), AppArmorException),
|
||||
((MountRule, 'priority=a remount,'), AppArmorException),
|
||||
((SignalRule, 'priority=a signal,'), AppArmorException),
|
||||
((PtraceRule, 'priority=a ptrace,'), AppArmorException),
|
||||
((PivotRootRule, 'priority=a pivot_root,'), AppArmorException),
|
||||
((UnixRule, 'priority=a unix,'), AppArmorException),
|
||||
((NetworkRule, 'priority=a network,'), AppArmorException),
|
||||
((UserNamespaceRule, 'priority=a userns,'), AppArmorException),
|
||||
((MessageQueueRule, 'priority=a mqueue,'), AppArmorException),
|
||||
((IOUringRule, 'priority=a io_uring,'), AppArmorException),
|
||||
((ChangeProfileRule, 'priority=a change_profile,'), AppArmorException),
|
||||
((FileRule, 'priority=a file,'), AppArmorException),
|
||||
((AllRule, 'priority=a all,'), AppArmorException),
|
||||
)
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
rule_cls, rule = params
|
||||
with self.assertRaises(expected):
|
||||
rule_cls.create_instance(rule) # Invalid rule
|
||||
|
||||
|
||||
class TestInvalid_init_priority(AATest):
|
||||
tests = (
|
||||
((CapabilityRule, (CapabilityRule.ALL,)), AppArmorException),
|
||||
((DbusRule, (DbusRule.ALL,) * 8), AppArmorException),
|
||||
((MountRule, (MountRule.ALL,) * 5), AppArmorException),
|
||||
((SignalRule, (SignalRule.ALL,) * 3), AppArmorException),
|
||||
((PtraceRule, (PtraceRule.ALL,) * 2), AppArmorException),
|
||||
((PivotRootRule, (PivotRootRule.ALL,) * 3), AppArmorException),
|
||||
((UnixRule, (UnixRule.ALL,) * 4), AppArmorException),
|
||||
((NetworkRule, (NetworkRule.ALL,) * 5), AppArmorException),
|
||||
((UserNamespaceRule, (UserNamespaceRule.ALL,) * 1), AppArmorException),
|
||||
((MessageQueueRule, (MessageQueueRule.ALL,) * 4), AppArmorException),
|
||||
((IOUringRule, (IOUringRule.ALL,) * 2), AppArmorException),
|
||||
((ChangeProfileRule, (ChangeProfileRule.ALL,) * 3), AppArmorException),
|
||||
((FileRule, (FileRule.ALL,) * 5), AppArmorException),
|
||||
((AllRule, ()), AppArmorException),
|
||||
)
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
rule_cls, args = params
|
||||
with self.assertRaises(expected):
|
||||
rule_cls(*args, priority="invalid") # ValueError
|
||||
|
||||
|
||||
setup_all_loops(__name__)
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=1)
|
@ -123,10 +123,10 @@ class MountTestParseInvalid(AATest):
|
||||
MountRule.create_instance('foo,')
|
||||
|
||||
def test_diff_non_mountrule(self):
|
||||
exp = namedtuple('exp', ('audit', 'deny'))
|
||||
exp = namedtuple('exp', ('audit', 'deny', 'priority'))
|
||||
obj = MountRule('mount', ('=', ['ext4']), MountRule.ALL, MountRule.ALL, MountRule.ALL)
|
||||
with self.assertRaises(AppArmorBug):
|
||||
obj.is_equal(exp(False, False), False)
|
||||
obj.is_equal(exp(False, False, None), False)
|
||||
|
||||
def test_diff_invalid_fstype_equals_or_in(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
@ -230,6 +230,12 @@ class MountTestClean(AATest):
|
||||
(' umount /foo , ', 'umount /foo,'),
|
||||
(' remount , ', 'remount,'),
|
||||
(' remount /foo , ', 'remount /foo,'),
|
||||
('priority =1 mount "" -> /foo , ', 'priority=1 mount "" -> /foo,'),
|
||||
('priority=0 audit mount "/f /b" -> "/foo bar" , ', 'priority=0 audit mount "/f /b" -> "/foo bar",'),
|
||||
(' priority = +10 umount , ', 'priority=10 umount,'),
|
||||
(' priority=-2 deny umount /foo , ', 'priority=-2 deny umount /foo,'),
|
||||
('priority= 32 audit deny remount , ', 'priority=32 audit deny remount,'),
|
||||
(' priority = -32 remount /foo , ', 'priority=-32 remount /foo,'),
|
||||
)
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
|
@ -77,10 +77,10 @@ class MessageQueueTestParseInvalid(AATest):
|
||||
MessageQueueRule.create_instance('foo,')
|
||||
|
||||
def test_diff_non_mqueuerule(self):
|
||||
exp = namedtuple('exp', ('audit', 'deny'))
|
||||
exp = namedtuple('exp', ('audit', 'deny', 'priority'))
|
||||
obj = MessageQueueRule(('open'), 'posix', 'bar', '/foo')
|
||||
with self.assertRaises(AppArmorBug):
|
||||
obj.is_equal(exp(False, False), False)
|
||||
obj.is_equal(exp(False, False, None), False)
|
||||
|
||||
def test_diff_access(self):
|
||||
obj1 = MessageQueueRule(('open'), 'posix', 'bar', '/foo')
|
||||
@ -171,6 +171,10 @@ class WriteMessageQueueTestAATest(AATest):
|
||||
('mqueue wr label=tst 1234,', 'mqueue wr label=tst 1234,'),
|
||||
('mqueue wr type=sysv label=tst 1234,', 'mqueue wr type=sysv label=tst 1234,'),
|
||||
('mqueue wr type=posix label=tst /foo,', 'mqueue wr type=posix label=tst /foo,'),
|
||||
(' priority = -82 mqueue getattr /foo,', 'priority=-82 mqueue getattr /foo,'),
|
||||
(' priority = 12 audit mqueue (setattr getattr) 1234,', 'priority=12 audit mqueue (getattr setattr) 1234,'),
|
||||
(' priority=0 mqueue getattr /foo,', 'priority=0 mqueue getattr /foo,'),
|
||||
(' priority=+82 mqueue getattr /foo,', 'priority=82 mqueue getattr /foo,'),
|
||||
)
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
|
@ -286,6 +286,10 @@ class WriteNetworkTestAATest(AATest):
|
||||
(' network stream peer = ( ip=::1 port=22 ) ,', 'network stream peer=(ip=::1 port=22),'),
|
||||
(' network ( bind , listen ) stream ip = ::1 port = 22 ,', 'network (bind, listen) stream ip=::1 port=22,'),
|
||||
(' allow network tcp ,# foo bar', 'allow network tcp, # foo bar'),
|
||||
(' priority = -02 allow network tcp ,# foo bar', 'priority=-2 allow network tcp, # foo bar'),
|
||||
(' priority = 0 allow network tcp ,# foo bar', 'priority=0 allow network tcp, # foo bar'),
|
||||
(' priority = 43 allow network tcp ,# foo bar', 'priority=43 allow network tcp, # foo bar'),
|
||||
(' priority=+123 allow network tcp ,# foo bar', 'priority=123 allow network tcp, # foo bar'),
|
||||
|
||||
)
|
||||
|
||||
|
@ -35,9 +35,6 @@ skip_startswith = (
|
||||
|
||||
# Pux and Cux (which actually mean PUx and CUx) get rejected by the tools
|
||||
'generated_x/exact-',
|
||||
|
||||
# don't handle rule priorities yet
|
||||
'file/priority/',
|
||||
)
|
||||
|
||||
# testcases that should raise an exception, but don't
|
||||
@ -246,11 +243,16 @@ unknown_line = (
|
||||
'file/ok_other_1.sd',
|
||||
'file/ok_other_2.sd',
|
||||
'file/ok_other_3.sd',
|
||||
'file/priority/ok_other_1.sd',
|
||||
'file/priority/ok_other_2.sd',
|
||||
'file/priority/ok_other_3.sd',
|
||||
|
||||
# 'unsafe' keyword
|
||||
'file/file/front_perms_ok_2.sd',
|
||||
'file/front_perms_ok_2.sd',
|
||||
'xtrans/simple_ok_cx_1.sd',
|
||||
'file/priority/front_perms_ok_3.sd',
|
||||
'file/priority/front_perms_ok_4.sd',
|
||||
|
||||
# owner / audit {...} blocks
|
||||
'file/file/owner/ok_1.sd',
|
||||
@ -355,6 +357,9 @@ syntax_failure = (
|
||||
'file/ok_5.sd', # Invalid mode UX
|
||||
'file/ok_2.sd', # Invalid mode RWM
|
||||
'file/ok_4.sd', # Invalid mode iX
|
||||
'file/priority/ok_5.sd', # Invalid mode UX
|
||||
'file/priority/ok_2.sd', # Invalid mode RWM
|
||||
'file/priority/ok_4.sd', # Invalid mode iX
|
||||
'xtrans/simple_ok_pix_1.sd', # Invalid mode pIx
|
||||
'xtrans/simple_ok_pux_1.sd', # Invalid mode rPux
|
||||
|
||||
@ -424,6 +429,8 @@ syntax_failure = (
|
||||
'file/ok_embedded_spaces_4.sd', # \-escaped space
|
||||
'file/file/ok_embedded_spaces_4.sd', # \-escaped space
|
||||
'file/ok_quoted_4.sd', # quoted string including \"
|
||||
'file/priority/ok_quoted_4.sd', # quoted string including \"
|
||||
'file/priority/ok_embedded_spaces_4.sd', # \-escaped space
|
||||
|
||||
# mount rules with multiple 'options' or 'fstype' are not supported by the tools yet, and when writing them, only the last 'options'/'fstype' would survive.
|
||||
# Therefore MountRule intentionally raises an exception when parsing such a rule.
|
||||
|
@ -261,6 +261,10 @@ class WritePivotRootTestAATest(AATest):
|
||||
(' pivot_root oldroot="/old" , # foo ', 'pivot_root oldroot=/old, # foo'),
|
||||
(' pivot_root oldroot=/old -> some_profile , ', 'pivot_root oldroot=/old -> some_profile,'),
|
||||
(' pivot_root oldroot=/old /new -> some_profile , ', 'pivot_root oldroot=/old /new -> some_profile,'),
|
||||
('priority=1 pivot_root oldroot=/old /new -> some_profile , ', 'priority=1 pivot_root oldroot=/old /new -> some_profile,'),
|
||||
('priority=0 pivot_root oldroot=/old /new -> some_profile , ', 'priority=0 pivot_root oldroot=/old /new -> some_profile,'),
|
||||
('priority=-1 pivot_root oldroot=/old /new -> some_profile , ', 'priority=-1 pivot_root oldroot=/old /new -> some_profile,'),
|
||||
('priority=+1 pivot_root oldroot=/old /new -> some_profile , ', 'priority=1 pivot_root oldroot=/old /new -> some_profile,'),
|
||||
)
|
||||
|
||||
def test_write_manually(self):
|
||||
|
@ -260,6 +260,10 @@ class WritePtraceTestAATest(AATest):
|
||||
('ptrace (read tracedby) peer=/usr/bin/bar,', 'ptrace (read tracedby) peer=/usr/bin/bar,'),
|
||||
('ptrace (trace read) peer=/usr/bin/bar,', 'ptrace (read trace) peer=/usr/bin/bar,'),
|
||||
('ptrace wr peer=/sbin/baz,', 'ptrace wr peer=/sbin/baz,'),
|
||||
('priority = 010 deny ptrace ( read ), ', 'priority=10 deny ptrace read,'),
|
||||
('priority = 0 deny ptrace ( read ), ', 'priority=0 deny ptrace read,'),
|
||||
('priority = -21 deny ptrace ( read ), ', 'priority=-21 deny ptrace read,'),
|
||||
('priority = +83 deny ptrace ( read ), ', 'priority=83 deny ptrace read,'),
|
||||
)
|
||||
|
||||
def test_write_manually(self):
|
||||
|
@ -218,11 +218,16 @@ class AARegexCapability(AARegexTest):
|
||||
self.regex = RE_PROFILE_CAP
|
||||
|
||||
tests = (
|
||||
(' capability net_raw,', (None, None, 'net_raw', 'net_raw', None)),
|
||||
('capability net_raw , ', (None, None, 'net_raw', 'net_raw', None)),
|
||||
(' capability,', (None, None, None, None, None)),
|
||||
(' capability , ', (None, None, None, None, None)),
|
||||
(' capabilitynet_raw,', False)
|
||||
(' capability net_raw,', (None, None, None, None, 'net_raw', 'net_raw', None)),
|
||||
('capability net_raw , ', (None, None, None, None, 'net_raw', 'net_raw', None)),
|
||||
(' capability,', (None, None, None, None, None, None, None)),
|
||||
(' capability , ', (None, None, None, None, None, None, None)),
|
||||
(' capabilitynet_raw,', False),
|
||||
(' priority=1 capability net_raw,', ('priority=1', '1', None, None, 'net_raw', 'net_raw', None)),
|
||||
('priority=1 capability net_raw , ', ('priority=1', '1', None, None, 'net_raw', 'net_raw', None)),
|
||||
(' priority=1 capability,', ('priority=1', '1', None, None, None, None, None)),
|
||||
(' priority=1 capability , ', ('priority=1', '1', None, None, None, None, None)),
|
||||
(' priority=1 capabilitynet_raw,', False),
|
||||
)
|
||||
|
||||
|
||||
@ -233,13 +238,19 @@ class AARegexDbus(AARegexTest):
|
||||
self.regex = RE_PROFILE_DBUS
|
||||
|
||||
tests = (
|
||||
(' dbus,', (None, None, 'dbus,', None, None)),
|
||||
(' audit dbus,', ('audit', None, 'dbus,', None, None)),
|
||||
(' dbus send member=no_comment,', (None, None, 'dbus send member=no_comment,', 'send member=no_comment', None)),
|
||||
(' dbus send member=no_comment, # comment', (None, None, 'dbus send member=no_comment,', 'send member=no_comment', '# comment')),
|
||||
(' dbus,', (None, None, None, None, 'dbus,', None, None)),
|
||||
(' audit dbus,', (None, None, 'audit', None, 'dbus,', None, None)),
|
||||
(' dbus send member=no_comment,', (None, None, None, None, 'dbus send member=no_comment,', 'send member=no_comment', None)),
|
||||
(' dbus send member=no_comment, # comment', (None, None, None, None, 'dbus send member=no_comment,', 'send member=no_comment', '# comment')),
|
||||
|
||||
(' priority=-11 dbus,', ('priority=-11', '-11', None, None, 'dbus,', None, None)),
|
||||
(' priority=-11 audit dbus,', ('priority=-11', '-11', 'audit', None, 'dbus,', None, None)),
|
||||
(' priority=-11 dbus send member=no_comment,', ('priority=-11', '-11', None, None, 'dbus send member=no_comment,', 'send member=no_comment', None)),
|
||||
(' priority=-11 dbus send member=no_comment, # comment', ('priority=-11', '-11', None, None, 'dbus send member=no_comment,', 'send member=no_comment', '# comment')),
|
||||
|
||||
(' dbusdriver,', False),
|
||||
(' audit dbusdriver,', False),
|
||||
(' priority=-11 audit dbusdriver,', False),
|
||||
)
|
||||
|
||||
|
||||
@ -250,19 +261,30 @@ class AARegexMount(AARegexTest):
|
||||
self.regex = RE_PROFILE_MOUNT
|
||||
|
||||
tests = (
|
||||
(' mount,', (None, None, 'mount,', 'mount', None, None)),
|
||||
(' audit mount,', ('audit', None, 'mount,', 'mount', None, None)),
|
||||
(' umount,', (None, None, 'umount,', 'umount', None, None)),
|
||||
(' audit umount,', ('audit', None, 'umount,', 'umount', None, None)),
|
||||
(' unmount,', (None, None, 'unmount,', 'unmount', None, None)),
|
||||
(' audit unmount,', ('audit', None, 'unmount,', 'unmount', None, None)),
|
||||
(' remount,', (None, None, 'remount,', 'remount', None, None)),
|
||||
(' deny remount,', (None, 'deny', 'remount,', 'remount', None, None)),
|
||||
(' mount,', (None, None, None, None, 'mount,', 'mount', None, None)),
|
||||
(' audit mount,', (None, None, 'audit', None, 'mount,', 'mount', None, None)),
|
||||
(' umount,', (None, None, None, None, 'umount,', 'umount', None, None)),
|
||||
(' audit umount,', (None, None, 'audit', None, 'umount,', 'umount', None, None)),
|
||||
(' unmount,', (None, None, None, None, 'unmount,', 'unmount', None, None)),
|
||||
(' audit unmount,', (None, None, 'audit', None, 'unmount,', 'unmount', None, None)),
|
||||
(' remount,', (None, None, None, None, 'remount,', 'remount', None, None)),
|
||||
(' deny remount,', (None, None, None, 'deny', 'remount,', 'remount', None, None)),
|
||||
|
||||
(' mount, # comment', (None, None, 'mount,', 'mount', None, '# comment')),
|
||||
(' priority = 0 mount,', ('priority = 0', '0', None, None, 'mount,', 'mount', None, None)),
|
||||
(' priority = 0 audit mount,', ('priority = 0', '0', 'audit', None, 'mount,', 'mount', None, None)),
|
||||
(' priority = 0 umount,', ('priority = 0', '0', None, None, 'umount,', 'umount', None, None)),
|
||||
(' priority = 0 audit umount,', ('priority = 0', '0', 'audit', None, 'umount,', 'umount', None, None)),
|
||||
(' priority = 0 unmount,', ('priority = 0', '0', None, None, 'unmount,', 'unmount', None, None)),
|
||||
(' priority = 0 audit unmount,', ('priority = 0', '0', 'audit', None, 'unmount,', 'unmount', None, None)),
|
||||
(' priority = 0 remount,', ('priority = 0', '0', None, None, 'remount,', 'remount', None, None)),
|
||||
(' priority = 0 deny remount,', ('priority = 0', '0', None, 'deny', 'remount,', 'remount', None, None)),
|
||||
|
||||
(' mount, # comment', (None, None, None, None, 'mount,', 'mount', None, '# comment')),
|
||||
(' priority = 0 mount, # comment', ('priority = 0', '0', None, None, 'mount,', 'mount', None, '# comment')),
|
||||
|
||||
(' mountain,', False),
|
||||
(' audit mountain,', False),
|
||||
(' priority = 0 audit mountain,', False),
|
||||
)
|
||||
|
||||
|
||||
@ -273,16 +295,25 @@ class AARegexSignal(AARegexTest):
|
||||
self.regex = RE_PROFILE_SIGNAL
|
||||
|
||||
tests = (
|
||||
(' signal,', (None, None, 'signal,', None, None)),
|
||||
(' audit signal,', ('audit', None, 'signal,', None, None)),
|
||||
(' signal receive,', (None, None, 'signal receive,', 'receive', None)),
|
||||
(' signal (send, receive),', (None, None, 'signal (send, receive),', '(send, receive)', None)),
|
||||
(' audit signal (receive),', ('audit', None, 'signal (receive),', '(receive)', None)),
|
||||
(' signal (send, receive) set=(usr1 usr2),', (None, None, 'signal (send, receive) set=(usr1 usr2),', '(send, receive) set=(usr1 usr2)', None)),
|
||||
(' signal send set=(hup, quit) peer=/usr/sbin/daemon,', (None, None, 'signal send set=(hup, quit) peer=/usr/sbin/daemon,', 'send set=(hup, quit) peer=/usr/sbin/daemon', None)),
|
||||
(' signal,', (None, None, None, None, 'signal,', None, None)),
|
||||
(' audit signal,', (None, None, 'audit', None, 'signal,', None, None)),
|
||||
(' signal receive,', (None, None, None, None, 'signal receive,', 'receive', None)),
|
||||
(' signal (send, receive),', (None, None, None, None, 'signal (send, receive),', '(send, receive)', None)),
|
||||
(' audit signal (receive),', (None, None, 'audit', None, 'signal (receive),', '(receive)', None)),
|
||||
(' signal (send, receive) set=(usr1 usr2),', (None, None, None, None, 'signal (send, receive) set=(usr1 usr2),', '(send, receive) set=(usr1 usr2)', None)),
|
||||
(' signal send set=(hup, quit) peer=/usr/sbin/daemon,', (None, None, None, None, 'signal send set=(hup, quit) peer=/usr/sbin/daemon,', 'send set=(hup, quit) peer=/usr/sbin/daemon', None)),
|
||||
|
||||
(' priority = -1 signal,', ('priority = -1', '-1', None, None, 'signal,', None, None)),
|
||||
(' priority = -1 audit signal,', ('priority = -1', '-1', 'audit', None, 'signal,', None, None)),
|
||||
(' priority = -1 signal receive,', ('priority = -1', '-1', None, None, 'signal receive,', 'receive', None)),
|
||||
(' priority = -1 signal (send, receive),', ('priority = -1', '-1', None, None, 'signal (send, receive),', '(send, receive)', None)),
|
||||
(' priority = -1 audit signal (receive),', ('priority = -1', '-1', 'audit', None, 'signal (receive),', '(receive)', None)),
|
||||
(' priority = -1 signal (send, receive) set=(usr1 usr2),', ('priority = -1', '-1', None, None, 'signal (send, receive) set=(usr1 usr2),', '(send, receive) set=(usr1 usr2)', None)),
|
||||
(' priority = -1 signal send set=(hup, quit) peer=/usr/sbin/daemon,', ('priority = -1', '-1', None, None, 'signal send set=(hup, quit) peer=/usr/sbin/daemon,', 'send set=(hup, quit) peer=/usr/sbin/daemon', None)),
|
||||
|
||||
(' signalling,', False),
|
||||
(' audit signalling,', False),
|
||||
(' priority = -1 audit signalling,', False),
|
||||
(' signalling receive,', False),
|
||||
)
|
||||
|
||||
@ -294,16 +325,24 @@ class AARegexPtrace(AARegexTest):
|
||||
self.regex = RE_PROFILE_PTRACE
|
||||
|
||||
tests = (
|
||||
# audit allow rule rule details comment
|
||||
(' ptrace,', (None, None, 'ptrace,', None, None)),
|
||||
(' audit ptrace,', ('audit', None, 'ptrace,', None, None)),
|
||||
(' ptrace trace,', (None, None, 'ptrace trace,', 'trace', None)),
|
||||
(' ptrace (tracedby, readby),', (None, None, 'ptrace (tracedby, readby),', '(tracedby, readby)', None)),
|
||||
(' audit ptrace (read),', ('audit', None, 'ptrace (read),', '(read)', None)),
|
||||
(' ptrace trace peer=/usr/sbin/daemon,', (None, None, 'ptrace trace peer=/usr/sbin/daemon,', 'trace peer=/usr/sbin/daemon', None)),
|
||||
# priority audit allow rule rule details comment
|
||||
(' ptrace,', (None, None, None, None, 'ptrace,', None, None)),
|
||||
(' audit ptrace,', (None, None, 'audit', None, 'ptrace,', None, None)),
|
||||
(' ptrace trace,', (None, None, None, None, 'ptrace trace,', 'trace', None)),
|
||||
(' ptrace (tracedby, readby),', (None, None, None, None, 'ptrace (tracedby, readby),', '(tracedby, readby)', None)),
|
||||
(' audit ptrace (read),', (None, None, 'audit', None, 'ptrace (read),', '(read)', None)),
|
||||
(' ptrace trace peer=/usr/sbin/daemon,', (None, None, None, None, 'ptrace trace peer=/usr/sbin/daemon,', 'trace peer=/usr/sbin/daemon', None)),
|
||||
|
||||
(' priority=100 ptrace,', ('priority=100', '100', None, None, 'ptrace,', None, None)),
|
||||
(' priority=100 audit ptrace,', ('priority=100', '100', 'audit', None, 'ptrace,', None, None)),
|
||||
(' priority=100 ptrace trace,', ('priority=100', '100', None, None, 'ptrace trace,', 'trace', None)),
|
||||
(' priority=100 ptrace (tracedby, readby),', ('priority=100', '100', None, None, 'ptrace (tracedby, readby),', '(tracedby, readby)', None)),
|
||||
(' priority=100 audit ptrace (read),', ('priority=100', '100', 'audit', None, 'ptrace (read),', '(read)', None)),
|
||||
(' priority=100 ptrace trace peer=/usr/sbin/daemon,', ('priority=100', '100', None, None, 'ptrace trace peer=/usr/sbin/daemon,', 'trace peer=/usr/sbin/daemon', None)),
|
||||
|
||||
(' ptraceback,', False),
|
||||
(' audit ptraceback,', False),
|
||||
(' priority=100 audit ptraceback,', False),
|
||||
(' ptraceback trace,', False),
|
||||
)
|
||||
|
||||
@ -315,12 +354,19 @@ class AARegexPivotRoot(AARegexTest):
|
||||
self.regex = RE_PROFILE_PIVOT_ROOT
|
||||
|
||||
tests = (
|
||||
(' pivot_root,', (None, None, 'pivot_root,', None, None)),
|
||||
(' audit pivot_root,', ('audit', None, 'pivot_root,', None, None)),
|
||||
(' pivot_root oldroot=/new/old,', (None, None, 'pivot_root oldroot=/new/old,', 'oldroot=/new/old', None)),
|
||||
(' pivot_root oldroot=/new/old /new,', (None, None, 'pivot_root oldroot=/new/old /new,', 'oldroot=/new/old /new', None)),
|
||||
(' pivot_root oldroot=/new/old /new -> child,', (None, None, 'pivot_root oldroot=/new/old /new -> child,', 'oldroot=/new/old /new -> child', None)),
|
||||
(' audit pivot_root oldroot=/new/old /new -> child,', ('audit', None, 'pivot_root oldroot=/new/old /new -> child,', 'oldroot=/new/old /new -> child', None)),
|
||||
(' pivot_root,', (None, None, None, None, 'pivot_root,', None, None)),
|
||||
(' audit pivot_root,', (None, None, 'audit', None, 'pivot_root,', None, None)),
|
||||
(' pivot_root oldroot=/new/old,', (None, None, None, None, 'pivot_root oldroot=/new/old,', 'oldroot=/new/old', None)),
|
||||
(' pivot_root oldroot=/new/old /new,', (None, None, None, None, 'pivot_root oldroot=/new/old /new,', 'oldroot=/new/old /new', None)),
|
||||
(' pivot_root oldroot=/new/old /new -> child,', (None, None, None, None, 'pivot_root oldroot=/new/old /new -> child,', 'oldroot=/new/old /new -> child', None)),
|
||||
(' audit pivot_root oldroot=/new/old /new -> child,', (None, None, 'audit', None, 'pivot_root oldroot=/new/old /new -> child,', 'oldroot=/new/old /new -> child', None)),
|
||||
|
||||
(' priority=-100 pivot_root,', ('priority=-100', '-100', None, None, 'pivot_root,', None, None)),
|
||||
(' priority=-100 audit pivot_root,', ('priority=-100', '-100', 'audit', None, 'pivot_root,', None, None)),
|
||||
(' priority=-100 pivot_root oldroot=/new/old,', ('priority=-100', '-100', None, None, 'pivot_root oldroot=/new/old,', 'oldroot=/new/old', None)),
|
||||
(' priority=-100 pivot_root oldroot=/new/old /new,', ('priority=-100', '-100', None, None, 'pivot_root oldroot=/new/old /new,', 'oldroot=/new/old /new', None)),
|
||||
(' priority=-100 pivot_root oldroot=/new/old /new -> child,', ('priority=-100', '-100', None, None, 'pivot_root oldroot=/new/old /new -> child,', 'oldroot=/new/old /new -> child', None)),
|
||||
(' priority=-100 audit pivot_root oldroot=/new/old /new -> child,', ('priority=-100', '-100', 'audit', None, 'pivot_root oldroot=/new/old /new -> child,', 'oldroot=/new/old /new -> child', None)),
|
||||
|
||||
('pivot_root', False), # comma missing
|
||||
|
||||
@ -329,6 +375,7 @@ class AARegexPivotRoot(AARegexTest):
|
||||
('pivot_rootbeer, # comment', False),
|
||||
('pivot_rootbeer /new, ', False),
|
||||
('pivot_rootbeer /new, # comment', False),
|
||||
('priority=-100 pivot_rootbeer /new, # comment', False),
|
||||
)
|
||||
|
||||
|
||||
@ -339,20 +386,35 @@ class AARegexUnix(AARegexTest):
|
||||
self.regex = RE_PROFILE_UNIX
|
||||
|
||||
tests = (
|
||||
(' unix,', (None, None, 'unix,', None, None)),
|
||||
(' audit unix,', ('audit', None, 'unix,', None, None)),
|
||||
(' unix accept,', (None, None, 'unix accept,', 'accept', None)),
|
||||
(' allow unix connect,', (None, 'allow', 'unix connect,', 'connect', None)),
|
||||
(' audit allow unix bind,', ('audit', 'allow', 'unix bind,', 'bind', None)),
|
||||
(' deny unix bind,', (None, 'deny', 'unix bind,', 'bind', None)),
|
||||
('unix peer=(label=@{profile_name}),', (None, None, 'unix peer=(label=@{profile_name}),', 'peer=(label=@{profile_name})', None)),
|
||||
('unix (receive) peer=(label=unconfined),', (None, None, 'unix (receive) peer=(label=unconfined),', '(receive) peer=(label=unconfined)', None)),
|
||||
(' unix (getattr, shutdown) peer=(addr=none),', (None, None, 'unix (getattr, shutdown) peer=(addr=none),', '(getattr, shutdown) peer=(addr=none)', None)),
|
||||
('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', (None, None, 'unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),',
|
||||
(' unix,', (None, None, None, None, 'unix,', None, None)),
|
||||
(' audit unix,', (None, None, 'audit', None, 'unix,', None, None)),
|
||||
(' unix accept,', (None, None, None, None, 'unix accept,', 'accept', None)),
|
||||
(' allow unix connect,', (None, None, None, 'allow', 'unix connect,', 'connect', None)),
|
||||
(' audit allow unix bind,', (None, None, 'audit', 'allow', 'unix bind,', 'bind', None)),
|
||||
(' deny unix bind,', (None, None, None, 'deny', 'unix bind,', 'bind', None)),
|
||||
('unix peer=(label=@{profile_name}),', (None, None, None, None, 'unix peer=(label=@{profile_name}),', 'peer=(label=@{profile_name})', None)),
|
||||
('unix (receive) peer=(label=unconfined),', (None, None, None, None, 'unix (receive) peer=(label=unconfined),', '(receive) peer=(label=unconfined)', None)),
|
||||
(' unix (getattr, shutdown) peer=(addr=none),', (None, None, None, None, 'unix (getattr, shutdown) peer=(addr=none),', '(getattr, shutdown) peer=(addr=none)', None)),
|
||||
('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', (None, None, None, None, 'unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),',
|
||||
'(connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*")', # noqa: E127
|
||||
None)), # noqa: E127
|
||||
|
||||
(' priority=1 unix,', ('priority=1', '1', None, None, 'unix,', None, None)),
|
||||
(' priority=1 audit unix,', ('priority=1', '1', 'audit', None, 'unix,', None, None)),
|
||||
(' priority=1 unix accept,', ('priority=1', '1', None, None, 'unix accept,', 'accept', None)),
|
||||
(' priority=1 allow unix connect,', ('priority=1', '1', None, 'allow', 'unix connect,', 'connect', None)),
|
||||
(' priority=1 audit allow unix bind,', ('priority=1', '1', 'audit', 'allow', 'unix bind,', 'bind', None)),
|
||||
(' priority=1 deny unix bind,', ('priority=1', '1', None, 'deny', 'unix bind,', 'bind', None)),
|
||||
('priority=1 unix peer=(label=@{profile_name}),', ('priority=1', '1', None, None, 'unix peer=(label=@{profile_name}),', 'peer=(label=@{profile_name})', None)),
|
||||
('priority=1 unix (receive) peer=(label=unconfined),', ('priority=1', '1', None, None, 'unix (receive) peer=(label=unconfined),', '(receive) peer=(label=unconfined)', None)),
|
||||
(' priority=1 unix (getattr, shutdown) peer=(addr=none),', ('priority=1', '1', None, None, 'unix (getattr, shutdown) peer=(addr=none),', '(getattr, shutdown) peer=(addr=none)', None)),
|
||||
('priority=1 unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', ('priority=1', '1', None, None, 'unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),',
|
||||
'(connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*")', # noqa: E127
|
||||
None)), # noqa: E127
|
||||
|
||||
('unixlike', False),
|
||||
('deny unixlike,', False),
|
||||
('priority=1 deny unixlike,', False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -174,6 +174,10 @@ class InvalidRlimitInit(AATest):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
RlimitRule('as', '1024MB', audit=True)
|
||||
|
||||
def test_priority_keyword(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
RlimitRule('as', '1024MB', priority=0)
|
||||
|
||||
|
||||
class InvalidRlimitTest(AATest):
|
||||
def _check_invalid_rawrule(self, rawrule):
|
||||
|
@ -277,6 +277,10 @@ class WriteSignalTestAATest(AATest):
|
||||
('signal receive peer=foo,', 'signal receive peer=foo,'),
|
||||
('signal (send receive) peer=/usr/bin/bar,', 'signal (receive send) peer=/usr/bin/bar,'),
|
||||
('signal wr set=(pipe, usr1) peer=/sbin/baz,', 'signal wr set=(pipe usr1) peer=/sbin/baz,'),
|
||||
('priority = 29 signal receive peer=foo,', 'priority=29 signal receive peer=foo,'),
|
||||
('priority = 0 signal receive peer=foo,', 'priority=0 signal receive peer=foo,'),
|
||||
('priority =-123 signal receive peer=foo,', 'priority=-123 signal receive peer=foo,'),
|
||||
('priority =+10 signal receive peer=foo,', 'priority=10 signal receive peer=foo,'),
|
||||
)
|
||||
|
||||
def test_write_manually(self):
|
||||
|
@ -166,15 +166,18 @@ class UnixTestGlob(AATest):
|
||||
|
||||
class UnixTestClean(AATest):
|
||||
tests = (
|
||||
(' audit unix , # foo ', 'audit unix, # foo'),
|
||||
(' audit deny unix label = foo , ', 'audit deny unix label=foo,'),
|
||||
(' audit allow unix peer = (addr = a) , # foo ', 'audit allow unix peer=(addr=a), # foo'),
|
||||
(' deny unix type = foo , ', 'deny unix type=foo,'),
|
||||
(' allow unix peer = (label=bb) , # foo ', 'allow unix peer=(label=bb), # foo'),
|
||||
(' unix , # foo ', 'unix, # foo'),
|
||||
(' unix addr = foo , ', 'unix addr=foo,'),
|
||||
(' unix ( accept , rw) protocol = AA type = BB opt = myopt label = bb peer = (addr = a label = bb ) , ', 'unix (accept, rw) type=BB protocol=AA label=bb opt=myopt peer=(addr=a label=bb),'),
|
||||
|
||||
(' audit unix , # foo ', 'audit unix, # foo'),
|
||||
(' audit deny unix label = foo , ', 'audit deny unix label=foo,'),
|
||||
(' audit allow unix peer = (addr = a) , # foo ', 'audit allow unix peer=(addr=a), # foo'),
|
||||
(' deny unix type = foo , ', 'deny unix type=foo,'),
|
||||
(' allow unix peer = (label=bb) , # foo ', 'allow unix peer=(label=bb), # foo'),
|
||||
(' unix , # foo ', 'unix, # foo'),
|
||||
(' unix addr = foo , ', 'unix addr=foo,'),
|
||||
(' unix ( accept , rw) protocol = AA type = BB opt = myopt label = bb peer = (addr = a label = bb ) , ', 'unix (accept, rw) type=BB protocol=AA label=bb opt=myopt peer=(addr=a label=bb),'),
|
||||
('priority=-42 unix ( accept , rw) protocol = AA type = BB opt = myopt label = bb peer = (addr = a label = bb ), ', 'priority=-42 unix (accept, rw) type=BB protocol=AA label=bb opt=myopt peer=(addr=a label=bb),'),
|
||||
('priority = 0 unix ( accept , rw) protocol = AA type = BB opt = myopt label = bb peer = (addr = a label = bb ), ', 'priority=0 unix (accept, rw) type=BB protocol=AA label=bb opt=myopt peer=(addr=a label=bb),'),
|
||||
('priority=211 unix ( accept , rw) protocol = AA type = BB opt = myopt label = bb peer = (addr = a label = bb ), ', 'priority=211 unix (accept, rw) type=BB protocol=AA label=bb opt=myopt peer=(addr=a label=bb),'),
|
||||
('priority=+45 unix ( accept , rw) protocol = AA type = BB opt = myopt label = bb peer = (addr = a label = bb ), ', 'priority=45 unix (accept, rw) type=BB protocol=AA label=bb opt=myopt peer=(addr=a label=bb),'),
|
||||
)
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
|
@ -59,10 +59,10 @@ class UserNamespaceTestParseInvalid(AATest):
|
||||
UserNamespaceRule.create_instance('foo,')
|
||||
|
||||
def test_diff_non_usernsrule(self):
|
||||
exp = namedtuple('exp', ('audit', 'deny'))
|
||||
exp = namedtuple('exp', ('audit', 'deny', 'priority'))
|
||||
obj = UserNamespaceRule(('create'))
|
||||
with self.assertRaises(AppArmorBug):
|
||||
obj.is_equal(exp(False, False), False)
|
||||
obj.is_equal(exp(False, False, None), False)
|
||||
|
||||
def test_diff_access(self):
|
||||
obj1 = UserNamespaceRule(UserNamespaceRule.ALL)
|
||||
@ -98,6 +98,10 @@ class WriteUserNamespaceTestAATest(AATest):
|
||||
(' allow userns create ,# foo bar', 'allow userns create, # foo bar'),
|
||||
('userns,', 'userns,'),
|
||||
('userns create,', 'userns create,'),
|
||||
(' priority = -1 allow userns create,', 'priority=-1 allow userns create,'),
|
||||
(' priority = 0 allow userns create,', 'priority=0 allow userns create,'),
|
||||
(' priority=+234 allow userns create,', 'priority=234 allow userns create,'),
|
||||
(' priority = 65 allow userns create,', 'priority=65 allow userns create,'),
|
||||
)
|
||||
|
||||
def _run_test(self, rawrule, expected):
|
||||
|
@ -30,10 +30,11 @@ exp = namedtuple('exp', ('comment', 'varname', 'mode', 'values'))
|
||||
|
||||
class VariableTest(AATest):
|
||||
def _compare_obj(self, obj, expected):
|
||||
# variables don't support the allow, audit or deny keyword
|
||||
# variables don't support the allow, audit, deny, or priority keyword
|
||||
self.assertEqual(False, obj.allow_keyword)
|
||||
self.assertEqual(False, obj.audit)
|
||||
self.assertEqual(False, obj.deny)
|
||||
self.assertEqual(None, obj.priority)
|
||||
|
||||
self.assertEqual(expected.varname, obj.varname)
|
||||
self.assertEqual(expected.mode, obj.mode)
|
||||
@ -166,6 +167,14 @@ class InvalidVariableInit(AATest):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
VariableRule('@{foo}', '=', '/bar', deny=True)
|
||||
|
||||
def test_invalid_priority_1(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
VariableRule('@{foo}', '=', '/bar', priority=98)
|
||||
|
||||
def test_invalid_priority_2(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
VariableRule('@{foo}', '=', '/bar', priority=0)
|
||||
|
||||
|
||||
class InvalidVariableTest(AATest):
|
||||
def _check_invalid_rawrule(self, rawrule, matches_regex=False):
|
||||
|
Loading…
x
Reference in New Issue
Block a user