From patchwork Mon Jul 11 19:31:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 9224019 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 5EFB960572 for ; Mon, 11 Jul 2016 19:32:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C5B827DCE for ; Mon, 11 Jul 2016 19:32:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4123727E5A; Mon, 11 Jul 2016 19:32:05 +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 E853B27DCE for ; Mon, 11 Jul 2016 19:32:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750968AbcGKTcC (ORCPT ); Mon, 11 Jul 2016 15:32:02 -0400 Received: from nm16.bullet.mail.bf1.yahoo.com ([98.139.212.175]:57174 "EHLO nm16.bullet.mail.bf1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750931AbcGKTcB (ORCPT ); Mon, 11 Jul 2016 15:32:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1468265520; bh=ta5GPQZ7HA+gMGiIqQC3JdtPHmUQyOxv7vh7Wo/C4x8=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From:Subject; b=m2RktKPqjnJU+e/fnwwgfeaNYbfz0oo+3nqoH23d7OstCK+ihaGylXGq58k7WIdn16kvWNo6iH1idGAaEgeWhCQlQCHKcV9HgrXniILjsksyG0PIKkH9yIbuO/dw1CKxufW0z4LkuI99oDNUAQm8dfNfLRvjoQOoVCE6B+802EnpZI2m1njQRjh28Yu4LCpcrzTqsDXSocvINX20gAKAyam5hExfTQKD9qfsPkJmtOfQV8MJKh8ebaWmTU15gyGE7iymzaLbtL2wMYtCvDjDwAAKy/K3clc+Ke/kHWIBfrcfTsvmPEU7K2B81BjKyYyaL7Ty71c0LXUyxrbjEAG0mw== Received: from [98.139.170.178] by nm16.bullet.mail.bf1.yahoo.com with NNFMP; 11 Jul 2016 19:32:00 -0000 Received: from [98.139.211.204] by tm21.bullet.mail.bf1.yahoo.com with NNFMP; 11 Jul 2016 19:32:00 -0000 Received: from [127.0.0.1] by smtp213.mail.bf1.yahoo.com with NNFMP; 11 Jul 2016 19:32:00 -0000 X-Yahoo-Newman-Id: 130116.73164.bm@smtp213.mail.bf1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: r3RAD9UVM1lqcg3AldALUe6HsXLddKwk90uy7U2ZipNQTAt dyE6HQ.Emy3d6myU2Bw.XhrL4ofS3TkPM0YPKxrMyQpt317OiUxyFH2JKalo xF.0R_a2.M3n6PPm9e_bOe_VGJ6yMQAljyMg0J9DSMhTkPeryf1loxklPUnb Q.8vDos49SgDE7iDuGwhrbVhzwV3SHZB_mdPokVF9ElVd8tsEH4.MQ1jYlDp z72Bj.rWEwMoYlYSzxD5S98uGtPibp94fw2aFlInGogvao23VvpGKYpLbOJX ByYqV956A7U61ET9Q6sMBnmqgDwjNgiIbctobIIyPaA78ucVMPYp6MAEQYh1 k325u.TyxR.WVRD.b3cUPwWrQ0YhbT2.879h7u7dOhPCoQ5KQ70soB66V1uo XfJhbmiQU9fmqCDfeyRv_CwCqU9LQfNI190dgRE4i9hD7f4Yc1h1SyOG.lei 3.Dv6uCQH5dnS.14YCcnARz5u6mErNtV5oHX7pFhFhd02zua7Qcg8RB0H9Kj 5Hw72t.n02WTojLAyKfjhIltdusI0o.OK2LPFSdKyb1EE3Pld_OCN X-Yahoo-SMTP: OIJXglSswBDfgLtXluJ6wiAYv6_cnw-- Subject: [PATCH RFC 10/10] LSM: Configuration for major module stacking To: LSM , James Morris References: Cc: John Johansen , Tetsuo Handa , Paul Moore , Stephen Smalley From: Casey Schaufler Message-ID: <520f980c-7e51-58fa-e9ce-f59420ef8868@schaufler-ca.com> Date: Mon, 11 Jul 2016 12:31:54 -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: Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Subject: [PATCH RFC 10/10] 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(-) -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html 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 51f40b3..b7bb470 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 9312c78..d83e995 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 incompatible. 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 232469b..c49d5cb 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 6c21b08..06efb4f 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -847,19 +847,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 88a9b48..513e319 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 9d769f3..b6b441d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6167,11 +6167,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 0027ccd..29ae112 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -317,6 +317,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; @@ -340,12 +341,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 94aff94..2296b43 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4720,6 +4720,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 * @@ -4731,7 +4737,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) {