apparmor: add a stop mode to apparmor Add the ability for AppArmor to stop tasks that generate a reject via sending them a SIG_STOP. This then allows a userspace program to examine the tasks state before allowing it to continue. Signed-off-by: John Johansen <john.johansen@canonical.com>
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c index d63cfb6..ff13f46 100644 --- a/security/apparmor/audit.c +++ b/security/apparmor/audit.c
@@ -212,6 +212,8 @@ if (sa->aad.type == AUDIT_APPARMOR_KILL) (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); + else if (STOP_MODE(profile)) + (void)send_sig_info(SIGSTOP, NULL, sa->tsk ? sa->tsk : current); if (sa->aad.type == AUDIT_APPARMOR_ALLOWED) return complain_error(sa->aad.error);
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index f2cf0fb..546b72e 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h
@@ -29,8 +29,7 @@ #include "file.h" #include "resource.h" -extern const char *profile_mode_names[]; -#define APPARMOR_NAMES_MAX_INDEX 3 +extern const char *profile_mode_names[4]; #define PROFILE_MODE(_profile, _mode) \ ((aa_g_profile_mode == (_mode)) || \ @@ -38,6 +37,8 @@ #define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN) +#define STOP_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_STOP) + #define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL) #define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT) @@ -52,6 +53,7 @@ APPARMOR_ENFORCE, /* enforce access rules */ APPARMOR_COMPLAIN, /* allow and log access violations */ APPARMOR_KILL, /* kill task on access violation */ + APPARMOR_STOP, /* stop task on access violation */ }; enum profile_flags {
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 23ac013..2986f56 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c
@@ -917,7 +917,7 @@ if (!val) return -EINVAL; - for (i = 0; i < APPARMOR_NAMES_MAX_INDEX; i++) { + for (i = 0; i < sizeof(profile_mode_names); i++) { if (strcmp(val, profile_mode_names[i]) == 0) { aa_g_profile_mode = i; return 0; @@ -985,6 +985,8 @@ aa_info_message("AppArmor initialized: complain mode enabled"); else if (aa_g_profile_mode == APPARMOR_KILL) aa_info_message("AppArmor initialized: kill mode enabled"); + else if (aa_g_profile_mode == APPARMOR_STOP) + aa_info_message("AppArmor initialized: stop mode enabled"); else aa_info_message("AppArmor initialized");
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 44c84b8..75e7ec4 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c
@@ -97,6 +97,7 @@ "enforce", "complain", "kill", + "stop", }; /**