From b46b2662fffea883f91e2b102a0463fc1eb0acb8 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 20 Oct 2020 03:53:06 -0700 Subject: [PATCH] parser: add support for attach_disconnected.path Add support for specifying the path prefix used when attach disconnected is specified. The kernel supports prepending a different value than / when a path is disconnected. Expose through a profile flag. Signed-off-by: John Johansen --- parser/apparmor.d.pod | 8 +++++++- parser/parser_interface.c | 6 ++++++ parser/parser_variable.c | 13 +++++++++++++ parser/parser_yacc.y | 7 +++++-- parser/profile.cc | 2 ++ parser/profile.h | 5 ++++- .../flags/flags_bad_disconnected_path1.sd | 13 +++++++++++++ .../flags/flags_bad_disconnected_path2.sd | 13 +++++++++++++ .../flags/flags_bad_disconnected_path3.sd | 16 ++++++++++++++++ .../flags/flags_bad_disconnected_path4.sd | 16 ++++++++++++++++ .../flags/flags_bad_disconnected_path5.sd | 16 ++++++++++++++++ .../profile/flags/flags_ok_disconnected_path1.sd | 13 +++++++++++++ .../profile/flags/flags_ok_disconnected_path2.sd | 13 +++++++++++++ .../profile/flags/flags_ok_disconnected_path3.sd | 13 +++++++++++++ .../profile/flags/flags_ok_disconnected_path4.sd | 13 +++++++++++++ .../profile/flags/flags_ok_disconnected_path5.sd | 16 ++++++++++++++++ .../profile/flags/flags_ok_disconnected_path6.sd | 16 ++++++++++++++++ .../profile/flags/flags_ok_disconnected_path7.sd | 16 ++++++++++++++++ .../profile/flags/flags_ok_disconnected_path8.sd | 16 ++++++++++++++++ utils/test/test-parser-simple-tests.py | 5 +++++ 20 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path1.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path2.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path3.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path4.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path5.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path1.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path2.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path3.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path4.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path5.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path6.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path7.sd create mode 100644 parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path8.sd diff --git a/parser/apparmor.d.pod b/parser/apparmor.d.pod index 4b2c5266c..e3479d1a0 100644 --- a/parser/apparmor.d.pod +++ b/parser/apparmor.d.pod @@ -113,7 +113,9 @@ B = I B = [ 'flags=' ] '(' comma or white space separated list of I ')' -B = I | I | 'mediate_deleted' | 'attach_disconnected' | 'chroot_relative' | 'debug' +B = I | I | 'mediate_deleted' +| 'attach_disconnected' | 'attach_disconneced.path' |'chroot_relative' +| 'debug' B = 'enforce' | 'complain' | 'kill' | 'unconfined' | 'prompt' @@ -491,6 +493,10 @@ though they are part of the namespace. WARNING this mode is unsafe and can result in aliasing and access to objects that should not be allowed. Its intent is a debug and policy development tool. +=item B If attach_disconnected is in use +attach disconnected object to the supplied path instead of the root of +the namespace. + =item B This forces file names to be relative to a chroot and behave as if the chroot is a mount namespace. diff --git a/parser/parser_interface.c b/parser/parser_interface.c index 85859e2bb..c7e478f92 100644 --- a/parser/parser_interface.c +++ b/parser/parser_interface.c @@ -420,6 +420,12 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile, } } + /* added in 4.13, unfortunately there is no features flag */ + if (profile->flags.disconnected_path) { + sd_write_string(buf, profile->flags.disconnected_path, + "disconnected"); + } + sd_write_struct(buf, "flags"); /* used to be flags.debug, but that's no longer supported */ sd_write_uint32(buf, profile->flags.flags); diff --git a/parser/parser_variable.c b/parser/parser_variable.c index 61cdcc3a8..35bbd7dd7 100644 --- a/parser/parser_variable.c +++ b/parser/parser_variable.c @@ -285,7 +285,20 @@ static int process_variables_in_name(Profile &prof) int error = expand_entry_variables(&prof.name); if (!error && prof.attachment) error = expand_entry_variables(&prof.attachment); + if (!error && prof.flags.disconnected_path) { + error = expand_entry_variables(&prof.flags.disconnected_path); + if (error) + return error; + filter_slashes(prof.flags.disconnected_path); + // TODO: semantic check should go somewhere else + if (prof.flags.disconnected_path[0] != '/') + yyerror(_("attach_disconnected_path value must begin with a /")); + int n = strlen(prof.flags.disconnected_path); + // removing trailing / */ + while (n && prof.flags.disconnected_path[n-1] == '/') + prof.flags.disconnected_path[--n] = 0; + } return error; } diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 85f993a9d..1dab93914 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -575,7 +575,7 @@ valuelist: valuelist TOK_VALUE } flags: { /* nothing */ - flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0 }; + flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0, NULL }; $$ = fv; }; @@ -627,7 +627,7 @@ flagvals: flagval flagval: TOK_VALUE { - flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0 }; + flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0, NULL }; enum profile_mode mode; if (strcmp($1, "debug") == 0) { @@ -653,6 +653,9 @@ flagval: TOK_VALUE fv.path |= PATH_CHROOT_NSATTACH; } else if (strcmp($1, "chroot_no_attach") == 0) { fv.path |= PATH_CHROOT_NO_ATTACH; + } else if (strncmp($1, "attach_disconnected.path=", 25) == 0) { + /* TODO: make this a proper parse */ + fv.disconnected_path = strdup($1 + 25); } else { yyerror(_("Invalid profile flag: %s."), $1); } diff --git a/parser/profile.cc b/parser/profile.cc index 0c46915a0..394099a0e 100644 --- a/parser/profile.cc +++ b/parser/profile.cc @@ -107,6 +107,8 @@ Profile::~Profile() free(name); if (attachment) free(attachment); + if (flags.disconnected_path) + free(flags.disconnected_path); if (ns) free(ns); for (int i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++) diff --git a/parser/profile.h b/parser/profile.h index 9ddf74ad3..a81b41eba 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -121,6 +121,7 @@ public: enum profile_mode mode; int audit; int path; + char *disconnected_path; ostream &dump(ostream &os) { @@ -132,6 +133,8 @@ public: if (flags & FLAG_HAT) os << ", Hat"; + if (disconnected_path) + os << ", attach_disconnected.path=" << disconnected_path; os << "\n"; return os; @@ -222,7 +225,7 @@ public: parent = NULL; - flags = { 0, MODE_UNSPECIFIED, 0, 0 }; + flags = { 0, MODE_UNSPECIFIED, 0, 0, NULL }; rlimits = {0, {}}; std::fill(exec_table, exec_table + AA_EXEC_COUNT, (char *)NULL); diff --git a/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path1.sd b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path1.sd new file mode 100644 index 000000000..55b8ba325 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path1.sd @@ -0,0 +1,13 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(attach_disconnected.path=foo) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path2.sd b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path2.sd new file mode 100644 index 000000000..a3da64956 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path2.sd @@ -0,0 +1,13 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(attach_disconnected.path=foo/) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path3.sd b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path3.sd new file mode 100644 index 000000000..dc866197e --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path3.sd @@ -0,0 +1,16 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# + +@{var}=bar + +/does/not/exist flags=(attach_disconnected.path=@{var}) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path4.sd b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path4.sd new file mode 100644 index 000000000..a343e596e --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path4.sd @@ -0,0 +1,16 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# + +@{var}=bar/ + +/does/not/exist flags=(attach_disconnected.path=@{var}) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path5.sd b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path5.sd new file mode 100644 index 000000000..a2776f924 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad_disconnected_path5.sd @@ -0,0 +1,16 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# + +@{var}=bar/ + +/does/not/exist flags=(attach_disconnected.path=@{var}/) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path1.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path1.sd new file mode 100644 index 000000000..91aeb1277 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path1.sd @@ -0,0 +1,13 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(attach_disconnected.path=/foo) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path2.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path2.sd new file mode 100644 index 000000000..f4f8c08c7 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path2.sd @@ -0,0 +1,13 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(attach_disconnected.path=/foo/) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path3.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path3.sd new file mode 100644 index 000000000..0936c89d7 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path3.sd @@ -0,0 +1,13 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(attach_disconnected.path=/foo//) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path4.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path4.sd new file mode 100644 index 000000000..e97518c19 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path4.sd @@ -0,0 +1,13 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(attach_disconnected.path=/foo/bar) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path5.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path5.sd new file mode 100644 index 000000000..12378a89c --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path5.sd @@ -0,0 +1,16 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# + +@{var}=/bar + +/does/not/exist flags=(attach_disconnected.path=/foo/@{var}) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path6.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path6.sd new file mode 100644 index 000000000..e75429f9f --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path6.sd @@ -0,0 +1,16 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# + +@{var}=/bar + +/does/not/exist flags=(attach_disconnected.path=/foo/@{var}/) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path7.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path7.sd new file mode 100644 index 000000000..da4923507 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path7.sd @@ -0,0 +1,16 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# + +@{var}=/bar + +/does/not/exist flags=(attach_disconnected.path=@{var}/foo) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path8.sd b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path8.sd new file mode 100644 index 000000000..d050a3460 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok_disconnected_path8.sd @@ -0,0 +1,16 @@ +# +#=DESCRIPTION validate some uses of the profile flags. +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# + +@{var}=/bar + +/does/not/exist flags=(attach_disconnected.path=@{var}) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} + diff --git a/utils/test/test-parser-simple-tests.py b/utils/test/test-parser-simple-tests.py index a1f5b2cb1..3df48bb24 100644 --- a/utils/test/test-parser-simple-tests.py +++ b/utils/test/test-parser-simple-tests.py @@ -164,6 +164,11 @@ exception_not_raised = ( 'profile/flags/flags_bad54.sd', 'profile/flags/flags_bad55.sd', 'profile/flags/flags_bad56.sd', + 'profile/flags/flags_bad_disconnected_path1.sd', + 'profile/flags/flags_bad_disconnected_path2.sd', + 'profile/flags/flags_bad_disconnected_path3.sd', + 'profile/flags/flags_bad_disconnected_path4.sd', + 'profile/flags/flags_bad_disconnected_path5.sd', 'profile/profile_ns_bad8.sd', # 'profile :ns/t' without terminating ':' 'ptrace/bad_05.sd', # actually contains a capability rule with invalid (ptrace-related) keyword 'ptrace/bad_06.sd', # actually contains a capability rule with invalid (ptrace-related) keyword