parser: int mode to perms

Move from using and int for permissions bit mask to a perms_t type.
Also move any perms mask that uses the name mode to perms to avoid
confusing it with other uses of mode.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2021-06-09 00:56:59 -07:00
parent b255ff8831
commit fd9a6fe133
26 changed files with 356 additions and 353 deletions

View file

@ -101,32 +101,32 @@ ostream &af_rule::dump_prefix(ostream &os)
ostream &af_rule::dump_local(ostream &os)
{
if (mode != AA_VALID_NET_PERMS) {
if (perms != AA_VALID_NET_PERMS) {
os << " (";
if (mode & AA_NET_SEND)
if (perms & AA_NET_SEND)
os << "send ";
if (mode & AA_NET_RECEIVE)
if (perms & AA_NET_RECEIVE)
os << "receive ";
if (mode & AA_NET_CREATE)
if (perms & AA_NET_CREATE)
os << "create ";
if (mode & AA_NET_SHUTDOWN)
if (perms & AA_NET_SHUTDOWN)
os << "shutdown ";
if (mode & AA_NET_CONNECT)
if (perms & AA_NET_CONNECT)
os << "connect ";
if (mode & AA_NET_SETATTR)
if (perms & AA_NET_SETATTR)
os << "setattr ";
if (mode & AA_NET_GETATTR)
if (perms & AA_NET_GETATTR)
os << "getattr ";
if (mode & AA_NET_BIND)
if (perms & AA_NET_BIND)
os << "bind ";
if (mode & AA_NET_ACCEPT)
if (perms & AA_NET_ACCEPT)
os << "accept ";
if (mode & AA_NET_LISTEN)
if (perms & AA_NET_LISTEN)
os << "listen ";
if (mode & AA_NET_SETOPT)
if (perms & AA_NET_SETOPT)
os << "setopt ";
if (mode & AA_NET_GETOPT)
if (perms & AA_NET_GETOPT)
os << "getopt ";
os << ")";
}

View file

@ -44,13 +44,13 @@ public:
int proto_n;
char *label;
char *peer_label;
int mode;
perms_t perms;
int audit;
bool deny;
af_rule(const char *name): af_name(name), sock_type(NULL),
sock_type_n(-1), proto(NULL), proto_n(0), label(NULL),
peer_label(NULL), mode(0), audit(0), deny(0)
peer_label(NULL), perms(0), audit(0), deny(0)
{}
virtual ~af_rule()

View file

@ -32,9 +32,9 @@
/* 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]";
int parse_unix_mode(const char *str_mode, int *mode, int fail)
int parse_unix_perms(const char *str_perms, perms_t *perms, int fail)
{
return parse_X_mode("unix", AA_VALID_NET_PERMS, str_mode, mode, fail);
return parse_X_perms("unix", AA_VALID_NET_PERMS, str_perms, perms, fail);
}
@ -104,26 +104,26 @@ unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied):
if (!sock_type)
yyerror("socket rule: invalid socket type '%d'", type_p);
}
mode = AA_VALID_NET_PERMS;
perms = AA_VALID_NET_PERMS;
audit = audit_p ? AA_VALID_NET_PERMS : 0;
deny = denied;
}
unix_rule::unix_rule(int mode_p, struct cond_entry *conds,
unix_rule::unix_rule(perms_t perms_p, struct cond_entry *conds,
struct cond_entry *peer_conds):
af_rule("unix"), addr(NULL), peer_addr(NULL)
{
move_conditionals(conds);
move_peer_conditionals(peer_conds);
if (mode_p) {
mode = mode_p;
if (mode & ~AA_VALID_NET_PERMS)
yyerror("mode contains invalid permissions for unix socket rules\n");
else if ((mode & ~AA_PEER_NET_PERMS) && has_peer_conds())
if (perms_p) {
perms = perms_p;
if (perms & ~AA_VALID_NET_PERMS)
yyerror("perms contains invalid permissions for unix socket rules\n");
else if ((perms & ~AA_PEER_NET_PERMS) && has_peer_conds())
yyerror("unix socket 'create', 'shutdown', 'setattr', 'getattr', 'bind', 'listen', 'setopt', and/or 'getopt' accesses cannot be used with peer socket conditionals\n");
} else {
mode = AA_VALID_NET_PERMS;
perms = AA_VALID_NET_PERMS;
}
free_cond_list(conds);
@ -187,7 +187,7 @@ static void writeu16(std::ostringstream &o, int v)
#define CMD_OPT 4
void unix_rule::downgrade_rule(Profile &prof) {
unsigned int mask = (unsigned int) -1;
perms_t mask = (perms_t) -1;
if (!prof.net.allow && !prof.alloc_net_table())
yyerror(_("Memory allocation error."));
@ -309,7 +309,7 @@ int unix_rule::gen_policy_re(Profile &prof)
std::ostringstream buffer;
std::string buf;
int mask = mode;
perms_t mask = perms;
/* always generate a downgraded rule. This doesn't change generated
* policy size and allows the binary policy to be loaded against
@ -432,7 +432,7 @@ int unix_rule::gen_policy_re(Profile &prof)
goto fail;
buf = buffer.str();
if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mode & AA_PEER_NET_PERMS), map_perms(audit), dfaflags))
if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit), dfaflags))
goto fail;
}

View file

@ -24,7 +24,7 @@
#include "profile.h"
#include "af_rule.h"
int parse_unix_mode(const char *str_mode, int *mode, int fail);
int parse_unix_perms(const char *str_mode, perms_t *perms, int fail);
class unix_rule: public af_rule {
void write_to_prot(std::ostringstream &buffer);
@ -38,7 +38,7 @@ public:
char *peer_addr;
unix_rule(unsigned int type_p, bool audit_p, bool denied);
unix_rule(int mode, struct cond_entry *conds,
unix_rule(perms_t perms, struct cond_entry *conds,
struct cond_entry *peer_conds);
virtual ~unix_rule()
{

View file

@ -30,9 +30,9 @@
#include "dbus.h"
int parse_dbus_mode(const char *str_mode, int *mode, int fail)
int parse_dbus_perms(const char *str_perms, perms_t *perms, int fail)
{
return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail);
return parse_X_perms("DBus", AA_VALID_DBUS_PERMS, str_perms, perms, fail);
}
void dbus_rule::move_conditionals(struct cond_entry *conds)
@ -66,10 +66,10 @@ void dbus_rule::move_conditionals(struct cond_entry *conds)
}
}
dbus_rule::dbus_rule(int mode_p, struct cond_entry *conds,
dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds,
struct cond_entry *peer_conds):
bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL),
mode(0), audit(0), deny(0)
perms(0), audit(0), deny(0)
{
int name_is_subject_cond = 0, message_rule = 0, service_rule = 0;
@ -93,27 +93,27 @@ dbus_rule::dbus_rule(int mode_p, struct cond_entry *conds,
if (message_rule && service_rule)
yyerror("dbus rule contains message conditionals and service conditionals\n");
/* Copy mode. If no mode was specified, assign an implied mode. */
if (mode_p) {
mode = mode_p;
if (mode & ~AA_VALID_DBUS_PERMS)
yyerror("mode contains unknown dbus access\n");
else if (message_rule && (mode & AA_DBUS_BIND))
/* Copy perms. If no perms was specified, assign an implied perms. */
if (perms_p) {
perms = perms_p;
if (perms & ~AA_VALID_DBUS_PERMS)
yyerror("perms contains unknown dbus access\n");
else if (message_rule && (perms & AA_DBUS_BIND))
yyerror("dbus \"bind\" access cannot be used with message rule conditionals\n");
else if (service_rule && (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)))
else if (service_rule && (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)))
yyerror("dbus \"send\" and/or \"receive\" accesses cannot be used with service rule conditionals\n");
else if (mode & AA_DBUS_EAVESDROP &&
else if (perms & AA_DBUS_EAVESDROP &&
(path || interface || member ||
peer_label || name)) {
yyerror("dbus \"eavesdrop\" access can only contain a bus conditional\n");
}
} else {
if (message_rule)
mode = (AA_DBUS_SEND | AA_DBUS_RECEIVE);
perms = (AA_DBUS_SEND | AA_DBUS_RECEIVE);
else if (service_rule)
mode = (AA_DBUS_BIND);
perms = (AA_DBUS_BIND);
else
mode = AA_VALID_DBUS_PERMS;
perms = AA_VALID_DBUS_PERMS;
}
free_cond_list(conds);
@ -129,19 +129,19 @@ ostream &dbus_rule::dump(ostream &os)
os << "dbus ( ";
if (mode & AA_DBUS_SEND)
if (perms & AA_DBUS_SEND)
os << "send ";
if (mode & AA_DBUS_RECEIVE)
if (perms & AA_DBUS_RECEIVE)
os << "receive ";
if (mode & AA_DBUS_BIND)
if (perms & AA_DBUS_BIND)
os << "bind ";
if (mode & AA_DBUS_EAVESDROP)
if (perms & AA_DBUS_EAVESDROP)
os << "eavesdrop ";
os << ")";
if (bus)
os << " bus=\"" << bus << "\"";
if ((mode & AA_DBUS_BIND) && name)
if ((perms & AA_DBUS_BIND) && name)
os << " name=\"" << name << "\"";
if (path)
os << " path=\"" << path << "\"";
@ -150,7 +150,7 @@ ostream &dbus_rule::dump(ostream &os)
if (member)
os << " member=\"" << member << "\"";
if (!(mode & AA_DBUS_BIND) && (peer_label || name)) {
if (!(perms & AA_DBUS_BIND) && (peer_label || name)) {
os << " peer=( ";
if (peer_label)
os << "label=\"" << peer_label << "\" ";
@ -277,22 +277,22 @@ int dbus_rule::gen_policy_re(Profile &prof)
vec[5] = default_match_pattern;
}
if (mode & AA_DBUS_BIND) {
if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_BIND,
if (perms & AA_DBUS_BIND) {
if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND,
audit & AA_DBUS_BIND,
2, vec, dfaflags, false))
goto fail;
}
if (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) {
if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) {
if (!prof.policy.rules->add_rule_vec(deny,
mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
6, vec, dfaflags, false))
goto fail;
}
if (mode & AA_DBUS_EAVESDROP) {
if (perms & AA_DBUS_EAVESDROP) {
if (!prof.policy.rules->add_rule_vec(deny,
mode & AA_DBUS_EAVESDROP,
perms & AA_DBUS_EAVESDROP,
audit & AA_DBUS_EAVESDROP,
1, vec, dfaflags, false))
goto fail;

View file

@ -23,7 +23,7 @@
#include "rule.h"
#include "profile.h"
extern int parse_dbus_mode(const char *str_mode, int *mode, int fail);
extern int parse_dbus_perms(const char *str_mode, perms_t *mode, int fail);
class dbus_rule: public rule_t {
void move_conditionals(struct cond_entry *conds);
@ -39,11 +39,11 @@ public:
char *path;
char *interface;
char *member;
int mode;
perms_t perms;
int audit;
int deny;
dbus_rule(int mode_p, struct cond_entry *conds,
dbus_rule(perms_t perms_p, struct cond_entry *conds,
struct cond_entry *peer_conds);
virtual ~dbus_rule() {
free(bus);

View file

@ -98,7 +98,7 @@
#define AA_LINK_BITS ((AA_OLD_MAY_LINK << AA_USER_SHIFT) | \
(AA_OLD_MAY_LINK << AA_OTHER_SHIFT))
#define SHIFT_MODE(MODE, SHIFT) ((((MODE) & AA_BASE_PERMS) << (SHIFT))\
#define SHIFT_PERMS(MODE, SHIFT) ((((MODE) & AA_BASE_PERMS) << (SHIFT))\
| ((MODE) & ~AA_FILE_PERMS))
#define SHIFT_TO_BASE(MODE, SHIFT) ((((MODE) & AA_FILE_PERMS) >> (SHIFT))\
| ((MODE) & ~AA_FILE_PERMS))

View file

@ -1057,7 +1057,7 @@ fail:
void mnt_rule::post_process(Profile &prof)
{
if (trans) {
unsigned int mode = 0;
perms_t perms = 0;
int n = add_entry_to_x_table(&prof, trans);
if (!n) {
PERROR("Profile %s has too many specified profile transitions.\n", prof.name);
@ -1065,11 +1065,11 @@ void mnt_rule::post_process(Profile &prof)
}
if (allow & AA_USER_EXEC)
mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT);
perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT);
if (allow & AA_OTHER_EXEC)
mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT);
perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT);
allow = ((allow & ~AA_ALL_EXEC_MODIFIERS) |
(mode & AA_ALL_EXEC_MODIFIERS));
(perms & AA_ALL_EXEC_MODIFIERS));
trans = NULL;
}

View file

@ -25,9 +25,9 @@
#include <iostream>
#include <sstream>
int parse_mqueue_mode(const char *str_mode, int *mode, int fail)
int parse_mqueue_perms(const char *str_perms, perms_t *perms, int fail)
{
return parse_X_mode("mqueue", AA_VALID_MQUEUE_PERMS, str_mode, mode, fail);
return parse_X_perms("mqueue", AA_VALID_MQUEUE_PERMS, str_perms, perms, fail);
}
static bool is_all_digits(char *str)
@ -86,7 +86,7 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds)
}
}
mqueue_rule::mqueue_rule(int mode_p, struct cond_entry *conds, char *qname_p):
mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p):
qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(0), deny(0)
{
move_conditionals(conds);
@ -94,20 +94,20 @@ mqueue_rule::mqueue_rule(int mode_p, struct cond_entry *conds, char *qname_p):
if (qname)
validate_qname();
if (mode_p) {
if (perms_p) {
// do we want to allow perms to imply type like we do for
// qname?
if (qtype == mqueue_posix && (mode_p & ~AA_VALID_POSIX_MQ_PERMS)) {
yyerror("mode contains invalid permissions for mqueue type=posix\n");
} else if (qtype == mqueue_sysv && (mode_p & ~AA_VALID_SYSV_MQ_PERMS)) {
yyerror("mode contains invalid permissions for mqueue type=sysv\n");
} else if (mode_p & ~AA_VALID_MQUEUE_PERMS) {
yyerror("mode contains invalid permissions for mqueue\n");
if (qtype == mqueue_posix && (perms_p & ~AA_VALID_POSIX_MQ_PERMS)) {
yyerror("perms contains invalid permissions for mqueue type=posix\n");
} else if (qtype == mqueue_sysv && (perms_p & ~AA_VALID_SYSV_MQ_PERMS)) {
yyerror("perms contains invalid permissions for mqueue type=sysv\n");
} else if (perms_p & ~AA_VALID_MQUEUE_PERMS) {
yyerror("perms contains invalid permissions for mqueue\n");
}
mode = mode_p;
perms = perms_p;
} else {
// default to all perms
mode = AA_VALID_MQUEUE_PERMS;
perms = AA_VALID_MQUEUE_PERMS;
}
qname = qname_p;
@ -129,22 +129,22 @@ ostream &mqueue_rule::dump(ostream &os)
else if (qtype == mqueue_sysv)
os << "type=sysv";
if (mode != AA_VALID_MQUEUE_PERMS) {
if (perms != AA_VALID_MQUEUE_PERMS) {
os << "(";
if (mode & AA_MQUEUE_WRITE)
if (perms & AA_MQUEUE_WRITE)
os << "write ";
if (mode & AA_MQUEUE_READ)
if (perms & AA_MQUEUE_READ)
os << "read ";
if (mode & AA_MQUEUE_OPEN)
if (perms & AA_MQUEUE_OPEN)
os << "open ";
if (mode & AA_MQUEUE_CREATE)
if (perms & AA_MQUEUE_CREATE)
os << "create ";
if (mode & AA_MQUEUE_DELETE)
if (perms & AA_MQUEUE_DELETE)
os << "delete ";
if (mode & AA_MQUEUE_SETATTR)
if (perms & AA_MQUEUE_SETATTR)
os << "setattr ";
if (mode & AA_MQUEUE_GETATTR)
if (perms & AA_MQUEUE_GETATTR)
os << "getattr ";
os << ")";
@ -229,14 +229,14 @@ int mqueue_rule::gen_policy_re(Profile &prof)
vec[1] = anyone_match_pattern;
}
if (mode & AA_VALID_POSIX_MQ_PERMS) {
if (perms & AA_VALID_POSIX_MQ_PERMS) {
/* store perms at name match so label doesn't need
* to be checked
*/
if (!label && !prof.policy.rules->add_rule_vec(deny, mode, audit, 1, vec, dfaflags, false))
if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, dfaflags, false))
goto fail;
/* also provide label match with perm */
if (!prof.policy.rules->add_rule_vec(deny, mode, audit, size, vec, dfaflags, false))
if (!prof.policy.rules->add_rule_vec(deny, perms, audit, size, vec, dfaflags, false))
goto fail;
}
}
@ -267,11 +267,11 @@ int mqueue_rule::gen_policy_re(Profile &prof)
vec[1] = anyone_match_pattern;
}
if (mode & AA_VALID_SYSV_MQ_PERMS) {
if (!label && !prof.policy.rules->add_rule_vec(deny, mode, audit, 1, vec, dfaflags, false))
if (perms & AA_VALID_SYSV_MQ_PERMS) {
if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, dfaflags, false))
goto fail;
/* also provide label match with perm */
if (!prof.policy.rules->add_rule_vec(deny, mode, audit, size, vec, dfaflags, false))
if (!prof.policy.rules->add_rule_vec(deny, perms, audit, size, vec, dfaflags, false))
goto fail;
}
}

View file

@ -79,7 +79,7 @@ typedef enum mqueue_type {
} mqueue_type;
int parse_mqueue_mode(const char *str_mode, int *mode, int fail);
int parse_mqueue_perms(const char *str_perms, perms_t *perms, int fail);
class mqueue_rule: public rule_t {
void move_conditionals(struct cond_entry *conds);
@ -87,11 +87,11 @@ public:
mqueue_type qtype;
char *qname;
char *label;
int mode;
perms_t perms;
int audit;
int deny;
mqueue_rule(int mode, struct cond_entry *conds, char *qname = NULL);
mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL);
virtual ~mqueue_rule()
{
free(qname);

View file

@ -32,9 +32,9 @@
#include "network.h"
int parse_net_mode(const char *str_mode, int *mode, int fail)
int parse_net_perms(const char *str_mode, perms_t *mode, int fail)
{
return parse_X_mode("net", AA_VALID_NET_PERMS, str_mode, mode, fail);
return parse_X_perms("net", AA_VALID_NET_PERMS, str_mode, mode, fail);
}
/* Bleah C++ doesn't have non-trivial designated initializers so we just

View file

@ -100,7 +100,7 @@ static inline uint32_t map_perms(uint32_t mask)
};
int parse_net_mode(const char *str_mode, int *mode, int fail);
int parse_net_perms(const char *str_mode, perms_t *perms, int fail);
extern struct aa_network_entry *new_network_ent(unsigned int family,
unsigned int type,
unsigned int protocol);

View file

@ -45,6 +45,8 @@ using namespace std;
class Profile;
class rule_t;
typedef uint32_t perms_t;
#define MODULE_NAME "apparmor"
/* Global variable to pass token to lexer. Will be replaced by parameter
@ -127,8 +129,8 @@ struct cod_entry {
char *nt_name;
Profile *prof; /* Special profile defined
* just for this executable */
int mode; /* mode is 'or' of AA_* bits */
int audit; /* audit flags for mode */
perms_t perms; /* perms is 'or' of AA_* bits */
int audit; /* audit flags for perms */
int deny; /* TRUE or FALSE */
int alias_ignore; /* ignore for alias processing */
@ -449,12 +451,12 @@ extern char *processunquoted(const char *string, int len);
extern int get_keyword_token(const char *keyword);
extern int get_rlimit(const char *name);
extern char *process_var(const char *var);
extern int parse_mode(const char *mode);
extern int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail);
extern perms_t parse_perms(const char *permstr);
extern int parse_X_perms(const char *X, int valid, const char *str_perms, perms_t *perms, int fail);
bool label_contains_ns(const char *label);
bool parse_label(bool *_stack, char **_ns, char **_name,
const char *label, bool yyerr);
extern struct cod_entry *new_entry(char *id, int mode, char *link_id);
extern struct cod_entry *new_entry(char *id, perms_t perms, char *link_id);
/* returns -1 if value != true or false, otherwise 0 == false, 1 == true */
extern int str_to_boolean(const char* str);

View file

@ -120,7 +120,7 @@ static void process_entries(const void *nodep, VISIT value, int level unused)
len = strlen((*t)->from);
list_for_each(target_list, entry) {
if ((entry->mode & AA_SHARED_PERMS) || entry->alias_ignore)
if ((entry->perms & AA_SHARED_PERMS) || entry->alias_ignore)
continue;
if (entry->name && strncmp((*t)->from, entry->name, len) == 0) {
char *n = do_alias(*t, entry->name);

View file

@ -89,12 +89,12 @@ static int process_file_entries(Profile *prof)
}
/* check for merged x consistency */
if (!is_merged_x_consistent(cur->mode, next->mode)) {
if (!is_merged_x_consistent(cur->perms, next->perms)) {
PERROR(_("profile %s: has merged rule %s with conflicting x modifiers\n"),
prof->name, cur->name);
return -1;
}
cur->mode |= next->mode;
cur->perms |= next->perms;
cur->audit |= next->audit;
cur->next = next->next;

View file

@ -540,139 +540,139 @@ void warn_uppercase(void)
}
}
static int parse_sub_mode(const char *str_mode, const char *mode_desc unused)
static perms_t parse_sub_perms(const char *str_perms, const char *perms_desc unused)
{
#define IS_DIFF_QUAL(mode, q) (((mode) & AA_MAY_EXEC) && (((mode) & AA_EXEC_TYPE) != ((q) & AA_EXEC_TYPE)))
#define IS_DIFF_QUAL(perms, q) (((perms) & AA_MAY_EXEC) && (((perms) & AA_EXEC_TYPE) != ((q) & AA_EXEC_TYPE)))
int mode = 0;
perms_t perms = 0;
const char *p;
PDEBUG("Parsing mode: %s\n", str_mode);
PDEBUG("Parsing perms: %s\n", str_perms);
if (!str_mode)
if (!str_perms)
return 0;
p = str_mode;
p = str_perms;
while (*p) {
char thisc = *p;
char next = *(p + 1);
char lower;
int tmode = 0;
perms_t tperms = 0;
reeval:
switch (thisc) {
case COD_READ_CHAR:
if (read_implies_exec) {
PDEBUG("Parsing mode: found %s READ imply X\n", mode_desc);
mode |= AA_MAY_READ | AA_OLD_EXEC_MMAP;
PDEBUG("Parsing perms: found %s READ imply X\n", perms_desc);
perms |= AA_MAY_READ | AA_OLD_EXEC_MMAP;
} else {
PDEBUG("Parsing mode: found %s READ\n", mode_desc);
mode |= AA_MAY_READ;
PDEBUG("Parsing perms: found %s READ\n", perms_desc);
perms |= AA_MAY_READ;
}
break;
case COD_WRITE_CHAR:
PDEBUG("Parsing mode: found %s WRITE\n", mode_desc);
if ((mode & AA_MAY_APPEND) && !(mode & AA_MAY_WRITE))
PDEBUG("Parsing perms: found %s WRITE\n", perms_desc);
if ((perms & AA_MAY_APPEND) && !(perms & AA_MAY_WRITE))
yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive."));
mode |= AA_MAY_WRITE | AA_MAY_APPEND;
perms |= AA_MAY_WRITE | AA_MAY_APPEND;
break;
case COD_APPEND_CHAR:
PDEBUG("Parsing mode: found %s APPEND\n", mode_desc);
if (mode & AA_MAY_WRITE)
PDEBUG("Parsing perms: found %s APPEND\n", perms_desc);
if (perms & AA_MAY_WRITE)
yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive."));
mode |= AA_MAY_APPEND;
perms |= AA_MAY_APPEND;
break;
case COD_LINK_CHAR:
PDEBUG("Parsing mode: found %s LINK\n", mode_desc);
mode |= AA_OLD_MAY_LINK;
PDEBUG("Parsing perms: found %s LINK\n", perms_desc);
perms |= AA_OLD_MAY_LINK;
break;
case COD_LOCK_CHAR:
PDEBUG("Parsing mode: found %s LOCK\n", mode_desc);
mode |= AA_OLD_MAY_LOCK;
PDEBUG("Parsing perms: found %s LOCK\n", perms_desc);
perms |= AA_OLD_MAY_LOCK;
break;
case COD_INHERIT_CHAR:
PDEBUG("Parsing mode: found INHERIT\n");
if (mode & AA_EXEC_MODIFIERS) {
PDEBUG("Parsing perms: found INHERIT\n");
if (perms & AA_EXEC_MODIFIERS) {
yyerror(_("Exec qualifier 'i' invalid, conflicting qualifier already specified"));
} else {
if (next != tolower(next))
warn_uppercase();
mode |= (AA_EXEC_INHERIT | AA_MAY_EXEC);
perms |= (AA_EXEC_INHERIT | AA_MAY_EXEC);
p++; /* skip 'x' */
}
break;
case COD_UNSAFE_UNCONFINED_CHAR:
tmode = AA_EXEC_UNSAFE;
tperms = AA_EXEC_UNSAFE;
pwarn(WARN_DANGEROUS, _("Unconfined exec qualifier (%c%c) allows some dangerous environment variables "
"to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n"),
COD_UNSAFE_UNCONFINED_CHAR, COD_EXEC_CHAR);
/* fall through */
case COD_UNCONFINED_CHAR:
tmode |= AA_EXEC_UNCONFINED | AA_MAY_EXEC;
PDEBUG("Parsing mode: found UNCONFINED\n");
if (IS_DIFF_QUAL(mode, tmode)) {
tperms |= AA_EXEC_UNCONFINED | AA_MAY_EXEC;
PDEBUG("Parsing perms: found UNCONFINED\n");
if (IS_DIFF_QUAL(perms, tperms)) {
yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"),
thisc);
} else {
if (next != tolower(next))
warn_uppercase();
mode |= tmode;
perms |= tperms;
p++; /* skip 'x' */
}
tmode = 0;
tperms = 0;
break;
case COD_UNSAFE_PROFILE_CHAR:
case COD_UNSAFE_LOCAL_CHAR:
tmode = AA_EXEC_UNSAFE;
tperms = AA_EXEC_UNSAFE;
/* fall through */
case COD_PROFILE_CHAR:
case COD_LOCAL_CHAR:
if (tolower(thisc) == COD_UNSAFE_PROFILE_CHAR)
tmode |= AA_EXEC_PROFILE | AA_MAY_EXEC;
tperms |= AA_EXEC_PROFILE | AA_MAY_EXEC;
else
{
tmode |= AA_EXEC_LOCAL | AA_MAY_EXEC;
tperms |= AA_EXEC_LOCAL | AA_MAY_EXEC;
}
PDEBUG("Parsing mode: found PROFILE\n");
PDEBUG("Parsing perms: found PROFILE\n");
if (tolower(next) == COD_INHERIT_CHAR) {
tmode |= AA_EXEC_INHERIT;
if (IS_DIFF_QUAL(mode, tmode)) {
tperms |= AA_EXEC_INHERIT;
if (IS_DIFF_QUAL(perms, tperms)) {
yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next);
} else {
mode |= tmode;
perms |= tperms;
p += 2; /* skip x */
}
} else if (tolower(next) == COD_UNSAFE_UNCONFINED_CHAR) {
tmode |= AA_EXEC_PUX;
if (IS_DIFF_QUAL(mode, tmode)) {
tperms |= AA_EXEC_PUX;
if (IS_DIFF_QUAL(perms, tperms)) {
yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next);
} else {
mode |= tmode;
perms |= tperms;
p += 2; /* skip x */
}
} else if (IS_DIFF_QUAL(mode, tmode)) {
} else if (IS_DIFF_QUAL(perms, tperms)) {
yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"), thisc);
} else {
if (next != tolower(next))
warn_uppercase();
mode |= tmode;
perms |= tperms;
p++; /* skip 'x' */
}
tmode = 0;
tperms = 0;
break;
case COD_MMAP_CHAR:
PDEBUG("Parsing mode: found %s MMAP\n", mode_desc);
mode |= AA_OLD_EXEC_MMAP;
PDEBUG("Parsing perms: found %s MMAP\n", perms_desc);
perms |= AA_OLD_EXEC_MMAP;
break;
case COD_EXEC_CHAR:
@ -680,7 +680,7 @@ reeval:
* but invalid for regular x transitions
* sort it out later.
*/
mode |= AA_MAY_EXEC;
perms |= AA_MAY_EXEC;
break;
/* error cases */
@ -695,13 +695,13 @@ reeval:
case COD_INHERIT_CHAR:
case COD_MMAP_CHAR:
case COD_EXEC_CHAR:
PDEBUG("Parsing mode: found invalid upper case char %c\n", thisc);
PDEBUG("Parsing perms: found invalid upper case char %c\n", thisc);
warn_uppercase();
thisc = lower;
goto reeval;
break;
default:
yyerror(_("Internal: unexpected mode character '%c' in input"),
yyerror(_("Internal: unexpected perms character '%c' in input"),
thisc);
break;
}
@ -711,33 +711,33 @@ reeval:
p++;
}
PDEBUG("Parsed mode: %s 0x%x\n", str_mode, mode);
PDEBUG("Parsed perms: %s 0x%x\n", str_perms, perms);
return mode;
return perms;
}
int parse_mode(const char *str_mode)
perms_t parse_perms(const char *str_perms)
{
int tmp, mode = 0;
tmp = parse_sub_mode(str_mode, "");
mode = SHIFT_MODE(tmp, AA_USER_SHIFT);
mode |= SHIFT_MODE(tmp, AA_OTHER_SHIFT);
if (mode & ~AA_VALID_PERMS)
yyerror(_("Internal error generated invalid perm 0x%llx\n"), mode);
return mode;
perms_t tmp, perms = 0;
tmp = parse_sub_perms(str_perms, "");
perms = SHIFT_PERMS(tmp, AA_USER_SHIFT);
perms |= SHIFT_PERMS(tmp, AA_OTHER_SHIFT);
if (perms & ~AA_VALID_PERMS)
yyerror(_("Internal error generated invalid perm 0x%llx\n"), perms);
return perms;
}
static int parse_X_sub_mode(const char *X, const char *str_mode, int *result, int fail, const char *mode_desc unused)
static int parse_X_sub_perms(const char *X, const char *str_perms, perms_t *result, int fail, const char *perms_desc unused)
{
int mode = 0;
perms_t perms = 0;
const char *p;
PDEBUG("Parsing %s mode: %s\n", X, str_mode);
PDEBUG("Parsing %s perms: %s\n", X, str_perms);
if (!str_mode)
if (!str_perms)
return 0;
p = str_mode;
p = str_perms;
while (*p) {
char current = *p;
char lower;
@ -745,14 +745,14 @@ static int parse_X_sub_mode(const char *X, const char *str_mode, int *result, in
reeval:
switch (current) {
case COD_READ_CHAR:
PDEBUG("Parsing %s mode: found %s READ\n", X, mode_desc);
mode |= AA_DBUS_RECEIVE;
PDEBUG("Parsing %s perms: found %s READ\n", X, perms_desc);
perms |= AA_DBUS_RECEIVE;
break;
case COD_WRITE_CHAR:
PDEBUG("Parsing %s mode: found %s WRITE\n", X,
mode_desc);
mode |= AA_DBUS_SEND;
PDEBUG("Parsing %s perms: found %s WRITE\n", X,
perms_desc);
perms |= AA_DBUS_SEND;
break;
/* error cases */
@ -762,7 +762,7 @@ reeval:
switch (lower) {
case COD_READ_CHAR:
case COD_WRITE_CHAR:
PDEBUG("Parsing %s mode: found invalid upper case char %c\n",
PDEBUG("Parsing %s perms: found invalid upper case char %c\n",
X, current);
warn_uppercase();
current = lower;
@ -770,7 +770,7 @@ reeval:
break;
default:
if (fail)
yyerror(_("Internal: unexpected %s mode character '%c' in input"),
yyerror(_("Internal: unexpected %s perms character '%c' in input"),
X, current);
else
return 0;
@ -781,21 +781,21 @@ reeval:
p++;
}
PDEBUG("Parsed %s mode: %s 0x%x\n", X, str_mode, mode);
PDEBUG("Parsed %s perms: %s 0x%x\n", X, str_perms, perms);
*result = mode;
*result = perms;
return 1;
}
int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail)
int parse_X_perms(const char *X, int valid, const char *str_perms, perms_t *perms, int fail)
{
*mode = 0;
if (!parse_X_sub_mode(X, str_mode, mode, fail, ""))
*perms = 0;
if (!parse_X_sub_perms(X, str_perms, perms, fail, ""))
return 0;
if (*mode & ~valid) {
if (*perms & ~valid) {
if (fail)
yyerror(_("Internal error generated invalid %s perm 0x%x\n"),
X, mode);
X, perms);
else
return 0;
}
@ -950,7 +950,7 @@ alloc_fail:
return false;
}
struct cod_entry *new_entry(char *id, int mode, char *link_id)
struct cod_entry *new_entry(char *id, perms_t perms, char *link_id)
{
struct cod_entry *entry = NULL;
@ -960,7 +960,7 @@ struct cod_entry *new_entry(char *id, int mode, char *link_id)
entry->name = id;
entry->link_name = link_id;
entry->mode = mode;
entry->perms = perms;
entry->audit = 0;
entry->deny = FALSE;
@ -984,7 +984,7 @@ struct cod_entry *copy_cod_entry(struct cod_entry *orig)
DUP_STRING(orig, entry, name, err);
DUP_STRING(orig, entry, link_name, err);
DUP_STRING(orig, entry, nt_name, err);
entry->mode = orig->mode;
entry->perms = orig->perms;
entry->audit = orig->audit;
entry->deny = orig->deny;
@ -1043,20 +1043,20 @@ void debug_cod_entries(struct cod_entry *list)
printf("--- Entries ---\n");
list_for_each(list, item) {
printf("Mode:\t");
if (HAS_CHANGE_PROFILE(item->mode))
printf("Perms:\t");
if (HAS_CHANGE_PROFILE(item->perms))
printf(" change_profile");
if (HAS_EXEC_UNSAFE(item->mode))
if (HAS_EXEC_UNSAFE(item->perms))
printf(" unsafe");
debug_base_perm_mask(SHIFT_TO_BASE(item->mode, AA_USER_SHIFT));
debug_base_perm_mask(SHIFT_TO_BASE(item->perms, AA_USER_SHIFT));
printf(":");
debug_base_perm_mask(SHIFT_TO_BASE(item->mode, AA_OTHER_SHIFT));
debug_base_perm_mask(SHIFT_TO_BASE(item->perms, AA_OTHER_SHIFT));
if (item->name)
printf("\tName:\t(%s)\n", item->name);
else
printf("\tName:\tNULL\n");
if (AA_LINK_BITS & item->mode)
if (AA_LINK_BITS & item->perms)
printf("\tlink:\t(%s)\n", item->link_name ? item->link_name : "/**");
}

View file

@ -101,10 +101,10 @@ static int add_named_transition(Profile *prof, struct cod_entry *entry)
free(entry->nt_name);
entry->nt_name = NULL;
return AA_EXEC_LOCAL >> 10;
} else if (((entry->mode & AA_USER_EXEC_MODIFIERS) ==
SHIFT_MODE(AA_EXEC_LOCAL, AA_USER_SHIFT)) ||
((entry->mode & AA_OTHER_EXEC_MODIFIERS) ==
SHIFT_MODE(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) {
} else if (((entry->perms & AA_USER_EXEC_MODIFIERS) ==
SHIFT_PERMS(AA_EXEC_LOCAL, AA_USER_SHIFT)) ||
((entry->perms & AA_OTHER_EXEC_MODIFIERS) ==
SHIFT_PERMS(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) {
if (strcmp(entry->nt_name, entry->name) == 0) {
free(entry->nt_name);
entry->nt_name = NULL;
@ -199,31 +199,31 @@ static bool add_proc_access(Profile *prof, const char *rule)
void post_process_file_entries(Profile *prof)
{
struct cod_entry *entry;
int cp_mode = 0;
perms_t cp_perms = 0;
list_for_each(prof->entries, entry) {
if (entry->nt_name) {
int mode = 0;
perms_t perms = 0;
int n = add_named_transition(prof, entry);
if (!n) {
PERROR("Profile %s has too many specified profile transitions.\n", prof->name);
exit(1);
}
if (entry->mode & AA_USER_EXEC)
mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT);
if (entry->mode & AA_OTHER_EXEC)
mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT);
entry->mode = ((entry->mode & ~AA_ALL_EXEC_MODIFIERS) |
(mode & AA_ALL_EXEC_MODIFIERS));
if (entry->perms & AA_USER_EXEC)
perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT);
if (entry->perms & AA_OTHER_EXEC)
perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT);
entry->perms = ((entry->perms & ~AA_ALL_EXEC_MODIFIERS) |
(perms & AA_ALL_EXEC_MODIFIERS));
}
/* FIXME: currently change_profile also implies onexec */
cp_mode |= entry->mode & (AA_CHANGE_PROFILE);
cp_perms |= entry->perms & (AA_CHANGE_PROFILE);
}
/* if there are change_profile rules, this implies that we need
* access to some /proc/ interfaces
*/
if (cp_mode & AA_CHANGE_PROFILE) {
if (cp_perms & AA_CHANGE_PROFILE) {
if (!add_proc_access(prof, CHANGEPROFILE_PATH))
exit(1);
}

View file

@ -575,7 +575,7 @@ build:
static int warn_change_profile = 1;
static bool is_change_profile_mode(int mode)
static bool is_change_profile_perms(perms_t perms)
{
/**
* A change_profile entry will have the AA_CHANGE_PROFILE bit set.
@ -583,13 +583,13 @@ static bool is_change_profile_mode(int mode)
* set by the frontend parser. That means that it is incorrect to
* identify change_profile modes using a test like this:
*
* (mode & ~AA_CHANGE_PROFILE)
* (perms & ~AA_CHANGE_PROFILE)
*
* The above test would incorrectly return true on a
* change_profile mode that has the
* (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE) bits set.
*/
return mode & AA_CHANGE_PROFILE;
return perms & AA_CHANGE_PROFILE;
}
static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
@ -602,7 +602,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
return TRUE;
if (!is_change_profile_mode(entry->mode))
if (!is_change_profile_perms(entry->perms))
filter_slashes(entry->name);
ptype = convert_aaregex_to_pcre(entry->name, 0, glob_default, tbuf, &pos);
if (ptype == ePatternInvalid)
@ -613,10 +613,10 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
/* ix implies m but the apparmor module does not add m bit to
* dfa states like it does for pcre
*/
if ((entry->mode >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT)
entry->mode |= AA_OLD_EXEC_MMAP << AA_OTHER_SHIFT;
if ((entry->mode >> AA_USER_SHIFT) & AA_EXEC_INHERIT)
entry->mode |= AA_OLD_EXEC_MMAP << AA_USER_SHIFT;
if ((entry->perms >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT)
entry->perms |= AA_OLD_EXEC_MMAP << AA_OTHER_SHIFT;
if ((entry->perms >> AA_USER_SHIFT) & AA_EXEC_INHERIT)
entry->perms |= AA_OLD_EXEC_MMAP << AA_USER_SHIFT;
/* the link bit on the first pair entry should not get masked
* out by a deny rule, as both pieces of the link pair must
@ -628,23 +628,23 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
* TODO: split link and change_profile entries earlier
*/
if (entry->deny) {
if ((entry->mode & ~AA_LINK_BITS) &&
!is_change_profile_mode(entry->mode) &&
if ((entry->perms & ~AA_LINK_BITS) &&
!is_change_profile_perms(entry->perms) &&
!dfarules->add_rule(tbuf.c_str(), entry->deny,
entry->mode & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
entry->audit & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
dfaflags))
return FALSE;
} else if (!is_change_profile_mode(entry->mode)) {
if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->mode,
} else if (!is_change_profile_perms(entry->perms)) {
if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms,
entry->audit, dfaflags))
return FALSE;
}
if (entry->mode & (AA_LINK_BITS)) {
if (entry->perms & (AA_LINK_BITS)) {
/* add the pair rule */
std::string lbuf;
int perms = AA_LINK_BITS & entry->mode;
int perms = AA_LINK_BITS & entry->perms;
const char *vec[2];
int pos;
vec[0] = tbuf.c_str();
@ -663,7 +663,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags, false))
return FALSE;
}
if (is_change_profile_mode(entry->mode)) {
if (is_change_profile_perms(entry->perms)) {
const char *vec[3];
std::string lbuf, xbuf;
autofree char *ns = NULL;
@ -725,7 +725,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry)
* pick up any exec bits, from the frontend parser, related to
* unsafe exec transitions
*/
onexec_perms |= (entry->mode & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE));
onexec_perms |= (entry->perms & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE));
if (!dfarules->add_rule_vec(entry->deny, onexec_perms,
0, index, vec, dfaflags, false))
return FALSE;

View file

@ -63,10 +63,10 @@
int parser_token = 0;
struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt);
struct cod_entry *do_file_rule(char *id, perms_t perms, char *link_id, char *nt);
mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
struct cond_entry *dst_conds, char *dst,
int mode);
perms_t perms);
mnt_rule *do_pivot_rule(struct cond_entry *old, char *root,
char *transition);
static void abi_features(char *filename, bool search);
@ -202,7 +202,7 @@ void add_local_entry(Profile *prof);
mqueue_rule *mqueue_entry;
flagvals flags;
int fmode;
perms_t fperms;
uint64_t cap;
unsigned int allowed_protocol;
char *set_var;
@ -220,7 +220,7 @@ void add_local_entry(Profile *prof);
%type <id> TOK_CONDID
%type <id> TOK_CONDLISTID
%type <mode> TOK_MODE
%type <fmode> file_mode
%type <fperms> file_perms
%type <prof> profile_base
%type <prof> profile
%type <prof> rules
@ -259,33 +259,33 @@ void add_local_entry(Profile *prof);
%type <boolean> opt_perm_mode
%type <id> opt_id
%type <prefix> opt_prefix
%type <fmode> dbus_perm
%type <fmode> dbus_perms
%type <fmode> opt_dbus_perm
%type <fperms> dbus_perm
%type <fperms> dbus_perms
%type <fperms> opt_dbus_perm
%type <dbus_entry> dbus_rule
%type <fmode> signal_perm
%type <fmode> signal_perms
%type <fmode> opt_signal_perm
%type <fperms> signal_perm
%type <fperms> signal_perms
%type <fperms> opt_signal_perm
%type <signal_entry> signal_rule
%type <fmode> ptrace_perm
%type <fmode> ptrace_perms
%type <fmode> opt_ptrace_perm
%type <fperms> ptrace_perm
%type <fperms> ptrace_perms
%type <fperms> opt_ptrace_perm
%type <ptrace_entry> ptrace_rule
%type <fmode> net_perm
%type <fmode> net_perms
%type <fmode> opt_net_perm
%type <fperms> net_perm
%type <fperms> net_perms
%type <fperms> opt_net_perm
%type <unix_entry> unix_rule
%type <id> opt_target
%type <id> opt_named_transition
%type <boolean> opt_exec_mode
%type <boolean> opt_file
%type <fmode> userns_perm
%type <fmode> userns_perms
%type <fmode> opt_userns_perm
%type <fperms> userns_perm
%type <fperms> userns_perms
%type <fperms> opt_userns_perm
%type <userns_entry> userns_rule
%type <fmode> mqueue_perm
%type <fmode> mqueue_perms
%type <fmode> opt_mqueue_perm
%type <fperms> mqueue_perm
%type <fperms> mqueue_perms
%type <fperms> opt_mqueue_perm
%type <mqueue_entry> mqueue_rule
%%
@ -686,21 +686,21 @@ rules: rules opt_prefix rule
if (!$3)
yyerror(_("Assert: `rule' returned NULL."));
$3->deny = $2.deny;
if (($2.deny && ($3->mode & AA_EXEC_BITS) &&
($3->mode & ALL_AA_EXEC_TYPE)))
yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
else if (!$2.deny && ($3->mode & AA_EXEC_BITS) &&
!($3->mode & ALL_AA_EXEC_TYPE) &&
if (($2.deny && ($3->perms & AA_EXEC_BITS) &&
($3->perms & ALL_AA_EXEC_TYPE)))
yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
else if (!$2.deny && ($3->perms & AA_EXEC_BITS) &&
!($3->perms & ALL_AA_EXEC_TYPE) &&
!($3->nt_name))
yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'"));
yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'"));
if ($2.owner == 1)
$3->mode &= (AA_USER_PERMS | AA_SHARED_PERMS);
$3->perms &= (AA_USER_PERMS | AA_SHARED_PERMS);
else if ($2.owner == 2)
$3->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
$3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
/* only set audit ctl quieting if the rule is not audited */
if (($2.deny && !$2.audit) || (!$2.deny && $2.audit))
$3->audit = $3->mode & ~ALL_AA_EXEC_TYPE;
$3->audit = $3->perms & ~ALL_AA_EXEC_TYPE;
add_entry_to_policy($1, $3);
$$ = $1;
@ -717,23 +717,23 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE
$2.deny ? "deny " : "", $2.owner ? "owner " : "");
list_for_each_safe($4->entries, entry, tmp) {
entry->next = NULL;
if (entry->mode & AA_EXEC_BITS) {
if (entry->perms & AA_EXEC_BITS) {
if (entry->deny &&
(entry->mode & ALL_AA_EXEC_TYPE))
yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
(entry->perms & ALL_AA_EXEC_TYPE))
yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
else if (!entry->deny &&
!(entry->mode & ALL_AA_EXEC_TYPE))
yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"));
!(entry->perms & ALL_AA_EXEC_TYPE))
yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"));
}
if ($2.owner == 1)
entry->mode &= (AA_USER_PERMS | AA_SHARED_PERMS);
entry->perms &= (AA_USER_PERMS | AA_SHARED_PERMS);
else if ($2.owner == 2)
entry->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
if ($2.audit && !entry->deny)
entry->audit = entry->mode & ~ALL_AA_EXEC_TYPE;
entry->audit = entry->perms & ~ALL_AA_EXEC_TYPE;
else if (!$2.audit && entry->deny)
entry->audit = entry->mode & ~ALL_AA_EXEC_TYPE;
entry->audit = entry->perms & ~ALL_AA_EXEC_TYPE;
add_entry_to_policy($1, entry);
}
$4->entries = NULL;
@ -817,9 +817,9 @@ rules: rules opt_prefix dbus_rule
$3->deny = 1;
} else if ($2.deny) {
$3->deny = 1;
$3->audit = $3->mode;
$3->audit = $3->perms;
} else if ($2.audit) {
$3->audit = $3->mode;
$3->audit = $3->perms;
}
$1->rule_ents.push_back($3);
$$ = $1;
@ -833,9 +833,9 @@ rules: rules opt_prefix signal_rule
$3->deny = 1;
} else if ($2.deny) {
$3->deny = 1;
$3->audit = $3->mode;
$3->audit = $3->perms;
} else if ($2.audit) {
$3->audit = $3->mode;
$3->audit = $3->perms;
}
$1->rule_ents.push_back($3);
$$ = $1;
@ -849,9 +849,9 @@ rules: rules opt_prefix ptrace_rule
$3->deny = 1;
} else if ($2.deny) {
$3->deny = 1;
$3->audit = $3->mode;
$3->audit = $3->perms;
} else if ($2.audit) {
$3->audit = $3->mode;
$3->audit = $3->perms;
}
$1->rule_ents.push_back($3);
$$ = $1;
@ -865,9 +865,9 @@ rules: rules opt_prefix unix_rule
$3->deny = 1;
} else if ($2.deny) {
$3->deny = 1;
$3->audit = $3->mode;
$3->audit = $3->perms;
} else if ($2.audit) {
$3->audit = $3->mode;
$3->audit = $3->perms;
}
$1->rule_ents.push_back($3);
$$ = $1;
@ -881,9 +881,9 @@ rules: rules opt_prefix userns_rule
$3->deny = 1;
} else if ($2.deny) {
$3->deny = 1;
$3->audit = $3->mode;
$3->audit = $3->perms;
} else if ($2.audit) {
$3->audit = $3->mode;
$3->audit = $3->perms;
}
$1->rule_ents.push_back($3);
$$ = $1;
@ -901,9 +901,9 @@ rules: rules opt_prefix change_profile
$3->deny = 1;
} else if ($2.deny) {
$3->deny = 1;
$3->audit = $3->mode;
$3->audit = $3->perms;
} else if ($2.audit) {
$3->audit = $3->mode;
$3->audit = $3->perms;
}
add_entry_to_policy($1, $3);
$$ = $1;
@ -936,9 +936,9 @@ rules: rules opt_prefix mqueue_rule
$3->deny = 1;
} else if ($2.deny) {
$3->deny = 1;
$3->audit = $3->mode;
$3->audit = $3->perms;
} else if ($2.audit) {
$3->audit = $3->mode;
$3->audit = $3->perms;
}
$1->rule_ents.push_back($3);
$$ = $1;
@ -1183,12 +1183,12 @@ opt_exec_mode: { /* nothing */ $$ = EXEC_MODE_EMPTY; }
opt_file: { /* nothing */ $$ = 0; }
| TOK_FILE { $$ = 1; }
frule: id_or_var file_mode opt_named_transition TOK_END_OF_RULE
frule: id_or_var file_perms opt_named_transition TOK_END_OF_RULE
{
$$ = do_file_rule($1, $2, NULL, $3);
};
frule: file_mode opt_subset_flag id_or_var opt_named_transition TOK_END_OF_RULE
frule: file_perms opt_subset_flag id_or_var opt_named_transition TOK_END_OF_RULE
{
if ($2 && ($1 & ~AA_LINK_BITS))
yyerror(_("subset can only be used with link rules."));
@ -1223,19 +1223,19 @@ file_rule: TOK_FILE TOK_END_OF_RULE
file_rule_tail: opt_exec_mode frule
{
if ($1 != EXEC_MODE_EMPTY) {
if (!($2->mode & AA_EXEC_BITS))
if (!($2->perms & AA_EXEC_BITS))
yyerror(_("unsafe rule missing exec permissions"));
if ($1 == EXEC_MODE_UNSAFE) {
$2->mode |= (($2->mode & AA_EXEC_BITS) << 8) &
$2->perms |= (($2->perms & AA_EXEC_BITS) << 8) &
ALL_AA_EXEC_UNSAFE;
}
else if ($1 == EXEC_MODE_SAFE)
$2->mode &= ~ALL_AA_EXEC_UNSAFE;
$2->perms &= ~ALL_AA_EXEC_UNSAFE;
}
$$ = $2;
};
file_rule_tail: opt_exec_mode id_or_var file_mode id_or_var
file_rule_tail: opt_exec_mode id_or_var file_perms id_or_var
{
/* Oopsie, we appear to be missing an EOL marker. If we
* were *smart*, we could work around it. Since we're
@ -1387,7 +1387,7 @@ dbus_perm: TOK_VALUE
else if (strcmp($1, "eavesdrop") == 0)
$$ = AA_DBUS_EAVESDROP;
else if ($1) {
parse_dbus_mode($1, &$$, 1);
parse_dbus_perms($1, &$$, 1);
} else
$$ = 0;
@ -1402,7 +1402,7 @@ dbus_perm: TOK_VALUE
| TOK_EAVESDROP { $$ = AA_DBUS_EAVESDROP; }
| TOK_MODE
{
parse_dbus_mode($1, &$$, 1);
parse_dbus_perms($1, &$$, 1);
free($1);
}
@ -1457,7 +1457,7 @@ net_perm: TOK_VALUE
else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
$$ = AA_NET_RECEIVE;
else if ($1) {
parse_net_mode($1, &$$, 1);
parse_net_perms($1, &$$, 1);
} else
$$ = 0;
@ -1480,7 +1480,7 @@ net_perm: TOK_VALUE
| TOK_WRITE { $$ = AA_NET_SEND; }
| TOK_MODE
{
parse_unix_mode($1, &$$, 1);
parse_unix_perms($1, &$$, 1);
free($1);
}
@ -1515,7 +1515,7 @@ signal_perm: TOK_VALUE
else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
$$ = AA_MAY_RECEIVE;
else if ($1) {
parse_signal_mode($1, &$$, 1);
parse_signal_perms($1, &$$, 1);
} else
$$ = 0;
@ -1528,7 +1528,7 @@ signal_perm: TOK_VALUE
| TOK_WRITE { $$ = AA_MAY_SEND; }
| TOK_MODE
{
parse_signal_mode($1, &$$, 1);
parse_signal_perms($1, &$$, 1);
free($1);
}
@ -1557,7 +1557,7 @@ ptrace_perm: TOK_VALUE
else if (strcmp($1, "readby") == 0)
$$ = AA_MAY_READBY;
else if ($1)
parse_ptrace_mode($1, &$$, 1);
parse_ptrace_perms($1, &$$, 1);
else
$$ = 0;
@ -1571,7 +1571,7 @@ ptrace_perm: TOK_VALUE
| TOK_READBY { $$ = AA_MAY_READBY; }
| TOK_MODE
{
parse_ptrace_mode($1, &$$, 1);
parse_ptrace_perms($1, &$$, 1);
free($1);
}
@ -1632,7 +1632,7 @@ mqueue_perm: TOK_VALUE
else if (strcmp($1, "read") == 0)
$$ = AA_MQUEUE_READ;
else if ($1) {
parse_mqueue_mode($1, &$$, 1);
parse_mqueue_perms($1, &$$, 1);
} else
$$ = 0;
@ -1648,7 +1648,7 @@ mqueue_perm: TOK_VALUE
| TOK_READ { $$ = AA_MQUEUE_READ; }
| TOK_MODE
{
parse_mqueue_mode($1, &$$, 1);
parse_mqueue_perms($1, &$$, 1);
free($1);
}
@ -1674,18 +1674,18 @@ mqueue_rule: TOK_MQUEUE opt_mqueue_perm opt_conds TOK_END_OF_RULE
hat_start: TOK_CARET {}
| TOK_HAT {}
file_mode: TOK_MODE
file_perms: TOK_MODE
{
/* A single TOK_MODE maps to the same permission in all
* of user::other */
$$ = parse_mode($1);
$$ = parse_perms($1);
free($1);
}
change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK_END_OF_RULE
{
struct cod_entry *entry;
int mode = AA_CHANGE_PROFILE;
perms_t perms = AA_CHANGE_PROFILE;
int exec_mode = $2;
char *exec = $3;
char *target = $4;
@ -1694,9 +1694,9 @@ change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK
/* exec bits required to trigger rule conflict if
* for overlapping safe and unsafe exec rules
*/
mode |= AA_EXEC_BITS;
perms |= AA_EXEC_BITS;
if (exec_mode == EXEC_MODE_UNSAFE)
mode |= ALL_AA_EXEC_UNSAFE;
perms |= ALL_AA_EXEC_UNSAFE;
else if (exec_mode == EXEC_MODE_SAFE &&
!features_supports_stacking) {
pwarn(WARN_RULE_DOWNGRADED, "downgrading change_profile safe rule to unsafe due to lack of necessary kernel support\n");
@ -1720,7 +1720,7 @@ change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK
yyerror(_("Memory allocation error."));
}
entry = new_entry(target, mode, exec);
entry = new_entry(target, perms, exec);
if (!entry)
yyerror(_("Memory allocation error."));
@ -1793,11 +1793,11 @@ void yyerror(const char *msg, ...)
exit(1);
}
struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt)
struct cod_entry *do_file_rule(char *id, perms_t perms, char *link_id, char *nt)
{
struct cod_entry *entry;
PDEBUG("Matched: tok_id (%s) tok_mode (0x%x)\n", id, mode);
entry = new_entry(id, mode, link_id);
PDEBUG("Matched: tok_id (%s) tok_perms (0x%x)\n", id, perms);
entry = new_entry(id, perms, link_id);
if (!entry)
yyerror(_("Memory allocation error."));
entry->nt_name = nt;
@ -1811,7 +1811,7 @@ struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt)
void add_local_entry(Profile *prof)
{
/* ugh this has to be called after the hat is attached to its parent */
if (prof->local_mode) {
if (prof->local_perms) {
struct cod_entry *entry;
char *trans = (char *) malloc(strlen(prof->parent->name) +
strlen(prof->name) + 3);
@ -1820,7 +1820,7 @@ void add_local_entry(Profile *prof)
yyerror(_("Memory allocation error."));
sprintf(name, "%s//%s", prof->parent->name, prof->name);
entry = new_entry(name, prof->local_mode, NULL);
entry = new_entry(name, prof->local_perms, NULL);
entry->audit = prof->local_audit;
entry->nt_name = trans;
if (!entry)
@ -1859,7 +1859,7 @@ int verify_mnt_conds(struct cond_entry *conds, int src)
mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
struct cond_entry *dst_conds, char *dst,
int mode)
perms_t perms)
{
if (verify_mnt_conds(src_conds, MNT_SRC_OPT) != 0)
yyerror(_("bad mount rule"));
@ -1871,7 +1871,7 @@ mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
if (dst_conds)
yyerror(_("mount point conditions not currently supported"));
mnt_rule *ent = new mnt_rule(src_conds, src, dst_conds, dst, mode);
mnt_rule *ent = new mnt_rule(src_conds, src, dst_conds, dst, perms);
if (!ent) {
yyerror(_("Memory allocation error."));
}

View file

@ -190,7 +190,7 @@ public:
/* char *sub_name; */ /* subdomain name or NULL */
/* int default_deny; */ /* TRUE or FALSE */
int local;
int local_mode; /* true if local, not hat */
perms_t local_perms;
int local_audit;
Profile *parent;
@ -221,7 +221,8 @@ public:
xattrs.list = NULL;
xattrs.name = NULL;
local = local_mode = local_audit = 0;
local_perms = 0;
local = local_audit = 0;
parent = NULL;

View file

@ -24,9 +24,9 @@
#include <string>
#include <sstream>
int parse_ptrace_mode(const char *str_mode, int *mode, int fail)
int parse_ptrace_perms(const char *str_perms, perms_t *perms, int fail)
{
return parse_X_mode("ptrace", AA_VALID_PTRACE_PERMS, str_mode, mode, fail);
return parse_X_perms("ptrace", AA_VALID_PTRACE_PERMS, str_perms, perms, fail);
}
void ptrace_rule::move_conditionals(struct cond_entry *conds)
@ -47,15 +47,15 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds)
}
}
ptrace_rule::ptrace_rule(int mode_p, struct cond_entry *conds):
ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds):
peer_label(NULL), audit(0), deny(0)
{
if (mode_p) {
if (mode_p & ~AA_VALID_PTRACE_PERMS)
yyerror("mode contains invalid permissions for ptrace\n");
mode = mode_p;
if (perms_p) {
if (perms_p & ~AA_VALID_PTRACE_PERMS)
yyerror("perms contains invalid permissions for ptrace\n");
perms = perms_p;
} else {
mode = AA_VALID_PTRACE_PERMS;
perms = AA_VALID_PTRACE_PERMS;
}
move_conditionals(conds);
@ -71,16 +71,16 @@ ostream &ptrace_rule::dump(ostream &os)
os << "ptrace";
if (mode != AA_VALID_PTRACE_PERMS) {
if (perms != AA_VALID_PTRACE_PERMS) {
os << " (";
if (mode & AA_MAY_READ)
if (perms & AA_MAY_READ)
os << "read ";
if (mode & AA_MAY_READBY)
if (perms & AA_MAY_READBY)
os << "readby ";
if (mode & AA_MAY_TRACE)
if (perms & AA_MAY_TRACE)
os << "trace ";
if (mode & AA_MAY_TRACEDBY)
if (perms & AA_MAY_TRACEDBY)
os << "tracedby ";
os << ")";
}
@ -136,8 +136,8 @@ int ptrace_rule::gen_policy_re(Profile &prof)
}
buf = buffer.str();
if (mode & AA_VALID_PTRACE_PERMS) {
if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
if (perms & AA_VALID_PTRACE_PERMS) {
if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit,
dfaflags))
goto fail;
}

View file

@ -27,17 +27,17 @@
#define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \
AA_MAY_TRACEDBY)
int parse_ptrace_mode(const char *str_mode, int *mode, int fail);
int parse_ptrace_perms(const char *str_perms, perms_t *perms, int fail);
class ptrace_rule: public rule_t {
void move_conditionals(struct cond_entry *conds);
public:
char *peer_label;
int mode;
perms_t perms;
int audit;
int deny;
ptrace_rule(int mode, struct cond_entry *conds);
ptrace_rule(perms_t perms, struct cond_entry *conds);
virtual ~ptrace_rule()
{
free(peer_label);

View file

@ -116,9 +116,9 @@ static const char *const sig_names[MAXMAPPED_SIG + 1] = {
};
int parse_signal_mode(const char *str_mode, int *mode, int fail)
int parse_signal_perms(const char *str_perms, perms_t *perms, int fail)
{
return parse_X_mode("signal", AA_VALID_SIGNAL_PERMS, str_mode, mode, fail);
return parse_X_perms("signal", AA_VALID_SIGNAL_PERMS, str_perms, perms, fail);
}
static int find_signal_mapping(const char *sig)
@ -173,15 +173,15 @@ void signal_rule::move_conditionals(struct cond_entry *conds)
}
}
signal_rule::signal_rule(int mode_p, struct cond_entry *conds):
signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds):
signals(), peer_label(NULL), audit(0), deny(0)
{
if (mode_p) {
mode = mode_p;
if (mode & ~AA_VALID_SIGNAL_PERMS)
yyerror("mode contains invalid permission for signals\n");
if (perms_p) {
perms = perms_p;
if (perms & ~AA_VALID_SIGNAL_PERMS)
yyerror("perms contains invalid permission for signals\n");
} else {
mode = AA_VALID_SIGNAL_PERMS;
perms = AA_VALID_SIGNAL_PERMS;
}
move_conditionals(conds);
@ -198,12 +198,12 @@ ostream &signal_rule::dump(ostream &os)
os << "signal";
if (mode != AA_VALID_SIGNAL_PERMS) {
if (perms != AA_VALID_SIGNAL_PERMS) {
os << " (";
if (mode & AA_MAY_SEND)
if (perms & AA_MAY_SEND)
os << "send ";
if (mode & AA_MAY_RECEIVE)
if (perms & AA_MAY_RECEIVE)
os << "receive ";
os << ")";
}
@ -291,8 +291,8 @@ int signal_rule::gen_policy_re(Profile &prof)
}
buf = buffer.str();
if (mode & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit,
dfaflags))
goto fail;
}

View file

@ -31,7 +31,7 @@
typedef set<int> Signals;
int parse_signal_mode(const char *str_mode, int *mode, int fail);
int parse_signal_perms(const char *str_perms, perms_t *perms, int fail);
class signal_rule: public rule_t {
void extract_sigs(struct value_list **list);
@ -39,11 +39,11 @@ class signal_rule: public rule_t {
public:
Signals signals;
char *peer_label;
int mode;
perms_t perms;
int audit;
int deny;
signal_rule(int mode, struct cond_entry *conds);
signal_rule(perms_t perms, struct cond_entry *conds);
virtual ~signal_rule() {
signals.clear();
free(peer_label);

View file

@ -40,17 +40,17 @@ void userns_rule::move_conditionals(struct cond_entry *conds)
}
}
userns_rule::userns_rule(int mode_p, struct cond_entry *conds):
userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds):
audit(0), deny(0)
{
if (mode_p) {
if (mode_p & ~AA_VALID_USERNS_PERMS)
yyerror("mode contains invalid permissions for userns\n");
mode = mode_p;
if (perms_p) {
if (perms_p & ~AA_VALID_USERNS_PERMS)
yyerror("perms contains invalid permissions for userns\n");
perms = perms_p;
} else {
/* default to all perms */
mode = AA_VALID_USERNS_PERMS;
perms = AA_VALID_USERNS_PERMS;
}
move_conditionals(conds);
@ -66,8 +66,8 @@ ostream &userns_rule::dump(ostream &os)
os << "userns ";
if (mode != AA_VALID_USERNS_PERMS) {
if (mode & AA_USERNS_CREATE)
if (perms != AA_VALID_USERNS_PERMS) {
if (perms & AA_USERNS_CREATE)
os << "create ";
}
@ -99,8 +99,8 @@ int userns_rule::gen_policy_re(Profile &prof)
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NS;
buf = buffer.str();
if (mode & AA_VALID_USERNS_PERMS) {
if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
if (perms & AA_VALID_USERNS_PERMS) {
if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit,
dfaflags))
goto fail;
}

View file

@ -26,11 +26,11 @@
class userns_rule: public rule_t {
void move_conditionals(struct cond_entry *conds);
public:
int mode;
perms_t perms;
int audit;
int deny;
userns_rule(int mode, struct cond_entry *conds);
userns_rule(perms_t perms, struct cond_entry *conds);
virtual ~userns_rule()
{
};