[apparmor] [PATCH 5/6] parser: Support stacking in exec and change_profile rules

John Johansen john.johansen at canonical.com
Fri Mar 4 16:29:19 UTC 2016


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 <tyhicks at canonical.com>

Acked-by: John Johansen <john.johansen at canonical.com>


> ---
>  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,
> +}
> 




More information about the AppArmor mailing list