From patchwork Sat Aug 13 20:36:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 9279337 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C051B60780 for ; Sun, 14 Aug 2016 11:51:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF79728A06 for ; Sun, 14 Aug 2016 11:51:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A411928A57; Sun, 14 Aug 2016 11:51:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4651E28A06 for ; Sun, 14 Aug 2016 11:50:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753482AbcHNLuz (ORCPT ); Sun, 14 Aug 2016 07:50:55 -0400 Received: from nm5-vm0.bullet.mail.bf1.yahoo.com ([98.139.213.150]:53497 "EHLO nm5-vm0.bullet.mail.bf1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753478AbcHNLux (ORCPT ); Sun, 14 Aug 2016 07:50:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1471120605; bh=SnZS9prfgeZyJIaAIalkaGmKwqIIOqYpIh7knu32dow=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From:Subject; b=eeQoLHzBXSFaksaUZC30eeWOOLpC5pVE0WRaGSri4U6YzEGW8oFCenmEcl48kkg+FESzuUd0KHz9uieK8R0MjHLhP9uQdLGw56Sn7MkUmOtaSlbQXn2+awGhw35sh7MnhFQoh1qwzLdT/WhfmOGrMebDNov/mViwRkzL97JtpvJYuinclbRDmzYjNUuclOmOe5QrvjUFmmQdVPYR4Xo36b83LECU0ppcviGkSatX+dz4Itv4cb+RMbc52xjewLZK/C8mzuUFLMb80DgPMpVzyyr/i8JBivt1dbAuokcscwHWElQQVSL9Rlx31Lj7+184vtKp0UaEVuwO/h/dfF1Wtg== Received: from [66.196.81.173] by nm5.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:36:45 -0000 Received: from [98.139.211.200] by tm19.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:36:45 -0000 Received: from [127.0.0.1] by smtp209.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:36:45 -0000 X-Yahoo-Newman-Id: 345859.78935.bm@smtp209.mail.bf1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: OQ5TrsQVM1lAuouX4I7FwRgBUUN7CTnuuLRlSSRTXsk50pD BbhtzS2XU5t3QIEb_u50ibNvyksgxfj5VgBZvbY3k0MObPRi83hPInpLnl7K dtC5HsY6k3pRAGs77SITK3.Zz.o7K0w5Rwqp8EhYfhkfaE_MU8MsdgPe4TOo u7yZAK.lyf8V1q161hbE3tGydkh4gY2Gmm5EWVUnoereyeQ9O1faUcKnAyhw s2nTRgn6DpZNTDatBeVGwR07az0XO38fcRwuWVilJh1UVPo4RiF7zz9YiDZy mHzh24jVfV7vs2PqNOxugrjvn_r_AUVtZlVJx3JrtUqLvZOI9BKByFPUppQd tqeIRe4R_kiStbGhLOEHfnDEK4lMbzMjfF8UO9XrKmcB9qe3OfkH44J3v72v mKak8YAaOaClB.5DXgMrNvcbWJwgoMprrha.U3pYzS9JKnzVAVEwr3I1wcUx HOWIBkwk1X65FoIULUx1UF9zM8QnCXKU6RUT8lmeFKNJrQfhfZgEH2CUNY.H GVqDvBmy4q2wHjc327MCMdL1GgcRaZRQEHHvNhutwGZlw9vntCC_z X-Yahoo-SMTP: OIJXglSswBDfgLtXluJ6wiAYv6_cnw-- Subject: [PATCH 13/25] LSM: Configuration for major module stacking To: LSM , James Morris References: <801ef9a9-e594-387c-f285-8d90879ee2bf@schaufler-ca.com> Cc: John Johansen , Tetsuo Handa , Paul Moore , Stephen Smalley From: Casey Schaufler Message-ID: <2adf8b81-21bd-b433-9d89-f17ddb6a740a@schaufler-ca.com> Date: Sat, 13 Aug 2016 13:36:42 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: <801ef9a9-e594-387c-f285-8d90879ee2bf@schaufler-ca.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Subject: [PATCH 13/25] LSM: Configuration for major module stacking The ability to stack "major" security modules is introduced with the configuration option CONFIG_SECURITY_STACKING. If this is enabled any "major" security module can be specified for use on the stack. If it is not set the CONFIG_DEFAULT_SECURITY value will identify a module to be used. The option CONFIG_SECURITY_APPARMOR_STACKED adds the AppArmor module. The option CONFIG_SECURITY_SELINUX_STACKED adds the SELinux module. The option CONFIG_SECURITY_SMACK_STACKED adds the Smack module. The option CONFIG_SECURITY_TOMOYO_STACKED adds the TOMOYO module. Signed-off-by: Casey Schaufler --- Documentation/security/LSM.txt | 10 ++++++++-- include/linux/lsm_hooks.h | 2 +- security/Kconfig | 22 ++++++++++++++++++++++ security/apparmor/Kconfig | 13 +++++++++++++ security/apparmor/include/context.h | 10 ++++++++++ security/apparmor/lsm.c | 11 +++++++++-- security/security.c | 26 +++++++++++++++++++++++++- security/selinux/Kconfig | 13 +++++++++++++ security/selinux/hooks.c | 8 +++++++- security/selinux/include/objsec.h | 8 ++++++++ security/smack/Kconfig | 13 +++++++++++++ security/smack/smack.h | 9 +++++++++ security/smack/smack_lsm.c | 8 +++++++- security/tomoyo/Kconfig | 13 +++++++++++++ security/tomoyo/common.h | 5 +++++ security/tomoyo/tomoyo.c | 8 +++++++- 16 files changed, 170 insertions(+), 9 deletions(-) diff --git a/Documentation/security/LSM.txt b/Documentation/security/LSM.txt index af3eb11..2840583 100644 --- a/Documentation/security/LSM.txt +++ b/Documentation/security/LSM.txt @@ -18,8 +18,14 @@ in the core functionality of Linux itself. The Linux capabilities modules will always be included. For more details on capabilities, see capabilities(7) in the Linux man-pages project. -This may be followed by any number of "minor" modules and at most one -"major" module. + +Security modules that do not use the security data blobs maintained +by the LSM infrastructure are considered "minor" modules. These may be +included at compile time and stacked explicitly. Security modules that +use the LSM maintained security blobs are considered "major" modules. +These may only be stacked if the CONFIG_SECURITY_STACKED configuration +option is used. If this is chosen all of the security modules selected +will be used. A list of the active security modules can be found by reading /sys/kernel/security/lsm. This is a comma separated list, and diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index bc8e0ac..acc7507 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1891,7 +1891,7 @@ static inline void security_delete_hooks(struct security_hook_list *hooks, } #endif /* CONFIG_SECURITY_SELINUX_DISABLE */ -extern int __init security_module_enable(const char *module); +extern int __init security_module_enable(const char *module, const int stacked); extern void __init capability_add_hooks(void); #ifdef CONFIG_SECURITY_YAMA extern void __init yama_add_hooks(void); diff --git a/security/Kconfig b/security/Kconfig index 856acb5..77a3b83 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -31,6 +31,28 @@ config SECURITY If you are unsure how to answer this question, answer N. +config SECURITY_STACKING + bool "Security module stacking" + depends on SECURITY + help + Allows multiple major security modules to be stacked. + Modules are invoked in the order registered with a + "bail on fail" policy, in which the infrastructure + will stop processing once a denial is detected. Not + all modules can be stacked. SELinux and Smack are + known to be incompatable. User space components may + have trouble identifying the security module providing + data in some cases. + + If you select this option you will have to select which + of the stackable modules you wish to be active. The + "Default security module" will be ignored. The boot line + "security=" option can be used to specify that one of + the modules identifed for stacking should be used instead + of the entire stack. + + If you are unsure how to answer this question, answer N. + config SECURITY_STACKING_DEBUG bool "Enable debugging of the LSM infrastructure" depends on SECURITY diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig index be5e941..8012bb3 100644 --- a/security/apparmor/Kconfig +++ b/security/apparmor/Kconfig @@ -14,6 +14,19 @@ config SECURITY_APPARMOR If you are unsure how to answer this question, answer N. +config SECURITY_APPARMOR_STACKED + bool "AppArmor support is enabled by default" + depends on SECURITY_APPARMOR && SECURITY_STACKING + default n + help + This option instructs the system to use the AppArmor checks. + If not selected the module will not be invoked. + Stacked security modules may interact in unexpected ways. + Please be sure your user space code is accomodating of + multiple security modules. + + If you are unsure how to answer this question, answer N. + config SECURITY_APPARMOR_BOOTPARAM_VALUE int "AppArmor boot parameter default value" depends on SECURITY_APPARMOR diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h index c140aad..666b975 100644 --- a/security/apparmor/include/context.h +++ b/security/apparmor/include/context.h @@ -87,14 +87,24 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token); int aa_restore_previous_profile(u64 cookie); struct aa_profile *aa_get_task_profile(struct task_struct *task); +extern struct lsm_blob_sizes apparmor_blob_sizes; + static inline struct aa_task_cxt *apparmor_cred(const struct cred *cred) { +#ifdef CONFIG_SECURITY_STACKING + return cred->security + apparmor_blob_sizes.lbs_cred; +#else return cred->security; +#endif } static inline struct aa_file_cxt *apparmor_file(const struct file *file) { +#ifdef CONFIG_SECURITY_STACKING + return file->f_security + apparmor_blob_sizes.lbs_file; +#else return file->f_security; +#endif } /** diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8542517..071e290 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -853,19 +853,26 @@ static int __init set_init_cxt(void) return 0; } +#ifdef CONFIG_SECURITY_APPARMOR_STACKED +#define STACKED 1 +#else +#define STACKED 0 +#endif + static int __init apparmor_init(void) { static int finish; int error; if (!finish) { - if (apparmor_enabled && security_module_enable("apparmor")) + if (apparmor_enabled && + security_module_enable("apparmor", STACKED)) security_add_blobs(&apparmor_blob_sizes); finish = 1; return 0; } - if (!apparmor_enabled || !security_module_enable("apparmor")) { + if (!apparmor_enabled || !security_module_enable("apparmor", STACKED)) { aa_info_message( "AppArmor disabled by boot time parameter"); apparmor_enabled = 0; diff --git a/security/security.c b/security/security.c index 66a2fa6..1a4d927 100644 --- a/security/security.c +++ b/security/security.c @@ -31,13 +31,18 @@ /* Maximum number of letters for an LSM name string */ #define SECURITY_NAME_MAX 10 +#define MODULE_STACK "(stacking)" char *lsm_names; static struct lsm_blob_sizes blob_sizes; /* Boot-time LSM user choice */ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = +#ifdef CONFIG_SECURITY_STACKING + MODULE_STACK; +#else CONFIG_DEFAULT_SECURITY; +#endif static void __init do_security_initcalls(void) { @@ -113,6 +118,7 @@ static int lsm_append(char *new, char **result) /** * security_module_enable - Load given security module on boot ? * @module: the name of the module + * @stacked: indicates that the module wants to be stacked * * Each LSM must pass this method before registering its own operations * to avoid security registration races. This method may also be used @@ -124,9 +130,27 @@ static int lsm_append(char *new, char **result) * choose an alternate LSM at boot time. * Otherwise, return false. */ -int __init security_module_enable(const char *module) +int __init security_module_enable(const char *module, const int stacked) { +#ifdef CONFIG_SECURITY_STACKING + /* + * Module defined on the command line security=XXXX + */ + if (strcmp(chosen_lsm, MODULE_STACK)) { + if (!strcmp(module, chosen_lsm)) { + pr_info("Command line sets the %s security module.\n", + module); + return 1; + } + return 0; + } + /* + * Module configured as stacked. + */ + return stacked; +#else return !strcmp(module, chosen_lsm); +#endif } /** diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index 8691e92..35a20dd 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig @@ -8,6 +8,19 @@ config SECURITY_SELINUX You will also need a policy configuration and a labeled filesystem. If you are unsure how to answer this question, answer N. +config SECURITY_SELINUX_STACKED + bool "NSA SELinux Support is enabled by default" + depends on SECURITY_SELINUX && SECURITY_STACKING + default n + help + This option instructs the system to use the SELinux checks. + If not selected the module will not be invoked. + Stacked security modules may interact in unexpected ways. + Please be sure your user space code is accomodating of + multiple security modules. + + If you are unsure how to answer this question, answer N. + config SECURITY_SELINUX_BOOTPARAM bool "NSA SELinux boot parameter" depends on SECURITY_SELINUX diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 72121575..03717c2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6199,11 +6199,17 @@ static struct security_hook_list selinux_hooks[] = { #endif }; +#ifdef CONFIG_SECURITY_SELINUX_STACKED +#define STACKED 1 +#else +#define STACKED 0 +#endif + static __init int selinux_init(void) { static int finish; - if (!security_module_enable("selinux")) { + if (!security_module_enable("selinux", STACKED)) { selinux_enabled = 0; return 0; } diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index b39e03b..8ec78d0 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -136,12 +136,20 @@ extern struct lsm_blob_sizes selinux_blob_sizes; static inline struct task_security_struct *selinux_cred(const struct cred *cred) { +#ifdef CONFIG_SECURITY_STACKING + return cred->security + selinux_blob_sizes.lbs_cred; +#else return cred->security; +#endif } static inline struct file_security_struct *selinux_file(const struct file *file) { +#ifdef CONFIG_SECURITY_STACKING + return file->f_security + selinux_blob_sizes.lbs_file; +#else return file->f_security; +#endif } #endif /* _SELINUX_OBJSEC_H_ */ diff --git a/security/smack/Kconfig b/security/smack/Kconfig index 271adae..362a865 100644 --- a/security/smack/Kconfig +++ b/security/smack/Kconfig @@ -12,6 +12,19 @@ config SECURITY_SMACK of other mandatory security schemes. If you are unsure how to answer this question, answer N. +config SECURITY_SMACK_STACKED + bool "Smack support is enabled by default" + depends on SECURITY_SMACK && SECURITY_STACKING + default n + help + This option instructs the system to use the Smack checks. + If not selected the module will not be invoked. + Stacked security modules may interact in unexpected ways. + Please be sure your user space code is accomodating of + multiple security modules. + + If you are unsure how to answer this question, answer N. + config SECURITY_SMACK_BRINGUP bool "Reporting on access granted by Smack rules" depends on SECURITY_SMACK diff --git a/security/smack/smack.h b/security/smack/smack.h index d941c48..9b201b4 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -323,6 +323,7 @@ extern struct smack_known *smack_syslog_label; extern struct smack_known *smack_unconfined; #endif extern int smack_ptrace_rule; +extern struct lsm_blob_sizes smack_blob_sizes; extern struct smack_known smack_known_floor; extern struct smack_known smack_known_hat; @@ -346,12 +347,20 @@ extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; static inline struct task_smack *smack_cred(const struct cred *cred) { +#ifdef CONFIG_SECURITY_STACKING + return cred->security + smack_blob_sizes.lbs_cred; +#else return cred->security; +#endif } static inline struct smack_known **smack_file(const struct file *file) { +#ifdef CONFIG_SECURITY_STACKING + return file->f_security + smack_blob_sizes.lbs_file; +#else return file->f_security; +#endif } /* diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 3833e6e..fbd0fb3 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4753,6 +4753,12 @@ static __init void init_smack_known_list(void) smk_insert_entry(&smack_known_web); } +#ifdef CONFIG_SECURITY_SMACK_STACKED +#define STACKED 1 +#else +#define STACKED 0 +#endif + /** * smack_init - initialize the smack system * @@ -4764,7 +4770,7 @@ static __init int smack_init(void) struct cred *cred = (struct cred *) current->cred; struct task_smack *tsp; - if (!security_module_enable("smack")) + if (!security_module_enable("smack", STACKED)) return 0; if (!finish) { diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig index 404dce6..746e8c4 100644 --- a/security/tomoyo/Kconfig +++ b/security/tomoyo/Kconfig @@ -14,6 +14,19 @@ config SECURITY_TOMOYO found at . If you are unsure how to answer this question, answer N. +config SECURITY_TOMOYO_STACKED + bool "TOMOYO support is enabled by default" + depends on SECURITY_TOMOYO && SECURITY_STACKING + default n + help + This option instructs the system to use the TOMOYO checks. + If not selected the module will not be invoked. + Stacked security modules may interact in unexpected ways. + Please be sure your user space code is accomodating of + multiple security modules. + + If you are unsure how to answer this question, answer N. + config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY int "Default maximal count for learning mode" default 2048 diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index cbcfccc..a78b354 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -1085,6 +1085,7 @@ extern struct tomoyo_domain_info tomoyo_kernel_domain; extern struct tomoyo_policy_namespace tomoyo_kernel_namespace; extern unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; +extern struct lsm_blob_sizes tomoyo_blob_sizes; /********** Inlined functions. **********/ @@ -1204,7 +1205,11 @@ static inline void tomoyo_put_group(struct tomoyo_group *group) */ static inline struct tomoyo_domain_info **tomoyo_cred(const struct cred *cred) { +#ifdef CONFIG_SECURITY_STACKING + return cred->security + tomoyo_blob_sizes.lbs_cred; +#else return cred->security; +#endif } /** diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 61285fe..a47ed03 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -550,6 +550,12 @@ static struct security_hook_list tomoyo_hooks[] = { /* Lock for GC. */ DEFINE_SRCU(tomoyo_ss); +#ifdef CONFIG_SECURITY_TOMOYO_STACKED +#define STACKED 1 +#else +#define STACKED 0 +#endif + /** * tomoyo_init - Register TOMOYO Linux as a LSM module. * @@ -561,7 +567,7 @@ static int __init tomoyo_init(void) struct cred *cred = (struct cred *) current_cred(); struct tomoyo_domain_info **blob; - if (!security_module_enable("tomoyo")) + if (!security_module_enable("tomoyo", STACKED)) return 0; if (!finish) {