diff --git a/parser/apparmor.d.pod b/parser/apparmor.d.pod index 95b7e9691..235c0c7e1 100644 --- a/parser/apparmor.d.pod +++ b/parser/apparmor.d.pod @@ -115,7 +115,7 @@ B = [ 'flags=' ] '(' comma or white space separated list of B = I | I | 'mediate_deleted' | 'attach_disconnected' | 'attach_disconneced.path='I | 'chroot_relative' -| 'debug' +| 'debug' | 'interruptible' B = 'enforce' | 'complain' | 'kill' | 'unconfined' | 'prompt' @@ -506,6 +506,8 @@ flags to control what messages will be output. Its effect is kernel dependent, and it should never appear in policy except when trying to debug kernel or policy problems. +=item B Enables interrupts for prompt upcall to userspace. + =back =head2 Access Modes diff --git a/parser/parser.h b/parser/parser.h index 95b177060..f3f4ac165 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -353,6 +353,7 @@ extern int features_supports_userns; extern int features_supports_posix_mqueue; extern int features_supports_sysv_mqueue; extern int features_supports_io_uring; +extern int features_supports_flag_interruptible; extern int kernel_supports_oob; extern int conf_verbose; extern int conf_quiet; diff --git a/parser/parser_common.c b/parser/parser_common.c index f117d2ffa..c7aac5f90 100644 --- a/parser/parser_common.c +++ b/parser/parser_common.c @@ -82,6 +82,7 @@ int features_supports_userns = 0; /* kernel supports user namespace */ int features_supports_posix_mqueue = 0; /* kernel supports mqueue rules */ int features_supports_sysv_mqueue = 0; /* kernel supports mqueue rules */ int features_supports_io_uring = 0; /* kernel supports io_uring rules */ +int features_supports_flag_interruptible = 0; int kernel_supports_oob = 0; /* out of band transitions */ int conf_verbose = 0; int conf_quiet = 0; diff --git a/parser/parser_main.c b/parser/parser_main.c index d46eb8ef2..62c364cfb 100644 --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -951,6 +951,9 @@ void set_supported_features() features_supports_io_uring = features_intersect(kernel_features, policy_features, "io_uring"); + features_supports_flag_interruptible = features_intersect(kernel_features, + policy_features, + "policy/profile/interruptible"); } static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path) diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 688edd5c9..dddeef2fc 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -657,6 +657,8 @@ flagval: TOK_VALUE /* TODO: make this a proper parse */ fv.path |= PATH_ATTACH; fv.disconnected_path = strdup($1 + 25); + } else if (strcmp($1, "interruptible") == 0) { + fv.flags |= FLAG_INTERRUPTIBLE; } else { yyerror(_("Invalid profile flag: %s."), $1); } diff --git a/parser/profile.cc b/parser/profile.cc index 394099a0e..111e9ae38 100644 --- a/parser/profile.cc +++ b/parser/profile.cc @@ -347,6 +347,14 @@ static int profile_add_hat_rules(Profile *prof) void Profile::post_parse_profile(void) { + /* semantic check stuff that can't be done in parse, like flags */ + if (flags.flags & FLAG_INTERRUPTIBLE) { + if (!features_supports_flag_interruptible) { + warn_once(name, "flag interruptible not supported. Ignoring"); + /* TODO: don't clear in parse data, only at encode */ + flags.flags &= ~FLAG_INTERRUPTIBLE; + } + } post_process_file_entries(this); post_process_rule_entries(this); } @@ -363,3 +371,9 @@ void Profile::add_implied_rules(void) } } + +/* do we want to warn once/profile or just once per compile?? */ +void Profile::warn_once(const char *name, const char *msg) +{ + common_warn_once(name, msg, &warned_name); +} diff --git a/parser/profile.h b/parser/profile.h index a81b41eba..b70bf987d 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -114,6 +114,7 @@ static inline enum profile_mode str_to_mode(const char *str) #define FLAG_HAT 1 #define FLAG_DEBUG1 2 #define FLAG_DEBUG2 4 +#define FLAG_INTERRUPTIBLE 8 class flagvals { public: @@ -319,6 +320,10 @@ public: void post_parse_profile(void); void add_implied_rules(void); + +protected: + const char *warned_name = NULL; + virtual void warn_once(const char *name, const char *msg); }; diff --git a/parser/tst/simple_tests/profile/flags/flags_bad64.sd b/parser/tst/simple_tests/profile/flags/flags_bad64.sd new file mode 100644 index 000000000..b92cabef8 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad64.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION Ensure conflicting mode flags cause an error +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(enforce, kill, interruptible) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_bad65.sd b/parser/tst/simple_tests/profile/flags/flags_bad65.sd new file mode 100644 index 000000000..63d6b9d3c --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad65.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION Ensure conflicting mode flags cause an error +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(complain, kill, interruptible) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_bad66.sd b/parser/tst/simple_tests/profile/flags/flags_bad66.sd new file mode 100644 index 000000000..4e303ed31 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_bad66.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION Ensure conflicting mode flags cause an error +#=EXRESULT FAIL +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(enforce, complain, kill, unconfined, interruptible) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok29.sd b/parser/tst/simple_tests/profile/flags/flags_ok29.sd new file mode 100644 index 000000000..962ad131a --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok29.sd @@ -0,0 +1,12 @@ +# +#=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=(interruptible) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok30.sd b/parser/tst/simple_tests/profile/flags/flags_ok30.sd new file mode 100644 index 000000000..c4cd9e0cf --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok30.sd @@ -0,0 +1,12 @@ +# +#=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=(interruptible audit) { + #include + + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok31.sd b/parser/tst/simple_tests/profile/flags/flags_ok31.sd new file mode 100644 index 000000000..8657e04b1 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok31.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(enforce, interruptible) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok32.sd b/parser/tst/simple_tests/profile/flags/flags_ok32.sd new file mode 100644 index 000000000..1ddfdf2f5 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok32.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(complain, interruptible) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok33.sd b/parser/tst/simple_tests/profile/flags/flags_ok33.sd new file mode 100644 index 000000000..b8e3e8b20 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok33.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(kill, interruptible) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok34.sd b/parser/tst/simple_tests/profile/flags/flags_ok34.sd new file mode 100644 index 000000000..50af6e471 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok34.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(interruptible, enforce) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok35.sd b/parser/tst/simple_tests/profile/flags/flags_ok35.sd new file mode 100644 index 000000000..a1b7b68a5 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok35.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(interruptible, complain) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok36.sd b/parser/tst/simple_tests/profile/flags/flags_ok36.sd new file mode 100644 index 000000000..1dc0278e8 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok36.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(interruptible, kill) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok37.sd b/parser/tst/simple_tests/profile/flags/flags_ok37.sd new file mode 100644 index 000000000..25068df2d --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok37.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(interruptible, unconfined) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok38.sd b/parser/tst/simple_tests/profile/flags/flags_ok38.sd new file mode 100644 index 000000000..8657e04b1 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok38.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(enforce, interruptible) { + /usr/X11R6/lib/lib*so* r, + /does/not/exist r, +} diff --git a/parser/tst/simple_tests/profile/flags/flags_ok39.sd b/parser/tst/simple_tests/profile/flags/flags_ok39.sd new file mode 100644 index 000000000..2980edd11 --- /dev/null +++ b/parser/tst/simple_tests/profile/flags/flags_ok39.sd @@ -0,0 +1,10 @@ +# +#=DESCRIPTION ensure flag does not conflict with other mdes, and flags +#=EXRESULT PASS +# vim:syntax=subdomain +# Last Modified: Sun Apr 17 19:44:44 2005 +# +/does/not/exist flags=(prompt, interruptible) { + /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 3df48bb24..a28e75bfa 100644 --- a/utils/test/test-parser-simple-tests.py +++ b/utils/test/test-parser-simple-tests.py @@ -164,6 +164,9 @@ exception_not_raised = ( 'profile/flags/flags_bad54.sd', 'profile/flags/flags_bad55.sd', 'profile/flags/flags_bad56.sd', + 'profile/flags/flags_bad64.sd', + 'profile/flags/flags_bad65.sd', + 'profile/flags/flags_bad66.sd', 'profile/flags/flags_bad_disconnected_path1.sd', 'profile/flags/flags_bad_disconnected_path2.sd', 'profile/flags/flags_bad_disconnected_path3.sd',