mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 01:57:43 +00:00
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:
parent
b255ff8831
commit
fd9a6fe133
@ -101,32 +101,32 @@ ostream &af_rule::dump_prefix(ostream &os)
|
|||||||
|
|
||||||
ostream &af_rule::dump_local(ostream &os)
|
ostream &af_rule::dump_local(ostream &os)
|
||||||
{
|
{
|
||||||
if (mode != AA_VALID_NET_PERMS) {
|
if (perms != AA_VALID_NET_PERMS) {
|
||||||
os << " (";
|
os << " (";
|
||||||
|
|
||||||
if (mode & AA_NET_SEND)
|
if (perms & AA_NET_SEND)
|
||||||
os << "send ";
|
os << "send ";
|
||||||
if (mode & AA_NET_RECEIVE)
|
if (perms & AA_NET_RECEIVE)
|
||||||
os << "receive ";
|
os << "receive ";
|
||||||
if (mode & AA_NET_CREATE)
|
if (perms & AA_NET_CREATE)
|
||||||
os << "create ";
|
os << "create ";
|
||||||
if (mode & AA_NET_SHUTDOWN)
|
if (perms & AA_NET_SHUTDOWN)
|
||||||
os << "shutdown ";
|
os << "shutdown ";
|
||||||
if (mode & AA_NET_CONNECT)
|
if (perms & AA_NET_CONNECT)
|
||||||
os << "connect ";
|
os << "connect ";
|
||||||
if (mode & AA_NET_SETATTR)
|
if (perms & AA_NET_SETATTR)
|
||||||
os << "setattr ";
|
os << "setattr ";
|
||||||
if (mode & AA_NET_GETATTR)
|
if (perms & AA_NET_GETATTR)
|
||||||
os << "getattr ";
|
os << "getattr ";
|
||||||
if (mode & AA_NET_BIND)
|
if (perms & AA_NET_BIND)
|
||||||
os << "bind ";
|
os << "bind ";
|
||||||
if (mode & AA_NET_ACCEPT)
|
if (perms & AA_NET_ACCEPT)
|
||||||
os << "accept ";
|
os << "accept ";
|
||||||
if (mode & AA_NET_LISTEN)
|
if (perms & AA_NET_LISTEN)
|
||||||
os << "listen ";
|
os << "listen ";
|
||||||
if (mode & AA_NET_SETOPT)
|
if (perms & AA_NET_SETOPT)
|
||||||
os << "setopt ";
|
os << "setopt ";
|
||||||
if (mode & AA_NET_GETOPT)
|
if (perms & AA_NET_GETOPT)
|
||||||
os << "getopt ";
|
os << "getopt ";
|
||||||
os << ")";
|
os << ")";
|
||||||
}
|
}
|
||||||
|
@ -44,13 +44,13 @@ public:
|
|||||||
int proto_n;
|
int proto_n;
|
||||||
char *label;
|
char *label;
|
||||||
char *peer_label;
|
char *peer_label;
|
||||||
int mode;
|
perms_t perms;
|
||||||
int audit;
|
int audit;
|
||||||
bool deny;
|
bool deny;
|
||||||
|
|
||||||
af_rule(const char *name): af_name(name), sock_type(NULL),
|
af_rule(const char *name): af_name(name), sock_type(NULL),
|
||||||
sock_type_n(-1), proto(NULL), proto_n(0), label(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()
|
virtual ~af_rule()
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
/* See unix(7) for autobind address definition */
|
/* 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]";
|
#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)
|
if (!sock_type)
|
||||||
yyerror("socket rule: invalid socket type '%d'", type_p);
|
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;
|
audit = audit_p ? AA_VALID_NET_PERMS : 0;
|
||||||
deny = denied;
|
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):
|
struct cond_entry *peer_conds):
|
||||||
af_rule("unix"), addr(NULL), peer_addr(NULL)
|
af_rule("unix"), addr(NULL), peer_addr(NULL)
|
||||||
{
|
{
|
||||||
move_conditionals(conds);
|
move_conditionals(conds);
|
||||||
move_peer_conditionals(peer_conds);
|
move_peer_conditionals(peer_conds);
|
||||||
|
|
||||||
if (mode_p) {
|
if (perms_p) {
|
||||||
mode = mode_p;
|
perms = perms_p;
|
||||||
if (mode & ~AA_VALID_NET_PERMS)
|
if (perms & ~AA_VALID_NET_PERMS)
|
||||||
yyerror("mode contains invalid permissions for unix socket rules\n");
|
yyerror("perms contains invalid permissions for unix socket rules\n");
|
||||||
else if ((mode & ~AA_PEER_NET_PERMS) && has_peer_conds())
|
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");
|
yyerror("unix socket 'create', 'shutdown', 'setattr', 'getattr', 'bind', 'listen', 'setopt', and/or 'getopt' accesses cannot be used with peer socket conditionals\n");
|
||||||
} else {
|
} else {
|
||||||
mode = AA_VALID_NET_PERMS;
|
perms = AA_VALID_NET_PERMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_cond_list(conds);
|
free_cond_list(conds);
|
||||||
@ -187,7 +187,7 @@ static void writeu16(std::ostringstream &o, int v)
|
|||||||
#define CMD_OPT 4
|
#define CMD_OPT 4
|
||||||
|
|
||||||
void unix_rule::downgrade_rule(Profile &prof) {
|
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())
|
if (!prof.net.allow && !prof.alloc_net_table())
|
||||||
yyerror(_("Memory allocation error."));
|
yyerror(_("Memory allocation error."));
|
||||||
@ -309,7 +309,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
|||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
std::string buf;
|
std::string buf;
|
||||||
|
|
||||||
int mask = mode;
|
perms_t mask = perms;
|
||||||
|
|
||||||
/* always generate a downgraded rule. This doesn't change generated
|
/* always generate a downgraded rule. This doesn't change generated
|
||||||
* policy size and allows the binary policy to be loaded against
|
* 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;
|
goto fail;
|
||||||
|
|
||||||
buf = buffer.str();
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#include "af_rule.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 {
|
class unix_rule: public af_rule {
|
||||||
void write_to_prot(std::ostringstream &buffer);
|
void write_to_prot(std::ostringstream &buffer);
|
||||||
@ -38,7 +38,7 @@ public:
|
|||||||
char *peer_addr;
|
char *peer_addr;
|
||||||
|
|
||||||
unix_rule(unsigned int type_p, bool audit_p, bool denied);
|
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);
|
struct cond_entry *peer_conds);
|
||||||
virtual ~unix_rule()
|
virtual ~unix_rule()
|
||||||
{
|
{
|
||||||
|
@ -30,9 +30,9 @@
|
|||||||
#include "dbus.h"
|
#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)
|
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):
|
struct cond_entry *peer_conds):
|
||||||
bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL),
|
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;
|
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)
|
if (message_rule && service_rule)
|
||||||
yyerror("dbus rule contains message conditionals and service conditionals\n");
|
yyerror("dbus rule contains message conditionals and service conditionals\n");
|
||||||
|
|
||||||
/* Copy mode. If no mode was specified, assign an implied mode. */
|
/* Copy perms. If no perms was specified, assign an implied perms. */
|
||||||
if (mode_p) {
|
if (perms_p) {
|
||||||
mode = mode_p;
|
perms = perms_p;
|
||||||
if (mode & ~AA_VALID_DBUS_PERMS)
|
if (perms & ~AA_VALID_DBUS_PERMS)
|
||||||
yyerror("mode contains unknown dbus access\n");
|
yyerror("perms contains unknown dbus access\n");
|
||||||
else if (message_rule && (mode & AA_DBUS_BIND))
|
else if (message_rule && (perms & AA_DBUS_BIND))
|
||||||
yyerror("dbus \"bind\" access cannot be used with message rule conditionals\n");
|
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");
|
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 ||
|
(path || interface || member ||
|
||||||
peer_label || name)) {
|
peer_label || name)) {
|
||||||
yyerror("dbus \"eavesdrop\" access can only contain a bus conditional\n");
|
yyerror("dbus \"eavesdrop\" access can only contain a bus conditional\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (message_rule)
|
if (message_rule)
|
||||||
mode = (AA_DBUS_SEND | AA_DBUS_RECEIVE);
|
perms = (AA_DBUS_SEND | AA_DBUS_RECEIVE);
|
||||||
else if (service_rule)
|
else if (service_rule)
|
||||||
mode = (AA_DBUS_BIND);
|
perms = (AA_DBUS_BIND);
|
||||||
else
|
else
|
||||||
mode = AA_VALID_DBUS_PERMS;
|
perms = AA_VALID_DBUS_PERMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_cond_list(conds);
|
free_cond_list(conds);
|
||||||
@ -129,19 +129,19 @@ ostream &dbus_rule::dump(ostream &os)
|
|||||||
|
|
||||||
os << "dbus ( ";
|
os << "dbus ( ";
|
||||||
|
|
||||||
if (mode & AA_DBUS_SEND)
|
if (perms & AA_DBUS_SEND)
|
||||||
os << "send ";
|
os << "send ";
|
||||||
if (mode & AA_DBUS_RECEIVE)
|
if (perms & AA_DBUS_RECEIVE)
|
||||||
os << "receive ";
|
os << "receive ";
|
||||||
if (mode & AA_DBUS_BIND)
|
if (perms & AA_DBUS_BIND)
|
||||||
os << "bind ";
|
os << "bind ";
|
||||||
if (mode & AA_DBUS_EAVESDROP)
|
if (perms & AA_DBUS_EAVESDROP)
|
||||||
os << "eavesdrop ";
|
os << "eavesdrop ";
|
||||||
os << ")";
|
os << ")";
|
||||||
|
|
||||||
if (bus)
|
if (bus)
|
||||||
os << " bus=\"" << bus << "\"";
|
os << " bus=\"" << bus << "\"";
|
||||||
if ((mode & AA_DBUS_BIND) && name)
|
if ((perms & AA_DBUS_BIND) && name)
|
||||||
os << " name=\"" << name << "\"";
|
os << " name=\"" << name << "\"";
|
||||||
if (path)
|
if (path)
|
||||||
os << " path=\"" << path << "\"";
|
os << " path=\"" << path << "\"";
|
||||||
@ -150,7 +150,7 @@ ostream &dbus_rule::dump(ostream &os)
|
|||||||
if (member)
|
if (member)
|
||||||
os << " member=\"" << member << "\"";
|
os << " member=\"" << member << "\"";
|
||||||
|
|
||||||
if (!(mode & AA_DBUS_BIND) && (peer_label || name)) {
|
if (!(perms & AA_DBUS_BIND) && (peer_label || name)) {
|
||||||
os << " peer=( ";
|
os << " peer=( ";
|
||||||
if (peer_label)
|
if (peer_label)
|
||||||
os << "label=\"" << peer_label << "\" ";
|
os << "label=\"" << peer_label << "\" ";
|
||||||
@ -277,22 +277,22 @@ int dbus_rule::gen_policy_re(Profile &prof)
|
|||||||
vec[5] = default_match_pattern;
|
vec[5] = default_match_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode & AA_DBUS_BIND) {
|
if (perms & AA_DBUS_BIND) {
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_BIND,
|
if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND,
|
||||||
audit & AA_DBUS_BIND,
|
audit & AA_DBUS_BIND,
|
||||||
2, vec, dfaflags, false))
|
2, vec, dfaflags, false))
|
||||||
goto fail;
|
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,
|
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),
|
audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE),
|
||||||
6, vec, dfaflags, false))
|
6, vec, dfaflags, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (mode & AA_DBUS_EAVESDROP) {
|
if (perms & AA_DBUS_EAVESDROP) {
|
||||||
if (!prof.policy.rules->add_rule_vec(deny,
|
if (!prof.policy.rules->add_rule_vec(deny,
|
||||||
mode & AA_DBUS_EAVESDROP,
|
perms & AA_DBUS_EAVESDROP,
|
||||||
audit & AA_DBUS_EAVESDROP,
|
audit & AA_DBUS_EAVESDROP,
|
||||||
1, vec, dfaflags, false))
|
1, vec, dfaflags, false))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
#include "profile.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 {
|
class dbus_rule: public rule_t {
|
||||||
void move_conditionals(struct cond_entry *conds);
|
void move_conditionals(struct cond_entry *conds);
|
||||||
@ -39,11 +39,11 @@ public:
|
|||||||
char *path;
|
char *path;
|
||||||
char *interface;
|
char *interface;
|
||||||
char *member;
|
char *member;
|
||||||
int mode;
|
perms_t perms;
|
||||||
int audit;
|
int audit;
|
||||||
int deny;
|
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);
|
struct cond_entry *peer_conds);
|
||||||
virtual ~dbus_rule() {
|
virtual ~dbus_rule() {
|
||||||
free(bus);
|
free(bus);
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
#define AA_LINK_BITS ((AA_OLD_MAY_LINK << AA_USER_SHIFT) | \
|
#define AA_LINK_BITS ((AA_OLD_MAY_LINK << AA_USER_SHIFT) | \
|
||||||
(AA_OLD_MAY_LINK << AA_OTHER_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))
|
| ((MODE) & ~AA_FILE_PERMS))
|
||||||
#define SHIFT_TO_BASE(MODE, SHIFT) ((((MODE) & AA_FILE_PERMS) >> (SHIFT))\
|
#define SHIFT_TO_BASE(MODE, SHIFT) ((((MODE) & AA_FILE_PERMS) >> (SHIFT))\
|
||||||
| ((MODE) & ~AA_FILE_PERMS))
|
| ((MODE) & ~AA_FILE_PERMS))
|
||||||
|
@ -1057,7 +1057,7 @@ fail:
|
|||||||
void mnt_rule::post_process(Profile &prof)
|
void mnt_rule::post_process(Profile &prof)
|
||||||
{
|
{
|
||||||
if (trans) {
|
if (trans) {
|
||||||
unsigned int mode = 0;
|
perms_t perms = 0;
|
||||||
int n = add_entry_to_x_table(&prof, trans);
|
int n = add_entry_to_x_table(&prof, trans);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
PERROR("Profile %s has too many specified profile transitions.\n", prof.name);
|
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)
|
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)
|
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) |
|
allow = ((allow & ~AA_ALL_EXEC_MODIFIERS) |
|
||||||
(mode & AA_ALL_EXEC_MODIFIERS));
|
(perms & AA_ALL_EXEC_MODIFIERS));
|
||||||
|
|
||||||
trans = NULL;
|
trans = NULL;
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#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)
|
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)
|
qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(0), deny(0)
|
||||||
{
|
{
|
||||||
move_conditionals(conds);
|
move_conditionals(conds);
|
||||||
@ -94,20 +94,20 @@ mqueue_rule::mqueue_rule(int mode_p, struct cond_entry *conds, char *qname_p):
|
|||||||
|
|
||||||
if (qname)
|
if (qname)
|
||||||
validate_qname();
|
validate_qname();
|
||||||
if (mode_p) {
|
if (perms_p) {
|
||||||
// do we want to allow perms to imply type like we do for
|
// do we want to allow perms to imply type like we do for
|
||||||
// qname?
|
// qname?
|
||||||
if (qtype == mqueue_posix && (mode_p & ~AA_VALID_POSIX_MQ_PERMS)) {
|
if (qtype == mqueue_posix && (perms_p & ~AA_VALID_POSIX_MQ_PERMS)) {
|
||||||
yyerror("mode contains invalid permissions for mqueue type=posix\n");
|
yyerror("perms contains invalid permissions for mqueue type=posix\n");
|
||||||
} else if (qtype == mqueue_sysv && (mode_p & ~AA_VALID_SYSV_MQ_PERMS)) {
|
} else if (qtype == mqueue_sysv && (perms_p & ~AA_VALID_SYSV_MQ_PERMS)) {
|
||||||
yyerror("mode contains invalid permissions for mqueue type=sysv\n");
|
yyerror("perms contains invalid permissions for mqueue type=sysv\n");
|
||||||
} else if (mode_p & ~AA_VALID_MQUEUE_PERMS) {
|
} else if (perms_p & ~AA_VALID_MQUEUE_PERMS) {
|
||||||
yyerror("mode contains invalid permissions for mqueue\n");
|
yyerror("perms contains invalid permissions for mqueue\n");
|
||||||
}
|
}
|
||||||
mode = mode_p;
|
perms = perms_p;
|
||||||
} else {
|
} else {
|
||||||
// default to all perms
|
// default to all perms
|
||||||
mode = AA_VALID_MQUEUE_PERMS;
|
perms = AA_VALID_MQUEUE_PERMS;
|
||||||
}
|
}
|
||||||
qname = qname_p;
|
qname = qname_p;
|
||||||
|
|
||||||
@ -129,22 +129,22 @@ ostream &mqueue_rule::dump(ostream &os)
|
|||||||
else if (qtype == mqueue_sysv)
|
else if (qtype == mqueue_sysv)
|
||||||
os << "type=sysv";
|
os << "type=sysv";
|
||||||
|
|
||||||
if (mode != AA_VALID_MQUEUE_PERMS) {
|
if (perms != AA_VALID_MQUEUE_PERMS) {
|
||||||
os << "(";
|
os << "(";
|
||||||
|
|
||||||
if (mode & AA_MQUEUE_WRITE)
|
if (perms & AA_MQUEUE_WRITE)
|
||||||
os << "write ";
|
os << "write ";
|
||||||
if (mode & AA_MQUEUE_READ)
|
if (perms & AA_MQUEUE_READ)
|
||||||
os << "read ";
|
os << "read ";
|
||||||
if (mode & AA_MQUEUE_OPEN)
|
if (perms & AA_MQUEUE_OPEN)
|
||||||
os << "open ";
|
os << "open ";
|
||||||
if (mode & AA_MQUEUE_CREATE)
|
if (perms & AA_MQUEUE_CREATE)
|
||||||
os << "create ";
|
os << "create ";
|
||||||
if (mode & AA_MQUEUE_DELETE)
|
if (perms & AA_MQUEUE_DELETE)
|
||||||
os << "delete ";
|
os << "delete ";
|
||||||
if (mode & AA_MQUEUE_SETATTR)
|
if (perms & AA_MQUEUE_SETATTR)
|
||||||
os << "setattr ";
|
os << "setattr ";
|
||||||
if (mode & AA_MQUEUE_GETATTR)
|
if (perms & AA_MQUEUE_GETATTR)
|
||||||
os << "getattr ";
|
os << "getattr ";
|
||||||
|
|
||||||
os << ")";
|
os << ")";
|
||||||
@ -229,14 +229,14 @@ int mqueue_rule::gen_policy_re(Profile &prof)
|
|||||||
vec[1] = anyone_match_pattern;
|
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
|
/* store perms at name match so label doesn't need
|
||||||
* to be checked
|
* 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;
|
goto fail;
|
||||||
/* also provide label match with perm */
|
/* 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;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,11 +267,11 @@ int mqueue_rule::gen_policy_re(Profile &prof)
|
|||||||
vec[1] = anyone_match_pattern;
|
vec[1] = anyone_match_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode & AA_VALID_SYSV_MQ_PERMS) {
|
if (perms & AA_VALID_SYSV_MQ_PERMS) {
|
||||||
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;
|
goto fail;
|
||||||
/* also provide label match with perm */
|
/* 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;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ typedef enum mqueue_type {
|
|||||||
} 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 {
|
class mqueue_rule: public rule_t {
|
||||||
void move_conditionals(struct cond_entry *conds);
|
void move_conditionals(struct cond_entry *conds);
|
||||||
@ -87,11 +87,11 @@ public:
|
|||||||
mqueue_type qtype;
|
mqueue_type qtype;
|
||||||
char *qname;
|
char *qname;
|
||||||
char *label;
|
char *label;
|
||||||
int mode;
|
perms_t perms;
|
||||||
int audit;
|
int audit;
|
||||||
int deny;
|
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()
|
virtual ~mqueue_rule()
|
||||||
{
|
{
|
||||||
free(qname);
|
free(qname);
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
#include "network.h"
|
#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
|
/* Bleah C++ doesn't have non-trivial designated initializers so we just
|
||||||
|
@ -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,
|
extern struct aa_network_entry *new_network_ent(unsigned int family,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
unsigned int protocol);
|
unsigned int protocol);
|
||||||
|
@ -45,6 +45,8 @@ using namespace std;
|
|||||||
class Profile;
|
class Profile;
|
||||||
class rule_t;
|
class rule_t;
|
||||||
|
|
||||||
|
typedef uint32_t perms_t;
|
||||||
|
|
||||||
#define MODULE_NAME "apparmor"
|
#define MODULE_NAME "apparmor"
|
||||||
|
|
||||||
/* Global variable to pass token to lexer. Will be replaced by parameter
|
/* Global variable to pass token to lexer. Will be replaced by parameter
|
||||||
@ -127,8 +129,8 @@ struct cod_entry {
|
|||||||
char *nt_name;
|
char *nt_name;
|
||||||
Profile *prof; /* Special profile defined
|
Profile *prof; /* Special profile defined
|
||||||
* just for this executable */
|
* just for this executable */
|
||||||
int mode; /* mode is 'or' of AA_* bits */
|
perms_t perms; /* perms is 'or' of AA_* bits */
|
||||||
int audit; /* audit flags for mode */
|
int audit; /* audit flags for perms */
|
||||||
int deny; /* TRUE or FALSE */
|
int deny; /* TRUE or FALSE */
|
||||||
|
|
||||||
int alias_ignore; /* ignore for alias processing */
|
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_keyword_token(const char *keyword);
|
||||||
extern int get_rlimit(const char *name);
|
extern int get_rlimit(const char *name);
|
||||||
extern char *process_var(const char *var);
|
extern char *process_var(const char *var);
|
||||||
extern int parse_mode(const char *mode);
|
extern perms_t parse_perms(const char *permstr);
|
||||||
extern int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail);
|
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 label_contains_ns(const char *label);
|
||||||
bool parse_label(bool *_stack, char **_ns, char **_name,
|
bool parse_label(bool *_stack, char **_ns, char **_name,
|
||||||
const char *label, bool yyerr);
|
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 */
|
/* returns -1 if value != true or false, otherwise 0 == false, 1 == true */
|
||||||
extern int str_to_boolean(const char* str);
|
extern int str_to_boolean(const char* str);
|
||||||
|
@ -120,7 +120,7 @@ static void process_entries(const void *nodep, VISIT value, int level unused)
|
|||||||
len = strlen((*t)->from);
|
len = strlen((*t)->from);
|
||||||
|
|
||||||
list_for_each(target_list, entry) {
|
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;
|
continue;
|
||||||
if (entry->name && strncmp((*t)->from, entry->name, len) == 0) {
|
if (entry->name && strncmp((*t)->from, entry->name, len) == 0) {
|
||||||
char *n = do_alias(*t, entry->name);
|
char *n = do_alias(*t, entry->name);
|
||||||
|
@ -89,12 +89,12 @@ static int process_file_entries(Profile *prof)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check for merged x consistency */
|
/* 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"),
|
PERROR(_("profile %s: has merged rule %s with conflicting x modifiers\n"),
|
||||||
prof->name, cur->name);
|
prof->name, cur->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cur->mode |= next->mode;
|
cur->perms |= next->perms;
|
||||||
cur->audit |= next->audit;
|
cur->audit |= next->audit;
|
||||||
cur->next = next->next;
|
cur->next = next->next;
|
||||||
|
|
||||||
|
@ -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;
|
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;
|
return 0;
|
||||||
|
|
||||||
p = str_mode;
|
p = str_perms;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
char thisc = *p;
|
char thisc = *p;
|
||||||
char next = *(p + 1);
|
char next = *(p + 1);
|
||||||
char lower;
|
char lower;
|
||||||
int tmode = 0;
|
perms_t tperms = 0;
|
||||||
|
|
||||||
reeval:
|
reeval:
|
||||||
switch (thisc) {
|
switch (thisc) {
|
||||||
case COD_READ_CHAR:
|
case COD_READ_CHAR:
|
||||||
if (read_implies_exec) {
|
if (read_implies_exec) {
|
||||||
PDEBUG("Parsing mode: found %s READ imply X\n", mode_desc);
|
PDEBUG("Parsing perms: found %s READ imply X\n", perms_desc);
|
||||||
mode |= AA_MAY_READ | AA_OLD_EXEC_MMAP;
|
perms |= AA_MAY_READ | AA_OLD_EXEC_MMAP;
|
||||||
} else {
|
} else {
|
||||||
PDEBUG("Parsing mode: found %s READ\n", mode_desc);
|
PDEBUG("Parsing perms: found %s READ\n", perms_desc);
|
||||||
mode |= AA_MAY_READ;
|
perms |= AA_MAY_READ;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_WRITE_CHAR:
|
case COD_WRITE_CHAR:
|
||||||
PDEBUG("Parsing mode: found %s WRITE\n", mode_desc);
|
PDEBUG("Parsing perms: found %s WRITE\n", perms_desc);
|
||||||
if ((mode & AA_MAY_APPEND) && !(mode & AA_MAY_WRITE))
|
if ((perms & AA_MAY_APPEND) && !(perms & AA_MAY_WRITE))
|
||||||
yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive."));
|
yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive."));
|
||||||
mode |= AA_MAY_WRITE | AA_MAY_APPEND;
|
perms |= AA_MAY_WRITE | AA_MAY_APPEND;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_APPEND_CHAR:
|
case COD_APPEND_CHAR:
|
||||||
PDEBUG("Parsing mode: found %s APPEND\n", mode_desc);
|
PDEBUG("Parsing perms: found %s APPEND\n", perms_desc);
|
||||||
if (mode & AA_MAY_WRITE)
|
if (perms & AA_MAY_WRITE)
|
||||||
yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive."));
|
yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive."));
|
||||||
mode |= AA_MAY_APPEND;
|
perms |= AA_MAY_APPEND;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_LINK_CHAR:
|
case COD_LINK_CHAR:
|
||||||
PDEBUG("Parsing mode: found %s LINK\n", mode_desc);
|
PDEBUG("Parsing perms: found %s LINK\n", perms_desc);
|
||||||
mode |= AA_OLD_MAY_LINK;
|
perms |= AA_OLD_MAY_LINK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_LOCK_CHAR:
|
case COD_LOCK_CHAR:
|
||||||
PDEBUG("Parsing mode: found %s LOCK\n", mode_desc);
|
PDEBUG("Parsing perms: found %s LOCK\n", perms_desc);
|
||||||
mode |= AA_OLD_MAY_LOCK;
|
perms |= AA_OLD_MAY_LOCK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_INHERIT_CHAR:
|
case COD_INHERIT_CHAR:
|
||||||
PDEBUG("Parsing mode: found INHERIT\n");
|
PDEBUG("Parsing perms: found INHERIT\n");
|
||||||
if (mode & AA_EXEC_MODIFIERS) {
|
if (perms & AA_EXEC_MODIFIERS) {
|
||||||
yyerror(_("Exec qualifier 'i' invalid, conflicting qualifier already specified"));
|
yyerror(_("Exec qualifier 'i' invalid, conflicting qualifier already specified"));
|
||||||
} else {
|
} else {
|
||||||
if (next != tolower(next))
|
if (next != tolower(next))
|
||||||
warn_uppercase();
|
warn_uppercase();
|
||||||
mode |= (AA_EXEC_INHERIT | AA_MAY_EXEC);
|
perms |= (AA_EXEC_INHERIT | AA_MAY_EXEC);
|
||||||
p++; /* skip 'x' */
|
p++; /* skip 'x' */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_UNSAFE_UNCONFINED_CHAR:
|
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 "
|
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"),
|
"to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n"),
|
||||||
COD_UNSAFE_UNCONFINED_CHAR, COD_EXEC_CHAR);
|
COD_UNSAFE_UNCONFINED_CHAR, COD_EXEC_CHAR);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case COD_UNCONFINED_CHAR:
|
case COD_UNCONFINED_CHAR:
|
||||||
tmode |= AA_EXEC_UNCONFINED | AA_MAY_EXEC;
|
tperms |= AA_EXEC_UNCONFINED | AA_MAY_EXEC;
|
||||||
PDEBUG("Parsing mode: found UNCONFINED\n");
|
PDEBUG("Parsing perms: found UNCONFINED\n");
|
||||||
if (IS_DIFF_QUAL(mode, tmode)) {
|
if (IS_DIFF_QUAL(perms, tperms)) {
|
||||||
yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"),
|
yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"),
|
||||||
thisc);
|
thisc);
|
||||||
} else {
|
} else {
|
||||||
if (next != tolower(next))
|
if (next != tolower(next))
|
||||||
warn_uppercase();
|
warn_uppercase();
|
||||||
mode |= tmode;
|
perms |= tperms;
|
||||||
p++; /* skip 'x' */
|
p++; /* skip 'x' */
|
||||||
}
|
}
|
||||||
tmode = 0;
|
tperms = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_UNSAFE_PROFILE_CHAR:
|
case COD_UNSAFE_PROFILE_CHAR:
|
||||||
case COD_UNSAFE_LOCAL_CHAR:
|
case COD_UNSAFE_LOCAL_CHAR:
|
||||||
tmode = AA_EXEC_UNSAFE;
|
tperms = AA_EXEC_UNSAFE;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case COD_PROFILE_CHAR:
|
case COD_PROFILE_CHAR:
|
||||||
case COD_LOCAL_CHAR:
|
case COD_LOCAL_CHAR:
|
||||||
if (tolower(thisc) == COD_UNSAFE_PROFILE_CHAR)
|
if (tolower(thisc) == COD_UNSAFE_PROFILE_CHAR)
|
||||||
tmode |= AA_EXEC_PROFILE | AA_MAY_EXEC;
|
tperms |= AA_EXEC_PROFILE | AA_MAY_EXEC;
|
||||||
else
|
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) {
|
if (tolower(next) == COD_INHERIT_CHAR) {
|
||||||
tmode |= AA_EXEC_INHERIT;
|
tperms |= AA_EXEC_INHERIT;
|
||||||
if (IS_DIFF_QUAL(mode, tmode)) {
|
if (IS_DIFF_QUAL(perms, tperms)) {
|
||||||
yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next);
|
yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next);
|
||||||
} else {
|
} else {
|
||||||
mode |= tmode;
|
perms |= tperms;
|
||||||
p += 2; /* skip x */
|
p += 2; /* skip x */
|
||||||
}
|
}
|
||||||
} else if (tolower(next) == COD_UNSAFE_UNCONFINED_CHAR) {
|
} else if (tolower(next) == COD_UNSAFE_UNCONFINED_CHAR) {
|
||||||
tmode |= AA_EXEC_PUX;
|
tperms |= AA_EXEC_PUX;
|
||||||
if (IS_DIFF_QUAL(mode, tmode)) {
|
if (IS_DIFF_QUAL(perms, tperms)) {
|
||||||
yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next);
|
yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next);
|
||||||
} else {
|
} else {
|
||||||
mode |= tmode;
|
perms |= tperms;
|
||||||
p += 2; /* skip x */
|
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);
|
yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"), thisc);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (next != tolower(next))
|
if (next != tolower(next))
|
||||||
warn_uppercase();
|
warn_uppercase();
|
||||||
mode |= tmode;
|
perms |= tperms;
|
||||||
p++; /* skip 'x' */
|
p++; /* skip 'x' */
|
||||||
}
|
}
|
||||||
tmode = 0;
|
tperms = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_MMAP_CHAR:
|
case COD_MMAP_CHAR:
|
||||||
PDEBUG("Parsing mode: found %s MMAP\n", mode_desc);
|
PDEBUG("Parsing perms: found %s MMAP\n", perms_desc);
|
||||||
mode |= AA_OLD_EXEC_MMAP;
|
perms |= AA_OLD_EXEC_MMAP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_EXEC_CHAR:
|
case COD_EXEC_CHAR:
|
||||||
@ -680,7 +680,7 @@ reeval:
|
|||||||
* but invalid for regular x transitions
|
* but invalid for regular x transitions
|
||||||
* sort it out later.
|
* sort it out later.
|
||||||
*/
|
*/
|
||||||
mode |= AA_MAY_EXEC;
|
perms |= AA_MAY_EXEC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* error cases */
|
/* error cases */
|
||||||
@ -695,13 +695,13 @@ reeval:
|
|||||||
case COD_INHERIT_CHAR:
|
case COD_INHERIT_CHAR:
|
||||||
case COD_MMAP_CHAR:
|
case COD_MMAP_CHAR:
|
||||||
case COD_EXEC_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();
|
warn_uppercase();
|
||||||
thisc = lower;
|
thisc = lower;
|
||||||
goto reeval;
|
goto reeval;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
yyerror(_("Internal: unexpected mode character '%c' in input"),
|
yyerror(_("Internal: unexpected perms character '%c' in input"),
|
||||||
thisc);
|
thisc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -711,33 +711,33 @@ reeval:
|
|||||||
p++;
|
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;
|
perms_t tmp, perms = 0;
|
||||||
tmp = parse_sub_mode(str_mode, "");
|
tmp = parse_sub_perms(str_perms, "");
|
||||||
mode = SHIFT_MODE(tmp, AA_USER_SHIFT);
|
perms = SHIFT_PERMS(tmp, AA_USER_SHIFT);
|
||||||
mode |= SHIFT_MODE(tmp, AA_OTHER_SHIFT);
|
perms |= SHIFT_PERMS(tmp, AA_OTHER_SHIFT);
|
||||||
if (mode & ~AA_VALID_PERMS)
|
if (perms & ~AA_VALID_PERMS)
|
||||||
yyerror(_("Internal error generated invalid perm 0x%llx\n"), mode);
|
yyerror(_("Internal error generated invalid perm 0x%llx\n"), perms);
|
||||||
return mode;
|
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;
|
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;
|
return 0;
|
||||||
|
|
||||||
p = str_mode;
|
p = str_perms;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
char current = *p;
|
char current = *p;
|
||||||
char lower;
|
char lower;
|
||||||
@ -745,14 +745,14 @@ static int parse_X_sub_mode(const char *X, const char *str_mode, int *result, in
|
|||||||
reeval:
|
reeval:
|
||||||
switch (current) {
|
switch (current) {
|
||||||
case COD_READ_CHAR:
|
case COD_READ_CHAR:
|
||||||
PDEBUG("Parsing %s mode: found %s READ\n", X, mode_desc);
|
PDEBUG("Parsing %s perms: found %s READ\n", X, perms_desc);
|
||||||
mode |= AA_DBUS_RECEIVE;
|
perms |= AA_DBUS_RECEIVE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COD_WRITE_CHAR:
|
case COD_WRITE_CHAR:
|
||||||
PDEBUG("Parsing %s mode: found %s WRITE\n", X,
|
PDEBUG("Parsing %s perms: found %s WRITE\n", X,
|
||||||
mode_desc);
|
perms_desc);
|
||||||
mode |= AA_DBUS_SEND;
|
perms |= AA_DBUS_SEND;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* error cases */
|
/* error cases */
|
||||||
@ -762,7 +762,7 @@ reeval:
|
|||||||
switch (lower) {
|
switch (lower) {
|
||||||
case COD_READ_CHAR:
|
case COD_READ_CHAR:
|
||||||
case COD_WRITE_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);
|
X, current);
|
||||||
warn_uppercase();
|
warn_uppercase();
|
||||||
current = lower;
|
current = lower;
|
||||||
@ -770,7 +770,7 @@ reeval:
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (fail)
|
if (fail)
|
||||||
yyerror(_("Internal: unexpected %s mode character '%c' in input"),
|
yyerror(_("Internal: unexpected %s perms character '%c' in input"),
|
||||||
X, current);
|
X, current);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@ -781,21 +781,21 @@ reeval:
|
|||||||
p++;
|
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;
|
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;
|
*perms = 0;
|
||||||
if (!parse_X_sub_mode(X, str_mode, mode, fail, ""))
|
if (!parse_X_sub_perms(X, str_perms, perms, fail, ""))
|
||||||
return 0;
|
return 0;
|
||||||
if (*mode & ~valid) {
|
if (*perms & ~valid) {
|
||||||
if (fail)
|
if (fail)
|
||||||
yyerror(_("Internal error generated invalid %s perm 0x%x\n"),
|
yyerror(_("Internal error generated invalid %s perm 0x%x\n"),
|
||||||
X, mode);
|
X, perms);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -950,7 +950,7 @@ alloc_fail:
|
|||||||
return false;
|
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;
|
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->name = id;
|
||||||
entry->link_name = link_id;
|
entry->link_name = link_id;
|
||||||
entry->mode = mode;
|
entry->perms = perms;
|
||||||
entry->audit = 0;
|
entry->audit = 0;
|
||||||
entry->deny = FALSE;
|
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, name, err);
|
||||||
DUP_STRING(orig, entry, link_name, err);
|
DUP_STRING(orig, entry, link_name, err);
|
||||||
DUP_STRING(orig, entry, nt_name, err);
|
DUP_STRING(orig, entry, nt_name, err);
|
||||||
entry->mode = orig->mode;
|
entry->perms = orig->perms;
|
||||||
entry->audit = orig->audit;
|
entry->audit = orig->audit;
|
||||||
entry->deny = orig->deny;
|
entry->deny = orig->deny;
|
||||||
|
|
||||||
@ -1043,20 +1043,20 @@ void debug_cod_entries(struct cod_entry *list)
|
|||||||
printf("--- Entries ---\n");
|
printf("--- Entries ---\n");
|
||||||
|
|
||||||
list_for_each(list, item) {
|
list_for_each(list, item) {
|
||||||
printf("Mode:\t");
|
printf("Perms:\t");
|
||||||
if (HAS_CHANGE_PROFILE(item->mode))
|
if (HAS_CHANGE_PROFILE(item->perms))
|
||||||
printf(" change_profile");
|
printf(" change_profile");
|
||||||
if (HAS_EXEC_UNSAFE(item->mode))
|
if (HAS_EXEC_UNSAFE(item->perms))
|
||||||
printf(" unsafe");
|
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(":");
|
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)
|
if (item->name)
|
||||||
printf("\tName:\t(%s)\n", item->name);
|
printf("\tName:\t(%s)\n", item->name);
|
||||||
else
|
else
|
||||||
printf("\tName:\tNULL\n");
|
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 : "/**");
|
printf("\tlink:\t(%s)\n", item->link_name ? item->link_name : "/**");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -101,10 +101,10 @@ static int add_named_transition(Profile *prof, struct cod_entry *entry)
|
|||||||
free(entry->nt_name);
|
free(entry->nt_name);
|
||||||
entry->nt_name = NULL;
|
entry->nt_name = NULL;
|
||||||
return AA_EXEC_LOCAL >> 10;
|
return AA_EXEC_LOCAL >> 10;
|
||||||
} else if (((entry->mode & AA_USER_EXEC_MODIFIERS) ==
|
} else if (((entry->perms & AA_USER_EXEC_MODIFIERS) ==
|
||||||
SHIFT_MODE(AA_EXEC_LOCAL, AA_USER_SHIFT)) ||
|
SHIFT_PERMS(AA_EXEC_LOCAL, AA_USER_SHIFT)) ||
|
||||||
((entry->mode & AA_OTHER_EXEC_MODIFIERS) ==
|
((entry->perms & AA_OTHER_EXEC_MODIFIERS) ==
|
||||||
SHIFT_MODE(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) {
|
SHIFT_PERMS(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) {
|
||||||
if (strcmp(entry->nt_name, entry->name) == 0) {
|
if (strcmp(entry->nt_name, entry->name) == 0) {
|
||||||
free(entry->nt_name);
|
free(entry->nt_name);
|
||||||
entry->nt_name = NULL;
|
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)
|
void post_process_file_entries(Profile *prof)
|
||||||
{
|
{
|
||||||
struct cod_entry *entry;
|
struct cod_entry *entry;
|
||||||
int cp_mode = 0;
|
perms_t cp_perms = 0;
|
||||||
|
|
||||||
list_for_each(prof->entries, entry) {
|
list_for_each(prof->entries, entry) {
|
||||||
if (entry->nt_name) {
|
if (entry->nt_name) {
|
||||||
int mode = 0;
|
perms_t perms = 0;
|
||||||
int n = add_named_transition(prof, entry);
|
int n = add_named_transition(prof, entry);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
PERROR("Profile %s has too many specified profile transitions.\n", prof->name);
|
PERROR("Profile %s has too many specified profile transitions.\n", prof->name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (entry->mode & AA_USER_EXEC)
|
if (entry->perms & AA_USER_EXEC)
|
||||||
mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT);
|
perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT);
|
||||||
if (entry->mode & AA_OTHER_EXEC)
|
if (entry->perms & AA_OTHER_EXEC)
|
||||||
mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT);
|
perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT);
|
||||||
entry->mode = ((entry->mode & ~AA_ALL_EXEC_MODIFIERS) |
|
entry->perms = ((entry->perms & ~AA_ALL_EXEC_MODIFIERS) |
|
||||||
(mode & AA_ALL_EXEC_MODIFIERS));
|
(perms & AA_ALL_EXEC_MODIFIERS));
|
||||||
}
|
}
|
||||||
/* FIXME: currently change_profile also implies onexec */
|
/* 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
|
/* if there are change_profile rules, this implies that we need
|
||||||
* access to some /proc/ interfaces
|
* access to some /proc/ interfaces
|
||||||
*/
|
*/
|
||||||
if (cp_mode & AA_CHANGE_PROFILE) {
|
if (cp_perms & AA_CHANGE_PROFILE) {
|
||||||
if (!add_proc_access(prof, CHANGEPROFILE_PATH))
|
if (!add_proc_access(prof, CHANGEPROFILE_PATH))
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -575,7 +575,7 @@ build:
|
|||||||
|
|
||||||
static int warn_change_profile = 1;
|
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.
|
* 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
|
* set by the frontend parser. That means that it is incorrect to
|
||||||
* identify change_profile modes using a test like this:
|
* 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
|
* The above test would incorrectly return true on a
|
||||||
* change_profile mode that has the
|
* change_profile mode that has the
|
||||||
* (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE) bits set.
|
* (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)
|
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;
|
return TRUE;
|
||||||
|
|
||||||
|
|
||||||
if (!is_change_profile_mode(entry->mode))
|
if (!is_change_profile_perms(entry->perms))
|
||||||
filter_slashes(entry->name);
|
filter_slashes(entry->name);
|
||||||
ptype = convert_aaregex_to_pcre(entry->name, 0, glob_default, tbuf, &pos);
|
ptype = convert_aaregex_to_pcre(entry->name, 0, glob_default, tbuf, &pos);
|
||||||
if (ptype == ePatternInvalid)
|
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
|
/* ix implies m but the apparmor module does not add m bit to
|
||||||
* dfa states like it does for pcre
|
* dfa states like it does for pcre
|
||||||
*/
|
*/
|
||||||
if ((entry->mode >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT)
|
if ((entry->perms >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT)
|
||||||
entry->mode |= AA_OLD_EXEC_MMAP << AA_OTHER_SHIFT;
|
entry->perms |= AA_OLD_EXEC_MMAP << AA_OTHER_SHIFT;
|
||||||
if ((entry->mode >> AA_USER_SHIFT) & AA_EXEC_INHERIT)
|
if ((entry->perms >> AA_USER_SHIFT) & AA_EXEC_INHERIT)
|
||||||
entry->mode |= AA_OLD_EXEC_MMAP << AA_USER_SHIFT;
|
entry->perms |= AA_OLD_EXEC_MMAP << AA_USER_SHIFT;
|
||||||
|
|
||||||
/* the link bit on the first pair entry should not get masked
|
/* 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
|
* 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
|
* TODO: split link and change_profile entries earlier
|
||||||
*/
|
*/
|
||||||
if (entry->deny) {
|
if (entry->deny) {
|
||||||
if ((entry->mode & ~AA_LINK_BITS) &&
|
if ((entry->perms & ~AA_LINK_BITS) &&
|
||||||
!is_change_profile_mode(entry->mode) &&
|
!is_change_profile_perms(entry->perms) &&
|
||||||
!dfarules->add_rule(tbuf.c_str(), entry->deny,
|
!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),
|
entry->audit & ~(AA_LINK_BITS | AA_CHANGE_PROFILE),
|
||||||
dfaflags))
|
dfaflags))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (!is_change_profile_mode(entry->mode)) {
|
} else if (!is_change_profile_perms(entry->perms)) {
|
||||||
if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->mode,
|
if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms,
|
||||||
entry->audit, dfaflags))
|
entry->audit, dfaflags))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->mode & (AA_LINK_BITS)) {
|
if (entry->perms & (AA_LINK_BITS)) {
|
||||||
/* add the pair rule */
|
/* add the pair rule */
|
||||||
std::string lbuf;
|
std::string lbuf;
|
||||||
int perms = AA_LINK_BITS & entry->mode;
|
int perms = AA_LINK_BITS & entry->perms;
|
||||||
const char *vec[2];
|
const char *vec[2];
|
||||||
int pos;
|
int pos;
|
||||||
vec[0] = tbuf.c_str();
|
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))
|
if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags, false))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (is_change_profile_mode(entry->mode)) {
|
if (is_change_profile_perms(entry->perms)) {
|
||||||
const char *vec[3];
|
const char *vec[3];
|
||||||
std::string lbuf, xbuf;
|
std::string lbuf, xbuf;
|
||||||
autofree char *ns = NULL;
|
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
|
* pick up any exec bits, from the frontend parser, related to
|
||||||
* unsafe exec transitions
|
* 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,
|
if (!dfarules->add_rule_vec(entry->deny, onexec_perms,
|
||||||
0, index, vec, dfaflags, false))
|
0, index, vec, dfaflags, false))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -63,10 +63,10 @@
|
|||||||
|
|
||||||
int parser_token = 0;
|
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,
|
mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
|
||||||
struct cond_entry *dst_conds, char *dst,
|
struct cond_entry *dst_conds, char *dst,
|
||||||
int mode);
|
perms_t perms);
|
||||||
mnt_rule *do_pivot_rule(struct cond_entry *old, char *root,
|
mnt_rule *do_pivot_rule(struct cond_entry *old, char *root,
|
||||||
char *transition);
|
char *transition);
|
||||||
static void abi_features(char *filename, bool search);
|
static void abi_features(char *filename, bool search);
|
||||||
@ -202,7 +202,7 @@ void add_local_entry(Profile *prof);
|
|||||||
mqueue_rule *mqueue_entry;
|
mqueue_rule *mqueue_entry;
|
||||||
|
|
||||||
flagvals flags;
|
flagvals flags;
|
||||||
int fmode;
|
perms_t fperms;
|
||||||
uint64_t cap;
|
uint64_t cap;
|
||||||
unsigned int allowed_protocol;
|
unsigned int allowed_protocol;
|
||||||
char *set_var;
|
char *set_var;
|
||||||
@ -220,7 +220,7 @@ void add_local_entry(Profile *prof);
|
|||||||
%type <id> TOK_CONDID
|
%type <id> TOK_CONDID
|
||||||
%type <id> TOK_CONDLISTID
|
%type <id> TOK_CONDLISTID
|
||||||
%type <mode> TOK_MODE
|
%type <mode> TOK_MODE
|
||||||
%type <fmode> file_mode
|
%type <fperms> file_perms
|
||||||
%type <prof> profile_base
|
%type <prof> profile_base
|
||||||
%type <prof> profile
|
%type <prof> profile
|
||||||
%type <prof> rules
|
%type <prof> rules
|
||||||
@ -259,33 +259,33 @@ void add_local_entry(Profile *prof);
|
|||||||
%type <boolean> opt_perm_mode
|
%type <boolean> opt_perm_mode
|
||||||
%type <id> opt_id
|
%type <id> opt_id
|
||||||
%type <prefix> opt_prefix
|
%type <prefix> opt_prefix
|
||||||
%type <fmode> dbus_perm
|
%type <fperms> dbus_perm
|
||||||
%type <fmode> dbus_perms
|
%type <fperms> dbus_perms
|
||||||
%type <fmode> opt_dbus_perm
|
%type <fperms> opt_dbus_perm
|
||||||
%type <dbus_entry> dbus_rule
|
%type <dbus_entry> dbus_rule
|
||||||
%type <fmode> signal_perm
|
%type <fperms> signal_perm
|
||||||
%type <fmode> signal_perms
|
%type <fperms> signal_perms
|
||||||
%type <fmode> opt_signal_perm
|
%type <fperms> opt_signal_perm
|
||||||
%type <signal_entry> signal_rule
|
%type <signal_entry> signal_rule
|
||||||
%type <fmode> ptrace_perm
|
%type <fperms> ptrace_perm
|
||||||
%type <fmode> ptrace_perms
|
%type <fperms> ptrace_perms
|
||||||
%type <fmode> opt_ptrace_perm
|
%type <fperms> opt_ptrace_perm
|
||||||
%type <ptrace_entry> ptrace_rule
|
%type <ptrace_entry> ptrace_rule
|
||||||
%type <fmode> net_perm
|
%type <fperms> net_perm
|
||||||
%type <fmode> net_perms
|
%type <fperms> net_perms
|
||||||
%type <fmode> opt_net_perm
|
%type <fperms> opt_net_perm
|
||||||
%type <unix_entry> unix_rule
|
%type <unix_entry> unix_rule
|
||||||
%type <id> opt_target
|
%type <id> opt_target
|
||||||
%type <id> opt_named_transition
|
%type <id> opt_named_transition
|
||||||
%type <boolean> opt_exec_mode
|
%type <boolean> opt_exec_mode
|
||||||
%type <boolean> opt_file
|
%type <boolean> opt_file
|
||||||
%type <fmode> userns_perm
|
%type <fperms> userns_perm
|
||||||
%type <fmode> userns_perms
|
%type <fperms> userns_perms
|
||||||
%type <fmode> opt_userns_perm
|
%type <fperms> opt_userns_perm
|
||||||
%type <userns_entry> userns_rule
|
%type <userns_entry> userns_rule
|
||||||
%type <fmode> mqueue_perm
|
%type <fperms> mqueue_perm
|
||||||
%type <fmode> mqueue_perms
|
%type <fperms> mqueue_perms
|
||||||
%type <fmode> opt_mqueue_perm
|
%type <fperms> opt_mqueue_perm
|
||||||
%type <mqueue_entry> mqueue_rule
|
%type <mqueue_entry> mqueue_rule
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -686,21 +686,21 @@ rules: rules opt_prefix rule
|
|||||||
if (!$3)
|
if (!$3)
|
||||||
yyerror(_("Assert: `rule' returned NULL."));
|
yyerror(_("Assert: `rule' returned NULL."));
|
||||||
$3->deny = $2.deny;
|
$3->deny = $2.deny;
|
||||||
if (($2.deny && ($3->mode & AA_EXEC_BITS) &&
|
if (($2.deny && ($3->perms & AA_EXEC_BITS) &&
|
||||||
($3->mode & ALL_AA_EXEC_TYPE)))
|
($3->perms & ALL_AA_EXEC_TYPE)))
|
||||||
yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
|
yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
|
||||||
else if (!$2.deny && ($3->mode & AA_EXEC_BITS) &&
|
else if (!$2.deny && ($3->perms & AA_EXEC_BITS) &&
|
||||||
!($3->mode & ALL_AA_EXEC_TYPE) &&
|
!($3->perms & ALL_AA_EXEC_TYPE) &&
|
||||||
!($3->nt_name))
|
!($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)
|
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)
|
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 */
|
/* only set audit ctl quieting if the rule is not audited */
|
||||||
if (($2.deny && !$2.audit) || (!$2.deny && $2.audit))
|
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);
|
add_entry_to_policy($1, $3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -717,23 +717,23 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE
|
|||||||
$2.deny ? "deny " : "", $2.owner ? "owner " : "");
|
$2.deny ? "deny " : "", $2.owner ? "owner " : "");
|
||||||
list_for_each_safe($4->entries, entry, tmp) {
|
list_for_each_safe($4->entries, entry, tmp) {
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
if (entry->mode & AA_EXEC_BITS) {
|
if (entry->perms & AA_EXEC_BITS) {
|
||||||
if (entry->deny &&
|
if (entry->deny &&
|
||||||
(entry->mode & ALL_AA_EXEC_TYPE))
|
(entry->perms & ALL_AA_EXEC_TYPE))
|
||||||
yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
|
yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
|
||||||
else if (!entry->deny &&
|
else if (!entry->deny &&
|
||||||
!(entry->mode & ALL_AA_EXEC_TYPE))
|
!(entry->perms & ALL_AA_EXEC_TYPE))
|
||||||
yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"));
|
yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"));
|
||||||
}
|
}
|
||||||
if ($2.owner == 1)
|
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)
|
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)
|
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)
|
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);
|
add_entry_to_policy($1, entry);
|
||||||
}
|
}
|
||||||
$4->entries = NULL;
|
$4->entries = NULL;
|
||||||
@ -817,9 +817,9 @@ rules: rules opt_prefix dbus_rule
|
|||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
} else if ($2.deny) {
|
} else if ($2.deny) {
|
||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
} else if ($2.audit) {
|
} else if ($2.audit) {
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
}
|
}
|
||||||
$1->rule_ents.push_back($3);
|
$1->rule_ents.push_back($3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -833,9 +833,9 @@ rules: rules opt_prefix signal_rule
|
|||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
} else if ($2.deny) {
|
} else if ($2.deny) {
|
||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
} else if ($2.audit) {
|
} else if ($2.audit) {
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
}
|
}
|
||||||
$1->rule_ents.push_back($3);
|
$1->rule_ents.push_back($3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -849,9 +849,9 @@ rules: rules opt_prefix ptrace_rule
|
|||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
} else if ($2.deny) {
|
} else if ($2.deny) {
|
||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
} else if ($2.audit) {
|
} else if ($2.audit) {
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
}
|
}
|
||||||
$1->rule_ents.push_back($3);
|
$1->rule_ents.push_back($3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -865,9 +865,9 @@ rules: rules opt_prefix unix_rule
|
|||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
} else if ($2.deny) {
|
} else if ($2.deny) {
|
||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
} else if ($2.audit) {
|
} else if ($2.audit) {
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
}
|
}
|
||||||
$1->rule_ents.push_back($3);
|
$1->rule_ents.push_back($3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -881,9 +881,9 @@ rules: rules opt_prefix userns_rule
|
|||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
} else if ($2.deny) {
|
} else if ($2.deny) {
|
||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
} else if ($2.audit) {
|
} else if ($2.audit) {
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
}
|
}
|
||||||
$1->rule_ents.push_back($3);
|
$1->rule_ents.push_back($3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -901,9 +901,9 @@ rules: rules opt_prefix change_profile
|
|||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
} else if ($2.deny) {
|
} else if ($2.deny) {
|
||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
} else if ($2.audit) {
|
} else if ($2.audit) {
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
}
|
}
|
||||||
add_entry_to_policy($1, $3);
|
add_entry_to_policy($1, $3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -936,9 +936,9 @@ rules: rules opt_prefix mqueue_rule
|
|||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
} else if ($2.deny) {
|
} else if ($2.deny) {
|
||||||
$3->deny = 1;
|
$3->deny = 1;
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
} else if ($2.audit) {
|
} else if ($2.audit) {
|
||||||
$3->audit = $3->mode;
|
$3->audit = $3->perms;
|
||||||
}
|
}
|
||||||
$1->rule_ents.push_back($3);
|
$1->rule_ents.push_back($3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -1183,12 +1183,12 @@ opt_exec_mode: { /* nothing */ $$ = EXEC_MODE_EMPTY; }
|
|||||||
opt_file: { /* nothing */ $$ = 0; }
|
opt_file: { /* nothing */ $$ = 0; }
|
||||||
| TOK_FILE { $$ = 1; }
|
| 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);
|
$$ = 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))
|
if ($2 && ($1 & ~AA_LINK_BITS))
|
||||||
yyerror(_("subset can only be used with link rules."));
|
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
|
file_rule_tail: opt_exec_mode frule
|
||||||
{
|
{
|
||||||
if ($1 != EXEC_MODE_EMPTY) {
|
if ($1 != EXEC_MODE_EMPTY) {
|
||||||
if (!($2->mode & AA_EXEC_BITS))
|
if (!($2->perms & AA_EXEC_BITS))
|
||||||
yyerror(_("unsafe rule missing exec permissions"));
|
yyerror(_("unsafe rule missing exec permissions"));
|
||||||
if ($1 == EXEC_MODE_UNSAFE) {
|
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;
|
ALL_AA_EXEC_UNSAFE;
|
||||||
}
|
}
|
||||||
else if ($1 == EXEC_MODE_SAFE)
|
else if ($1 == EXEC_MODE_SAFE)
|
||||||
$2->mode &= ~ALL_AA_EXEC_UNSAFE;
|
$2->perms &= ~ALL_AA_EXEC_UNSAFE;
|
||||||
}
|
}
|
||||||
$$ = $2;
|
$$ = $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
|
/* Oopsie, we appear to be missing an EOL marker. If we
|
||||||
* were *smart*, we could work around it. Since we're
|
* were *smart*, we could work around it. Since we're
|
||||||
@ -1387,7 +1387,7 @@ dbus_perm: TOK_VALUE
|
|||||||
else if (strcmp($1, "eavesdrop") == 0)
|
else if (strcmp($1, "eavesdrop") == 0)
|
||||||
$$ = AA_DBUS_EAVESDROP;
|
$$ = AA_DBUS_EAVESDROP;
|
||||||
else if ($1) {
|
else if ($1) {
|
||||||
parse_dbus_mode($1, &$$, 1);
|
parse_dbus_perms($1, &$$, 1);
|
||||||
} else
|
} else
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
|
|
||||||
@ -1402,7 +1402,7 @@ dbus_perm: TOK_VALUE
|
|||||||
| TOK_EAVESDROP { $$ = AA_DBUS_EAVESDROP; }
|
| TOK_EAVESDROP { $$ = AA_DBUS_EAVESDROP; }
|
||||||
| TOK_MODE
|
| TOK_MODE
|
||||||
{
|
{
|
||||||
parse_dbus_mode($1, &$$, 1);
|
parse_dbus_perms($1, &$$, 1);
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1457,7 +1457,7 @@ net_perm: TOK_VALUE
|
|||||||
else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
|
else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
|
||||||
$$ = AA_NET_RECEIVE;
|
$$ = AA_NET_RECEIVE;
|
||||||
else if ($1) {
|
else if ($1) {
|
||||||
parse_net_mode($1, &$$, 1);
|
parse_net_perms($1, &$$, 1);
|
||||||
} else
|
} else
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
|
|
||||||
@ -1480,7 +1480,7 @@ net_perm: TOK_VALUE
|
|||||||
| TOK_WRITE { $$ = AA_NET_SEND; }
|
| TOK_WRITE { $$ = AA_NET_SEND; }
|
||||||
| TOK_MODE
|
| TOK_MODE
|
||||||
{
|
{
|
||||||
parse_unix_mode($1, &$$, 1);
|
parse_unix_perms($1, &$$, 1);
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1515,7 +1515,7 @@ signal_perm: TOK_VALUE
|
|||||||
else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
|
else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
|
||||||
$$ = AA_MAY_RECEIVE;
|
$$ = AA_MAY_RECEIVE;
|
||||||
else if ($1) {
|
else if ($1) {
|
||||||
parse_signal_mode($1, &$$, 1);
|
parse_signal_perms($1, &$$, 1);
|
||||||
} else
|
} else
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
|
|
||||||
@ -1528,7 +1528,7 @@ signal_perm: TOK_VALUE
|
|||||||
| TOK_WRITE { $$ = AA_MAY_SEND; }
|
| TOK_WRITE { $$ = AA_MAY_SEND; }
|
||||||
| TOK_MODE
|
| TOK_MODE
|
||||||
{
|
{
|
||||||
parse_signal_mode($1, &$$, 1);
|
parse_signal_perms($1, &$$, 1);
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1557,7 +1557,7 @@ ptrace_perm: TOK_VALUE
|
|||||||
else if (strcmp($1, "readby") == 0)
|
else if (strcmp($1, "readby") == 0)
|
||||||
$$ = AA_MAY_READBY;
|
$$ = AA_MAY_READBY;
|
||||||
else if ($1)
|
else if ($1)
|
||||||
parse_ptrace_mode($1, &$$, 1);
|
parse_ptrace_perms($1, &$$, 1);
|
||||||
else
|
else
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
|
|
||||||
@ -1571,7 +1571,7 @@ ptrace_perm: TOK_VALUE
|
|||||||
| TOK_READBY { $$ = AA_MAY_READBY; }
|
| TOK_READBY { $$ = AA_MAY_READBY; }
|
||||||
| TOK_MODE
|
| TOK_MODE
|
||||||
{
|
{
|
||||||
parse_ptrace_mode($1, &$$, 1);
|
parse_ptrace_perms($1, &$$, 1);
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1632,7 +1632,7 @@ mqueue_perm: TOK_VALUE
|
|||||||
else if (strcmp($1, "read") == 0)
|
else if (strcmp($1, "read") == 0)
|
||||||
$$ = AA_MQUEUE_READ;
|
$$ = AA_MQUEUE_READ;
|
||||||
else if ($1) {
|
else if ($1) {
|
||||||
parse_mqueue_mode($1, &$$, 1);
|
parse_mqueue_perms($1, &$$, 1);
|
||||||
} else
|
} else
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
|
|
||||||
@ -1648,7 +1648,7 @@ mqueue_perm: TOK_VALUE
|
|||||||
| TOK_READ { $$ = AA_MQUEUE_READ; }
|
| TOK_READ { $$ = AA_MQUEUE_READ; }
|
||||||
| TOK_MODE
|
| TOK_MODE
|
||||||
{
|
{
|
||||||
parse_mqueue_mode($1, &$$, 1);
|
parse_mqueue_perms($1, &$$, 1);
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1674,18 +1674,18 @@ mqueue_rule: TOK_MQUEUE opt_mqueue_perm opt_conds TOK_END_OF_RULE
|
|||||||
hat_start: TOK_CARET {}
|
hat_start: TOK_CARET {}
|
||||||
| TOK_HAT {}
|
| TOK_HAT {}
|
||||||
|
|
||||||
file_mode: TOK_MODE
|
file_perms: TOK_MODE
|
||||||
{
|
{
|
||||||
/* A single TOK_MODE maps to the same permission in all
|
/* A single TOK_MODE maps to the same permission in all
|
||||||
* of user::other */
|
* of user::other */
|
||||||
$$ = parse_mode($1);
|
$$ = parse_perms($1);
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
|
|
||||||
change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK_END_OF_RULE
|
change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK_END_OF_RULE
|
||||||
{
|
{
|
||||||
struct cod_entry *entry;
|
struct cod_entry *entry;
|
||||||
int mode = AA_CHANGE_PROFILE;
|
perms_t perms = AA_CHANGE_PROFILE;
|
||||||
int exec_mode = $2;
|
int exec_mode = $2;
|
||||||
char *exec = $3;
|
char *exec = $3;
|
||||||
char *target = $4;
|
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
|
/* exec bits required to trigger rule conflict if
|
||||||
* for overlapping safe and unsafe exec rules
|
* for overlapping safe and unsafe exec rules
|
||||||
*/
|
*/
|
||||||
mode |= AA_EXEC_BITS;
|
perms |= AA_EXEC_BITS;
|
||||||
if (exec_mode == EXEC_MODE_UNSAFE)
|
if (exec_mode == EXEC_MODE_UNSAFE)
|
||||||
mode |= ALL_AA_EXEC_UNSAFE;
|
perms |= ALL_AA_EXEC_UNSAFE;
|
||||||
else if (exec_mode == EXEC_MODE_SAFE &&
|
else if (exec_mode == EXEC_MODE_SAFE &&
|
||||||
!features_supports_stacking) {
|
!features_supports_stacking) {
|
||||||
pwarn(WARN_RULE_DOWNGRADED, "downgrading change_profile safe rule to unsafe due to lack of necessary kernel support\n");
|
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."));
|
yyerror(_("Memory allocation error."));
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = new_entry(target, mode, exec);
|
entry = new_entry(target, perms, exec);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
yyerror(_("Memory allocation error."));
|
yyerror(_("Memory allocation error."));
|
||||||
|
|
||||||
@ -1793,11 +1793,11 @@ void yyerror(const char *msg, ...)
|
|||||||
exit(1);
|
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;
|
struct cod_entry *entry;
|
||||||
PDEBUG("Matched: tok_id (%s) tok_mode (0x%x)\n", id, mode);
|
PDEBUG("Matched: tok_id (%s) tok_perms (0x%x)\n", id, perms);
|
||||||
entry = new_entry(id, mode, link_id);
|
entry = new_entry(id, perms, link_id);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
yyerror(_("Memory allocation error."));
|
yyerror(_("Memory allocation error."));
|
||||||
entry->nt_name = nt;
|
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)
|
void add_local_entry(Profile *prof)
|
||||||
{
|
{
|
||||||
/* ugh this has to be called after the hat is attached to its parent */
|
/* 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;
|
struct cod_entry *entry;
|
||||||
char *trans = (char *) malloc(strlen(prof->parent->name) +
|
char *trans = (char *) malloc(strlen(prof->parent->name) +
|
||||||
strlen(prof->name) + 3);
|
strlen(prof->name) + 3);
|
||||||
@ -1820,7 +1820,7 @@ void add_local_entry(Profile *prof)
|
|||||||
yyerror(_("Memory allocation error."));
|
yyerror(_("Memory allocation error."));
|
||||||
sprintf(name, "%s//%s", prof->parent->name, prof->name);
|
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->audit = prof->local_audit;
|
||||||
entry->nt_name = trans;
|
entry->nt_name = trans;
|
||||||
if (!entry)
|
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,
|
mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
|
||||||
struct cond_entry *dst_conds, char *dst,
|
struct cond_entry *dst_conds, char *dst,
|
||||||
int mode)
|
perms_t perms)
|
||||||
{
|
{
|
||||||
if (verify_mnt_conds(src_conds, MNT_SRC_OPT) != 0)
|
if (verify_mnt_conds(src_conds, MNT_SRC_OPT) != 0)
|
||||||
yyerror(_("bad mount rule"));
|
yyerror(_("bad mount rule"));
|
||||||
@ -1871,7 +1871,7 @@ mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
|
|||||||
if (dst_conds)
|
if (dst_conds)
|
||||||
yyerror(_("mount point conditions not currently supported"));
|
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) {
|
if (!ent) {
|
||||||
yyerror(_("Memory allocation error."));
|
yyerror(_("Memory allocation error."));
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ public:
|
|||||||
/* char *sub_name; */ /* subdomain name or NULL */
|
/* char *sub_name; */ /* subdomain name or NULL */
|
||||||
/* int default_deny; */ /* TRUE or FALSE */
|
/* int default_deny; */ /* TRUE or FALSE */
|
||||||
int local;
|
int local;
|
||||||
int local_mode; /* true if local, not hat */
|
perms_t local_perms;
|
||||||
int local_audit;
|
int local_audit;
|
||||||
|
|
||||||
Profile *parent;
|
Profile *parent;
|
||||||
@ -221,7 +221,8 @@ public:
|
|||||||
xattrs.list = NULL;
|
xattrs.list = NULL;
|
||||||
xattrs.name = NULL;
|
xattrs.name = NULL;
|
||||||
|
|
||||||
local = local_mode = local_audit = 0;
|
local_perms = 0;
|
||||||
|
local = local_audit = 0;
|
||||||
|
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#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)
|
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)
|
peer_label(NULL), audit(0), deny(0)
|
||||||
{
|
{
|
||||||
if (mode_p) {
|
if (perms_p) {
|
||||||
if (mode_p & ~AA_VALID_PTRACE_PERMS)
|
if (perms_p & ~AA_VALID_PTRACE_PERMS)
|
||||||
yyerror("mode contains invalid permissions for ptrace\n");
|
yyerror("perms contains invalid permissions for ptrace\n");
|
||||||
mode = mode_p;
|
perms = perms_p;
|
||||||
} else {
|
} else {
|
||||||
mode = AA_VALID_PTRACE_PERMS;
|
perms = AA_VALID_PTRACE_PERMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
move_conditionals(conds);
|
move_conditionals(conds);
|
||||||
@ -71,16 +71,16 @@ ostream &ptrace_rule::dump(ostream &os)
|
|||||||
|
|
||||||
os << "ptrace";
|
os << "ptrace";
|
||||||
|
|
||||||
if (mode != AA_VALID_PTRACE_PERMS) {
|
if (perms != AA_VALID_PTRACE_PERMS) {
|
||||||
os << " (";
|
os << " (";
|
||||||
|
|
||||||
if (mode & AA_MAY_READ)
|
if (perms & AA_MAY_READ)
|
||||||
os << "read ";
|
os << "read ";
|
||||||
if (mode & AA_MAY_READBY)
|
if (perms & AA_MAY_READBY)
|
||||||
os << "readby ";
|
os << "readby ";
|
||||||
if (mode & AA_MAY_TRACE)
|
if (perms & AA_MAY_TRACE)
|
||||||
os << "trace ";
|
os << "trace ";
|
||||||
if (mode & AA_MAY_TRACEDBY)
|
if (perms & AA_MAY_TRACEDBY)
|
||||||
os << "tracedby ";
|
os << "tracedby ";
|
||||||
os << ")";
|
os << ")";
|
||||||
}
|
}
|
||||||
@ -136,8 +136,8 @@ int ptrace_rule::gen_policy_re(Profile &prof)
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf = buffer.str();
|
buf = buffer.str();
|
||||||
if (mode & AA_VALID_PTRACE_PERMS) {
|
if (perms & AA_VALID_PTRACE_PERMS) {
|
||||||
if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
|
if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit,
|
||||||
dfaflags))
|
dfaflags))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -27,17 +27,17 @@
|
|||||||
#define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \
|
#define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \
|
||||||
AA_MAY_TRACEDBY)
|
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 {
|
class ptrace_rule: public rule_t {
|
||||||
void move_conditionals(struct cond_entry *conds);
|
void move_conditionals(struct cond_entry *conds);
|
||||||
public:
|
public:
|
||||||
char *peer_label;
|
char *peer_label;
|
||||||
int mode;
|
perms_t perms;
|
||||||
int audit;
|
int audit;
|
||||||
int deny;
|
int deny;
|
||||||
|
|
||||||
ptrace_rule(int mode, struct cond_entry *conds);
|
ptrace_rule(perms_t perms, struct cond_entry *conds);
|
||||||
virtual ~ptrace_rule()
|
virtual ~ptrace_rule()
|
||||||
{
|
{
|
||||||
free(peer_label);
|
free(peer_label);
|
||||||
|
@ -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)
|
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)
|
signals(), peer_label(NULL), audit(0), deny(0)
|
||||||
{
|
{
|
||||||
if (mode_p) {
|
if (perms_p) {
|
||||||
mode = mode_p;
|
perms = perms_p;
|
||||||
if (mode & ~AA_VALID_SIGNAL_PERMS)
|
if (perms & ~AA_VALID_SIGNAL_PERMS)
|
||||||
yyerror("mode contains invalid permission for signals\n");
|
yyerror("perms contains invalid permission for signals\n");
|
||||||
} else {
|
} else {
|
||||||
mode = AA_VALID_SIGNAL_PERMS;
|
perms = AA_VALID_SIGNAL_PERMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
move_conditionals(conds);
|
move_conditionals(conds);
|
||||||
@ -198,12 +198,12 @@ ostream &signal_rule::dump(ostream &os)
|
|||||||
|
|
||||||
os << "signal";
|
os << "signal";
|
||||||
|
|
||||||
if (mode != AA_VALID_SIGNAL_PERMS) {
|
if (perms != AA_VALID_SIGNAL_PERMS) {
|
||||||
os << " (";
|
os << " (";
|
||||||
|
|
||||||
if (mode & AA_MAY_SEND)
|
if (perms & AA_MAY_SEND)
|
||||||
os << "send ";
|
os << "send ";
|
||||||
if (mode & AA_MAY_RECEIVE)
|
if (perms & AA_MAY_RECEIVE)
|
||||||
os << "receive ";
|
os << "receive ";
|
||||||
os << ")";
|
os << ")";
|
||||||
}
|
}
|
||||||
@ -291,8 +291,8 @@ int signal_rule::gen_policy_re(Profile &prof)
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf = buffer.str();
|
buf = buffer.str();
|
||||||
if (mode & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
|
if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
|
||||||
if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
|
if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit,
|
||||||
dfaflags))
|
dfaflags))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
typedef set<int> Signals;
|
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 {
|
class signal_rule: public rule_t {
|
||||||
void extract_sigs(struct value_list **list);
|
void extract_sigs(struct value_list **list);
|
||||||
@ -39,11 +39,11 @@ class signal_rule: public rule_t {
|
|||||||
public:
|
public:
|
||||||
Signals signals;
|
Signals signals;
|
||||||
char *peer_label;
|
char *peer_label;
|
||||||
int mode;
|
perms_t perms;
|
||||||
int audit;
|
int audit;
|
||||||
int deny;
|
int deny;
|
||||||
|
|
||||||
signal_rule(int mode, struct cond_entry *conds);
|
signal_rule(perms_t perms, struct cond_entry *conds);
|
||||||
virtual ~signal_rule() {
|
virtual ~signal_rule() {
|
||||||
signals.clear();
|
signals.clear();
|
||||||
free(peer_label);
|
free(peer_label);
|
||||||
|
@ -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)
|
audit(0), deny(0)
|
||||||
{
|
{
|
||||||
if (mode_p) {
|
if (perms_p) {
|
||||||
if (mode_p & ~AA_VALID_USERNS_PERMS)
|
if (perms_p & ~AA_VALID_USERNS_PERMS)
|
||||||
yyerror("mode contains invalid permissions for userns\n");
|
yyerror("perms contains invalid permissions for userns\n");
|
||||||
mode = mode_p;
|
perms = perms_p;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* default to all perms */
|
/* default to all perms */
|
||||||
mode = AA_VALID_USERNS_PERMS;
|
perms = AA_VALID_USERNS_PERMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
move_conditionals(conds);
|
move_conditionals(conds);
|
||||||
@ -66,8 +66,8 @@ ostream &userns_rule::dump(ostream &os)
|
|||||||
|
|
||||||
os << "userns ";
|
os << "userns ";
|
||||||
|
|
||||||
if (mode != AA_VALID_USERNS_PERMS) {
|
if (perms != AA_VALID_USERNS_PERMS) {
|
||||||
if (mode & AA_USERNS_CREATE)
|
if (perms & AA_USERNS_CREATE)
|
||||||
os << "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;
|
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NS;
|
||||||
buf = buffer.str();
|
buf = buffer.str();
|
||||||
if (mode & AA_VALID_USERNS_PERMS) {
|
if (perms & AA_VALID_USERNS_PERMS) {
|
||||||
if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
|
if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit,
|
||||||
dfaflags))
|
dfaflags))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,11 @@
|
|||||||
class userns_rule: public rule_t {
|
class userns_rule: public rule_t {
|
||||||
void move_conditionals(struct cond_entry *conds);
|
void move_conditionals(struct cond_entry *conds);
|
||||||
public:
|
public:
|
||||||
int mode;
|
perms_t perms;
|
||||||
int audit;
|
int audit;
|
||||||
int deny;
|
int deny;
|
||||||
|
|
||||||
userns_rule(int mode, struct cond_entry *conds);
|
userns_rule(perms_t perms, struct cond_entry *conds);
|
||||||
virtual ~userns_rule()
|
virtual ~userns_rule()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user