parser: add opt_cond in preparation to finer grained network mediation

Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
This commit is contained in:
Georgia Garcia 2023-08-02 11:57:24 -03:00 committed by John Johansen
parent 05de4b82e7
commit 2be9c431ca
4 changed files with 54 additions and 29 deletions

View file

@ -298,6 +298,21 @@ const struct network_tuple *net_find_mapping(const struct network_tuple *map,
return NULL; return NULL;
} }
void network_rule::move_conditionals(struct cond_entry *conds)
{
struct cond_entry *cond_ent;
list_for_each(conds, cond_ent) {
/* for now disallow keyword 'in' (list) */
if (!cond_ent->eq)
yyerror("keyword \"in\" is not allowed in network rules\n");
/* no valid conditionals atm */
yyerror("invalid network rule conditional \"%s\"\n",
cond_ent->name);
}
}
void network_rule::set_netperm(unsigned int family, unsigned int type) void network_rule::set_netperm(unsigned int family, unsigned int type)
{ {
if (type > SOCK_PACKET) { if (type > SOCK_PACKET) {
@ -307,33 +322,41 @@ void network_rule::set_netperm(unsigned int family, unsigned int type)
network_perms[family] |= 1 << type; network_perms[family] |= 1 << type;
} }
network_rule::network_rule(const char *family, const char *type, network_rule::network_rule(struct cond_entry *conds):
const char *protocol):
dedup_perms_rule_t(AA_CLASS_NETV8) dedup_perms_rule_t(AA_CLASS_NETV8)
{ {
if (!family && !type && !protocol) { size_t family_index;
size_t family_index; for (family_index = AF_UNSPEC; family_index < get_af_max(); family_index++) {
for (family_index = AF_UNSPEC; family_index < get_af_max(); family_index++) { network_map[family_index].push_back({ family_index, 0xFFFFFFFF, 0xFFFFFFFF });
network_map[family_index].push_back({ family_index, 0xFFFFFFFF, 0xFFFFFFFF }); set_netperm(family_index, 0xFFFFFFFF);
set_netperm(family_index, 0xFFFFFFFF); }
}
} else { move_conditionals(conds);
const struct network_tuple *mapping = NULL; free_cond_list(conds);
while ((mapping = net_find_mapping(mapping, family, type, protocol))) { }
network_rule::network_rule(const char *family, const char *type,
const char *protocol, struct cond_entry *conds):
dedup_perms_rule_t(AA_CLASS_NETV8)
{
const struct network_tuple *mapping = NULL;
while ((mapping = net_find_mapping(mapping, family, type, protocol))) {
network_map[mapping->family].push_back({ mapping->family, mapping->type, mapping->protocol });
set_netperm(mapping->family, mapping->type);
}
if (type == NULL && network_map.empty()) {
while ((mapping = net_find_mapping(mapping, type, family, protocol))) {
network_map[mapping->family].push_back({ mapping->family, mapping->type, mapping->protocol }); network_map[mapping->family].push_back({ mapping->family, mapping->type, mapping->protocol });
set_netperm(mapping->family, mapping->type); set_netperm(mapping->family, mapping->type);
} }
if (type == NULL && network_map.empty()) {
while ((mapping = net_find_mapping(mapping, type, family, protocol))) {
network_map[mapping->family].push_back({ mapping->family, mapping->type, mapping->protocol });
set_netperm(mapping->family, mapping->type);
}
}
if (network_map.empty())
yyerror(_("Invalid network entry."));
} }
if (network_map.empty())
yyerror(_("Invalid network entry."));
move_conditionals(conds);
free_cond_list(conds);
} }
network_rule::network_rule(unsigned int family, unsigned int type): network_rule::network_rule(unsigned int family, unsigned int type):

View file

@ -105,6 +105,7 @@ const char *net_find_type_name(int type);
const char *net_find_af_name(unsigned int af); const char *net_find_af_name(unsigned int af);
class network_rule: public dedup_perms_rule_t { class network_rule: public dedup_perms_rule_t {
void move_conditionals(struct cond_entry *conds);
public: public:
std::unordered_map<unsigned int, std::vector<struct aa_network_entry>> network_map; std::unordered_map<unsigned int, std::vector<struct aa_network_entry>> network_map;
std::unordered_map<unsigned int, perms_t> network_perms; std::unordered_map<unsigned int, perms_t> network_perms;
@ -113,8 +114,9 @@ public:
* static elements to maintain compatibility with * static elements to maintain compatibility with
* AA_CLASS_NET */ * AA_CLASS_NET */
network_rule(): dedup_perms_rule_t(AA_CLASS_NETV8) { } network_rule(): dedup_perms_rule_t(AA_CLASS_NETV8) { }
network_rule(struct cond_entry *conds);
network_rule(const char *family, const char *type, network_rule(const char *family, const char *type,
const char *protocol); const char *protocol, struct cond_entry *conds);
network_rule(unsigned int family, unsigned int type); network_rule(unsigned int family, unsigned int type);
virtual ~network_rule() virtual ~network_rule()
{ {

View file

@ -378,7 +378,7 @@ GT >
yyterminate(); yyterminate();
} }
<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE>{ <INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE,NETWORK_MODE>{
(peer|xattrs)/{WS}*={WS}*\( { (peer|xattrs)/{WS}*={WS}*\( {
/* we match to the = in the lexer so that we can switch scanner /* we match to the = in the lexer so that we can switch scanner
* state. By the time the parser see the = it may be too late * state. By the time the parser see the = it may be too late

View file

@ -1080,22 +1080,22 @@ link_rule: TOK_LINK opt_subset_flag id_or_var TOK_ARROW id_or_var TOK_END_OF_RUL
$$ = entry; $$ = entry;
}; };
network_rule: TOK_NETWORK TOK_END_OF_RULE network_rule: TOK_NETWORK opt_conds TOK_END_OF_RULE
{ {
network_rule *entry = new network_rule(NULL, NULL, NULL); network_rule *entry = new network_rule($2);
$$ = entry; $$ = entry;
} }
network_rule: TOK_NETWORK TOK_ID TOK_END_OF_RULE network_rule: TOK_NETWORK TOK_ID opt_conds TOK_END_OF_RULE
{ {
network_rule *entry = new network_rule($2, NULL, NULL); network_rule *entry = new network_rule($2, NULL, NULL, $3);
free($2); free($2);
$$ = entry; $$ = entry;
} }
network_rule: TOK_NETWORK TOK_ID TOK_ID TOK_END_OF_RULE network_rule: TOK_NETWORK TOK_ID TOK_ID opt_conds TOK_END_OF_RULE
{ {
network_rule *entry = new network_rule($2, $3, NULL); network_rule *entry = new network_rule($2, $3, NULL, $4);
free($2); free($2);
free($3); free($3);
$$ = entry; $$ = entry;