parser: add interruptible flag

Allow indicating that prompt upcalls to userspace can be interrupted

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2023-08-14 12:30:01 -07:00
parent 5f6e213d23
commit 30707be87f
22 changed files with 176 additions and 1 deletions

View file

@ -115,7 +115,7 @@ B<PROFILE FLAG CONDS> = [ 'flags=' ] '(' comma or white space separated list of
B<PROFILE FLAGS> = I<PROFILE MODE> | I<AUDIT_MODE> | 'mediate_deleted'
| 'attach_disconnected' | 'attach_disconneced.path='I<ABS PATH> | 'chroot_relative'
| 'debug'
| 'debug' | 'interruptible'
B<PROFILE MODE> = '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<interruptible> Enables interrupts for prompt upcall to userspace.
=back
=head2 Access Modes

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
};

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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 <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View file

@ -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 <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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,
}

View file

@ -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',