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

Reply via email to