[apparmor] [PATCH] Add support for variable expansion in profile names, and attachments

John Johansen john.johansen at canonical.com
Mon Jun 8 08:54:37 UTC 2015


allow
  @{FOO}=bar
  /foo@{FOO} { }

to be expanded into
  /foobar { }

and
  @{FOO}=bar baz
  /foo@{FOO} { }

to be expanded into
  /foo{bar,baz} { }
which is used as a regular expression for attachment purposes

Further allow variable expansion in attachment specifications
  profile foo /foo@{FOO} { }

profile name (if begun with profile keyword) and attachments to begin
with a variable
  profile @{FOO} { }
  profile /foo @{FOO} { }
  profile @{FOO} @{BAR} {}

hats
  ^@{FOO}
  hat @{FOO}

and for subprofiles as well

Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 parser/parser_variable.c                              | 19 ++++++++++++++++++-
 parser/parser_yacc.y                                  | 11 ++++++-----
 parser/tst/simple_tests/vars/vars_profile_name_1.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_10.sd  |  9 +++++++++
 parser/tst/simple_tests/vars/vars_profile_name_11.sd  |  9 +++++++++
 parser/tst/simple_tests/vars/vars_profile_name_12.sd  |  9 +++++++++
 parser/tst/simple_tests/vars/vars_profile_name_13.sd  |  9 +++++++++
 parser/tst/simple_tests/vars/vars_profile_name_14.sd  |  9 +++++++++
 parser/tst/simple_tests/vars/vars_profile_name_15.sd  |  9 +++++++++
 parser/tst/simple_tests/vars/vars_profile_name_16.sd  |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_17.sd  |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_18.sd  |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_19.sd  |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_2.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_20.sd  |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_21.sd  |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_3.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_4.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_5.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_6.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_7.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_8.sd   |  8 ++++++++
 parser/tst/simple_tests/vars/vars_profile_name_9.sd   |  9 +++++++++
 .../tst/simple_tests/vars/vars_profile_name_bad_1.sd  |  8 ++++++++
 .../tst/simple_tests/vars/vars_profile_name_bad_2.sd  |  6 ++++++
 25 files changed, 213 insertions(+), 6 deletions(-)
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_1.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_10.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_11.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_12.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_13.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_14.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_15.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_16.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_17.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_18.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_19.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_2.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_20.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_21.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_3.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_4.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_5.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_6.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_7.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_8.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_9.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_bad_1.sd
 create mode 100644 parser/tst/simple_tests/vars/vars_profile_name_bad_2.sd

diff --git a/parser/parser_variable.c b/parser/parser_variable.c
index ac334dc..7250c0b 100644
--- a/parser/parser_variable.c
+++ b/parser/parser_variable.c
@@ -275,12 +275,29 @@ static int process_variables_in_rules(Profile &prof)
 	return 0;
 }
 
+static int process_variables_in_name(Profile &prof)
+{
+	/* this needs to be done before alias expansion, ie. altnames are
+	 * setup
+	 */
+	int error = expand_entry_variables(&prof.name);
+	if (!error && prof.attachment)
+		error = expand_entry_variables(&prof.attachment);
+
+	return error;
+}
 
 int process_profile_variables(Profile *prof)
 {
 	int error = 0, rc;
 
-	error = new_set_var(PROFILE_NAME_VARIABLE, prof->get_name(true).c_str());
+	/* needs to be before PROFILE_NAME_VARIABLE so that variable will
+	 * have the correct name
+	 */
+	error = process_variables_in_name(*prof);
+
+	if (!error)
+		error = new_set_var(PROFILE_NAME_VARIABLE, prof->get_name(true).c_str());
 
 	if (!error)
 		error = process_variables_in_entries(prof->entries);
diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y
index b3083d5..68bdede 100644
--- a/parser/parser_yacc.y
+++ b/parser/parser_yacc.y
@@ -252,6 +252,7 @@ void add_local_entry(Profile *prof);
 %type <val_list> valuelist
 %type <boolean> expr
 %type <id>	id_or_var
+%type <id>	opt_id_or_var
 %type <boolean> opt_subset_flag
 %type <boolean> opt_audit_flag
 %type <boolean> opt_owner_flag
@@ -307,7 +308,10 @@ opt_ns: { /* nothing */ $$ = NULL; }
 opt_id: { /* nothing */ $$ = NULL; }
 	| TOK_ID { $$ = $1; }
 
-profile_base: TOK_ID opt_id flags TOK_OPEN rules TOK_CLOSE
+opt_id_or_var: { /* nothing */ $$ = NULL; }
+	| id_or_var { $$ = $1; }
+
+profile_base: TOK_ID opt_id_or_var flags TOK_OPEN rules TOK_CLOSE
 	{
 		Profile *prof = $5;
 
@@ -317,10 +321,7 @@ profile_base: TOK_ID opt_id flags TOK_OPEN rules TOK_CLOSE
 
 		prof->name = $1;
 		prof->attachment = $2;
-		if ($2 && $2[0] != '/')
-			/* we don't support variables as part of the profile
-			 * name or attachment atm
-			 */
+		if ($2 && !($2[0] == '/' || strncmp($2, "@{", 2) == 0))
 			yyerror(_("Profile attachment must begin with a '/'."));
 		prof->flags = $3;
 		if (force_complain && kernel_abi_version == 5)
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_1.sd b/parser/tst/simple_tests/vars/vars_profile_name_1.sd
new file mode 100644
index 0000000..a83c2e7
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_1.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+/does/not/exist@{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_10.sd b/parser/tst/simple_tests/vars/vars_profile_name_10.sd
new file mode 100644
index 0000000..e6a574f
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_10.sd
@@ -0,0 +1,9 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+@{BAR}=baz
+
+profile /does/not@{BAR} /exist@{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_11.sd b/parser/tst/simple_tests/vars/vars_profile_name_11.sd
new file mode 100644
index 0000000..3265648
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_11.sd
@@ -0,0 +1,9 @@
+#=DESCRIPTION profiles declared with the profile keyword can begin with var
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+@{BAR}=baz foo
+
+profile /does/not/exist@{BAR} @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_12.sd b/parser/tst/simple_tests/vars/vars_profile_name_12.sd
new file mode 100644
index 0000000..3265648
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_12.sd
@@ -0,0 +1,9 @@
+#=DESCRIPTION profiles declared with the profile keyword can begin with var
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+@{BAR}=baz foo
+
+profile /does/not/exist@{BAR} @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_13.sd b/parser/tst/simple_tests/vars/vars_profile_name_13.sd
new file mode 100644
index 0000000..efaae53
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_13.sd
@@ -0,0 +1,9 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar
+@{BAR}=baz
+
+profile @{BAR} @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_14.sd b/parser/tst/simple_tests/vars/vars_profile_name_14.sd
new file mode 100644
index 0000000..5e7af13
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_14.sd
@@ -0,0 +1,9 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+@{BAR}=baz
+
+profile @{BAR} @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_15.sd b/parser/tst/simple_tests/vars/vars_profile_name_15.sd
new file mode 100644
index 0000000..67e8669
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_15.sd
@@ -0,0 +1,9 @@
+#=DESCRIPTION profiles declared with the profile keyword can begin with var
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+@{BAR}=baz foo
+
+profile @{BAR} @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_16.sd b/parser/tst/simple_tests/vars/vars_profile_name_16.sd
new file mode 100644
index 0000000..f2d66f2
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_16.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION var in sub profile name
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not/exist {
+  profile foo@{FOO} { }
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_17.sd b/parser/tst/simple_tests/vars/vars_profile_name_17.sd
new file mode 100644
index 0000000..1c44b85
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_17.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION var in sub profile name
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not/exist {
+  profile @{FOO} { }
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_18.sd b/parser/tst/simple_tests/vars/vars_profile_name_18.sd
new file mode 100644
index 0000000..fd5b54f
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_18.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION var in hat name
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not/exist {
+  ^foo@{FOO} { }
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_19.sd b/parser/tst/simple_tests/vars/vars_profile_name_19.sd
new file mode 100644
index 0000000..e952c7b
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_19.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION var in sub profile name
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not/exist {
+  ^@{FOO} { }
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_2.sd b/parser/tst/simple_tests/vars/vars_profile_name_2.sd
new file mode 100644
index 0000000..672af43
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_2.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+
+/does/not/exist@{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_20.sd b/parser/tst/simple_tests/vars/vars_profile_name_20.sd
new file mode 100644
index 0000000..4a512df
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_20.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION var in sub profile name
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not/exist {
+  hat foo@{FOO} { }
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_21.sd b/parser/tst/simple_tests/vars/vars_profile_name_21.sd
new file mode 100644
index 0000000..ee79cda
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_21.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION var in sub profile name
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not/exist {
+  hat @{FOO} { }
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_3.sd b/parser/tst/simple_tests/vars/vars_profile_name_3.sd
new file mode 100644
index 0000000..23037c8
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_3.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION profiles declared with the profile keyword can begin with var
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_4.sd b/parser/tst/simple_tests/vars/vars_profile_name_4.sd
new file mode 100644
index 0000000..3224759
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_4.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION profiles declared with the profile keyword can begin with var
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+
+profile @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_5.sd b/parser/tst/simple_tests/vars/vars_profile_name_5.sd
new file mode 100644
index 0000000..746b789
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_5.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not /exist@{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_6.sd b/parser/tst/simple_tests/vars/vars_profile_name_6.sd
new file mode 100644
index 0000000..b051c24
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_6.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+
+profile /does/not /exist@{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_7.sd b/parser/tst/simple_tests/vars/vars_profile_name_7.sd
new file mode 100644
index 0000000..d558820
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_7.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION profiles declared with the profile keyword can begin with var
+#=EXRESULT PASS
+
+@{FOO}=bar
+
+profile /does/not/exist @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_8.sd b/parser/tst/simple_tests/vars/vars_profile_name_8.sd
new file mode 100644
index 0000000..433d355
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_8.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION profiles declared with the profile keyword can begin with var
+#=EXRESULT PASS
+
+@{FOO}=bar baz
+
+profile /does/not/exist @{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_9.sd b/parser/tst/simple_tests/vars/vars_profile_name_9.sd
new file mode 100644
index 0000000..48c11bf
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_9.sd
@@ -0,0 +1,9 @@
+#=DESCRIPTION reference variables in rules that also have alternations
+#=EXRESULT PASS
+
+@{FOO}=bar
+@{BAR}=baz
+
+profile /does/not@{BAR} /exist@{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_bad_1.sd b/parser/tst/simple_tests/vars/vars_profile_name_bad_1.sd
new file mode 100644
index 0000000..0b308c8
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_bad_1.sd
@@ -0,0 +1,8 @@
+#=DESCRIPTION bare profile names must start with /
+#=EXRESULT FAIL
+
+@{FOO}=bar
+
+@{FOO} {
+  /does/not/exist r,
+}
diff --git a/parser/tst/simple_tests/vars/vars_profile_name_bad_2.sd b/parser/tst/simple_tests/vars/vars_profile_name_bad_2.sd
new file mode 100644
index 0000000..009d0b8
--- /dev/null
+++ b/parser/tst/simple_tests/vars/vars_profile_name_bad_2.sd
@@ -0,0 +1,6 @@
+#=DESCRIPTION special @{profile_name} not defined for profile name declaration
+#=EXRESULT FAIL
+
+profile @{profile_name} {
+  /does/not/exist r,
+}
-- 
2.1.4





More information about the AppArmor mailing list