From 05029cb9b7df0c06e1aac3ac207c805e0ec213a5 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Thu, 29 Aug 2013 12:34:13 -0700 Subject: [PATCH] parser - add support for variable expansion in dbus rules Bug: https://bugs.launchpad.net/bugs/1218099 This patch adds support for expanding variables with dbus rules. Specifically, they can expanded within the bus, name, path, member, interface, and peer label fields. Parser test cases and regression test cases are added as well. Patch history: v1: initial version of patch v2: add equality.sh tests to verify that the results of using variable expansion is the same as what should be equivalent rules Signed-off-by: Steve Beattie Acked-by: Tyler Hicks Acked-by: Seth Arnold --- parser/dbus.c | 24 +++++++++ parser/dbus.h | 1 + parser/parser_variable.c | 54 +++++++++++++++++++++ parser/tst/equality.sh | 29 +++++++++++ parser/tst/simple_tests/vars/vars_dbus_1.sd | 11 +++++ parser/tst/simple_tests/vars/vars_dbus_2.sd | 11 +++++ parser/tst/simple_tests/vars/vars_dbus_3.sd | 10 ++++ parser/tst/simple_tests/vars/vars_dbus_4.sd | 13 +++++ parser/tst/simple_tests/vars/vars_dbus_5.sd | 12 +++++ parser/tst/simple_tests/vars/vars_dbus_6.sd | 11 +++++ parser/tst/simple_tests/vars/vars_dbus_7.sd | 11 +++++ tests/regression/apparmor/dbus.inc | 11 +++++ tests/regression/apparmor/dbus_message.sh | 28 +++++++++++ 13 files changed, 226 insertions(+) create mode 100644 parser/tst/simple_tests/vars/vars_dbus_1.sd create mode 100644 parser/tst/simple_tests/vars/vars_dbus_2.sd create mode 100644 parser/tst/simple_tests/vars/vars_dbus_3.sd create mode 100644 parser/tst/simple_tests/vars/vars_dbus_4.sd create mode 100644 parser/tst/simple_tests/vars/vars_dbus_5.sd create mode 100644 parser/tst/simple_tests/vars/vars_dbus_6.sd create mode 100644 parser/tst/simple_tests/vars/vars_dbus_7.sd diff --git a/parser/dbus.c b/parser/dbus.c index d08462d32..26298fcda 100644 --- a/parser/dbus.c +++ b/parser/dbus.c @@ -141,6 +141,30 @@ out: return ent; } +#define DUP_STRING(orig, new, field) \ + (new)->field = (orig)->field ? strdup((orig)->field) : NULL + +struct dbus_entry *dup_dbus_entry(struct dbus_entry *orig) +{ + struct dbus_entry *ent = NULL; + ent = (struct dbus_entry *) calloc(1, sizeof(struct dbus_entry)); + if (!ent) + return NULL; + + DUP_STRING(orig, ent, bus); + DUP_STRING(orig, ent, name); + DUP_STRING(orig, ent, peer_label); + DUP_STRING(orig, ent, path); + DUP_STRING(orig, ent, interface); + DUP_STRING(orig, ent, member); + ent->mode = orig->mode; + ent->audit = orig->audit; + ent->deny = orig->deny; + + ent->next = orig->next; + + return ent; +} void print_dbus_entry(struct dbus_entry *ent) { diff --git a/parser/dbus.h b/parser/dbus.h index 32991f2f6..bec072cc6 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -43,6 +43,7 @@ struct dbus_entry { void free_dbus_entry(struct dbus_entry *ent); struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds, struct cond_entry *peer_conds); +struct dbus_entry *dup_dbus_entry(struct dbus_entry *ent); void print_dbus_entry(struct dbus_entry *ent); #endif /* __AA_DBUS_H */ diff --git a/parser/parser_variable.c b/parser/parser_variable.c index 48f2fe7e7..519be01ff 100644 --- a/parser/parser_variable.c +++ b/parser/parser_variable.c @@ -29,6 +29,7 @@ #include "parser.h" #include "mount.h" +#include "dbus.h" static inline char *get_var_end(char *var) { @@ -213,6 +214,19 @@ int clone_and_chain_mnt(void *v) return 1; } +int clone_and_chain_dbus(void *v) +{ + struct dbus_entry *entry = v; + + struct dbus_entry *dup = dup_dbus_entry(entry); + if (!dup) + return 0; + + entry->next = dup; + + return 1; +} + static int process_variables_in_entries(struct cod_entry *entry_list) { int ret = TRUE, rc; @@ -253,6 +267,42 @@ static int process_variables_in_mnt_entries(struct mnt_entry *entry_list) return ret; } +static int process_dbus_variables(struct dbus_entry *entry_list) +{ + int ret = TRUE, rc; + struct dbus_entry *entry; + + list_for_each(entry_list, entry) { + rc = expand_entry_variables(&entry->bus, entry, + clone_and_chain_dbus); + if (!rc) + return FALSE; + rc = expand_entry_variables(&entry->name, entry, + clone_and_chain_dbus); + if (!rc) + return FALSE; + rc = expand_entry_variables(&entry->peer_label, entry, + clone_and_chain_dbus); + if (!rc) + return FALSE; + rc = expand_entry_variables(&entry->path, entry, + clone_and_chain_dbus); + if (!rc) + return FALSE; + rc = expand_entry_variables(&entry->interface, entry, + clone_and_chain_dbus); + if (!rc) + return FALSE; + rc = expand_entry_variables(&entry->member, entry, + clone_and_chain_dbus); + if (!rc) + return FALSE; + + } + + return ret; +} + int process_variables(struct codomain *cod) { int error = 0; @@ -265,6 +315,10 @@ int process_variables(struct codomain *cod) error = -1; } + if (!process_dbus_variables(cod->dbus_ents)) { + error = -1; + } + if (process_hat_variables(cod) != 0) { error = -1; } diff --git a/parser/tst/equality.sh b/parser/tst/equality.sh index f77803101..e329a87b4 100755 --- a/parser/tst/equality.sh +++ b/parser/tst/equality.sh @@ -148,6 +148,35 @@ verify_binary_equality "dbus access parsing" \ "/t { dbus (send,receive,,,,,,,,,,,,,,,,bind), }" \ "/t { dbus (send,send,send,send send receive,bind), }" \ +verify_binary_equality "dbus variable expansion" \ + "/t { dbus (send, receive) path=/com/foo member=spork interface=org.foo peer=(name=com.foo label=/com/foo), }" \ + "@{FOO}=foo + /t { dbus (send, receive) path=/com/@{FOO} member=spork interface=org.@{FOO} peer=(name=com.@{FOO} label=/com/@{FOO}), }" \ + "@{FOO}=foo + @{SPORK}=spork + /t { dbus (send, receive) path=/com/@{FOO} member=@{SPORK} interface=org.@{FOO} peer=(name=com.@{FOO} label=/com/@{FOO}), }" \ + "@{FOO}=/com/foo + /t { dbus (send, receive) path=@{FOO} member=spork interface=org.foo peer=(name=com.foo label=@{FOO}), }" \ + "@{FOO}=com + /t { dbus (send, receive) path=/@{FOO}/foo member=spork interface=org.foo peer=(name=@{FOO}.foo label=/@{FOO}/foo), }" + +verify_binary_equality "dbus variable expansion, multiple values/rules" \ + "/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, }" \ + "@{FOO}=foo + /t { dbus (send, receive) path=/com/@{FOO}, dbus (send, receive) path=/com/bar, }" \ + "@{FOO}=foo bar + /t { dbus (send, receive) path=/com/@{FOO}, }" \ + "@{FOO}=bar foo + /t { dbus (send, receive) path=/com/@{FOO}, }" + +verify_binary_equality "dbus variable expansion, ensure rule de-duping occurs" \ + "/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, }" \ + "/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, dbus (send, receive) path=/com/bar, }" \ + "@{FOO}=bar foo bar foo + /t { dbus (send, receive) path=/com/@{FOO}, }" \ + "@{FOO}=bar foo bar foo + /t { dbus (send, receive) path=/com/@{FOO}, dbus (send, receive) path=/com/@{FOO}, }" + if [ $fails -ne 0 -o $errors -ne 0 ] then printf "ERRORS: %d\nFAILS: %d\n" $errors $fails 2>&1 diff --git a/parser/tst/simple_tests/vars/vars_dbus_1.sd b/parser/tst/simple_tests/vars/vars_dbus_1.sd new file mode 100644 index 000000000..c0ccadf69 --- /dev/null +++ b/parser/tst/simple_tests/vars/vars_dbus_1.sd @@ -0,0 +1,11 @@ +#=DESCRIPTION reference variables in dbus rules +#=EXRESULT PASS + +@{FOO}=bar baz +@{BAR}=@{FOO} blort + +/does/not/exist { + dbus (send) + bus=session + path="/com/canonical/hud/applications/@{BAR}", +} diff --git a/parser/tst/simple_tests/vars/vars_dbus_2.sd b/parser/tst/simple_tests/vars/vars_dbus_2.sd new file mode 100644 index 000000000..2fe987473 --- /dev/null +++ b/parser/tst/simple_tests/vars/vars_dbus_2.sd @@ -0,0 +1,11 @@ +#=DESCRIPTION reference variables in dbus rules, interfaces +#=EXRESULT PASS + +@{ORGS}=freedesktop ubuntu gnome kde + +/does/not/exist { + dbus (receive) + bus=accessibility + interface=org.@{ORGS}.DBus.Properties + path="/com/canonical/hud/applications/bar", +} diff --git a/parser/tst/simple_tests/vars/vars_dbus_3.sd b/parser/tst/simple_tests/vars/vars_dbus_3.sd new file mode 100644 index 000000000..727465fa2 --- /dev/null +++ b/parser/tst/simple_tests/vars/vars_dbus_3.sd @@ -0,0 +1,10 @@ +#=DESCRIPTION reference variables in dbus rules, bus fields +#=EXRESULT PASS + +@{BUSES}=session system accessability choochoo + +/does/not/exist { + dbus (send) + bus=@{BUSES} + path="/com/canonical/hud/applications/baz", +} diff --git a/parser/tst/simple_tests/vars/vars_dbus_4.sd b/parser/tst/simple_tests/vars/vars_dbus_4.sd new file mode 100644 index 000000000..9ce713e3e --- /dev/null +++ b/parser/tst/simple_tests/vars/vars_dbus_4.sd @@ -0,0 +1,13 @@ +#=DESCRIPTION reference variables in dbus rules, members +#=EXRESULT PASS + +@{MEMBERS}=blurt blirt @{BAR} +@{BAR}=@{FOO} blort +@{FOO}=bink bank bonk blurry* + +/does/not/exist { + dbus (send) + bus=session + member=@{MEMBERS} + path="/com/canonical/hud/applications/biff", +} diff --git a/parser/tst/simple_tests/vars/vars_dbus_5.sd b/parser/tst/simple_tests/vars/vars_dbus_5.sd new file mode 100644 index 000000000..0a581b7ac --- /dev/null +++ b/parser/tst/simple_tests/vars/vars_dbus_5.sd @@ -0,0 +1,12 @@ +#=DESCRIPTION reference variables in dbus rules, with peers +#=EXRESULT PASS + +@{FOO}=bar baz +@{BAR}=@{FOO} blort + +/does/not/exist { + dbus (send, receive) + bus=session + path="/foo/bar" member="bar" + peer=(name="com.@{FOO}" label="/usr/bin/app.@{FOO}"), +} diff --git a/parser/tst/simple_tests/vars/vars_dbus_6.sd b/parser/tst/simple_tests/vars/vars_dbus_6.sd new file mode 100644 index 000000000..4d1318697 --- /dev/null +++ b/parser/tst/simple_tests/vars/vars_dbus_6.sd @@ -0,0 +1,11 @@ +#=DESCRIPTION reference variables in dbus rules, with name +#=EXRESULT PASS + +@{FOO}=bar baz +@{BAR}=@{FOO} blort + +/does/not/exist { + dbus (bind) + bus=session + name="com.@{BAR}.@{FOO}", +} diff --git a/parser/tst/simple_tests/vars/vars_dbus_7.sd b/parser/tst/simple_tests/vars/vars_dbus_7.sd new file mode 100644 index 000000000..dd7806eef --- /dev/null +++ b/parser/tst/simple_tests/vars/vars_dbus_7.sd @@ -0,0 +1,11 @@ +#=DESCRIPTION reference variables in dbus rules, with duplicates +#=EXRESULT PASS + +@{FOO}=bar baz bar +@{BAR}=@{FOO} blort + +/does/not/exist { + dbus (bind) + bus=session + name="com.@{BAR}.@{FOO}", +} diff --git a/tests/regression/apparmor/dbus.inc b/tests/regression/apparmor/dbus.inc index 70d39061b..2fd99f6c2 100755 --- a/tests/regression/apparmor/dbus.inc +++ b/tests/regression/apparmor/dbus.inc @@ -10,11 +10,22 @@ gendbusprofile() { genprofile --stdin <