[apparmor] [PATCH 2/2] parser: Properly parse named transition targets

Tyler Hicks tyhicks at canonical.com
Thu Feb 11 21:57:59 UTC 2016


https://launchpad.net/bugs/1540666

Reuse the new parse_label() function to initialize named_transition
structs so that transition targets, when used with change_profile, are
properly seperated into a profile namespace and profile name.

Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
 parser/parser.h                            |  2 ++
 parser/parser_misc.c                       | 13 ++++++++
 parser/parser_yacc.y                       | 52 ++++++++++--------------------
 tests/regression/apparmor/changeprofile.sh |  8 +++++
 4 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/parser/parser.h b/parser/parser.h
index b72c601..581a87a 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -394,6 +394,8 @@ 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);
 void parse_label(char **ns, char **name, const char *label);
+void parse_named_transition_target(struct named_transition *nt,
+				   const char *target);
 extern struct cod_entry *new_entry(char *ns, char *id, int mode, char *link_id);
 
 /* returns -1 if value != true or false, otherwise 0 == false, 1 == true */
diff --git a/parser/parser_misc.c b/parser/parser_misc.c
index a0e62ea..a13f71c 100644
--- a/parser/parser_misc.c
+++ b/parser/parser_misc.c
@@ -615,6 +615,19 @@ void parse_label(char **ns, char **name, const char *label)
 	*name = _name;
 }
 
+void parse_named_transition_target(struct named_transition *nt,
+				   const char *target)
+{
+	memset(nt, 0, sizeof(*nt));
+	if (!target) {
+		/* Return with nt->present set to 0 (thanks to the memset) */
+		return;
+	}
+
+	parse_label(&nt->ns, &nt->name, target);
+	nt->present = 1;
+}
+
 struct cod_entry *new_entry(char *ns, char *id, int mode, char *link_id)
 {
 	struct cod_entry *entry = NULL;
diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y
index c116e61..1f00480 100644
--- a/parser/parser_yacc.y
+++ b/parser/parser_yacc.y
@@ -258,8 +258,6 @@ void add_local_entry(Profile *prof);
 %type <boolean> opt_profile_flag
 %type <boolean> opt_flags
 %type <boolean> opt_perm_mode
-%type <id>	opt_ns
-%type <id>	ns_id
 %type <id>	opt_id
 %type <prefix>  opt_prefix
 %type <fmode>	dbus_perm
@@ -299,11 +297,6 @@ opt_profile_flag: { /* nothing */ $$ = 0; }
 	| TOK_PROFILE { $$ = 1; }
 	| hat_start { $$ = 2; }
 
-ns_id: TOK_COLON id_or_var TOK_COLON { $$ = $2; }
-
-opt_ns: { /* nothing */ $$ = NULL; }
-	| ns_id { $$ = $1; }
-
 opt_id: { /* nothing */ $$ = NULL; }
 	| TOK_ID { $$ = $1; }
 
@@ -1053,21 +1046,12 @@ id_or_var: TOK_SET_VAR { $$ = $1; };
 
 opt_named_transition:
 	{ /* nothing */
-		$$.present = 0;
-		$$.ns = NULL;
-		$$.name = NULL;
+		parse_named_transition_target(&$$, NULL);
 	}
 	| TOK_ARROW id_or_var
 	{
-		$$.present = 1;
-		$$.ns = NULL;
-		$$.name = $2;
-	}
-	| TOK_ARROW ns_id id_or_var
-	{
-		$$.present = 1;
-		$$.ns = $2;
-		$$.name = $3;
+		parse_named_transition_target(&$$, $2);
+		free($2);
 	};
 
 rule: file_rule { $$ = $1; }
@@ -1508,27 +1492,25 @@ change_profile_head: TOK_CHANGE_PROFILE opt_id
 		$$ = $2;
 	}
 
-change_profile: change_profile_head TOK_END_OF_RULE
+change_profile: change_profile_head opt_named_transition TOK_END_OF_RULE
 	{
 		struct cod_entry *entry;
-		char *rule = strdup("**");
-		if (!rule)
-			yyerror(_("Memory allocation error."));
-		PDEBUG("Matched change_profile,\n");
-		entry = new_entry(NULL, rule, AA_CHANGE_PROFILE, $1);
-		if (!entry)
-			yyerror(_("Memory allocation error."));
-		PDEBUG("change_profile,\n");
-		$$ = entry;
-	};
 
-change_profile:	change_profile_head TOK_ARROW opt_ns TOK_ID TOK_END_OF_RULE
-	{
-		struct cod_entry *entry;
-		PDEBUG("Matched change_profile: tok_id (:%s://%s)\n", $3 ? $3 : "", $4);
-		entry = new_entry($3, $4, AA_CHANGE_PROFILE, $1);
+		if ($2.present) {
+			PDEBUG("Matched change_profile: tok_id (:%s://%s)\n",
+			       $2.ns ? $2.ns : "", $2.name);
+			entry = new_entry($2.ns, $2.name, AA_CHANGE_PROFILE, $1);
+		} else {
+			char *rule = strdup("**");
+			if (!rule)
+				yyerror(_("Memory allocation error."));
+
+			PDEBUG("Matched change_profile,\n");
+			entry = new_entry(NULL, rule, AA_CHANGE_PROFILE, $1);
+		}
 		if (!entry)
 			yyerror(_("Memory allocation error."));
+
 		PDEBUG("change_profile.entry: (%s)\n", entry->name);
 		$$ = entry;
 	};
diff --git a/tests/regression/apparmor/changeprofile.sh b/tests/regression/apparmor/changeprofile.sh
index a00e24e..dea28d6 100755
--- a/tests/regression/apparmor/changeprofile.sh
+++ b/tests/regression/apparmor/changeprofile.sh
@@ -29,6 +29,7 @@ fqsubbase="$pwd/changeprofile"
 fqsubtest="$fqsubbase//$subtest"
 subtest2="$pwd//sub2"
 subtest3="$pwd//sub3"
+nstest=":ns:changeprofile"
 
 
 touch $file $subfile
@@ -70,3 +71,10 @@ runchecktest "CHANGEPROFILE_RE (nochange access file)" pass nochange $file
 runchecktest_errno EACCES "CHANGEPROFILE_RE (nochange access subfile)" fail nochange $subfile
 runchecktest_errno EACCES "CHANGEPROFILE_RE (access file)" fail $fqsubtest $file
 runchecktest "CHANGEPROFILE_RE (access sub file)" pass $fqsubtest $subfile
+
+genprofile --stdin <<EOF
+$test { file, change_profile -> ${nstest}, }
+$nstest { $subfile ${okperm}, }
+EOF
+runchecktest "CHANGEPROFILE_NS (access sub file)" pass $nstest $subfile
+runchecktest "CHANGEPROFILE_NS (access file)" fail $nstest $file
-- 
2.5.0




More information about the AppArmor mailing list