From 2be9c431cace53ca2d25ab24242f2774a7217439 Mon Sep 17 00:00:00 2001 From: Georgia Garcia Date: Wed, 2 Aug 2023 11:57:24 -0300 Subject: [PATCH] parser: add opt_cond in preparation to finer grained network mediation Signed-off-by: Georgia Garcia --- parser/network.cc | 65 ++++++++++++++++++++++++++++++-------------- parser/network.h | 4 ++- parser/parser_lex.l | 2 +- parser/parser_yacc.y | 12 ++++---- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/parser/network.cc b/parser/network.cc index 3698514cb..aa0a44174 100644 --- a/parser/network.cc +++ b/parser/network.cc @@ -298,6 +298,21 @@ const struct network_tuple *net_find_mapping(const struct network_tuple *map, 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) { 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_rule::network_rule(const char *family, const char *type, - const char *protocol): +network_rule::network_rule(struct cond_entry *conds): dedup_perms_rule_t(AA_CLASS_NETV8) { - if (!family && !type && !protocol) { - size_t family_index; - for (family_index = AF_UNSPEC; family_index < get_af_max(); family_index++) { - network_map[family_index].push_back({ family_index, 0xFFFFFFFF, 0xFFFFFFFF }); - set_netperm(family_index, 0xFFFFFFFF); - } - } else { - const struct network_tuple *mapping = NULL; - while ((mapping = net_find_mapping(mapping, family, type, protocol))) { + size_t family_index; + for (family_index = AF_UNSPEC; family_index < get_af_max(); family_index++) { + network_map[family_index].push_back({ family_index, 0xFFFFFFFF, 0xFFFFFFFF }); + set_netperm(family_index, 0xFFFFFFFF); + } + + move_conditionals(conds); + free_cond_list(conds); +} + +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 }); 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): diff --git a/parser/network.h b/parser/network.h index a649ea165..e0557750a 100644 --- a/parser/network.h +++ b/parser/network.h @@ -105,6 +105,7 @@ const char *net_find_type_name(int type); const char *net_find_af_name(unsigned int af); class network_rule: public dedup_perms_rule_t { + void move_conditionals(struct cond_entry *conds); public: std::unordered_map> network_map; std::unordered_map network_perms; @@ -113,8 +114,9 @@ public: * static elements to maintain compatibility with * AA_CLASS_NET */ network_rule(): dedup_perms_rule_t(AA_CLASS_NETV8) { } + network_rule(struct cond_entry *conds); 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); virtual ~network_rule() { diff --git a/parser/parser_lex.l b/parser/parser_lex.l index 6579284a7..b00743338 100644 --- a/parser/parser_lex.l +++ b/parser/parser_lex.l @@ -378,7 +378,7 @@ GT > yyterminate(); } -{ +{ (peer|xattrs)/{WS}*={WS}*\( { /* 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 diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 7b858d612..1238e5b59 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -1080,22 +1080,22 @@ link_rule: TOK_LINK opt_subset_flag id_or_var TOK_ARROW id_or_var TOK_END_OF_RUL $$ = 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; } -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); $$ = 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($3); $$ = entry;