diff --git a/kernel-patches/for-mainline/apparmor-features.diff b/kernel-patches/for-mainline/apparmor-features.diff new file mode 100644 index 000000000..e888e5f98 --- /dev/null +++ b/kernel-patches/for-mainline/apparmor-features.diff @@ -0,0 +1,47 @@ +--- + security/apparmor/apparmorfs.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -99,6 +99,22 @@ static struct file_operations apparmorfs + .read = aa_matching_read, + }; + ++/* apparmor/features */ ++static ssize_t aa_features_read(struct file *file, char __user *buf, ++ size_t size, loff_t *ppos) ++{ ++ const char *features = "file=3.0 capability=1.0 network=1.0 " ++ "change_hat=1.3 change_profile=1.0 " ++ "aanamespaces=1.0"; ++ ++ return simple_read_from_buffer(buf, size, ppos, features, ++ strlen(features)); ++} ++ ++static struct file_operations apparmorfs_features_fops = { ++ .read = aa_features_read, ++}; ++ + /* apparmor/.load */ + static ssize_t aa_profile_load(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +@@ -204,6 +220,7 @@ void destroy_apparmorfs(void) + aafs_remove(".replace"); + aafs_remove(".load"); + aafs_remove("matching"); ++ aafs_remove("features"); + aafs_remove("profiles"); + securityfs_remove(apparmor_dentry); + apparmor_dentry = NULL; +@@ -232,6 +249,9 @@ int create_apparmorfs(void) + error = aafs_create("matching", 0444, &apparmorfs_matching_fops); + if (error) + goto error; ++ error = aafs_create("features", 0444, &apparmorfs_features_fops); ++ if (error) ++ goto error; + error = aafs_create(".load", 0640, &apparmorfs_profile_load); + if (error) + goto error; diff --git a/kernel-patches/for-mainline/fgetattr.diff b/kernel-patches/for-mainline/fgetattr.diff index 2b96aa298..92a69396b 100644 --- a/kernel-patches/for-mainline/fgetattr.diff +++ b/kernel-patches/for-mainline/fgetattr.diff @@ -28,6 +28,7 @@ difficult to implement open-unlink-fstat semantics correctly in the client, without having this information. Signed-off-by: Miklos Szeredi +Signed-off-by: John Johansen --- --- diff --git a/kernel-patches/for-mainline/fsetattr.diff b/kernel-patches/for-mainline/fsetattr.diff index f55efc75b..6fd1b257c 100644 --- a/kernel-patches/for-mainline/fsetattr.diff +++ b/kernel-patches/for-mainline/fsetattr.diff @@ -14,6 +14,7 @@ separate file operation for this, so remove ia_file, ATTR_FILE and convert existing users: fuse and AFS. Signed-off-by: Miklos Szeredi --- +Signed-off-by: John Johansen --- --- fs/afs/dir.c | 1 + diff --git a/kernel-patches/for-mainline/series b/kernel-patches/for-mainline/series index 1ca3fbf06..5915b969a 100644 --- a/kernel-patches/for-mainline/series +++ b/kernel-patches/for-mainline/series @@ -84,3 +84,6 @@ apparmor-security-goal.diff # vfs_rmdir-args.diff # vfs_unlink-args.diff # may_delete-args.diff +apparmor-matching-string.diff +apparmor-features.diff +split_init.diff diff --git a/kernel-patches/for-mainline/split_init.diff b/kernel-patches/for-mainline/split_init.diff new file mode 100644 index 000000000..276c4b191 --- /dev/null +++ b/kernel-patches/for-mainline/split_init.diff @@ -0,0 +1,202 @@ +--- + security/apparmor/Kconfig | 15 ++++++ + security/apparmor/apparmorfs.c | 12 +++++ + security/apparmor/lsm.c | 93 +++++++++++++++++++++++++++++++++-------- + 3 files changed, 103 insertions(+), 17 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/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -231,6 +231,9 @@ int create_apparmorfs(void) + { + int error; + ++ if (!apparmor_initialized) ++ return 0; ++ + if (apparmor_dentry) { + AA_ERROR("%s: AppArmor securityfs already exists\n", + __FUNCTION__); +@@ -262,11 +265,20 @@ int create_apparmorfs(void) + if (error) + goto error; + ++ /* Report that AppArmor has been successfully initialized */ ++ if (apparmor_complain) ++ info_message("AppArmor initialized: complainmode enabled"); ++ else ++ info_message("AppArmor initialized"); ++ + 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,19 @@ 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 param_set_aabool(const char *val, struct kernel_param *kp) + { + if (aa_task_context(current)) +@@ -103,6 +108,34 @@ static int param_get_aauint(char *buffer + return param_get_uint(buffer, kp); + } + ++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 (aa_task_context(current)) ++ return -EPERM; ++ ++ if (!apparmor_enabled) ++ return -EINVAL; ++ ++ 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) + { +@@ -879,13 +912,13 @@ 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); ++ printk(KERN_INFO "AppArmor: %s\n", str); + aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS); + } + +@@ -913,10 +946,12 @@ static int __init apparmor_init(void) + goto register_security_out; + } + +- if (apparmor_complain) +- info_message("AppArmor initialized: complainmode enabled"); +- else +- info_message("AppArmor initialized"); ++ /* Report that AppArmor successfully registered but delay ++ * reporting on success/failure of initialization until apparmorfs ++ * is created ++ */ ++ apparmor_initialized = 1; ++ info_message("AppArmor registered"); + + return error; + +@@ -931,7 +966,31 @@ 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); ++ aa_profile_ns_list_release(); ++ ++ /* FIXME: cleanup profiles references on files */ ++ free_default_namespace(); ++ ++ /* ++ * 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");