The match {VARIABLE_NAME}/{WS}*={WS}*\( is too broad causing mount and dbus rules to fail for sets of values eg.
mount options=(ro bind) Instead of doing a broad match, for now lets lock it down to just peer=(...) being the only cond that can cause entry into CONDLISTID Signed-off-by: John Johansen <john.johan...@canonical.com> --- parser/dbus.c | 22 ++++++---------------- parser/parser.h | 8 ++++++++ parser/parser_lex.l | 18 ++++++++++-------- parser/parser_misc.c | 11 +++++++++++ parser/parser_yacc.y | 25 ++++++++++++++----------- parser/signal.c | 7 ++++--- parser/signal.h | 2 +- 7 files changed, 54 insertions(+), 39 deletions(-) --- 2.9-test.orig/parser/dbus.c +++ 2.9-test/parser/dbus.c @@ -38,16 +38,6 @@ return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail); } -static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent) -{ - if (*dst_ptr) - yyerror("dbus conditional \"%s\" can only be specified once\n", - cond_ent->name); - - *dst_ptr = cond_ent->vals->value; - cond_ent->vals->value = NULL; -} - void dbus_rule::move_conditionals(struct cond_entry *conds) { struct cond_entry *cond_ent; @@ -61,17 +51,17 @@ cond_ent->name); if (strcmp(cond_ent->name, "bus") == 0) { - move_conditional_value(&bus, cond_ent); + move_conditional_value("dbus", &bus, cond_ent); } else if (strcmp(cond_ent->name, "name") == 0) { - move_conditional_value(&name, cond_ent); + move_conditional_value("dbus", &name, cond_ent); } else if (strcmp(cond_ent->name, "label") == 0) { - move_conditional_value(&peer_label, cond_ent); + move_conditional_value("dbus", &peer_label, cond_ent); } else if (strcmp(cond_ent->name, "path") == 0) { - move_conditional_value(&path, cond_ent); + move_conditional_value("dbus", &path, cond_ent); } else if (strcmp(cond_ent->name, "interface") == 0) { - move_conditional_value(&interface, cond_ent); + move_conditional_value("dbus", &interface, cond_ent); } else if (strcmp(cond_ent->name, "member") == 0) { - move_conditional_value(&member, cond_ent); + move_conditional_value("dbus", &member, cond_ent); } else { yyerror("invalid dbus conditional \"%s\"\n", cond_ent->name); --- 2.9-test.orig/parser/parser.h +++ 2.9-test/parser/parser.h @@ -78,6 +78,12 @@ struct cond_entry *next; }; +struct cond_entry_list { + char *name; + + struct cond_entry *list; +}; + struct cod_entry { char *ns; char *name; @@ -362,6 +368,8 @@ extern void free_value_list(struct value_list *list); extern void print_value_list(struct value_list *list); extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list); +extern void move_conditional_value(const char *rulename, char **dst_ptr, + struct cond_entry *cond_ent); extern void free_cond_entry(struct cond_entry *ent); extern void free_cond_list(struct cond_entry *ents); extern void print_cond_entry(struct cond_entry *ent); --- 2.9-test.orig/parser/parser_lex.l +++ 2.9-test/parser/parser_lex.l @@ -295,19 +295,21 @@ } <INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{ + {VARIABLE_NAME}/{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 + * as bison may have requested the next token from the scanner + */ + yylval.id = processid(yytext, yyleng); + PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID); + } {VARIABLE_NAME}/{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 * as bison may have requested the next token from the scanner */ - int token = get_keyword_token(yytext); - - if (token == TOK_PEER) { - PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID); - } else { - yylval.id = processid(yytext, yyleng); - PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID); - } + yylval.id = processid(yytext, yyleng); + PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID); } {VARIABLE_NAME}/{WS}+in{WS}*\( { /* we match to 'in' in the lexer so that we can switch scanner --- 2.9-test.orig/parser/parser_misc.c +++ 2.9-test/parser/parser_misc.c @@ -1205,6 +1205,17 @@ } } +void move_conditional_value(const char *rulename, char **dst_ptr, + struct cond_entry *cond_ent) +{ + if (*dst_ptr) + yyerror("%s conditional \"%s\" can only be specified once\n", + rulename, cond_ent->name); + + *dst_ptr = cond_ent->vals->value; + cond_ent->vals->value = NULL; +} + struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list) { struct cond_entry *ent = (struct cond_entry *) calloc(1, sizeof(struct cond_entry)); --- 2.9-test.orig/parser/parser_yacc.y +++ 2.9-test/parser/parser_yacc.y @@ -166,6 +166,7 @@ %token TOK_FLAGS %code requires { + #include "parser.h" #include "profile.h" #include "mount.h" #include "dbus.h" @@ -194,6 +195,7 @@ char *var_val; struct value_list *val_list; struct cond_entry *cond_entry; + struct cond_entry_list cond_entry_list; int boolean; struct named_transition transition; struct prefixes prefix; @@ -219,8 +221,8 @@ %type <mnt_entry> mnt_rule %type <cond_entry> opt_conds %type <cond_entry> cond -%type <cond_entry> cond_list -%type <cond_entry> opt_cond_list +%type <cond_entry_list> cond_list +%type <cond_entry_list> opt_cond_list %type <flags> flags %type <flags> flagvals %type <flags> flagval @@ -1145,10 +1147,11 @@ cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN { - $$ = $4; + $$.name = $1; + $$.list = $4; } -opt_cond_list: { /* nothing */ $$ = NULL; } +opt_cond_list: { /* nothing */ $$ = { NULL, NULL }; } | cond_list { $$ = $1; } mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE @@ -1232,7 +1235,12 @@ { dbus_rule *ent; - ent = new dbus_rule($2, $3, $4); + if ($4.name) { + if (strcmp($4.name, "peer") != 0) + yyerror(_("dbus rule: invalid conditional group %s=()"), $4.name); + free($4.name); + } + ent = new dbus_rule($2, $3, $4.list); if (!ent) { yyerror(_("Memory allocation error.")); } @@ -1273,12 +1281,7 @@ signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE { - signal_rule *ent = new signal_rule($2, $3, NULL); - $$ = ent; - } - | TOK_SIGNAL opt_signal_perm opt_conds TOK_ID TOK_END_OF_RULE - { - signal_rule *ent = new signal_rule($2, $3, $4); + signal_rule *ent = new signal_rule($2, $3); $$ = ent; } --- 2.9-test.orig/parser/signal.c +++ 2.9-test/parser/signal.c @@ -165,6 +165,8 @@ yyerror("keyword \"in\" is not allowed in signal rules\n"); if (strcmp(cond_ent->name, "set") == 0) { extract_sigs(&cond_ent->vals); + } else if (strcmp(cond_ent->name, "peer") == 0) { + move_conditional_value("signal", &peer_label, cond_ent); } else { yyerror("invalid signal rule conditional \"%s\"\n", cond_ent->name); @@ -172,9 +174,8 @@ } } -signal_rule::signal_rule(int mode_p, struct cond_entry *conds, - char *peer): - signals(), peer_label(peer), audit(0), deny(0) +signal_rule::signal_rule(int mode_p, struct cond_entry *conds): + signals(), peer_label(NULL), audit(0), deny(0) { if (mode_p) { mode = mode_p; --- 2.9-test.orig/parser/signal.h +++ 2.9-test/parser/signal.h @@ -43,7 +43,7 @@ int audit; int deny; - signal_rule(int mode, struct cond_entry *conds, char *peer); + signal_rule(int mode, struct cond_entry *conds); virtual ~signal_rule() { signals.clear(); free(peer_label); -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor