diff --git a/parser/af_unix.cc b/parser/af_unix.cc index 742cd5241..b1fc38c14 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -202,7 +202,7 @@ void unix_rule::downgrade_rule(Profile &prof) { if (audit == AUDIT_FORCE) prof.net.audit[AF_UNIX] |= mask; const char *error; - network_rule *netv8 = new network_rule(AF_UNIX, sock_type_n); + network_rule *netv8 = new network_rule(perms, AF_UNIX, sock_type_n); if(!netv8->add_prefix({audit, rule_mode, owner}, error)) yyerror(error); prof.rule_ents.push_back(netv8); diff --git a/parser/all_rule.cc b/parser/all_rule.cc index 0f20c6359..89129d92f 100644 --- a/parser/all_rule.cc +++ b/parser/all_rule.cc @@ -83,7 +83,7 @@ void all_rule::add_implied_rules(Profile &prof) (void) rule->add_prefix(*prefix); prof.rule_ents.push_back(rule); - rule = new network_rule(NULL); + rule = new network_rule(0, NULL); (void) rule->add_prefix(*prefix); prof.rule_ents.push_back(rule); diff --git a/parser/network.cc b/parser/network.cc index aa0a44174..f71a0463f 100644 --- a/parser/network.cc +++ b/parser/network.cc @@ -322,7 +322,7 @@ void network_rule::set_netperm(unsigned int family, unsigned int type) network_perms[family] |= 1 << type; } -network_rule::network_rule(struct cond_entry *conds): +network_rule::network_rule(perms_t perms_p, struct cond_entry *conds): dedup_perms_rule_t(AA_CLASS_NETV8) { size_t family_index; @@ -333,9 +333,18 @@ network_rule::network_rule(struct cond_entry *conds): move_conditionals(conds); free_cond_list(conds); + + if (perms_p) { + perms = perms_p; + if (perms & ~AA_VALID_NET_PERMS) + yyerror("perms contains invalid permissions for network rules\n"); + /* can conds change permission availability? */ + } else { + perms = AA_VALID_NET_PERMS; + } } -network_rule::network_rule(const char *family, const char *type, +network_rule::network_rule(perms_t perms_p, const char *family, const char *type, const char *protocol, struct cond_entry *conds): dedup_perms_rule_t(AA_CLASS_NETV8) { @@ -357,13 +366,31 @@ network_rule::network_rule(const char *family, const char *type, move_conditionals(conds); free_cond_list(conds); + + if (perms_p) { + perms = perms_p; + if (perms & ~AA_VALID_NET_PERMS) + yyerror("perms contains invalid permissions for network rules\n"); + /* can conds change permission availability? */ + } else { + perms = AA_VALID_NET_PERMS; + } } -network_rule::network_rule(unsigned int family, unsigned int type): +network_rule::network_rule(perms_t perms_p, unsigned int family, unsigned int type): dedup_perms_rule_t(AA_CLASS_NETV8) { network_map[family].push_back({ family, type, 0xFFFFFFFF }); set_netperm(family, type); + + if (perms_p) { + perms = perms_p; + if (perms & ~AA_VALID_NET_PERMS) + yyerror("perms contains invalid permissions for network rules\n"); + /* can conds change permission availability? */ + } else { + perms = AA_VALID_NET_PERMS; + } } ostream &network_rule::dump(ostream &os) diff --git a/parser/network.h b/parser/network.h index e0557750a..473444400 100644 --- a/parser/network.h +++ b/parser/network.h @@ -114,10 +114,10 @@ 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, + network_rule(perms_t perms_p, struct cond_entry *conds); + network_rule(perms_t perms_p, const char *family, const char *type, const char *protocol, struct cond_entry *conds); - network_rule(unsigned int family, unsigned int type); + network_rule(perms_t perms_p, unsigned int family, unsigned int type); virtual ~network_rule() { if (allow) { diff --git a/parser/parser_lex.l b/parser/parser_lex.l index de7141d33..aa09c367c 100644 --- a/parser/parser_lex.l +++ b/parser/parser_lex.l @@ -558,7 +558,7 @@ GT > {LT_EQUAL} { RETURN_TOKEN(TOK_LE); } } -{ +{ listen { RETURN_TOKEN(TOK_LISTEN); } accept { RETURN_TOKEN(TOK_ACCEPT); } connect { RETURN_TOKEN(TOK_CONNECT); } @@ -567,7 +567,7 @@ GT > shutdown { RETURN_TOKEN(TOK_SHUTDOWN); } } -{ +{ create { RETURN_TOKEN(TOK_CREATE); } } @@ -576,12 +576,12 @@ GT > delete { RETURN_TOKEN(TOK_DELETE); } } -{ +{ getattr { RETURN_TOKEN(TOK_GETATTR); } setattr { RETURN_TOKEN(TOK_SETATTR); } } -{ +{ bind { RETURN_TOKEN(TOK_BIND); } } @@ -589,7 +589,7 @@ GT > eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); } } -{ +{ send { RETURN_TOKEN(TOK_SEND); } receive { RETURN_TOKEN(TOK_RECEIVE); } } @@ -600,7 +600,7 @@ GT > tracedby { RETURN_TOKEN(TOK_TRACEDBY); } } -{ +{ read { RETURN_TOKEN(TOK_READ); } write { RETURN_TOKEN(TOK_WRITE); } {OPEN_PAREN} { diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index f16195927..417adee6e 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -1083,27 +1083,38 @@ link_rule: TOK_LINK opt_subset_flag id_or_var TOK_ARROW id_or_var TOK_END_OF_RUL $$ = entry; }; -network_rule: TOK_NETWORK opt_conds TOK_END_OF_RULE +network_rule: TOK_NETWORK opt_net_perm opt_cond_list TOK_END_OF_RULE { - network_rule *entry = new network_rule($2); + network_rule *entry; + + entry = new network_rule($2, $3.list); $$ = entry; } -network_rule: TOK_NETWORK TOK_ID opt_conds TOK_END_OF_RULE +network_rule: TOK_NETWORK opt_net_perm TOK_ID opt_cond_list TOK_END_OF_RULE { - network_rule *entry = new network_rule($2, NULL, NULL, $3); - free($2); - $$ = entry; - } + network_rule *entry; -network_rule: TOK_NETWORK TOK_ID TOK_ID opt_conds TOK_END_OF_RULE - { - network_rule *entry = new network_rule($2, $3, NULL, $4); - free($2); + entry = new network_rule($2, $3, NULL, NULL, $4.list); free($3); $$ = entry; } +network_rule: TOK_NETWORK opt_net_perm TOK_ID TOK_ID opt_cond_list TOK_END_OF_RULE + { + network_rule *entry; + + if ($5.name) { + if (strcmp($5.name, "peer") != 0) + yyerror(_("network rule: invalid conditional group %s=()"), $5.name); + free($5.name); + } + entry = new network_rule($2, $3, $4, NULL, $5.list); + free($3); + free($4); + $$ = entry; + } + cond: TOK_CONDID { struct cond_entry *ent;