2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-05 00:35:13 +00:00
Files
apparmor/kernel-patches/2.6.24/split_init.diff
2008-02-15 05:37:07 +00:00

231 lines
6.4 KiB
Diff

---
security/apparmor/Kconfig | 15 +++++
security/apparmor/apparmor.h | 5 +
security/apparmor/apparmorfs.c | 8 ++
security/apparmor/lsm.c | 110 +++++++++++++++++++++++++++++++++++------
4 files changed, 124 insertions(+), 14 deletions(-)
--- a/security/apparmor/Kconfig
+++ b/security/apparmor/Kconfig
@@ -25,3 +25,18 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
bootup.
If you are unsure how to answer this question, answer 1.
+
+config SECURITY_APPARMOR_DISABLE
+ bool "AppArmor runtime disable"
+ depends on SECURITY_APPARMOR
+ default n
+ help
+ This option enables writing to a apparmorfs node 'disable', which
+ allows AppArmor to be disabled at runtime prior to the policy load.
+ AppArmor will then remain disabled until the next boot.
+ This option is similar to the apparmor.enabled=0 boot parameter,
+ but is to support runtime disabling of AppArmor, e.g. from
+ /sbin/init, for portability across platforms where boot
+ parameters are difficult to employ.
+
+ If you are unsure how to answer this question, answer N.
--- a/security/apparmor/apparmor.h
+++ b/security/apparmor/apparmor.h
@@ -231,6 +231,11 @@ extern int aa_net_perm(struct aa_profile
int family, int type, int protocol);
extern int aa_revalidate_sk(struct sock *sk, char *operation);
+/* lsm.c */
+extern int apparmor_initialized;
+extern void info_message(const char *str);
+extern void apparmor_disable(void);
+
/* list.c */
extern void aa_profilelist_release(void);
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -214,6 +214,9 @@ int create_apparmorfs(void)
{
int error;
+ if (!apparmor_initialized)
+ return 0;
+
if (apparmor_dentry) {
AA_ERROR("%s: AppArmor securityfs already exists\n",
__FUNCTION__);
@@ -242,11 +245,16 @@ int create_apparmorfs(void)
if (error)
goto error;
+ /* Report that AppArmor fs is enabled */
+ info_message("AppArmor Filesystem Enabled");
return 0;
error:
destroy_apparmorfs();
AA_ERROR("Error creating AppArmor securityfs\n");
+ apparmor_disable();
return error;
}
+fs_initcall(create_apparmorfs);
+
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -23,16 +23,8 @@
#include "apparmor.h"
#include "inline.h"
-/* Boot time disable flag */
-int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
-
-static int __init apparmor_enabled_setup(char *str)
-{
- apparmor_enabled = simple_strtol(str, NULL, 0);
- return 1;
-}
-__setup("apparmor=", apparmor_enabled_setup);
-
+/* Flag indicating whether initialization completed */
+int apparmor_initialized = 0;
static int param_set_aabool(const char *val, struct kernel_param *kp);
static int param_get_aabool(char *buffer, struct kernel_param *kp);
@@ -75,6 +67,25 @@ unsigned int apparmor_path_max = 2 * PAT
module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed");
+/* Boot time disable flag */
+#ifdef CONFIG_SECURITY_APPARMOR_DISABLE
+#define AA_ENABLED_PERMS 0600
+#else
+#define AA_ENABLED_PERMS 0400
+#endif
+static int param_set_aa_enabled(const char *val, struct kernel_param *kp);
+unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
+module_param_call(enabled, param_set_aa_enabled, param_get_aauint,
+ &apparmor_enabled, AA_ENABLED_PERMS);
+MODULE_PARM_DESC(apparmor_enabled, "Enable/Disable Apparmor on boot");
+
+static int __init apparmor_enabled_setup(char *str)
+{
+ apparmor_enabled = simple_strtol(str, NULL, 0);
+ return 1;
+}
+__setup("apparmor=", apparmor_enabled_setup);
+
static int param_set_aabool(const char *val, struct kernel_param *kp)
{
if (aa_task_context(current))
@@ -103,6 +114,35 @@ static int param_get_aauint(char *buffer
return param_get_uint(buffer, kp);
}
+/* allow run time disabling of apparmor */
+static int param_set_aa_enabled(const char *val, struct kernel_param *kp)
+{
+ char *endp;
+ unsigned long l;
+
+ if (!apparmor_initialized) {
+ apparmor_enabled = 0;
+ return 0;
+ }
+
+ if (!apparmor_enabled)
+ return -EINVAL;
+
+ if (aa_task_context(current))
+ return -EPERM;
+
+ if (!val)
+ return -EINVAL;
+
+ l = simple_strtoul(val, &endp, 0);
+ if (endp == val || l != 0)
+ return -EINVAL;
+
+ apparmor_enabled = 0;
+ apparmor_disable();
+ return 0;
+}
+
static int aa_reject_syscall(struct task_struct *task, gfp_t flags,
const char *name)
{
@@ -880,14 +920,15 @@ struct security_operations apparmor_ops
.socket_shutdown = apparmor_socket_shutdown,
};
-static void info_message(const char *str)
+void info_message(const char *str)
{
struct aa_audit sa;
memset(&sa, 0, sizeof(sa));
sa.gfp_mask = GFP_KERNEL;
sa.info = str;
- printk(KERN_INFO "AppArmor: %s", str);
- aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS);
+ printk(KERN_INFO "AppArmor: %s\n", str);
+ if (audit_enabled)
+ aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS);
}
static int __init apparmor_init(void)
@@ -914,6 +955,8 @@ static int __init apparmor_init(void)
goto register_security_out;
}
+ /* Report that AppArmor successfully initialized */
+ apparmor_initialized = 1;
if (apparmor_complain)
info_message("AppArmor initialized: complainmode enabled");
else
@@ -932,7 +975,46 @@ createfs_out:
}
-module_init(apparmor_init);
+security_initcall(apparmor_init);
+
+void apparmor_disable(void)
+{
+ /* Remove and release all the profiles on the profile list. */
+ mutex_lock(&aa_interface_lock);
+ write_lock(&profile_list_lock);
+ while (!list_empty(&profile_list)) {
+ struct aa_profile *profile =
+ list_entry(profile_list.next, struct aa_profile, list);
+
+ /* Remove the profile from each task context it is on. */
+ lock_profile(profile);
+ profile->isstale = 1;
+ aa_unconfine_tasks(profile);
+ unlock_profile(profile);
+
+ /* Release the profile itself. */
+ list_del_init(&profile->list);
+ aa_put_profile(profile);
+ }
+ write_unlock(&profile_list_lock);
+
+ /* FIXME: cleanup profiles references on files */
+
+ free_null_complain_profile();
+ /*
+ * Delay for an rcu cycle to make sure that all active task
+ * context readers have finished, and all profiles have been
+ * freed by their rcu callbacks.
+ */
+ synchronize_rcu();
+
+ destroy_apparmorfs();
+ mutex_unlock(&aa_interface_lock);
+
+ apparmor_initialized = 0;
+
+ info_message("AppArmor protection removed");
+}
MODULE_DESCRIPTION("AppArmor process confinement");
MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org");