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",
};
/**