From patchwork Sat Aug 13 20:36:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 9279287 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 59F8260231 for ; Sun, 14 Aug 2016 11:47:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 49D6C289E6 for ; Sun, 14 Aug 2016 11:47:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3E70F28A57; Sun, 14 Aug 2016 11:47:48 +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 4A68C289E6 for ; Sun, 14 Aug 2016 11:47:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934190AbcHNLrp (ORCPT ); Sun, 14 Aug 2016 07:47:45 -0400 Received: from nm3-vm0.bullet.mail.bf1.yahoo.com ([98.139.212.154]:51693 "EHLO nm3-vm0.bullet.mail.bf1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934172AbcHNLra (ORCPT ); Sun, 14 Aug 2016 07:47:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1471120595; bh=gYFhXurCljk35W6ngE4KpPh9ow8BaGGRCQUfDuaTuG0=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From:Subject; b=c1fH6c54wvCtaiDMp65mr1f+sBZGRaxrwXsCtxDqZCHIT70EJKJ1aCsIu0Bpmw0U6iDjoJA0ISaFfgYJm23dyP9VG/eAlPYP+ijOHiMiCoWvvTUlNIEyVch7yjwEXD9YvpNSLi3ahgmQP318Gnb6jzCwMLK4HS+D9kzgEEeEUU/jUxCRjWCyAK5pvinJWw6+0CiS06NWExZRBxnA91PrxrQk3PHr5RqwnoVeRCdV4CoMoAPW2+p/ct2MqmJZigimOokG/Ixvkf/DOH4gSgcQtZ7tjR+Jo5dd2U9cdhIRiPu/Wr5KiDHLI884OmlZ6pC9FX40ESGWB5m/rUHZVr7AsQ== Received: from [98.139.215.140] by nm3.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:36:35 -0000 Received: from [98.139.211.192] by tm11.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:36:35 -0000 Received: from [127.0.0.1] by smtp201.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:36:35 -0000 X-Yahoo-Newman-Id: 227501.24285.bm@smtp201.mail.bf1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: HAUfP1wVM1m8rJhcA0MNgWDc.pHfTyVUvyqlEX90LUmOak6 i.4QUqQE1LjIKeMJHFKbRaGxIvzFQaBnIkZSmefvBxzj1hQymrNHOrhFf0O4 OlaZiVQXfMq6s76zA77d64SEptkRYt5LV1JKVm63psUpAMubXe98H6thDFbg K5DEep_YRmM8jIOXzE8qj9zkbbdsEaLDyFqQD9gB6AzqQ9lEz.uqAt7tnHYJ kjWfSlwJagBm1QiqYRU2b7w16i9dHrs7.iGseveg9.LXW0Y32g5Zul_QwcjR 5VJjZPelwMKH_i.gseisxUbawwwYnYKVMQUw0OlmHinJzesKVZXEngXkmuV6 rHtdLjGXrinGSTxVvplyLCAUM5WHjJhJilWGqSzYVS9YhO.eTQK.K.FZDDlx 0UFLnFbPm6Gu06scEVKDhqElBe51B3KjnjPZCE73mwvIFfcg7JaWUwFMdFBc s4zH7qSUdqkTiU0SW0uvRJoIqYAroe9Jnr0vAgq6jKi4FUc2HVvrHJ88tDPw TSt3jA_pwRJFdDhWQ.BDam0dJwRD.B8l_gMV1jMoDaGuZ45f.hKaT8xWEmbC WJRh.mIeOd4Ao X-Yahoo-SMTP: OIJXglSswBDfgLtXluJ6wiAYv6_cnw-- Subject: [PATCH 12/25] LSM: Infrastructure managed file 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: <19d0be16-37e9-edf5-d3df-57fe2a30ab85@schaufler-ca.com> Date: Sat, 13 Aug 2016 13:36:33 -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 12/25] LSM: Infrastructure managed file security blob Move management of the file security blob from the security modules to the LSM infrastructure. Module hooks that are no longer required are removed. Smack was stuffing a pointer that it manages into file->f_security. Now a blob big enough for the pointer is allocated by the infrastruture and the pointer is saved there. It might make sense to revise the way this module manages its file data. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 1 + security/apparmor/lsm.c | 20 +------------------- security/security.c | 34 ++++++++++++++++++++++++++++++++++ security/selinux/hooks.c | 25 ++----------------------- security/smack/smack.h | 2 +- security/smack/smack_lsm.c | 26 +++++++++----------------- 6 files changed, 48 insertions(+), 60 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index dde837f..bc8e0ac 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1849,6 +1849,7 @@ struct security_hook_list { */ struct lsm_blob_sizes { int lbs_cred; + int lbs_file; }; /* diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index c91ce01..8542517 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -352,23 +352,6 @@ static int apparmor_file_open(struct file *file, const struct cred *cred) return error; } -static int apparmor_file_alloc_security(struct file *file) -{ - /* freed by apparmor_file_free_security */ - file->f_security = aa_alloc_file_context(GFP_KERNEL); - if (!file->f_security) - return -ENOMEM; - return 0; - -} - -static void apparmor_file_free_security(struct file *file) -{ - struct aa_file_cxt *cxt = file_cxt(file); - - aa_free_file_context(cxt); -} - static int common_file_perm(int op, struct file *file, u32 mask) { struct aa_file_cxt *fcxt = file_cxt(file); @@ -592,6 +575,7 @@ static int apparmor_task_setrlimit(struct task_struct *task, struct lsm_blob_sizes apparmor_blob_sizes = { .lbs_cred = sizeof(struct aa_task_cxt), + .lbs_file = sizeof(struct aa_file_cxt), }; static struct security_hook_list apparmor_hooks[] = { @@ -614,8 +598,6 @@ static struct security_hook_list apparmor_hooks[] = { LSM_HOOK_INIT(file_open, apparmor_file_open), LSM_HOOK_INIT(file_permission, apparmor_file_permission), - LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security), - LSM_HOOK_INIT(file_free_security, apparmor_file_free_security), LSM_HOOK_INIT(mmap_file, apparmor_mmap_file), LSM_HOOK_INIT(file_mprotect, apparmor_file_mprotect), LSM_HOOK_INIT(file_lock, apparmor_file_lock), diff --git a/security/security.c b/security/security.c index 762726d..66a2fa6 100644 --- a/security/security.c +++ b/security/security.c @@ -80,6 +80,7 @@ int __init security_init(void) #ifdef CONFIG_SECURITY_STACKING_DEBUG pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); + pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); #endif return 0; @@ -199,6 +200,32 @@ static void __init lsm_set_size(int *need, int *lbs) void __init security_add_blobs(struct lsm_blob_sizes *needed) { lsm_set_size(&needed->lbs_cred, &blob_sizes.lbs_cred); + lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file); +} + +/** + * lsm_file_alloc - allocate a composite file blob + * @file: the file that needs a blob + * + * Allocate the file blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_file_alloc(struct file *file) +{ +#ifdef CONFIG_SECURITY_STACKING_DEBUG + if (file->f_security) { + pr_info("%s: Inbound file blob is not NULL.\n", __func__); + return 0; + } +#endif + if (blob_sizes.lbs_file == 0) + return 0; + + file->f_security = kzalloc(blob_sizes.lbs_file, GFP_KERNEL); + if (file->f_security == NULL) + return -ENOMEM; + return 0; } /* @@ -865,12 +892,19 @@ int security_file_permission(struct file *file, int mask) int security_file_alloc(struct file *file) { + int rc = lsm_file_alloc(file); + + if (rc) + return rc; return call_int_hook(file_alloc_security, 0, file); } void security_file_free(struct file *file) { call_void_hook(file_free_security, file); + + kfree(file->f_security); + file->f_security = NULL; } int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 04c8e9a..72121575 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -126,7 +126,6 @@ int selinux_enabled = 1; #endif static struct kmem_cache *sel_inode_cache; -static struct kmem_cache *file_security_cache; /** * selinux_secmark_enabled - Check to see if SECMARK is currently enabled @@ -355,27 +354,15 @@ static void inode_free_security(struct inode *inode) static int file_alloc_security(struct file *file) { - struct file_security_struct *fsec; + struct file_security_struct *fsec = selinux_file(file); u32 sid = current_sid(); - fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL); - if (!fsec) - return -ENOMEM; - fsec->sid = sid; fsec->fown_sid = sid; - file->f_security = fsec; return 0; } -static void file_free_security(struct file *file) -{ - struct file_security_struct *fsec = selinux_file(file); - file->f_security = NULL; - kmem_cache_free(file_security_cache, fsec); -} - static int superblock_alloc_security(struct super_block *sb) { struct superblock_security_struct *sbsec; @@ -3330,11 +3317,6 @@ static int selinux_file_alloc_security(struct file *file) return file_alloc_security(file); } -static void selinux_file_free_security(struct file *file) -{ - file_free_security(file); -} - /* * Check whether a task has the ioctl permission and cmd * operation to an inode. @@ -6004,6 +5986,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) struct lsm_blob_sizes selinux_blob_sizes = { .lbs_cred = sizeof(struct task_security_struct), + .lbs_file = sizeof(struct file_security_struct), }; static struct security_hook_list selinux_hooks[] = { @@ -6072,7 +6055,6 @@ static struct security_hook_list selinux_hooks[] = { LSM_HOOK_INIT(file_permission, selinux_file_permission), LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), - LSM_HOOK_INIT(file_free_security, selinux_file_free_security), LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), LSM_HOOK_INIT(mmap_file, selinux_mmap_file), LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), @@ -6247,9 +6229,6 @@ static __init int selinux_init(void) sel_inode_cache = kmem_cache_create("selinux_inode_security", sizeof(struct inode_security_struct), 0, SLAB_PANIC, NULL); - file_security_cache = kmem_cache_create("selinux_file_security", - sizeof(struct file_security_struct), - 0, SLAB_PANIC, NULL); avc_init(); security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); diff --git a/security/smack/smack.h b/security/smack/smack.h index d95c56d..d941c48 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -349,7 +349,7 @@ static inline struct task_smack *smack_cred(const struct cred *cred) return cred->security; } -static inline struct smack_known *smack_file(const struct file *file) +static inline struct smack_known **smack_file(const struct file *file) { return file->f_security; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index be7b3e6..3833e6e 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1588,25 +1588,13 @@ static void smack_inode_getsecid(struct inode *inode, u32 *secid) */ static int smack_file_alloc_security(struct file *file) { - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_file(file); - file->f_security = skp; + *blob = smk_of_current(); return 0; } /** - * smack_file_free_security - clear a file security blob - * @file: the object - * - * The security blob for a file is a pointer to the master - * label list, so no memory is freed. - */ -static void smack_file_free_security(struct file *file) -{ - file->f_security = NULL; -} - -/** * smack_file_ioctl - Smack check on ioctls * @file: the object * @cmd: what to do @@ -1818,7 +1806,9 @@ static int smack_mmap_file(struct file *file, */ static void smack_file_set_fowner(struct file *file) { - file->f_security = smk_of_current(); + struct smack_known **blob = smack_file(file); + + *blob = smk_of_current(); } /** @@ -1835,6 +1825,7 @@ static void smack_file_set_fowner(struct file *file) static int smack_file_send_sigiotask(struct task_struct *tsk, struct fown_struct *fown, int signum) { + struct smack_known **blob; struct smack_known *skp; struct smack_known *tkp = smk_of_task(smack_cred(tsk->cred)); struct file *file; @@ -1847,7 +1838,8 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, file = container_of(fown, struct file, f_owner); /* we don't log here as rc can be overriden */ - skp = smack_file(file); + blob = smack_file(file); + skp = *blob; rc = smk_access(skp, tkp, MAY_WRITE, NULL); rc = smk_bu_note("sigiotask", skp, tkp, MAY_WRITE, rc); if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) @@ -4587,6 +4579,7 @@ static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) struct lsm_blob_sizes smack_blob_sizes = { .lbs_cred = sizeof(struct task_smack), + .lbs_file = sizeof(struct smack_known *), }; static struct security_hook_list smack_hooks[] = { @@ -4626,7 +4619,6 @@ static struct security_hook_list smack_hooks[] = { LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid), LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security), - LSM_HOOK_INIT(file_free_security, smack_file_free_security), LSM_HOOK_INIT(file_ioctl, smack_file_ioctl), LSM_HOOK_INIT(file_lock, smack_file_lock), LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),