On 03/04/2016 12:16 AM, Tyler Hicks wrote: > Allow for a leading '&' character to be present in the named transition > target strings to indicate that the transition should stack the current > profile with the specified profile. > > Signed-off-by: Tyler Hicks <[email protected]>
Acked-by: John Johansen <[email protected]> > --- > parser/parser.h | 2 +- > parser/parser_lex.l | 5 +++-- > parser/parser_misc.c | 22 > ++++++++++++++++++---- > parser/parser_yacc.y | 7 ++++++- > .../simple_tests/change_profile/stacking_ok_1.sd | 7 +++++++ > .../simple_tests/change_profile/stacking_ok_2.sd | 7 +++++++ > .../simple_tests/change_profile/stacking_ok_3.sd | 7 +++++++ > parser/tst/simple_tests/file/stacking_ok_1.sd | 7 +++++++ > 8 files changed, 56 insertions(+), 8 deletions(-) > create mode 100644 parser/tst/simple_tests/change_profile/stacking_ok_1.sd > create mode 100644 parser/tst/simple_tests/change_profile/stacking_ok_2.sd > create mode 100644 parser/tst/simple_tests/change_profile/stacking_ok_3.sd > create mode 100644 parser/tst/simple_tests/file/stacking_ok_1.sd > > diff --git a/parser/parser.h b/parser/parser.h > index ab55a74..81f211a 100644 > --- a/parser/parser.h > +++ b/parser/parser.h > @@ -386,7 +386,7 @@ extern char *process_var(const char *var); > extern int parse_mode(const char *mode); > extern int parse_X_mode(const char *X, int valid, const char *str_mode, int > *mode, int fail); > bool label_contains_ns(const char *label); > -void parse_label(char **ns, char **name, const char *label); > +void parse_label(bool *stack, char **ns, char **name, const char *label); > extern struct cod_entry *new_entry(char *id, int mode, char *link_id); > > /* returns -1 if value != true or false, otherwise 0 == false, 1 == true */ > diff --git a/parser/parser_lex.l b/parser/parser_lex.l > index e26b2b9..49b1f22 100644 > --- a/parser/parser_lex.l > +++ b/parser/parser_lex.l > @@ -192,6 +192,7 @@ OPEN_BRACE \{ > CLOSE_BRACE \} > SLASH \/ > COLON : > +AMPERSAND & > END_OF_RULE [,] > RANGE - > MODE_CHARS ([RrWwaLlMmkXx])|(([Pp]|[Cc])[Xx])|(([Pp]|[Cc])?([IiUu])[Xx]) > @@ -225,8 +226,8 @@ SET_VAR_PREFIX @ > SET_VARIABLE {SET_VAR_PREFIX}(\{{VARIABLE_NAME}\}|{VARIABLE_NAME}) > BOOL_VARIABLE $(\{{VARIABLE_NAME}\}|{VARIABLE_NAME}) > > -LABEL (\/|{SET_VARIABLE}{POST_VAR_ID}|{COLON}){ID}* > -QUOTED_LABEL \"(\/|{SET_VAR_PREFIX}|{COLON})([^\0"]|\\\")*\" > +LABEL > (\/|{SET_VARIABLE}{POST_VAR_ID}|{COLON}|{AMPERSAND}){ID}* > +QUOTED_LABEL \"(\/|{SET_VAR_PREFIX}|{COLON}|{AMPERSAND})([^\0"]|\\\")*\" > > OPEN_PAREN \( > CLOSE_PAREN \) > diff --git a/parser/parser_misc.c b/parser/parser_misc.c > index aa29675..22f6fef 100644 > --- a/parser/parser_misc.c > +++ b/parser/parser_misc.c > @@ -571,6 +571,7 @@ int parse_X_mode(const char *X, int valid, const char > *str_mode, int *mode, int > > /** > * parse_label - break a label down to the namespace and profile name > + * @stack: Will be true if the first char in @label is '&' to indicate > stacking > * @ns: Will point to the first char in the namespace upon return or NULL > * if no namespace is present > * @ns_len: Number of chars in the namespace string or 0 if no namespace > @@ -589,7 +590,8 @@ int parse_X_mode(const char *X, int valid, const char > *str_mode, int *mode, int > * 2) Namespace is empty meaning @label starts with "::" > * 3) Profile name is empty > */ > -static int _parse_label(char **ns, size_t *ns_len, > +static int _parse_label(bool *stack, > + char **ns, size_t *ns_len, > char **name, size_t *name_len, > const char *label) > { > @@ -597,6 +599,17 @@ static int _parse_label(char **ns, size_t *ns_len, > const char *ns_start = NULL; > const char *ns_end = NULL; > > + if (label[0] == '&') { > + /** > + * Leading ampersand means that the current profile should > + * be stacked with the rest of the label > + */ > + *stack = true; > + label++; > + } else { > + *stack = false; > + } > + > if (label[0] != ':') { > /* There is no namespace specified in the label */ > name_start = label; > @@ -639,15 +652,16 @@ static int _parse_label(char **ns, size_t *ns_len, > > bool label_contains_ns(const char *label) > { > + bool stack = false; > char *ns = NULL; > char *name = NULL; > size_t ns_len = 0; > size_t name_len = 0; > > - return _parse_label(&ns, &ns_len, &name, &name_len, label) == 0 && ns; > + return _parse_label(&stack, &ns, &ns_len, &name, &name_len, label) == 0 > && ns; > } > > -void parse_label(char **_ns, char **_name, const char *label) > +void parse_label(bool *_stack, char **_ns, char **_name, const char *label) > { > char *ns = NULL; > char *name = NULL; > @@ -655,7 +669,7 @@ void parse_label(char **_ns, char **_name, const char > *label) > size_t name_len = 0; > int res; > > - res = _parse_label(&ns, &ns_len, &name, &name_len, label); > + res = _parse_label(_stack, &ns, &ns_len, &name, &name_len, label); > if (res == 1) { > yyerror(_("Namespace not terminated: %s\n"), label); > } else if (res == 2) { > diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y > index 69fa4ff..44793f7 100644 > --- a/parser/parser_yacc.y > +++ b/parser/parser_yacc.y > @@ -305,14 +305,19 @@ opt_id_or_var: { /* nothing */ $$ = NULL; } > profile_base: TOK_ID opt_id_or_var flags TOK_OPEN rules TOK_CLOSE > { > Profile *prof = $5; > + bool self_stack = false; > > if (!prof) { > yyerror(_("Memory allocation error.")); > } > > - parse_label(&prof->ns, &prof->name, $1); > + parse_label(&self_stack, &prof->ns, &prof->name, $1); > free($1); > > + if (self_stack) { > + yyerror(_("Profile names must begin with a '/' or a > namespace")); > + } > + > /* Honor the --namespace-string command line option */ > if (profile_ns) { > /** > diff --git a/parser/tst/simple_tests/change_profile/stacking_ok_1.sd > b/parser/tst/simple_tests/change_profile/stacking_ok_1.sd > new file mode 100644 > index 0000000..402bf78 > --- /dev/null > +++ b/parser/tst/simple_tests/change_profile/stacking_ok_1.sd > @@ -0,0 +1,7 @@ > +# > +#=DESCRIPTION change_profile w/ stacking > +#=EXRESULT PASS > +# > +/usr/bin/foo { > + change_profile -> &/bin/foo, > +} > diff --git a/parser/tst/simple_tests/change_profile/stacking_ok_2.sd > b/parser/tst/simple_tests/change_profile/stacking_ok_2.sd > new file mode 100644 > index 0000000..9b616ae > --- /dev/null > +++ b/parser/tst/simple_tests/change_profile/stacking_ok_2.sd > @@ -0,0 +1,7 @@ > +# > +#=DESCRIPTION change_profile w/ stacking > +#=EXRESULT PASS > +# > +/usr/bin/foo { > + change_profile -> &bar, > +} > diff --git a/parser/tst/simple_tests/change_profile/stacking_ok_3.sd > b/parser/tst/simple_tests/change_profile/stacking_ok_3.sd > new file mode 100644 > index 0000000..cb4f3a3 > --- /dev/null > +++ b/parser/tst/simple_tests/change_profile/stacking_ok_3.sd > @@ -0,0 +1,7 @@ > +# > +#=DESCRIPTION change_profile w/ stacking > +#=EXRESULT PASS > +# > +/usr/bin/foo { > + change_profile /bin/foo -> &bar, > +} > diff --git a/parser/tst/simple_tests/file/stacking_ok_1.sd > b/parser/tst/simple_tests/file/stacking_ok_1.sd > new file mode 100644 > index 0000000..f1e747e > --- /dev/null > +++ b/parser/tst/simple_tests/file/stacking_ok_1.sd > @@ -0,0 +1,7 @@ > +# > +#=Description basic file exec rule with stacking target > +#=EXRESULT PASS > +# > +/usr/bin/foo { > + /bin/bar px -> &baz, > +} > -- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
