From patchwork Sat Aug 13 20:37:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 9279327 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 8FD1F60231 for ; Sun, 14 Aug 2016 11:50:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7FDD228A4A for ; Sun, 14 Aug 2016 11:50:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F43C28A06; Sun, 14 Aug 2016 11:50:30 +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 902CC28A06 for ; Sun, 14 Aug 2016 11:50:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752532AbcHNLu2 (ORCPT ); Sun, 14 Aug 2016 07:50:28 -0400 Received: from nm19-vm0.bullet.mail.bf1.yahoo.com ([98.139.213.162]:47393 "EHLO nm19-vm0.bullet.mail.bf1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751681AbcHNLu0 (ORCPT ); Sun, 14 Aug 2016 07:50:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1471120679; bh=4ghQ1dPVHDtZYYWbDWeRhEGhPyX1H380iazwbycX/Qk=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From:Subject; b=FQG50i7ghPTW2VuCQ+aoNGA4kBBJMhlalOsdn7j9e+pTWGia1U1IpVBEquQjIuDSK165EwpI0qQMu2+qf+wklkxG903X5LRns5WhgwiJJgoCN4B4ZUSWifTxJoH8ICll859wgJnbiH5k6hCph5eRhpd10xFAKVUGaQLFLydlp5zVQqkMdGmto4jd4O7yUS80sBEqdvs235DsK+yfesbJcpwlG68nDQOHQqLK7qfbi7kdO75m+672nfbMDRj2TekNG0AhW89+iLd6BAgVETs0uXlB+oRUJMkPDdPY0KkDpPlD77tE97CZYcKlBnq4z3xOvvwYrMdhPJqYYAONledc8Q== Received: from [98.139.170.179] by nm19.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:37:59 -0000 Received: from [68.142.230.77] by tm22.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:37:59 -0000 Received: from [127.0.0.1] by smtp234.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:37:59 -0000 X-Yahoo-Newman-Id: 713841.39776.bm@smtp234.mail.bf1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: sMNdjJcVM1mER4YyNcgl0H581ZUQYwoSjYR4v5AiATk2nB. IcAbOI9wfW7jjMXmkehLd36Vw0h3lzapDrIPUQYd._csSllvrhRpOnG_1OcN wy15SIba4YUmCXclIZmQ13gK7irxvxJR_QgbGSZLkaQDcnI1qR9HWQzYcUCS n_BHMdDE5z1RcgD9rNV9CFuIGhCPyUTG_4RSJeNaJSNjk2Qjzule56cQ9HR1 4v1nr2Z8l_aPTZE7b7d9QzGaQPskubd2WW_tDw2nnkO7gnsTxYugNkKH4QPB nYYJdY96gB5MePz.uLxA_5gNLPCWISmdWxK6NHyNJDp88LWZ3_ULLLi3v4kj Vs7cwUVlma6DVwAZdnpeJwbw.X8duMFk4VxbG7abZ5icBiAX_c.AZctiFuOo IRAdLiEdJmdNlUMQ_20xY8ZQP8pqSI6l.Tv_o9AdckoFLiwaoanSBeIBaq9b v.P.yRYQtFX8b39tgGdLv3Aa_B0D5xXeZTILwt3iZifwo4le_c7lDD05CS_h RkZ7Z_kr7Qe5yyO.8ElCeK_99fqWi3uIl96829kMSBW9MTr6OX2WuRe6uDkm ozoZBPs6trzhI X-Yahoo-SMTP: OIJXglSswBDfgLtXluJ6wiAYv6_cnw-- Subject: [PATCH 20/25] LSM: Infrastructure managed superblock security blob 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: <5d7f7242-1ad0-3650-0b94-8cb3d9d84039@schaufler-ca.com> Date: Sat, 13 Aug 2016 13:37:57 -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 20/25] LSM: Infrastructure managed superblock security blob Move management of the superblock security blob from the security modules to the LSM infrastructure. This requires that the modules declare the blob size they require, so the module registration process has to include that. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 1 + security/security.c | 33 +++++++++++++++++++++++++++++++++ security/selinux/hooks.c | 21 ++------------------- security/selinux/include/objsec.h | 4 ++++ security/smack/smack.h | 4 ++++ security/smack/smack_lsm.c | 23 ++--------------------- 6 files changed, 46 insertions(+), 40 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index c03d339..70a2e7f 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1852,6 +1852,7 @@ struct lsm_blob_sizes { int lbs_file; int lbs_inode; int lbs_sock; + int lbs_superblock; }; /* diff --git a/security/security.c b/security/security.c index b728624..36ce44f 100644 --- a/security/security.c +++ b/security/security.c @@ -89,6 +89,7 @@ int __init security_init(void) pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); pr_info("LSM: sock blob size = %d\n", blob_sizes.lbs_sock); + pr_info("LSM: superblock blob size = %d\n", blob_sizes.lbs_superblock); #endif return 0; @@ -230,6 +231,7 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file); lsm_set_size(&needed->lbs_inode, &blob_sizes.lbs_inode); lsm_set_size(&needed->lbs_sock, &blob_sizes.lbs_sock); + lsm_set_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); } /** @@ -307,6 +309,31 @@ int lsm_sock_alloc(struct sock *sock) return 0; } +/** + * lsm_superblock_alloc - allocate a composite superblock blob + * @sb: the superblock that needs a blob + * + * Allocate the superblock blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_superblock_alloc(struct super_block *sb) +{ +#ifdef CONFIG_SECURITY_STACKING_DEBUG + if (sb->s_security) { + pr_info("%s: Inbound superblock blob is not NULL.\n", __func__); + return 0; + } +#endif + if (blob_sizes.lbs_superblock == 0) + return 0; + + sb->s_security = kzalloc(blob_sizes.lbs_superblock, GFP_KERNEL); + if (sb->s_security == NULL) + return -ENOMEM; + return 0; +} + /* * Hook list operation macros. * @@ -479,12 +506,18 @@ int security_bprm_secureexec(struct linux_binprm *bprm) int security_sb_alloc(struct super_block *sb) { + int rc = lsm_superblock_alloc(sb); + + if (rc) + return rc; return call_int_hook(sb_alloc_security, 0, sb); } void security_sb_free(struct super_block *sb) { call_void_hook(sb_free_security, sb); + kfree(sb->s_security); + sb->s_security = NULL; } int security_sb_copy_data(char *orig, char *copy) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f930c9f..6effdf9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -340,11 +340,7 @@ static int file_alloc_security(struct file *file) static int superblock_alloc_security(struct super_block *sb) { - struct superblock_security_struct *sbsec; - - sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL); - if (!sbsec) - return -ENOMEM; + struct superblock_security_struct *sbsec = selinux_superblock(sb); mutex_init(&sbsec->lock); INIT_LIST_HEAD(&sbsec->isec_head); @@ -353,18 +349,10 @@ static int superblock_alloc_security(struct super_block *sb) sbsec->sid = SECINITSID_UNLABELED; sbsec->def_sid = SECINITSID_FILE; sbsec->mntpoint_sid = SECINITSID_UNLABELED; - sb->s_security = sbsec; return 0; } -static void superblock_free_security(struct super_block *sb) -{ - struct superblock_security_struct *sbsec = selinux_superblock(sb); - sb->s_security = NULL; - kfree(sbsec); -} - /* The file system's label must be initialized prior to use. */ static const char *labeling_behaviors[7] = { @@ -2553,11 +2541,6 @@ static int selinux_sb_alloc_security(struct super_block *sb) return superblock_alloc_security(sb); } -static void selinux_sb_free_security(struct super_block *sb) -{ - superblock_free_security(sb); -} - static inline int match_prefix(char *prefix, int plen, char *option, int olen) { if (plen > olen) @@ -5960,6 +5943,7 @@ struct lsm_blob_sizes selinux_blob_sizes = { .lbs_file = sizeof(struct file_security_struct), .lbs_inode = sizeof(struct inode_security_struct), .lbs_sock = sizeof(struct sk_security_struct), + .lbs_superblock = sizeof(struct superblock_security_struct), }; static struct security_hook_list selinux_hooks[] = { @@ -5986,7 +5970,6 @@ static struct security_hook_list selinux_hooks[] = { LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec), LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), - LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data), LSM_HOOK_INIT(sb_remount, selinux_sb_remount), LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index f2820a8..336172e 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -161,7 +161,11 @@ static inline struct inode_security_struct *selinux_inode( static inline struct superblock_security_struct *selinux_superblock( const struct super_block *superblock) { +#ifdef CONFIG_SECURITY_STACKING + return superblock->s_security + selinux_blob_sizes.lbs_superblock; +#else return superblock->s_security; +#endif } static inline struct msg_security_struct *selinux_msg_msg( diff --git a/security/smack/smack.h b/security/smack/smack.h index d377efe..e8de2fc 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -380,7 +380,11 @@ static inline struct socket_smack *smack_sock(const struct sock *sock) static inline struct superblock_smack *smack_superblock( const struct super_block *superblock) { +#ifdef CONFIG_SECURITY_STACKING + return superblock->s_security + smack_blob_sizes.lbs_superblock; +#else return superblock->s_security; +#endif } static inline struct smack_known *smack_msg_msg(const struct msg_msg *msg) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index c8e4d02..76df1e1 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -522,12 +522,7 @@ static int smack_syslog(int typefrom_file) */ static int smack_sb_alloc_security(struct super_block *sb) { - struct superblock_smack *sbsp; - - sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL); - - if (sbsp == NULL) - return -ENOMEM; + struct superblock_smack *sbsp = smack_superblock(sb); sbsp->smk_root = &smack_known_floor; sbsp->smk_default = &smack_known_floor; @@ -536,25 +531,11 @@ static int smack_sb_alloc_security(struct super_block *sb) /* * SMK_SB_INITIALIZED will be zero from kzalloc. */ - sb->s_security = sbsp; return 0; } /** - * smack_sb_free_security - free a superblock blob - * @sb: the superblock getting the blob - * - */ -static void smack_sb_free_security(struct super_block *sb) -{ - struct superblock_smack *sbsp = smack_superblock(sb); - - kfree(sbsp); - sb->s_security = NULL; -} - -/** * smack_sb_copy_data - copy mount options data for processing * @orig: where to start * @smackopts: mount options string @@ -4551,6 +4532,7 @@ struct lsm_blob_sizes smack_blob_sizes = { .lbs_file = sizeof(struct smack_known *), .lbs_inode = sizeof(struct inode_smack), .lbs_sock = sizeof(struct socket_smack), + .lbs_superblock = sizeof(struct superblock_smack), }; static struct security_hook_list smack_hooks[] = { @@ -4559,7 +4541,6 @@ static struct security_hook_list smack_hooks[] = { LSM_HOOK_INIT(syslog, smack_syslog), LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security), - LSM_HOOK_INIT(sb_free_security, smack_sb_free_security), LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data), LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount), LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),